From 6b8b20d0c91e1b05dfdc3956d049758c0cf42942 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Thu, 17 Aug 2023 14:09:51 +0000 Subject: [PATCH] delete preview for 2578 --- .../assets/elements_diagram.svg | 162 -- .../assets/parents_diagram.svg | 136 -- .../AbstractAlgebra/constructors/index.html | 5 - .../AbstractAlgebra/direct_sum/index.html | 240 --- .../euclidean_interface/index.html | 2 - .../extending_abstractalgebra/index.html | 98 -- .../PR2578/AbstractAlgebra/field/index.html | 4 - .../field_interface/index.html | 2 - .../field_introduction/index.html | 2 - .../AbstractAlgebra/finfield/index.html | 55 - .../AbstractAlgebra/fraction/index.html | 190 --- .../fraction_interface/index.html | 2 - .../free_associative_algebra/index.html | 94 -- .../AbstractAlgebra/free_module/index.html | 24 - .../AbstractAlgebra/function_field/index.html | 223 --- .../AbstractAlgebra/functional_map/index.html | 17 - .../PR2578/AbstractAlgebra/ideal/index.html | 75 - previews/PR2578/AbstractAlgebra/img/types.dia | Bin 2988 -> 0 bytes previews/PR2578/AbstractAlgebra/img/types.png | Bin 17647 -> 0 bytes previews/PR2578/AbstractAlgebra/index.html | 44 - .../PR2578/AbstractAlgebra/integer/index.html | 60 - .../interface_introduction/index.html | 2 - .../laurent_mpolynomial/index.html | 27 - .../laurent_polynomial/index.html | 49 - .../AbstractAlgebra/map_cache/index.html | 36 - .../AbstractAlgebra/map_interface/index.html | 8 - .../map_introduction/index.html | 2 - .../map_with_inverse/index.html | 51 - .../PR2578/AbstractAlgebra/mathjaxhelper.js | 10 - .../PR2578/AbstractAlgebra/matrix/index.html | 928 ----------- .../matrix_algebras/index.html | 40 - .../matrix_interface/index.html | 16 - .../matrix_introduction/index.html | 2 - .../PR2578/AbstractAlgebra/misc/index.html | 102 -- .../PR2578/AbstractAlgebra/module/index.html | 96 -- .../module_homomorphism/index.html | 54 - .../module_interface/index.html | 2 - .../module_introduction/index.html | 2 - .../mpoly_interface/index.html | 6 - .../AbstractAlgebra/mpolynomial/index.html | 424 ----- .../PR2578/AbstractAlgebra/mseries/index.html | 78 - .../AbstractAlgebra/ncpolynomial/index.html | 213 --- .../ncring_interface/index.html | 3 - .../AbstractAlgebra/numberfield/index.html | 10 - .../PR2578/AbstractAlgebra/perm/index.html | 188 --- .../AbstractAlgebra/poly_interface/index.html | 4 - .../AbstractAlgebra/polynomial/index.html | 508 ------ .../PR2578/AbstractAlgebra/puiseux/index.html | 157 -- .../quotient_module/index.html | 69 - .../PR2578/AbstractAlgebra/rand/index.html | 53 - .../AbstractAlgebra/rational/index.html | 58 - .../PR2578/AbstractAlgebra/real/index.html | 51 - .../PR2578/AbstractAlgebra/residue/index.html | 132 -- .../residue_interface/index.html | 3 - .../PR2578/AbstractAlgebra/ring/index.html | 27 - .../AbstractAlgebra/ring_interface/index.html | 275 ---- .../ring_introduction/index.html | 2 - .../PR2578/AbstractAlgebra/series/index.html | 302 ---- .../series_interface/index.html | 18 - .../AbstractAlgebra/submodule/index.html | 86 - .../AbstractAlgebra/total_fraction/index.html | 108 -- .../PR2578/AbstractAlgebra/types/index.html | 18 - .../AbstractAlgebra/univpolynomial/index.html | 11 - .../visualizing_types/index.html | 2 - .../PR2578/AbstractAlgebra/ytabs/index.html | 260 --- .../AffineAlgebraicSet/index.html | 72 - .../ProjectiveAlgebraicSet/index.html | 41 - .../AffineVariety/index.html | 23 - .../ProjectiveVariety/index.html | 23 - .../Curves/para_rational_curves/index.html | 49 - .../Miscellaneous/miscellaneous/index.html | 9 - .../RationalPoints/Affine/index.html | 20 - .../RationalPoints/Projective/index.html | 17 - .../Schemes/AffineSchemes/index.html | 471 ------ .../ArchitectureOfAffineSchemes/index.html | 24 - .../Schemes/CoveredSchemes/index.html | 142 -- .../Schemes/CoveringsAndGlueings/index.html | 133 -- .../Schemes/GeneralSchemes/index.html | 4 - .../MorphismsOfAffineSchemes/index.html | 284 ---- .../MorphismsOfProjectiveSchemes/index.html | 33 - .../Schemes/ProjectiveSchemes/index.html | 201 --- .../Schemes/intro/index.html | 2 - .../Surfaces/K3Surfaces/index.html | 4 - .../Surfaces/SurfacesP4/index.html | 2 - .../ToricVarieties/AlgebraicCycles/index.html | 205 --- .../CohomologyClasses/index.html | 179 --- .../CyclicQuotientSingularities/index.html | 59 - .../NormalToricVarieties/index.html | 418 ----- .../ToricVarieties/Subvarieties/index.html | 50 - .../ToricDivisorClasses/index.html | 65 - .../ToricVarieties/ToricDivisors/index.html | 130 -- .../ToricLineBundles/index.html | 142 -- .../ToricVarieties/ToricMorphisms/index.html | 163 -- .../ToricVarieties/cohomCalg/index.html | 69 - .../ToricVarieties/intro/index.html | 2 - .../TropicalGeometry/curve/index.html | 174 -- .../TropicalGeometry/intro/index.html | 214 --- .../PR2578/AlgebraicGeometry/intro/index.html | 2 - .../PR2578/Combinatorics/graphs/index.html | 225 --- .../PR2578/Combinatorics/intro/index.html | 2 - .../PR2578/Combinatorics/matroids/index.html | 410 ----- .../Combinatorics/partitions/index.html | 74 - .../schur_polynomials/index.html | 18 - .../simplicialcomplexes/index.html | 66 - .../PR2578/Combinatorics/tableaux/index.html | 21 - .../module_localizations/index.html | 8 - .../FrameWorks/ring_localizations/index.html | 4 - .../GroebnerBases/groebner_bases/index.html | 429 ----- .../groebner_bases_integers/index.html | 22 - .../GroebnerBases/orderings/index.html | 443 ------ .../Miscellaneous/binomial_ideals/index.html | 106 -- .../complexes/index.html | 119 -- .../free_modules/index.html | 404 ----- .../hom_operations/index.html | 2 - .../homological_algebra/index.html | 728 --------- .../intro/index.html | 2 - .../module_operations/index.html | 411 ----- .../subquotients/index.html | 1416 ----------------- .../affine_algebras/index.html | 1123 ------------- .../CommutativeAlgebra/ideals/index.html | 811 ---------- .../CommutativeAlgebra/intro/index.html | 2 - .../localizations/index.html | 487 ------ .../CommutativeAlgebra/rings/index.html | 626 -------- .../AbstractCollection/index.html | 9 - .../SubObjectIterator/index.html | 49 - .../debugging/index.html | 60 - .../design_decisions/index.html | 5 - .../documentation/index.html | 25 - .../gap_integration/index.html | 56 - .../new_developers/index.html | 7 - .../printing_details/index.html | 120 -- .../serialization/index.html | 34 - .../styleguide/index.html | 45 - .../FTheoryTools/hypersurface/index.html | 118 -- .../FTheoryTools/introduction/index.html | 2 - .../FTheoryTools/literature/index.html | 308 ---- .../Experimental/FTheoryTools/tate/index.html | 159 -- .../FTheoryTools/weierstrass/index.html | 86 - .../ideals_and_subalgebras/index.html | 2 - .../LieAlgebras/introduction/index.html | 2 - .../LieAlgebras/lie_algebras/index.html | 101 -- .../LieAlgebras/modules/index.html | 4 - .../LinearQuotients/cox_rings/index.html | 2 - .../LinearQuotients/introduction/index.html | 2 - .../linear_quotients/index.html | 2 - .../OrthogonalDiscriminants/access/index.html | 23 - .../introduction/index.html | 2 - .../OrthogonalDiscriminants/misc/index.html | 4 - .../PlaneCurve/divisors/index.html | 189 --- .../PlaneCurve/elliptic_curves/index.html | 131 -- .../PlaneCurve/introduction/index.html | 2 - .../PlaneCurve/non_plane_curves/index.html | 77 - .../PlaneCurve/plane_curves/index.html | 293 ---- .../QuadFormAndIsom/enumeration/index.html | 118 -- .../QuadFormAndIsom/introduction/index.html | 17 - .../QuadFormAndIsom/latwithisom/index.html | 1057 ------------ .../QuadFormAndIsom/primembed/index.html | 24 - .../QuadFormAndIsom/spacewithisom/index.html | 419 ----- .../Singularities/intro/index.html | 2 - .../Singularities/space_germs/index.html | 7 - .../affine_toric_schemes/index.html | 9 - .../ToricSchemes/introduction/index.html | 2 - .../normal_toric_schemes/index.html | 35 - previews/PR2578/Experimental/intro/index.html | 11 - .../Fields/algebraic_closure_fp/index.html | 11 - previews/PR2578/Fields/intro/index.html | 2 - .../PR2578/General/architecture/index.html | 2 - previews/PR2578/General/complex/index.html | 2 - previews/PR2578/General/faq/index.html | 18 - previews/PR2578/General/other/index.html | 20 - .../PR2578/General/serialization/index.html | 51 - previews/PR2578/Groups/action/index.html | 189 --- previews/PR2578/Groups/autgroup/index.html | 98 -- previews/PR2578/Groups/basics/index.html | 144 -- previews/PR2578/Groups/fpgroup/index.html | 55 - .../PR2578/Groups/group_characters/index.html | 337 ---- previews/PR2578/Groups/grouphom/index.html | 88 - previews/PR2578/Groups/grouplib/index.html | 247 --- previews/PR2578/Groups/intro/index.html | 2 - previews/PR2578/Groups/matgroup/index.html | 99 -- previews/PR2578/Groups/pcgroup/index.html | 41 - previews/PR2578/Groups/permgroup/index.html | 383 ----- previews/PR2578/Groups/products/index.html | 151 -- previews/PR2578/Groups/quotients/index.html | 38 - previews/PR2578/Groups/subgroups/index.html | 284 ---- previews/PR2578/Hecke/FacElem/index.html | 9 - previews/PR2578/Hecke/Hecke.bib | 96 -- .../PR2578/Hecke/abelian/elements/index.html | 16 - .../Hecke/abelian/introduction/index.html | 6 - previews/PR2578/Hecke/abelian/maps/index.html | 20 - .../Hecke/abelian/structural/index.html | 99 -- .../Hecke/class_fields/intro/index.html | 16 - previews/PR2578/Hecke/css/extra.css | 64 - previews/PR2578/Hecke/dev/test/index.html | 35 - .../Hecke/elliptic_curves/basics/index.html | 51 - .../elliptic_curves/finite_fields/index.html | 62 - .../Hecke/elliptic_curves/intro/index.html | 2 - .../elliptic_curves/number_fields/index.html | 2 - previews/PR2578/Hecke/examples/index.html | 2 - .../Hecke/examples/reduction/index.html | 18 - .../PR2578/Hecke/features/macros/index.html | 143 -- .../Hecke/function_fields/basics/index.html | 2 - .../degree_localization/index.html | 2 - .../Hecke/function_fields/elements/index.html | 2 - .../Hecke/function_fields/internal/index.html | 2 - .../Hecke/function_fields/intro/index.html | 2 - previews/PR2578/Hecke/index.html | 32 - previews/PR2578/Hecke/misc/Map/index.html | 16 - .../PR2578/Hecke/misc/conjugacy/index.html | 15 - previews/PR2578/Hecke/misc/index.html | 25 - .../complex_embeddings/index.html | 135 -- .../number_fields/conventions/index.html | 11 - .../Hecke/number_fields/elements/index.html | 14 - .../Hecke/number_fields/fields/index.html | 59 - .../Hecke/number_fields/internal/index.html | 2 - .../Hecke/number_fields/intro/index.html | 2 - .../PR2578/Hecke/orders/elements/index.html | 37 - .../Hecke/orders/frac_ideals/index.html | 6 - .../PR2578/Hecke/orders/ideals/index.html | 112 -- .../Hecke/orders/introduction/index.html | 22 - .../PR2578/Hecke/orders/orders/index.html | 11 - .../PR2578/Hecke/pmat/introduction/index.html | 16 - .../Hecke/quad_forms/Zgenera/index.html | 5 - .../PR2578/Hecke/quad_forms/basics/index.html | 62 - .../quad_forms/discriminant_group/index.html | 228 --- .../Hecke/quad_forms/genusherm/index.html | 139 -- .../quad_forms/integer_lattices/index.html | 341 ---- .../Hecke/quad_forms/introduction/index.html | 2 - .../Hecke/quad_forms/lattices/index.html | 262 --- previews/PR2578/Hecke/sparse/intro/index.html | 5 - .../InvariantTheory/finite_groups/index.html | 534 ------- .../PR2578/InvariantTheory/intro/index.html | 2 - .../reductive_groups/index.html | 2 - .../PR2578/LinearAlgebra/intro/index.html | 2 - previews/PR2578/Nemo/about/index.html | 2 - previews/PR2578/Nemo/acb/index.html | 184 --- previews/PR2578/Nemo/algebraic/index.html | 92 -- previews/PR2578/Nemo/arb/index.html | 115 -- previews/PR2578/Nemo/complex/index.html | 83 - previews/PR2578/Nemo/constructors/index.html | 4 - .../Nemo/developer/conventions/index.html | 2 - .../PR2578/Nemo/developer/future/index.html | 2 - previews/PR2578/Nemo/developer/img/types.svg | 3 - previews/PR2578/Nemo/developer/img/types2.svg | 3 - .../Nemo/developer/interfaces/index.html | 2 - .../Nemo/developer/introduction/index.html | 7 - .../PR2578/Nemo/developer/parents/index.html | 12 - .../PR2578/Nemo/developer/topics/index.html | 6 - .../Nemo/developer/typesystem/index.html | 2 - previews/PR2578/Nemo/exact/index.html | 172 -- previews/PR2578/Nemo/factor/index.html | 21 - previews/PR2578/Nemo/ff_embedding/index.html | 32 - previews/PR2578/Nemo/finitefield/index.html | 73 - previews/PR2578/Nemo/fraction/index.html | 36 - previews/PR2578/Nemo/gfp/index.html | 11 - previews/PR2578/Nemo/img/types.dia | Bin 2988 -> 0 bytes previews/PR2578/Nemo/img/types.png | Bin 17647 -> 0 bytes previews/PR2578/Nemo/index.html | 74 - previews/PR2578/Nemo/integer/index.html | 184 --- previews/PR2578/Nemo/mathjaxhelper.js | 10 - previews/PR2578/Nemo/matrix/index.html | 104 -- previews/PR2578/Nemo/misc/index.html | 16 - previews/PR2578/Nemo/mpolynomial/index.html | 2 - previews/PR2578/Nemo/numberfield/index.html | 43 - previews/PR2578/Nemo/padic/index.html | 42 - previews/PR2578/Nemo/polynomial/index.html | 66 - previews/PR2578/Nemo/puiseux/index.html | 12 - previews/PR2578/Nemo/qadic/index.html | 87 - previews/PR2578/Nemo/rational/index.html | 2 - previews/PR2578/Nemo/real/index.html | 225 --- previews/PR2578/Nemo/residue/index.html | 6 - previews/PR2578/Nemo/series/index.html | 27 - previews/PR2578/Nemo/types/index.html | 2 - .../PBWAlgebras/creation/index.html | 90 -- .../PBWAlgebras/ideals/index.html | 335 ---- .../PBWAlgebras/intro/index.html | 2 - .../PBWAlgebras/quotients/index.html | 88 - .../free_associative_algebra/index.html | 3 - .../NoncommutativeAlgebra/intro/index.html | 2 - .../NumberTheory/abelian_closure/index.html | 25 - .../PR2578/NumberTheory/galois/index.html | 162 -- previews/PR2578/NumberTheory/intro/index.html | 2 - .../Polyhedra/auxiliary/index.html | 559 ------- .../Polyhedra/constructions/index.html | 351 ---- .../Polyhedra/intro/index.html | 2 - .../Polyhedra/polymake/index.html | 42 - .../PolyhedralGeometry/cones/index.html | 196 --- .../PR2578/PolyhedralGeometry/fans/index.html | 306 ---- .../PolyhedralGeometry/intro/index.html | 53 - .../linear_programs/index.html | 115 -- .../mixed_integer_linear_programs/index.html | 45 - .../polyhedral_complexes/index.html | 251 --- .../subdivisions_of_points/index.html | 114 -- previews/PR2578/Rings/integer/index.html | 225 --- previews/PR2578/Rings/intro/index.html | 2 - previews/PR2578/Rings/rational/index.html | 107 -- .../abstractalgebra/index.html | 140 -- .../StraightLinePrograms/gapslps/index.html | 91 -- .../StraightLinePrograms/intro/index.html | 134 -- previews/PR2578/assets/documenter.js | 331 ---- previews/PR2578/assets/logo.png | Bin 15093 -> 0 bytes previews/PR2578/assets/search.js | 267 ---- .../PR2578/assets/themes/documenter-dark.css | 7 - .../PR2578/assets/themes/documenter-light.css | 9 - previews/PR2578/assets/themeswap.js | 66 - previews/PR2578/assets/warner.js | 49 - previews/PR2578/index.html | 2 - previews/PR2578/manualindex/index.html | 2 - previews/PR2578/references/index.html | 450 ------ previews/PR2578/search/index.html | 2 - previews/PR2578/search_index.js | 3 - previews/PR2578/siteinfo.js | 1 - 312 files changed, 32342 deletions(-) delete mode 100644 previews/PR2578/AbstractAlgebra/assets/elements_diagram.svg delete mode 100644 previews/PR2578/AbstractAlgebra/assets/parents_diagram.svg delete mode 100644 previews/PR2578/AbstractAlgebra/constructors/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/direct_sum/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/euclidean_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/extending_abstractalgebra/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/field/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/field_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/field_introduction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/finfield/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/fraction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/fraction_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/free_associative_algebra/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/free_module/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/function_field/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/functional_map/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/ideal/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/img/types.dia delete mode 100644 previews/PR2578/AbstractAlgebra/img/types.png delete mode 100644 previews/PR2578/AbstractAlgebra/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/integer/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/interface_introduction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/laurent_mpolynomial/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/laurent_polynomial/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/map_cache/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/map_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/map_introduction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/map_with_inverse/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/mathjaxhelper.js delete mode 100644 previews/PR2578/AbstractAlgebra/matrix/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/matrix_algebras/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/matrix_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/matrix_introduction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/misc/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/module/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/module_homomorphism/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/module_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/module_introduction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/mpoly_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/mpolynomial/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/mseries/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/ncpolynomial/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/ncring_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/numberfield/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/perm/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/poly_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/polynomial/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/puiseux/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/quotient_module/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/rand/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/rational/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/real/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/residue/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/residue_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/ring/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/ring_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/ring_introduction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/series/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/series_interface/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/submodule/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/total_fraction/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/types/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/univpolynomial/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/visualizing_types/index.html delete mode 100644 previews/PR2578/AbstractAlgebra/ytabs/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/AffineVariety/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Curves/para_rational_curves/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/RationalPoints/Affine/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/RationalPoints/Projective/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/AffineSchemes/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/CoveredSchemes/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/CoveringsAndGlueings/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/GeneralSchemes/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Schemes/intro/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Surfaces/K3Surfaces/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/Surfaces/SurfacesP4/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/Subvarieties/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/ToricVarieties/intro/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/TropicalGeometry/curve/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/TropicalGeometry/intro/index.html delete mode 100644 previews/PR2578/AlgebraicGeometry/intro/index.html delete mode 100644 previews/PR2578/Combinatorics/graphs/index.html delete mode 100644 previews/PR2578/Combinatorics/intro/index.html delete mode 100644 previews/PR2578/Combinatorics/matroids/index.html delete mode 100644 previews/PR2578/Combinatorics/partitions/index.html delete mode 100644 previews/PR2578/Combinatorics/schur_polynomials/index.html delete mode 100644 previews/PR2578/Combinatorics/simplicialcomplexes/index.html delete mode 100644 previews/PR2578/Combinatorics/tableaux/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/FrameWorks/module_localizations/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/FrameWorks/ring_localizations/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/GroebnerBases/orderings/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/complexes/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/intro/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/affine_algebras/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/ideals/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/intro/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/localizations/index.html delete mode 100644 previews/PR2578/CommutativeAlgebra/rings/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/AbstractCollection/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/SubObjectIterator/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/debugging/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/design_decisions/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/documentation/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/gap_integration/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/new_developers/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/printing_details/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/serialization/index.html delete mode 100644 previews/PR2578/DeveloperDocumentation/styleguide/index.html delete mode 100644 previews/PR2578/Experimental/FTheoryTools/hypersurface/index.html delete mode 100644 previews/PR2578/Experimental/FTheoryTools/introduction/index.html delete mode 100644 previews/PR2578/Experimental/FTheoryTools/literature/index.html delete mode 100644 previews/PR2578/Experimental/FTheoryTools/tate/index.html delete mode 100644 previews/PR2578/Experimental/FTheoryTools/weierstrass/index.html delete mode 100644 previews/PR2578/Experimental/LieAlgebras/ideals_and_subalgebras/index.html delete mode 100644 previews/PR2578/Experimental/LieAlgebras/introduction/index.html delete mode 100644 previews/PR2578/Experimental/LieAlgebras/lie_algebras/index.html delete mode 100644 previews/PR2578/Experimental/LieAlgebras/modules/index.html delete mode 100644 previews/PR2578/Experimental/LinearQuotients/cox_rings/index.html delete mode 100644 previews/PR2578/Experimental/LinearQuotients/introduction/index.html delete mode 100644 previews/PR2578/Experimental/LinearQuotients/linear_quotients/index.html delete mode 100644 previews/PR2578/Experimental/OrthogonalDiscriminants/access/index.html delete mode 100644 previews/PR2578/Experimental/OrthogonalDiscriminants/introduction/index.html delete mode 100644 previews/PR2578/Experimental/OrthogonalDiscriminants/misc/index.html delete mode 100644 previews/PR2578/Experimental/PlaneCurve/divisors/index.html delete mode 100644 previews/PR2578/Experimental/PlaneCurve/elliptic_curves/index.html delete mode 100644 previews/PR2578/Experimental/PlaneCurve/introduction/index.html delete mode 100644 previews/PR2578/Experimental/PlaneCurve/non_plane_curves/index.html delete mode 100644 previews/PR2578/Experimental/PlaneCurve/plane_curves/index.html delete mode 100644 previews/PR2578/Experimental/QuadFormAndIsom/enumeration/index.html delete mode 100644 previews/PR2578/Experimental/QuadFormAndIsom/introduction/index.html delete mode 100644 previews/PR2578/Experimental/QuadFormAndIsom/latwithisom/index.html delete mode 100644 previews/PR2578/Experimental/QuadFormAndIsom/primembed/index.html delete mode 100644 previews/PR2578/Experimental/QuadFormAndIsom/spacewithisom/index.html delete mode 100644 previews/PR2578/Experimental/Singularities/intro/index.html delete mode 100644 previews/PR2578/Experimental/Singularities/space_germs/index.html delete mode 100644 previews/PR2578/Experimental/ToricSchemes/affine_toric_schemes/index.html delete mode 100644 previews/PR2578/Experimental/ToricSchemes/introduction/index.html delete mode 100644 previews/PR2578/Experimental/ToricSchemes/normal_toric_schemes/index.html delete mode 100644 previews/PR2578/Experimental/intro/index.html delete mode 100644 previews/PR2578/Fields/algebraic_closure_fp/index.html delete mode 100644 previews/PR2578/Fields/intro/index.html delete mode 100644 previews/PR2578/General/architecture/index.html delete mode 100644 previews/PR2578/General/complex/index.html delete mode 100644 previews/PR2578/General/faq/index.html delete mode 100644 previews/PR2578/General/other/index.html delete mode 100644 previews/PR2578/General/serialization/index.html delete mode 100644 previews/PR2578/Groups/action/index.html delete mode 100644 previews/PR2578/Groups/autgroup/index.html delete mode 100644 previews/PR2578/Groups/basics/index.html delete mode 100644 previews/PR2578/Groups/fpgroup/index.html delete mode 100644 previews/PR2578/Groups/group_characters/index.html delete mode 100644 previews/PR2578/Groups/grouphom/index.html delete mode 100644 previews/PR2578/Groups/grouplib/index.html delete mode 100644 previews/PR2578/Groups/intro/index.html delete mode 100644 previews/PR2578/Groups/matgroup/index.html delete mode 100644 previews/PR2578/Groups/pcgroup/index.html delete mode 100644 previews/PR2578/Groups/permgroup/index.html delete mode 100644 previews/PR2578/Groups/products/index.html delete mode 100644 previews/PR2578/Groups/quotients/index.html delete mode 100644 previews/PR2578/Groups/subgroups/index.html delete mode 100644 previews/PR2578/Hecke/FacElem/index.html delete mode 100644 previews/PR2578/Hecke/Hecke.bib delete mode 100644 previews/PR2578/Hecke/abelian/elements/index.html delete mode 100644 previews/PR2578/Hecke/abelian/introduction/index.html delete mode 100644 previews/PR2578/Hecke/abelian/maps/index.html delete mode 100644 previews/PR2578/Hecke/abelian/structural/index.html delete mode 100644 previews/PR2578/Hecke/class_fields/intro/index.html delete mode 100644 previews/PR2578/Hecke/css/extra.css delete mode 100644 previews/PR2578/Hecke/dev/test/index.html delete mode 100644 previews/PR2578/Hecke/elliptic_curves/basics/index.html delete mode 100644 previews/PR2578/Hecke/elliptic_curves/finite_fields/index.html delete mode 100644 previews/PR2578/Hecke/elliptic_curves/intro/index.html delete mode 100644 previews/PR2578/Hecke/elliptic_curves/number_fields/index.html delete mode 100644 previews/PR2578/Hecke/examples/index.html delete mode 100644 previews/PR2578/Hecke/examples/reduction/index.html delete mode 100644 previews/PR2578/Hecke/features/macros/index.html delete mode 100644 previews/PR2578/Hecke/function_fields/basics/index.html delete mode 100644 previews/PR2578/Hecke/function_fields/degree_localization/index.html delete mode 100644 previews/PR2578/Hecke/function_fields/elements/index.html delete mode 100644 previews/PR2578/Hecke/function_fields/internal/index.html delete mode 100644 previews/PR2578/Hecke/function_fields/intro/index.html delete mode 100644 previews/PR2578/Hecke/index.html delete mode 100644 previews/PR2578/Hecke/misc/Map/index.html delete mode 100644 previews/PR2578/Hecke/misc/conjugacy/index.html delete mode 100644 previews/PR2578/Hecke/misc/index.html delete mode 100644 previews/PR2578/Hecke/number_fields/complex_embeddings/index.html delete mode 100644 previews/PR2578/Hecke/number_fields/conventions/index.html delete mode 100644 previews/PR2578/Hecke/number_fields/elements/index.html delete mode 100644 previews/PR2578/Hecke/number_fields/fields/index.html delete mode 100644 previews/PR2578/Hecke/number_fields/internal/index.html delete mode 100644 previews/PR2578/Hecke/number_fields/intro/index.html delete mode 100644 previews/PR2578/Hecke/orders/elements/index.html delete mode 100644 previews/PR2578/Hecke/orders/frac_ideals/index.html delete mode 100644 previews/PR2578/Hecke/orders/ideals/index.html delete mode 100644 previews/PR2578/Hecke/orders/introduction/index.html delete mode 100644 previews/PR2578/Hecke/orders/orders/index.html delete mode 100644 previews/PR2578/Hecke/pmat/introduction/index.html delete mode 100644 previews/PR2578/Hecke/quad_forms/Zgenera/index.html delete mode 100644 previews/PR2578/Hecke/quad_forms/basics/index.html delete mode 100644 previews/PR2578/Hecke/quad_forms/discriminant_group/index.html delete mode 100644 previews/PR2578/Hecke/quad_forms/genusherm/index.html delete mode 100644 previews/PR2578/Hecke/quad_forms/integer_lattices/index.html delete mode 100644 previews/PR2578/Hecke/quad_forms/introduction/index.html delete mode 100644 previews/PR2578/Hecke/quad_forms/lattices/index.html delete mode 100644 previews/PR2578/Hecke/sparse/intro/index.html delete mode 100644 previews/PR2578/InvariantTheory/finite_groups/index.html delete mode 100644 previews/PR2578/InvariantTheory/intro/index.html delete mode 100644 previews/PR2578/InvariantTheory/reductive_groups/index.html delete mode 100644 previews/PR2578/LinearAlgebra/intro/index.html delete mode 100644 previews/PR2578/Nemo/about/index.html delete mode 100644 previews/PR2578/Nemo/acb/index.html delete mode 100644 previews/PR2578/Nemo/algebraic/index.html delete mode 100644 previews/PR2578/Nemo/arb/index.html delete mode 100644 previews/PR2578/Nemo/complex/index.html delete mode 100644 previews/PR2578/Nemo/constructors/index.html delete mode 100644 previews/PR2578/Nemo/developer/conventions/index.html delete mode 100644 previews/PR2578/Nemo/developer/future/index.html delete mode 100644 previews/PR2578/Nemo/developer/img/types.svg delete mode 100644 previews/PR2578/Nemo/developer/img/types2.svg delete mode 100644 previews/PR2578/Nemo/developer/interfaces/index.html delete mode 100644 previews/PR2578/Nemo/developer/introduction/index.html delete mode 100644 previews/PR2578/Nemo/developer/parents/index.html delete mode 100644 previews/PR2578/Nemo/developer/topics/index.html delete mode 100644 previews/PR2578/Nemo/developer/typesystem/index.html delete mode 100644 previews/PR2578/Nemo/exact/index.html delete mode 100644 previews/PR2578/Nemo/factor/index.html delete mode 100644 previews/PR2578/Nemo/ff_embedding/index.html delete mode 100644 previews/PR2578/Nemo/finitefield/index.html delete mode 100644 previews/PR2578/Nemo/fraction/index.html delete mode 100644 previews/PR2578/Nemo/gfp/index.html delete mode 100644 previews/PR2578/Nemo/img/types.dia delete mode 100644 previews/PR2578/Nemo/img/types.png delete mode 100644 previews/PR2578/Nemo/index.html delete mode 100644 previews/PR2578/Nemo/integer/index.html delete mode 100644 previews/PR2578/Nemo/mathjaxhelper.js delete mode 100644 previews/PR2578/Nemo/matrix/index.html delete mode 100644 previews/PR2578/Nemo/misc/index.html delete mode 100644 previews/PR2578/Nemo/mpolynomial/index.html delete mode 100644 previews/PR2578/Nemo/numberfield/index.html delete mode 100644 previews/PR2578/Nemo/padic/index.html delete mode 100644 previews/PR2578/Nemo/polynomial/index.html delete mode 100644 previews/PR2578/Nemo/puiseux/index.html delete mode 100644 previews/PR2578/Nemo/qadic/index.html delete mode 100644 previews/PR2578/Nemo/rational/index.html delete mode 100644 previews/PR2578/Nemo/real/index.html delete mode 100644 previews/PR2578/Nemo/residue/index.html delete mode 100644 previews/PR2578/Nemo/series/index.html delete mode 100644 previews/PR2578/Nemo/types/index.html delete mode 100644 previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/creation/index.html delete mode 100644 previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html delete mode 100644 previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/intro/index.html delete mode 100644 previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html delete mode 100644 previews/PR2578/NoncommutativeAlgebra/free_associative_algebra/index.html delete mode 100644 previews/PR2578/NoncommutativeAlgebra/intro/index.html delete mode 100644 previews/PR2578/NumberTheory/abelian_closure/index.html delete mode 100644 previews/PR2578/NumberTheory/galois/index.html delete mode 100644 previews/PR2578/NumberTheory/intro/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/Polyhedra/auxiliary/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/Polyhedra/constructions/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/Polyhedra/intro/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/Polyhedra/polymake/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/cones/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/fans/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/intro/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/linear_programs/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/mixed_integer_linear_programs/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/polyhedral_complexes/index.html delete mode 100644 previews/PR2578/PolyhedralGeometry/subdivisions_of_points/index.html delete mode 100644 previews/PR2578/Rings/integer/index.html delete mode 100644 previews/PR2578/Rings/intro/index.html delete mode 100644 previews/PR2578/Rings/rational/index.html delete mode 100644 previews/PR2578/StraightLinePrograms/abstractalgebra/index.html delete mode 100644 previews/PR2578/StraightLinePrograms/gapslps/index.html delete mode 100644 previews/PR2578/StraightLinePrograms/intro/index.html delete mode 100644 previews/PR2578/assets/documenter.js delete mode 100644 previews/PR2578/assets/logo.png delete mode 100644 previews/PR2578/assets/search.js delete mode 100644 previews/PR2578/assets/themes/documenter-dark.css delete mode 100644 previews/PR2578/assets/themes/documenter-light.css delete mode 100644 previews/PR2578/assets/themeswap.js delete mode 100644 previews/PR2578/assets/warner.js delete mode 100644 previews/PR2578/index.html delete mode 100644 previews/PR2578/manualindex/index.html delete mode 100644 previews/PR2578/references/index.html delete mode 100644 previews/PR2578/search/index.html delete mode 100644 previews/PR2578/search_index.js delete mode 100644 previews/PR2578/siteinfo.js diff --git a/previews/PR2578/AbstractAlgebra/assets/elements_diagram.svg b/previews/PR2578/AbstractAlgebra/assets/elements_diagram.svg deleted file mode 100644 index c1e1b07fd4fa..000000000000 --- a/previews/PR2578/AbstractAlgebra/assets/elements_diagram.svg +++ /dev/null @@ -1,162 +0,0 @@ -SetElemIdealElem{T}Map{D, C, S, T}SetMapIdentityMapFunctionalMapFPModuleHomomorphismGroupElemAbstractPermAdditiveGroupElemModuleElem{T}FPModuleElem{T}MatElem{T}NCRingElemMatAlgElem{T}NCPolyRingElem{T}RingElemPolyRingElem{T}SeriesElem{T}LaurentPolyRingElem{T}ResElem{T}FieldElemFinFieldElemResFieldElem{T}NumFieldElem{T}SimpleNumFieldElem{T}FracElem{T} \ No newline at end of file diff --git a/previews/PR2578/AbstractAlgebra/assets/parents_diagram.svg b/previews/PR2578/AbstractAlgebra/assets/parents_diagram.svg deleted file mode 100644 index b857bd6e8fe0..000000000000 --- a/previews/PR2578/AbstractAlgebra/assets/parents_diagram.svg +++ /dev/null @@ -1,136 +0,0 @@ -SetIdeal{T}GroupAbstractPermutationGroupAdditiveGroupModule{T}FPModule{T}MatSpace{T}NCRingMatAlgebra{T}NCPolyRing{T}RingFieldPolyRing{T}LaurentPolynomialRing{T}SeriesRing{T}ResidueRing{T}ResidueField{T}NumField{T}SimpleNumField{T}FracField{T}FinField \ No newline at end of file diff --git a/previews/PR2578/AbstractAlgebra/constructors/index.html b/previews/PR2578/AbstractAlgebra/constructors/index.html deleted file mode 100644 index 60bdac7536b8..000000000000 --- a/previews/PR2578/AbstractAlgebra/constructors/index.html +++ /dev/null @@ -1,5 +0,0 @@ - -Constructing mathematical objects in AbstractAlgebra.jl · Oscar.jl

Constructing mathematical objects in AbstractAlgebra.jl

Constructing objects in Julia

In Julia, one constructs objects of a given type by calling a type constructor. This is simply a function with the same name as the type itself. For example, to construct a BigInt object from an Int in Julia, we simply call the BigInt constructor:

n = BigInt(123)

Note that a number literal too big to fit in an Int or Int128 automatically creates a BigInt:

julia> typeof(12345678765456787654567890987654567898765678909876567890)
-BigInt

How we construct objects in AbstractAlgebra.jl

As we explain in Elements and parents, Julia types don't contain enough information to properly model groups, rings, fields, etc. Instead of using types to construct objects, we use special objects that we refer to as parent objects. They behave a lot like Julia types.

Consider the following simple example, to create a multiprecision integer:

n = ZZ(12345678765456787654567890987654567898765678909876567890)

Here ZZ is not a Julia type, but a callable object. However, for most purposes one can think of such a parent object as though it were a type.

Constructing parent objects

For more complicated groups, rings, fields, etc., one first needs to construct the parent object before one can use it to construct element objects.

AbstractAlgebra.jl provides a set of functions for constructing such parent objects. For example, to create a parent object for univariate polynomials over the integers, we use the polynomial_ring parent object constructor.

R, x = polynomial_ring(ZZ, "x")
-f = x^3 + 3x + 1
-g = R(12)

In this example, R is the parent object and we use it to convert the Int value $12$ to an element of the polynomial ring $\mathbb{Z}[x]$.

List of parent object constructors

For convenience, we provide a list of all the parent object constructors in AbstractAlgebra.jl and explain what mathematical domains they represent.

MathematicsAbstractAlgebra.jl constructor
$R = \mathbb{Z}$R = ZZ
$R = \mathbb{Q}$R = QQ
$R = \mathbb{F}_{p}$R = GF(p)
$R = \mathbb{Z}/n\mathbb{Z}$R = residue_ring(ZZ, n)
$S = R[x]$S, x = polynomial_ring(R, "x")
$S = R[x, y]$S, (x, y) = polynomial_ring(R, ["x", "y"])
$S = R[[x]]$ (to precision $n$)S, x = power_series_ring(R, n, "x")
$S = R((x))$ (to precision $n$)S, x = laurent_series_ring(R, n, "x")
$S = K((x))$ (to precision $n$)S, x = laurent_series_field(K, n, "x")
$S = \mathrm{Frac}_R$S = fraction_field(R)
$S = R/(f)$S = residue_ring(R, f)
$S = R/(f)$ (with $(f)$ maximal)S = residue_field(R, f)
$S = \mathrm{Mat}_{m\times n}(R)$S = matrix_space(R, m, n)
$S = \mathbb{Q}[x]/(f)$S, a = number_field(f, "a")
diff --git a/previews/PR2578/AbstractAlgebra/direct_sum/index.html b/previews/PR2578/AbstractAlgebra/direct_sum/index.html deleted file mode 100644 index 3fddbd95b7b7..000000000000 --- a/previews/PR2578/AbstractAlgebra/direct_sum/index.html +++ /dev/null @@ -1,240 +0,0 @@ - -Direct Sums · Oscar.jl

Direct Sums

AbstractAlgebra allows the construction of the external direct sum of any nonempty vector of finitely presented modules.

Note that external direct sums are considered equal iff they are the same object.

Generic direct sum type

AbstractAlgebra provides a generic direct sum type Generic.DirectSumModule{T} where T is the element type of the base ring. The implementation is in src/generic/DirectSum.jl

Elements of direct sum modules have type Generic.DirectSumModuleElem{T}.

Abstract types

Direct sum module types belong to the abstract type FPModule{T} and their elements to FPModuleElem{T}.

Constructors

direct_sumFunction
direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T

Given modules $M_1\dots M_n$, say, return the direct sum $\bigoplus_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical injections $M_i\to\bigoplus_{i=1}^n M_i$ if task = :sum (default),
  • a vector containing the canonical projections $\bigoplus_{i=1}^n M_i\to M_i$ if task = :prod,
  • two vectors containing the canonical injections and projections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_sum(M::Matroid, N::Matroid)

The direct sum of the matroids M and N. Optionally one can also pass a vector of matroids.

See Section 4.2 of James Oxley (2011).

To obtain the direct sum of the Fano and a uniform matroid type:

Examples

julia> direct_sum(fano_matroid(), uniform_matroid(2,4))
-Matroid of rank 5 on 11 elements

To take the sum of three uniform matroids use:

Examples

julia> matroids = Vector([uniform_matroid(2,4), uniform_matroid(1,3), uniform_matroid(3,4)]);
-
-julia> M = direct_sum(matroids)
-Matroid of rank 6 on 11 elements
source
direct_sum(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}
-direct_sum(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}

Given a collection of quadratic spaces with isometries $(V_1, f_1), \ldots, (V_n, f_n)$, return the quadratic space with isometry $(V, f)$ together with the injections $V_i \to V$, where V is the direct sum $V := V_1 \oplus \ldots \oplus V_n$ and f is the isometry of V induced by the diagonal actions of the $f_i$'s.

For objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(V, f)$ as a direct product with the projections $V \to V_i$, one should call direct_product(x). If one wants to obtain $(V, f)$ as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

Examples

julia> V1 = quadratic_space(QQ, QQ[2 5;
-                                   5 6])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[2   5]
-[5   6]
-
-julia> Vf1 = quadratic_space_with_isometry(V1, neg=true)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [-1    0]
-  [ 0   -1]
-
-julia> V2 = quadratic_space(QQ, QQ[ 2 -1;
-                                   -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> f = matrix(QQ, 2, 2, [1  1;
-                             0 -1])
-[1    1]
-[0   -1]
-
-julia> Vf2 = quadratic_space_with_isometry(V2, f)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
-
-julia> Vf3, inj = direct_sum(Vf1, Vf2)
-(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 2
-Codomain:
-=========
-Quadratic space of dimension 4, Map with following data
-Domain:
-=======
-Quadratic space of dimension 2
-Codomain:
-=========
-Quadratic space of dimension 4])
-
-julia> Vf3
-Quadratic space of dimension 4
-  with isometry of finite order 2
-  given by
-  [-1    0   0    0]
-  [ 0   -1   0    0]
-  [ 0    0   1    1]
-  [ 0    0   0   -1]
-
-julia> space(Vf3)
-Quadratic space of dimension 4
-  over rational field
-with gram matrix
-[2   5    0    0]
-[5   6    0    0]
-[0   0    2   -1]
-[0   0   -1    2]
source
direct_sum(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                   Vector{AbstractSpaceMor}
-direct_sum(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                   Vector{AbstractSpaceMor}

Given a collection of lattices with isometries $(L_1, f_1), \ldots, (L_n, f_n)$, return the lattice with isometry $(L, f)$ together with the injections $L_i \to L$, where L is the direct sum $L := L_1 \oplus \ldots \oplus L_n$ and f is the isometry of L induced by the diagonal actions of the $f_i$'s.

For objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(L, f)$ as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain $(L, f)$ as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> g = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lg = integer_lattice_with_isometry(L, g)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 5
-  given by
-  [1    1    1    1    1]
-  [0   -1   -1   -1   -1]
-  [0    1    0    0    0]
-  [0    0    1    0    0]
-  [0    0    0    1    0]
-
-julia> Lh, inj = direct_sum(Lf, Lg)
-(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 5
-Codomain:
-=========
-Quadratic space of dimension 10, Map with following data
-Domain:
-=======
-Quadratic space of dimension 5
-Codomain:
-=========
-Quadratic space of dimension 10])
-
-julia> Lh
-Integer lattice of rank 10 and degree 10
-  with isometry of finite order 10
-  given by
-  [ 1    0    0    0    0   0    0    0    0    0]
-  [-1   -1   -1   -1   -1   0    0    0    0    0]
-  [ 0    0    0    0    1   0    0    0    0    0]
-  [ 0    0    0    1    0   0    0    0    0    0]
-  [ 0    0    1    0    0   0    0    0    0    0]
-  [ 0    0    0    0    0   1    1    1    1    1]
-  [ 0    0    0    0    0   0   -1   -1   -1   -1]
-  [ 0    0    0    0    0   0    1    0    0    0]
-  [ 0    0    0    0    0   0    0    1    0    0]
-  [ 0    0    0    0    0   0    0    0    1    0]
source
direct_sum(G::GrpAbFinGen, H::GrpAbFinGen, V::Vector{<:Map{GrpAbFinGen, GrpAbFinGen}})

For groups G = prod G_i and H = prod H_i as well as maps V_i: G_i -> H_i, build the induced map from G -> H.

source
direct_sum(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}
-⊕(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}

Construct the direct sum of the modules V....

source
direct_sum(G::GrpAbFinGen...) -> GrpAbFinGen, Vector{GrpAbFinGenMap}

Return the direct sum $D$ of the (finitely many) abelian groups $G_i$, together with the injections $G_i \to D$.

For finite abelian groups, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $D$ as a direct product together with the projections $ D \to Gi$, one should call `directproduct(G...). If one wants to obtain $D$ as a biproduct together with the projections and the injections, one should callbiproduct(G...)`.

Otherwise, one could also call canonical_injections(D) or canonical_projections(D) later on.

direct_sum(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}
-direct_sum(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian spaces $V_1, \ldots, V_n$, return their direct sum $V := V_1 \oplus \ldots \oplus V_n$, together with the injections $V_i \to V$.

For objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct product with the projections $V \to V_i$, one should call direct_product(x). If one wants to obtain V as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

direct_sum(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
-direct_sum(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian lattices $L_1, \ldots, L_n$, return their direct sum $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$ (seen as maps between the corresponding ambient spaces).

For objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

direct_sum(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}
-direct_sum(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}

Given a collection of torsion quadratic modules $T_1, \ldots, T_n$, return their direct sum $T := T_1\oplus \ldots \oplus T_n$, together with the injections $T_i \to T$.

For objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct product with the projections $T \to T_i$, one should call direct_product(x). If one wants to obtain T as a biproduct with the injections $T_i \to T$ and the projections $T \to T_i$, one should call biproduct(x).

direct_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls

Return the isometry class of the direct sum of two representatives.

direct_sum(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}
-direct_sum(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}

Given a collection of $\mathbb Z$-lattices $L_1, \ldots, L_n$, return their direct sum $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$. (seen as maps between the corresponding ambient spaces).

For objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

direct_sum(S1::ZZLocalGenus, S2::ZZLocalGenus) -> ZZLocalGenus

Return the local genus of the direct sum of two representatives.

direct_sum(G1::ZZGenus, G2::ZZGenus) -> ZZGenus

Return the genus of the direct sum of G1 and G2.

The direct sum is defined via representatives.

direct_sum(g1::HermLocalGenus, g2::HermLocalGenus) -> HermLocalGenus

Given two local genus symbols g1 and g2 for hermitian lattices over $E/K$ at the same prime ideal $\mathfrak p$ of $\mathcal O_K$, return their direct sum. It corresponds to the local genus symbol of the $\mathfrak p$-adic completion of the direct sum of respective representatives of g1 and g2.

direct_sum(G1::HermGenus, G2::HermGenus) -> HermGenus

Given two global genus symbols G1 and G2 for hermitian lattices over $E/K$, return their direct sum. It corresponds to the global genus symbol of the direct sum of respective representatives of G1 and G2.

direct_sum(m::Vector{<:FPModule{T}}) where T <: RingElement
-direct_sum(vals::FPModule{T}...) where T <: RingElement

Return a tuple $M, f, g$ consisting of $M$ the direct sum of the modules m (supplied as a vector of modules), a vector $f$ of the injections of the $m[i]$ into $M$ and a vector $g$ of the projections from $M$ onto the $m[i]$.

Examples

julia> F = FreeModule(ZZ, 5)
-Free module of rank 5 over integers
-
-julia> m1 = F(BigInt[4, 7, 8, 2, 6])
-(4, 7, 8, 2, 6)
-
-julia> m2 = F(BigInt[9, 7, -2, 2, -4])
-(9, 7, -2, 2, -4)
-
-julia> S1, f1 = sub(F, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)
-
-julia> m1 = F(BigInt[3, 1, 7, 7, -7])
-(3, 1, 7, 7, -7)
-
-julia> m2 = F(BigInt[-8, 6, 10, -1, 1])
-(-8, 6, 10, -1, 1)
-
-julia> S2, f2 = sub(F, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)
-
-julia> m1 = F(BigInt[2, 4, 2, -3, -10])
-(2, 4, 2, -3, -10)
-
-julia> m2 = F(BigInt[5, 7, -6, 9, -5])
-(5, 7, -6, 9, -5)
-
-julia> S3, f3 = sub(F, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)
-
-julia> D, f = direct_sum(S1, S2, S3)
-(DirectSumModule over integers, AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule], AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations])

Functionality for direct sums

In addition to the Module interface, AbstractAlgebra direct sums implement the following functionality.

Basic manipulation

summandsMethod
summands(M::DirectSumModule{T}) where T <: RingElement

Return the modules that this module is a direct sum of.

Examples

julia> F = FreeModule(ZZ, 5)
-Free module of rank 5 over integers
-
-julia> m1 = F(BigInt[4, 7, 8, 2, 6])
-(4, 7, 8, 2, 6)
-
-julia> m2 = F(BigInt[9, 7, -2, 2, -4])
-(9, 7, -2, 2, -4)
-
-julia> S1, f1 = sub(F, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)
-
-julia> m1 = F(BigInt[3, 1, 7, 7, -7])
-(3, 1, 7, 7, -7)
-
-julia> m2 = F(BigInt[-8, 6, 10, -1, 1])
-(-8, 6, 10, -1, 1)
-
-julia> S2, f2 = sub(F, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)
-
-julia> m1 = F(BigInt[2, 4, 2, -3, -10])
-(2, 4, 2, -3, -10)
-
-julia> m2 = F(BigInt[5, 7, -6, 9, -5])
-(5, 7, -6, 9, -5)
-
-julia> S3, f3 = sub(F, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)
-
-julia> D, f = direct_sum(S1, S2, S3)
-(DirectSumModule over integers, AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule], AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations])
-
-julia> summands(D)
-3-element Vector{AbstractAlgebra.Generic.Submodule{BigInt}}:
- Submodule over Integers with 2 generators and no relations
- Submodule over Integers with 2 generators and no relations
- Submodule over Integers with 2 generators and no relations
    (D::DirectSumModule{T}(::Vector{<:FPModuleElem{T}}) where T <: RingElement

Given a vector (or $1$-dim array) of module elements, where the $i$-th entry has to be an element of the $i$-summand of $D$, create the corresponding element in $D$.

Examples

julia> N = FreeModule(QQ, 1);
-
-julia> M = FreeModule(QQ, 2);
-
-julia> D, _ = direct_sum(M, N, M);
-
-julia> D([gen(M, 1), gen(N, 1), gen(M, 2)])
-(1//1, 0//1, 1//1, 0//1, 1//1)

Special Homomorphisms

Due to the special structure as direct sums, homomorphisms can be created by specifying homomorphisms for all summands. In case of the codmain being a direct sum as well, any homomorphism may be thought of as a matrix containing maps from the $i$-th source summand to the $j$-th target module:

ModuleHomomorphism(D::DirectSumModule{T}, S::DirectSumModule{T}, m::Matrix{Any}) where T <: RingElement

Given a matrix $m$ such that the $(i,j)$-th entry is either $0$ (Int(0)) or a ModuleHomomorphism from the $i$-th summand of $D$ to the $j$-th summand of $S$, construct the corresponding homomorphism.

ModuleHomomorphism(D::DirectSumModule{T}, S::FPModuleElem{T}, m::Vector{ModuleHomomorphism})

Given an array $a$ of ModuleHomomorphism such that $a_i$, the $i$-th entry of $a$ is a ModuleHomomorphism from the $i$-th summand of D into S, construct the direct sum of the components.

Given a matrix $m$ such that the $(i,j)$-th entry is either $0$ (Int(0)) or a ModuleHomomorphism from the $i$-th summand of $D$ to the $j$-th summand of $S$, construct the corresponding homomorphism.

Examples

julia> N = FreeModule(QQ, 2);
-
-julia> D, _ = direct_sum(N, N);
-
-julia> p = ModuleHomomorphism(N, N, [3,4] .* basis(N));
-
-julia> q = ModuleHomomorphism(N, N, [5,7] .* basis(N));
-
-julia> phi = ModuleHomomorphism(D, D, [p 0; 0 q])
-Module homomorphism
-  from DirectSumModule over rationals
-  to DirectSumModule over rationals
-
-julia> r = ModuleHomomorphism(N, D, [2,3] .* gens(D)[1:2])
-Module homomorphism
-  from vector space of dimension 2 over rationals
-  to DirectSumModule over rationals
-
-julia> psi = ModuleHomomorphism(D, D, [r, r])
-Module homomorphism
-  from DirectSumModule over rationals
-  to DirectSumModule over rationals
diff --git a/previews/PR2578/AbstractAlgebra/euclidean_interface/index.html b/previews/PR2578/AbstractAlgebra/euclidean_interface/index.html deleted file mode 100644 index 9f02362abf2f..000000000000 --- a/previews/PR2578/AbstractAlgebra/euclidean_interface/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Euclidean Ring Interface · Oscar.jl

Euclidean Ring Interface

If a ring provides a meaningful Euclidean structure such that a useful Euclidean remainder can be computed practically, various additional functionality is provided by AbstractAlgebra.jl for those rings. This functionality depends on the following functions existing. An implementation must provide divrem, and the remaining are optional as generic fallbacks exist.

divremMethod
divrem(f::T, g::T) where T <: RingElem

Return a pair q, r consisting of the Euclidean quotient and remainder of $f$ by $g$. A DivideError should be thrown if $g$ is zero.

modMethod
mod(f::T, g::T) where T <: RingElem

Return the Euclidean remainder of $f$ by $g$. A DivideError should be thrown if $g$ is zero.

Note

For best compatibility with the internal assumptions made by AbstractAlgebra, the Euclidean remainder function should provide unique representatives for the residue classes; the mod function should satisfy

  1. mod(a_1, b) = mod(a_2, b) if and only if $b$ divides $a_1 - a_2$, and
  2. mod(0, b) = 0.
divMethod
div(f::T, g::T) where T <: RingElem

Return the Euclidean quotient of $f$ by $g$. A DivideError should be thrown if $g$ is zero.

mulmodMethod
mulmod(f::T, g::T, m::T) where T <: RingElem

Return mod(f*g, m) but possibly computed more efficiently.

powermodMethod
powermod(f::T, e::Int, m::T) where T <: RingElem

Return mod(f^e, m) but possibly computed more efficiently.

invmodMethod
invmod(f::T, m::T) where T <: RingElem

Return an inverse of $f$ modulo $m$, meaning that isone(mod(invmod(f,m)*f,m)) returns true.

If such an inverse doesn't exist, a NotInvertibleError should be thrown.

dividesMethod
divides(f::T, g::T) where T <: RingElem

Return a pair, flag, q, where flag is set to true if $g$ divides $f$, in which case q is set to the quotient, or flag is set to false and q is set to zero(f).

removeMethod
remove(f::T, p::T) where T <: RingElem

Return a pair v, q where $p^v$ is the highest power of $p$ dividing $f$ and $q$ is the cofactor after $f$ is divided by this power.

See also valuation, which only returns the valuation.

valuationMethod
valuation(f::T, p::T) where T <: RingElem

Return v where $p^v$ is the highest power of $p$ dividing $f$.

See also remove.

gcdMethod
gcd(a::T, b::T) where T <: RingElem

Return a greatest common divisor of $a$ and $b$, i.e., an element $g$ which is a common divisor of $a$ and $b$, and with the property that any other common divisor of $a$ and $b$ divides $g$.

Note

For best compatibility with the internal assumptions made by AbstractAlgebra, the return is expected to be unit-normalized in such a way that if the return is a unit, that unit should be one.

gcdMethod
gcd(f::T, g::T, hs::T...) where T <: RingElem

Return a greatest common divisor of $f$, $g$ and the elements in hs.

gcdMethod
gcd(fs::AbstractArray{<:T}) where T <: RingElem

Return a greatest common divisor of the elements in fs. Requires that fs is not empty.

lcmMethod
lcm(f::T, g::T) where T <: RingElem

Return a least common multiple of $f$ and $g$, i.e., an element $d$ which is a common multiple of $f$ and $g$, and with the property that any other common multiple of $f$ and $g$ is a multiple of $d$.

lcmMethod
lcm(f::T, g::T, hs::T...) where T <: RingElem

Return a least common multiple of $f$, $g$ and the elements in hs.

lcmMethod
lcm(fs::AbstractArray{<:T}) where T <: RingElem

Return a least common multiple of the elements in fs. Requires that fs is not empty.

gcdxMethod
gcdx(f::T, g::T) where T <: RingElem

Return a triple d, s, t such that $d = gcd(f, g)$ and $d = sf + tg$, with $s$ loosely reduced modulo $g/d$ and $t$ loosely reduced modulo $f/d$.

gcdinvMethod
gcdinv(f::T, g::T) where T <: RingElem

Return a tuple d, s such that $d = gcd(f, g)$ and $s = (f/d)^{-1} \pmod{g/d}$. Note that $d = 1$ iff $f$ is invertible modulo $g$, in which case $s = f^{-1} \pmod{g}$.

crtMethod
crt(r1::T, m1::T, r2::T, m2::T; check::Bool=true) where T <: RingElement

Return an element congruent to $r_1$ modulo $m_1$ and $r_2$ modulo $m_2$. If check = true and no solution exists, an error is thrown.

If T is a fixed precision integer type (like Int), the result will be correct if abs(ri) <= abs(mi) and abs(m1 * m2) < typemax(T).

crtMethod
crt(r::Vector{T}, m::Vector{T}; check::Bool=true) where T <: RingElement

Return an element congruent to $r_i$ modulo $m_i$ for each $i$.

crt_with_lcmMethod
crt_with_lcm(r1::T, m1::T, r2::T, m2::T; check::Bool=true) where T <: RingElement

Return a tuple consisting of an element congruent to $r_1$ modulo $m_1$ and $r_2$ modulo $m_2$ and the least common multiple of $m_1$ and $m_2$. If check = true and no solution exists, an error is thrown.

crt_with_lcmMethod
crt_with_lcm(r::Vector{T}, m::Vector{T}; check::Bool=true) where T <: RingElement

Return a tuple consisting of an element congruent to $r_i$ modulo $m_i$ for each $i$ and the least common multiple of the $m_i$.

diff --git a/previews/PR2578/AbstractAlgebra/extending_abstractalgebra/index.html b/previews/PR2578/AbstractAlgebra/extending_abstractalgebra/index.html deleted file mode 100644 index 9348130a93fe..000000000000 --- a/previews/PR2578/AbstractAlgebra/extending_abstractalgebra/index.html +++ /dev/null @@ -1,98 +0,0 @@ - -Extending the interface of AbstractAlgebra.jl · Oscar.jl

Extending the interface of AbstractAlgebra.jl

In this section we will discuss on how to extend the interface of AbstractAlgebra.jl.

Elements and parents

Any implementation with elements and parents should implement the following interface:

parentFunction
parent(a)

Return parent object of given element $a$.

Examples

julia> G = SymmetricGroup(5); g = Perm([3,4,5,2,1])
-(1,3,5)(2,4)
-
-julia> parent(g) == G
-true
-
-julia> S, x = laurent_series_ring(ZZ, 3, "x")
-(Laurent series ring in x over integers, x + O(x^4))
-
-julia> parent(x) == S
-true
elem_typeFunction
elem_type(::Type{T}) where T <: GAPGroup
-elem_type(::T) where T <: GAPGroup

elem_type maps (the type of) a group to the type of its elements. For now, a group of type T has elements of type BasicGAPGroupElem{T}. So we provide it mostly for consistency with other parts of OSCAR. In the future, a more elaborate setup for group element types might also be needed.

source
elem_type(parent)
-elem_type(parent_type)

Given a parent object (or its type), return the type of its elements.

Examples

julia> S, x = power_series_ring(QQ, 2, "x")
-(Univariate power series ring over rationals, x + O(x^3))
-
-julia> elem_type(S) == typeof(x)
-true
parent_typeFunction
parent_type(element)
-parent_type(element_type)

Given an element (or its type), return the type of its parent object.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = matrix_space(R, 2, 2)
-Matrix space of 2 rows and 2 columns
-  over univariate polynomial ring in x over integers
-
-julia> a = rand(S, 0:1, 0:1);
-
-julia> parent_type(a) == typeof(S)
-true

Acquiring associated elements and parents

Further, if one has a base ring, like polynomials over the integers $\mathbb{Z}[x]$, then one should implement

base_ringFunction
base_ring(a)

Return base ring $R$ of given element or parent $a$.

Examples

julia> S, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> base_ring(S) == QQ
-true
-
-julia> R = GF(7)
-Finite field F_7
-
-julia> base_ring(R)
-Union{}

Special elements

For rings, one has to extend the following methods:

oneFunction
one(a)

Return the multiplicative identity in the algebraic structure of $a$, which can be either an element or parent.

Examples

julia> S = matrix_space(ZZ, 2, 2)
-Matrix space of 2 rows and 2 columns
-  over integers
-
-julia> one(S)
-[1   0]
-[0   1]
-
-julia> R, x = PuiseuxSeriesField(QQ, 4, "x")
-(Puiseux series field in x over rationals, x + O(x^5))
-
-julia> one(x)
-1 + O(x^4)
-
-julia> G = GF(5)
-Finite field F_5
-
-julia> one(G)
-1
zeroFunction
zero(a)

Return the additive identity in the algebraic structure of $a$, which can be either an element or parent.

Examples

julia> S = MatrixAlgebra(QQ, 2)
-Matrix algebra of degree 2
-  over rationals
-
-julia> zero(S)
-[0//1   0//1]
-[0//1   0//1]
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> zero(x^3 + 2)
-0

Groups should only extend at least one of these. The one that is required depends on if the group is additive (commutative) or multiplicative.

Basic manipulation

If one would like to implement a ring, these are the basic manipulation methods that all rings should extend:

isoneFunction
isone(a)

Return true if $a$ is the multiplicative identity, else return false.

Examples

julia> S = matrix_space(ZZ, 2, 2); T = matrix_space(ZZ, 2, 3); U = matrix_space(ZZ, 3, 2);
-
-julia> isone(S([1 0; 0 1]))
-true
-
-julia> isone(T([1 0 0; 0 1 0]))
-false
-
-julia> isone(U([1 0; 0 1; 0 0]))
-false
-
-julia> T, x = PuiseuxSeriesField(QQ, 10, "x")
-(Puiseux series field in x over rationals, x + O(x^11))
-
-julia> isone(x), isone(T(1))
-(false, true)
iszeroFunction
iszero(a)

Return true if $a$ is the additative identity, else return false.

Examples

julia> T, x = PuiseuxSeriesField(QQ, 10, "x")
-(Puiseux series field in x over rationals, x + O(x^11))
-
-julia> a = T(0)
-O(x^10)
-
-julia> iszero(a)
-true
is_unitFunction
is_unit(a::T) where {T <: NCRingElem}

Return true if $a$ is invertible, else return false.

Examples

julia> S, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> is_unit(x), is_unit(S(1)), is_unit(S(4))
-(false, true, true)
-
-julia> is_unit(ZZ(-1)), is_unit(ZZ(4))
-(true, false)

With the same logic as earlier, groups only need to extend one of the methods isone and iszero.

diff --git a/previews/PR2578/AbstractAlgebra/field/index.html b/previews/PR2578/AbstractAlgebra/field/index.html deleted file mode 100644 index 904f2e090e93..000000000000 --- a/previews/PR2578/AbstractAlgebra/field/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Field functionality · Oscar.jl

Field functionality

Abstract types for rings

All field types in AbstractAlgebra belong to the Field abstract type and field elements belong to the FieldElem abstract type.

As Julia types cannot belong to our FieldElem type hierarchy, we also provide the union type FieldElement which includes FieldElem in union with the Julia types Rational and AbstractFloat.

Note that

Field <: Ring
-FieldElem <: RingElem
-FieldElement <: RingElement

Of course all Ring functionality is available for AbstractAlgebra fields and their elements.

Functions for types and parents of fields

characteristic(R::MyParent)

Return the characteristic of the field. If the characteristic is not known, an exception is raised.

Basic functions

is_unit(f::MyElem)

Return true if the given element is invertible, i.e. nonzero in the field.

diff --git a/previews/PR2578/AbstractAlgebra/field_interface/index.html b/previews/PR2578/AbstractAlgebra/field_interface/index.html deleted file mode 100644 index 5f031b565b6a..000000000000 --- a/previews/PR2578/AbstractAlgebra/field_interface/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Field Interface · Oscar.jl

Field Interface

AbstractAlgebra.jl generic code makes use of a standardised set of functions which it expects to be implemented for all fields. Here we document this interface. All libraries which want to make use of the generic capabilities of AbstractAlgebra.jl must supply all of the required functionality for their fields.

Types

Most fields must supply two types:

  • a type for the parent object (representing the field itself)
  • a type for elements of that field

For example, the generic fraction field type in AbstractAlgebra.jl provides two types in generic/GenericTypes.jl:

  • Generic.FracField{T} for the parent objects
  • Generic.Frac{T} for the actual fractions

The parent type must belong to Field and the element type must belong to FieldElem. Of course, the types may belong to these abstract types transitively.

For parameterised fields, we advise that the types of both the parent objects and element objects to be parameterised by the types of the elements of the base ring.

There can be variations on this theme: e.g. in some areas of mathematics there is a notion of a coefficient domain, in which case it may make sense to parameterise all types by the type of elements of this coefficient domain. But note that this may have implications for the ad hoc operators one might like to explicitly implement.

FieldElement type union

Because of its lack of multiple inheritance, Julia does not allow Julia Base types to belong to FieldElem. To allow us to work equally with AbstractAlgebra and Julia types that represent elements of fields we define a union type FieldElement in src/julia/JuliaTypes.

So far, in addition to FieldElem the union type FieldElement includes the Julia types Rational and AbstractFloat.

Most of the generic code in AbstractAlgebra makes use of the union type FieldElement instead of FieldElem so that the generic functions also accept the Julia Base field types.

Note

One must be careful when defining ad hoc binary operations for field element types. It is often necessary to define separate versions of the functions for FieldElem then for each of the Julia types separately in order to avoid ambiguity warnings.

Note that even though FieldElement is a union type we still have the following inclusion

FieldElement <: RingElement

Parent object caches

In many cases, it is desirable to have only one object in the system to represent each field. This means that if the same field is constructed twice, elements of the two fields will be compatible as far as arithmetic is concerned.

In order to facilitate this, global caches of fields are stored in AbstractAlgebra.jl, usually implemented using dictionaries. For example, the Generic.FracField parent objects are looked up in a dictionary FracDict to see if they have been previously defined.

Whether these global caches are provided or not, depends on both mathematical and algorithmic considerations. E.g. in the case of number fields, it isn't desirable to identify all number fields with the same defining polynomial, as they may be considered with distinct embeddings into one another. In other cases, identifying whether two fields are the same may be prohibitively expensive. Generally, it may only make sense algorithmically to identify two fields if they were constructed from identical data.

If a global cache is provided, it must be optionally possible to construct the parent objects without caching. This is done by passing a boolean value cached to the inner constructor of the parent object. See generic/GenericTypes.jl for examples of how to construct and handle such caches.

Required functions for all fields

In the following, we list all the functions that are required to be provided for fields in AbstractAlgebra.jl or by external libraries wanting to use AbstractAlgebra.jl.

We give this interface for fictitious types MyParent for the type of the field parent object R and MyElem for the type of the elements of the field.

Note

Generic functions in AbstractAlgebra.jl may not rely on the existence of functions that are not documented here. If they do, those functions will only be available for fields that implement that additional functionality, and should be documented as such.

In the first place, all fields are rings and therefore any field type must implement all of the Ring interface. The functionality below is in addition to this basic functionality.

Data type and parent object methods

characteristic(R::MyParent)

Return the characteristic of the field. If the characteristic is not known, an exception is raised.

Basic manipulation of rings and elements

is_unit(f::MyElem)

Return true if the given element is invertible, i.e. nonzero in the field.

diff --git a/previews/PR2578/AbstractAlgebra/field_introduction/index.html b/previews/PR2578/AbstractAlgebra/field_introduction/index.html deleted file mode 100644 index 9aa49d44d0ba..000000000000 --- a/previews/PR2578/AbstractAlgebra/field_introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

A number of basic fields are provided, such as the rationals, finite fields, the real field, etc.

Various generic field constructions can then be made recursively on top of these basic fields. For example, fraction fields, residue fields, function fields, etc.

From the point of view of the system, all fields are rings and whether an object is a ring/field or an element thereof can be determined at the type level. There are abstract types for all field and for all field element types.

The field hierarchy can be extended by implementing new fields to follow one or more field interfaces, including the interface that all fields must follow. Once an interface is satisfied, all the corresponding generic functionality will work over the new field.

Implementations of new fields can either be generic or can be specialised implementations provided by, for example, a C library.

diff --git a/previews/PR2578/AbstractAlgebra/finfield/index.html b/previews/PR2578/AbstractAlgebra/finfield/index.html deleted file mode 100644 index f7e0f90f1ad4..000000000000 --- a/previews/PR2578/AbstractAlgebra/finfield/index.html +++ /dev/null @@ -1,55 +0,0 @@ - -Finite fields · Oscar.jl

Finite fields

AbstractAlgebra.jl provides a module, implemented in src/julia/GF.jl for finite fields. The module is a naive implementation that supports only fields of degree $1$ (prime fields). They are modelled as $\mathbb{Z}/p\mathbb{Z}$ for $p$ a prime.

Types and parent objects

Finite fields have type GFField{T} where T is either Int or BigInt.

Elements of such a finite field have type GFElem{T}.

Finite field constructors

In order to construct finite fields in AbstractAlgebra.jl, one must first construct the field itself. This is accomplished with the following constructors.

GFMethod
GF(p::T; check::Bool=true) where T <: Integer

Return the finite field $\mathbb{F}_p$, where $p$ is a prime. By default, the integer $p$ is checked with a probabilistic algorithm for primality. When check == false, no check is made, but the behaviour of the resulting object is undefined if $p$ is composite.

Here are some examples of creating a finite field and making use of the resulting parent object to coerce various elements into the field.

Examples

julia> F = GF(13)
-Finite field F_13
-
-julia> g = F(3)
-3
-
-julia> h = F(g)
-3
-
-julia> GF(4)
-ERROR: DomainError with 4:
-Characteristic is not prime in GF(p)
-Stacktrace:
-[...]

Basic field functionality

The finite field module in AbstractAlgebra.jl implements the full Field interface.

We give some examples of such functionality.

Examples

julia> F = GF(13)
-Finite field F_13
-
-julia> f = F(7)
-7
-
-julia> h = zero(F)
-0
-
-julia> k = one(F)
-1
-
-julia> isone(k)
-true
-
-julia> iszero(h)
-true
-
-julia> T = parent(h)
-Finite field F_13
-
-julia> h == deepcopy(h)
-true
-
-julia> h = h + 2
-2
-
-julia> m = inv(k)
-1
-

Basic manipulation of fields and elements

dataMethod
data(R::GFElem)

Return the internal data used to represent the finite field element. This coincides with lift except where the internal data ids a machine integer.

liftMethod
lift(R::GFElem)

Lift the finite field element to the integers. The result will be a multiprecision integer regardless of how the field element is represented internally.

genMethod
gen(R::GFField{T}) where T <: Integer

Return a generator of the field. Currently this returns 1.

orderMethod
order(R::GFField)

Return the order, i.e. the number of element in the given finite field.

degreeMethod
degree(R::GFField)

Return the degree of the given finite field.

Examples

julia> F = GF(13)
-Finite field F_13
-
-julia> d = degree(F)
-1
-
-julia> n = order(F)
-13
-
-julia> g = gen(F)
-1
-
diff --git a/previews/PR2578/AbstractAlgebra/fraction/index.html b/previews/PR2578/AbstractAlgebra/fraction/index.html deleted file mode 100644 index 054f0da9b1d5..000000000000 --- a/previews/PR2578/AbstractAlgebra/fraction/index.html +++ /dev/null @@ -1,190 +0,0 @@ - -Generic fraction fields · Oscar.jl

Generic fraction fields

AbstractAlgebra.jl provides a module, implemented in src/Fraction.jl for fraction fields over any gcd domain belonging to the AbstractAlgebra.jl abstract type hierarchy.

Generic fraction types

AbstractAlgebra.jl implements a generic fraction type Generic.Frac{T} where T is the type of elements of the base ring. See the file src/generic/GenericTypes.jl for details.

Parent objects of such fraction elements have type Generic.FracField{T}.

Factored fraction types

AbstractAlgebra.jl also implements a fraction type Generic.FactoredFrac{T} with parent objects of such fractions having type Generic.FactoredFracField{T}. As opposed to the fractions of type Generic.Frac{T}, which are just a numerator and denominator, these fractions are maintained in factored form as much as possible.

Abstract types

All fraction element types belong to the abstract type FracElem{T} and the fraction field types belong to the abstract type FracField{T}. This enables one to write generic functions that can accept any AbstractAlgebra fraction type.

Note

Both the generic fraction field type Generic.FracField{T} and the abstract type it belongs to, FracField{T} are both called FracField. The former is a (parameterised) concrete type for a fraction field over a given base ring whose elements have type T. The latter is an abstract type representing all fraction field types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).

Fraction field constructors

In order to construct fractions in AbstractAlgebra.jl, one can first construct the fraction field itself. This is accomplished with the following constructor.

fraction_field(R::Ring; cached::Bool = true)

Given a base ring R return the parent object of the fraction field of $R$. By default the parent object S will depend only on R and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Here are some examples of creating fraction fields and making use of the resulting parent objects to coerce various elements into the fraction field.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = fraction_field(R)
-Fraction field
-  of univariate polynomial ring in x over integers
-
-julia> f = S()
-0
-
-julia> g = S(123)
-123
-
-julia> h = S(BigInt(1234))
-1234
-
-julia> k = S(x + 1)
-x + 1

Factored Fraction field constructors

The corresponding factored field uses the following constructor.

FactoredFractionField(R::Ring; cached::Bool = true)

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> S = FactoredFractionField(R)
-Factored fraction field of Multivariate polynomial ring in 2 variables over integers
-
-julia> (X, Y) = (S(x), S(y))
-(x, y)
-
-julia> f = X^6*(X+Y)^2*(X^2+Y)^3*(X+2*Y)^-3*(X+3*Y)^-4
-x^6*(x + y)^2*(x^2 + y)^3/((x + 2*y)^3*(x + 3*y)^4)
-
-julia> numerator(f)
-x^14 + 2*x^13*y + x^12*y^2 + 3*x^12*y + 6*x^11*y^2 + 3*x^10*y^3 + 3*x^10*y^2 + 6*x^9*y^3 + 3*x^8*y^4 + x^8*y^3 + 2*x^7*y^4 + x^6*y^5
-
-julia> denominator(f)
-x^7 + 18*x^6*y + 138*x^5*y^2 + 584*x^4*y^3 + 1473*x^3*y^4 + 2214*x^2*y^5 + 1836*x*y^6 + 648*y^7
-
-julia> derivative(f, x)
-x^5*(x + y)*(x^2 + y)^2*(7*x^5 + 58*x^4*y + 127*x^3*y^2 + x^3*y + 72*x^2*y^3 + 22*x^2*y^2 + 61*x*y^3 + 36*y^4)/((x + 2*y)^4*(x + 3*y)^5)

Fraction constructors

One can construct fractions using the fraction field parent object, as for any ring or field.

(R::FracField)() # constructs zero
-(R::FracField)(c::Integer)
-(R::FracField)(c::elem_type(R))
-(R::FracField{T})(a::T) where T <: RingElement

One may also use the Julia double slash operator to construct elements of the fraction field without constructing the fraction field parent first.

//(x::T, y::T) where T <: RingElement

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = fraction_field(R)
-Fraction field
-  of univariate polynomial ring in x over rationals
-
-julia> f = S(x + 1)
-x + 1
-
-julia> g = (x^2 + x + 1)//(x^3 + 3x + 1)
-(x^2 + x + 1)//(x^3 + 3*x + 1)
-
-julia> x//f
-x//(x + 1)
-
-julia> f//x
-(x + 1)//x

Functions for types and parents of fraction fields

Fraction fields in AbstractAlgebra.jl implement the Ring interface.

base_ring(R::FracField)
-base_ring(a::FracElem)

Return the base ring of which the fraction field was constructed.

parent(a::FracElem)

Return the fraction field of the given fraction.

characteristic(R::FracField)

Return the characteristic of the base ring of the fraction field. If the characteristic is not known an exception is raised.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = fraction_field(R)
-Fraction field
-  of univariate polynomial ring in x over rationals
-
-julia> f = S(x + 1)
-x + 1
-
-julia> U = base_ring(S)
-Univariate polynomial ring in x over rationals
-
-julia> V = base_ring(f)
-Univariate polynomial ring in x over rationals
-
-julia> T = parent(f)
-Fraction field
-  of univariate polynomial ring in x over rationals
-
-julia> m = characteristic(S)
-0

Fraction field functions

Basic functions

Fraction fields implement the Ring interface.

zero(R::FracField)
-one(R::FracField)
-iszero(a::FracElem)
-isone(a::FracElem)
inv(a::T) where T <: FracElem

They also implement the field interface.

is_unit(f::FracElem)

And they implement the fraction field interface.

numerator(a::FracElem)
-denominator(a::FracElem)

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = fraction_field(R)
-Fraction field
-  of univariate polynomial ring in x over rationals
-
-julia> f = S(x + 1)
-x + 1
-
-julia> g = (x^2 + x + 1)//(x^3 + 3x + 1)
-(x^2 + x + 1)//(x^3 + 3*x + 1)
-
-julia> h = zero(S)
-0
-
-julia> k = one(S)
-1
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> r = deepcopy(f)
-x + 1
-
-julia> n = numerator(g)
-x^2 + x + 1
-
-julia> d = denominator(g)
-x^3 + 3*x + 1

Greatest common divisor

gcdMethod
gcd(a::FracElem{T}, b::FracElem{T}) where {T <: RingElem}

Return a greatest common divisor of $a$ and $b$ if one exists. N.B: we define the GCD of $a/b$ and $c/d$ to be gcd$(ad, bc)/bd$, reduced to lowest terms. This requires the existence of a greatest common divisor function for the base ring.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> f = (x + 1)//(x^3 + 3x + 1)
-(x + 1)//(x^3 + 3*x + 1)
-
-julia> g = (x^2 + 2x + 1)//(x^2 + x + 1)
-(x^2 + 2*x + 1)//(x^2 + x + 1)
-
-julia> h = gcd(f, g)
-(x + 1)//(x^5 + x^4 + 4*x^3 + 4*x^2 + 4*x + 1)
-

Square root

is_squareMethod
is_square(a::FracElem{T}) where T <: RingElem

Return true if $a$ is a square.

sqrtMethod
Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = fraction_field(R)
-Fraction field
-  of univariate polynomial ring in x over rationals
-
-julia> a = (21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
-(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
-
-julia> sqrt(a^2)
-(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
-
-julia> is_square(a^2)
-true

Remove and valuation

When working over a Euclidean domain, it is convenient to extend valuations to the fraction field. To facilitate this, we define the following functions.

removeMethod
remove(z::FracElem{T}, p::T) where {T <: RingElem}

Return the tuple $n, x$ such that $z = p^nx$ where $x$ has valuation $0$ at $p$.

valuationMethod
valuation(z::FracElem{T}, p::T) where {T <: RingElem}

Return the valuation of $z$ at $p$.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> f = (x + 1)//(x^3 + 3x + 1)
-(x + 1)//(x^3 + 3*x + 1)
-
-julia> g = (x^2 + 1)//(x^2 + x + 1)
-(x^2 + 1)//(x^2 + x + 1)
-
-julia> v, q = remove(f^3*g, x + 1)
-(3, (x^2 + 1)//(x^11 + x^10 + 10*x^9 + 12*x^8 + 39*x^7 + 48*x^6 + 75*x^5 + 75*x^4 + 66*x^3 + 37*x^2 + 10*x + 1))
-
-julia> v = valuation(f^3*g, x + 1)
-3
-

Random generation

Random fractions can be generated using rand. The parameters passed after the fraction field tell rand how to generate random elements of the base ring.

rand(R::FracField, v...)

Examples

julia> K = fraction_field(ZZ)
-Rationals
-
-julia> f = rand(K, -10:10)
--1//3
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = fraction_field(R)
-Fraction field
-  of univariate polynomial ring in x over integers
-
-julia> g = rand(S, -1:3, -10:10)
-(-4*x - 4)//(4*x^2 + x - 4)

Extra functionality for factored fractions

The Generic.FactoredFrac{T} type implements an interface similar to that of the Fac{T} type for iterating over the terms in the factorisation. There is also the function push_term!(a, b, e) for efficiently performing a *= b^e, and the function normalise returns relatively prime terms.

Examples

julia> F = FactoredFractionField(ZZ)
-Factored fraction field of Integers
-
-julia> f = F(-1)
--1
-
-julia> push_term!(f, 10, 10)
--10^10
-
-julia> push_term!(f, 42, -8)
--10^10/42^8
-
-julia> normalise(f)
--5^10*2^2/21^8
-
-julia> unit(f)
--1
-
-julia> collect(f)
-2-element Vector{Tuple{BigInt, Int64}}:
- (10, 10)
- (42, -8)
diff --git a/previews/PR2578/AbstractAlgebra/fraction_interface/index.html b/previews/PR2578/AbstractAlgebra/fraction_interface/index.html deleted file mode 100644 index f472b20e70c7..000000000000 --- a/previews/PR2578/AbstractAlgebra/fraction_interface/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Fraction Field Interface · Oscar.jl

Fraction Field Interface

Fraction fields are supported in AbstractAlgebra.jl, at least for gcd domains. In addition to the standard Ring interface, some additional functions are required to be present for fraction fields.

Types and parents

AbstractAlgebra provides two abstract types for fraction fields and their elements:

  • FracField{T} is the abstract type for fraction field parent types
  • FracElem{T} is the abstract type for types of fractions

We have that FracField{T} <: Field and FracElem{T} <: FieldElem.

Note that both abstract types are parameterised. The type T should usually be the type of elements of the base ring of the fraction field.

Fraction fields should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Fraction fields should at least be distinguished based on their base ring.

See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).

Required functionality for fraction fields

In addition to the required functionality for the Field interface the Fraction Field interface has the following required functions.

We suppose that R is a fictitious base ring, and that S is the fraction field with parent object S of type MyFracField{T}. We also assume the fractions in the field have type MyFrac{T}, where T is the type of elements of the base ring.

Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.

Note that the type T must (transitively) belong to the abstract type RingElem.

Constructors

The following constructors create fractions. Note that these constructors don't require construction of the parent object first. This is easier to achieve if the fraction element type doesn't contain a reference to the parent object, but merely contains a reference to the base ring. The parent object can then be constructed on demand.

//(x::T, y::T) where T <: RingElem

Return the fraction $x/y$.

//(x::T, y::FracElem{T}) where T <: RingElem

Return $x/y$ where $x$ is in the base ring of $y$.

//(x::FracElem{T}, y::T) where T <: RingElem

Return $x/y$ where $y$ is in the base ring of $x$.

Basic manipulation of fields and elements

numerator(d::MyFrac{T}) where T <: RingElem

Given a fraction $d = a/b$ return $a$, where $a/b$ is in lowest terms with respect to the canonical_unit and gcd functions on the base ring.

denominator(d::MyFrac{T}) where T <: RingElem

Given a fraction $d = a/b$ return $b$, where $a/b$ is in lowest terms with respect to the canonical_unit and gcd functions on the base ring.

diff --git a/previews/PR2578/AbstractAlgebra/free_associative_algebra/index.html b/previews/PR2578/AbstractAlgebra/free_associative_algebra/index.html deleted file mode 100644 index 3aad9e02187f..000000000000 --- a/previews/PR2578/AbstractAlgebra/free_associative_algebra/index.html +++ /dev/null @@ -1,94 +0,0 @@ - -Free algebras · Oscar.jl

Free algebras

AbstractAlgebra.jl provides a module, implemented in src/FreeAssAlgebra.jl for free associative algebras over any commutative ring belonging to the AbstractAlgebra abstract type hierarchy.

Generic free algebra types

AbstractAlgebra provides a generic type Generic.FreeAssAlgElem{T} where T is the type of elements of the coefficient ring. The elements are implemented using a Julia array of coefficients and a vector of vectors of Ints for the monomial words. Parent objects of such elements have type Generic.FreeAssAlgebra{T}.

The element types belong to the abstract type NCRingElem, and the algebra types belong to the abstract type NCRing.

The following basic functions are implemented.

base_ring(R::FreeAssAlgebra)
-base_ring(a::FreeAssAlgElem)
-parent(a::FreeAssAlgElem)
-characteristic(R::FreeAssAlgebra)

Free algebra constructors

free_associative_algebra(R::Ring, s::AbstractVector{<:VarName}; cached::Bool = true)
-free_associative_algebra(R::Ring, n::Int, s::VarName; cached::Bool = false)

The first constructor, given a base ring R and an array s of variables, will return a tuple S, (x, ...) representing the new algebra $S = R \left<x, \ldots \right>$ and a tuple of generators $(x, ...)$.

The second constructor given a string s and a number of variables n will do the same as the first constructor except that the variables will be automatically numbered as, s1, s2, ..., sn.

By default the parent object S will depend only on R and (x, ...) and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Examples

julia> R, (x, y) = free_associative_algebra(ZZ, ["x", "y"])
-(Free associative algebra on 2 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[x, y])
-
-julia> (x + y + 1)^2
-x^2 + x*y + y*x + y^2 + 2*x + 2*y + 1
-
-
-julia> (x*y*x*x)^4
-x*y*x^3*y*x^3*y*x^3*y*x^2

Free algebra element constructors

Elements of a free algebra can be constructed from the generators in the usual way using arithmetic operations. Also, all of the standard ring element constructors may be used. Finally, the MPolyBuildCtx is overloaded to work with coefficients and monomial words and not exponent vectors.

Examples

julia> R, (x, y, z) = free_associative_algebra(ZZ, ["x", "y", "z"])
-(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[x, y, z])
-
-julia> B = MPolyBuildCtx(R)
-Builder for an element of Free associative algebra on 3 indeterminates over integers
-
-julia> push_term!(B, ZZ(1), [1,2,3,1]); push_term!(B, ZZ(2), [3,3,1]); finish(B)
-x*y*z*x + 2*z^2*x
-
-julia> push_term!(B, ZZ(3), [3,3,3]); push_term!(B, ZZ(4), Int[]); finish(B)
-3*z^3 + 4
-
-julia> [gen(R, 2), R(9)]
-2-element Vector{AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}}:
- y
- 9

Element functions

Basic manipulation

The standard ring functions are available. The following functions from the multivariate polynomial interface are provided.

symbols(S::FreeAssAlgebra)
-nvars(f::FreeAssAlgebra)
-gens(S::FreeAssAlgebra)
-gen(S::FreeAssAlgebra, i::Int)
-is_gen(x::FreeAssAlgElem)
-total_degree(a::FreeAssAlgElem)
-length(f::FreeAssAlgElem)

As with multivariate polynomials, an implementation must provide access to the elements as a sum of individual terms in some order. The length function provides the number of such terms, and the following functions provide the first such term.

leading_coefficient(a::FreeAssAlgElem)
-leading_monomial(a::FreeAssAlgElem)
-leading_term(a::FreeAssAlgElem)
-leading_exponent_word(a::FreeAssAlgElem)

For types that allow constant time access to coefficients, the following are also available, allowing access to the given coefficient, monomial or term. Terms are numbered from the most significant first.

coeff(f::FreeAssAlgElem, n::Int)
-monomial(f::FreeAssAlgElem, n::Int)
-term(f::FreeAssAlgElem, n::Int)

In contrast with the interface for multivariable polynomials, the function exponent_vector is replaced by exponent_word

exponent_wordMethod
exponent_word(a::FreeAssAlgElem{T}, i::Int) where T <: RingElement

Return a vector of variable indices corresponding to the monomial of the $i$-th term of $a$. Term numbering begins at $1$, and the variable indices are given in the order of the variables for the ring.

Examples

julia> R, (x, y, z) = free_associative_algebra(ZZ, ["x", "y", "z"])
-(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[x, y, z])
-
-julia> map(total_degree, (R(0), R(1), -x^2*y^2*z^2*x + z*y))
-(-1, 0, 7)
-
-julia> leading_term(-x^2*y^2*z^2*x + z*y)
--x^2*y^2*z^2*x
-
-julia> leading_monomial(-x^2*y^2*z^2*x + z*y)
-x^2*y^2*z^2*x
-
-julia> leading_coefficient(-x^2*y^2*z^2*x + z*y)
--1
-
-julia> exponent_word(-x^2*y^2*z^2*x + z*y, 1)
-7-element Vector{Int64}:
- 1
- 1
- 2
- 2
- 3
- 3
- 1

Iterators

The following iterators are provided for elements of a free associative algebra, with exponent_words providing the analogous functionality that exponent_vectors provides for multivariate polynomials.

terms(p::FreeAssAlgElem)
-coefficients(p::FreeAssAlgElem)
-monomials(p::FreeAssAlgElem)
exponent_wordsMethod
exponent_words(a::AbstractAlgebra.FreeAssAlgElem{T}) where T <: RingElement

Return an iterator for the exponent words of the given polynomial. To retrieve an array of the exponent words, use collect(exponent_words(a)).

Examples

julia> R, (a, b, c) = free_associative_algebra(ZZ, ["a", "b", "c"])
-(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[a, b, c])
-
-julia> collect(terms(3*b*a*c - b + c + 2))
-4-element Vector{Any}:
- 3*b*a*c
- -b
- c
- 2
-
-julia> collect(coefficients(3*b*a*c - b + c + 2))
-4-element Vector{Any}:
-  3
- -1
-  1
-  2
-
-julia> collect(monomials(3*b*a*c - b + c + 2))
-4-element Vector{Any}:
- b*a*c
- b
- c
- 1
-
-julia> collect(exponent_words(3*b*a*c - b + c + 2))
-4-element Vector{Vector{Int64}}:
- [2, 1, 3]
- [2]
- [3]
- []
diff --git a/previews/PR2578/AbstractAlgebra/free_module/index.html b/previews/PR2578/AbstractAlgebra/free_module/index.html deleted file mode 100644 index 8fcd9c821035..000000000000 --- a/previews/PR2578/AbstractAlgebra/free_module/index.html +++ /dev/null @@ -1,24 +0,0 @@ - -Free Modules and Vector Spaces · Oscar.jl

Free Modules and Vector Spaces

AbstractAlgebra allows the construction of free modules of any rank over any Euclidean ring and the vector space of any dimension over a field. By default the system considers the free module of a given rank over a given ring or vector space of given dimension over a field to be unique.

Generic free module and vector space types

AbstractAlgebra provides generic types for free modules and vector spaces, via the type FreeModule{T} for free modules, where T is the type of the elements of the ring $R$ over which the module is built.

Elements of a free module have type FreeModuleElem{T}.

Vector spaces are simply free modules over a field.

The implementation of generic free modules can be found in src/generic/FreeModule.jl.

The free module of a given rank over a given ring is made unique on the system by caching them (unless an optional cache parameter is set to false).

See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).

Abstract types

The type FreeModule{T} belongs to FPModule{T} and FreeModuleElem{T} to FPModuleElem{T}. Here the FP prefix stands for finitely presented.

Functionality for free modules

As well as implementing the entire module interface, free modules provide the following functionality.

Constructors

FreeModuleMethod
FreeModule(R::NCRing, rank::Int; cached::Bool = true)

Return the free module over the ring $R$ with the given rank.

VectorSpaceMethod
VectorSpace(R::Field, dim::Int; cached::Bool = true)

Return the vector space over the field $R$ with the given dimension.

Construct the free module/vector space of given rank/dimension.

Examples

julia> M = FreeModule(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> V = VectorSpace(QQ, 2)
-Vector space of dimension 2 over rationals
-

Basic manipulation

rank(M::Generic.FreeModule{T}) where T <: RingElem
-dim(V::Generic.FreeModule{T}) where T <: FieldElem
-basis(V::Generic.FreeModule{T}) where T <: FieldElem

Examples

julia> M = FreeModule(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> V = VectorSpace(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> rank(M)
-3
-
-julia> dim(V)
-2
-
-julia> basis(V)
-2-element Vector{AbstractAlgebra.Generic.FreeModuleElem{Rational{BigInt}}}:
- (1//1, 0//1)
- (0//1, 1//1)
diff --git a/previews/PR2578/AbstractAlgebra/function_field/index.html b/previews/PR2578/AbstractAlgebra/function_field/index.html deleted file mode 100644 index 95be04507867..000000000000 --- a/previews/PR2578/AbstractAlgebra/function_field/index.html +++ /dev/null @@ -1,223 +0,0 @@ - -Rational function fields · Oscar.jl

Rational function fields

AbstractAlgebra.jl provides a module, implemented in src/generic/RationalFunctionField.jl for rational function fields $k(x)$ or k[x_1, x_2, \ldots, x_n] over a field $k$.

Generic rational function field type

Rational functions have type Generic.RationalFunctionFieldElem{T, U} where T is the type of elements of the coefficient field $k$ and U is the type of polynomials (either univariate or multivariate) over that field. See the file src/generic/GenericTypes.jl for details.

Parent objects corresponding to the rational function field $k$ have type Generic.RationalFunctionField{T, U}.

Abstract types

The rational function types belong to the abstract type Field and the rational function field types belong to the abstract type FieldElem.

Rational function field constructors

In order to construct rational functions in AbstractAlgebra.jl, one can first construct the function field itself. This is accomplished with one of the following constructors.

RationalFunctionField(k::Field, s::VarName; cached::Bool = true)
-RationalFunctionField(k::Field, s::Vector{<:VarName}; cached::Bool = true)

Given a coefficient field k return a tuple (S, x) consisting of the parent object of the rational function field over $k$ and the generator(s) x. By default the parent object S will depend only on R and s and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Here are some examples of creating rational function fields and making use of the resulting parent objects to coerce various elements into the function field.

Examples

julia> S, x = RationalFunctionField(QQ, "x")
-(Rational function field over rationals, x)
-
-julia> f = S()
-0
-
-julia> g = S(123)
-123
-
-julia> h = S(BigInt(1234))
-1234
-
-julia> k = S(x + 1)
-x + 1
-
-julia> m = S(numerator(x + 1, false), numerator(x + 2, false))
-(x + 1)//(x + 2)
-
-julia> R, (x, y) = RationalFunctionField(QQ, ["x", "y"])
-(Rational function field over rationals, AbstractAlgebra.Generic.RationalFunctionFieldElem{Rational{BigInt}, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}[x, y])
-
-julia> (x + y)//y^2
-(x + y)//y^2

Basic rational function field functionality

Fraction fields in AbstractAlgebra.jl implement the full Field interface and the entire fraction field interface.

We give some examples of such functionality.

Examples

julia> S, x = RationalFunctionField(QQ, "x")
-(Rational function field over rationals, x)
-
-julia> f = S(x + 1)
-x + 1
-
-julia> g = (x^2 + x + 1)//(x^3 + 3x + 1)
-(x^2 + x + 1)//(x^3 + 3*x + 1)
-
-julia> h = zero(S)
-0
-
-julia> k = one(S)
-1
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> m = characteristic(S)
-0
-
-julia> U = base_ring(S)
-Rationals
-
-julia> V = base_ring(f)
-Rationals
-
-julia> T = parent(f)
-Rational function field
-  over rationals
-
-julia> r = deepcopy(f)
-x + 1
-
-julia> n = numerator(g)
-x^2 + x + 1
-
-julia> d = denominator(g)
-x^3 + 3*x + 1
-

Note that numerator and denominator are returned as elements of a polynomial ring whose variable is printed the same way as that of the generator of the rational function field.

Rational function field functionality provided by AbstractAlgebra.jl

The following functionality is provided for rational function fields.

Greatest common divisor

gcdMethod
gcd(a::RationalFunctionFieldElem{T, U}, b::RationalFunctionFieldElem{T, U}) where {T <: FieldElement, U <: Union{PolyRingElem, MPolyRingElem}}

Return a greatest common divisor of $a$ and $b$ if one exists. N.B: we define the GCD of $a/b$ and $c/d$ to be gcd$(ad, bc)/bd$, reduced to lowest terms.

Examples

julia> R, x = RationalFunctionField(QQ, "x")
-(Rational function field over rationals, x)
-
-julia> f = (x + 1)//(x^3 + 3x + 1)
-(x + 1)//(x^3 + 3*x + 1)
-
-julia> g = (x^2 + 2x + 1)//(x^2 + x + 1)
-(x^2 + 2*x + 1)//(x^2 + x + 1)
-
-julia> h = gcd(f, g)
-(x + 1)//(x^5 + x^4 + 4*x^3 + 4*x^2 + 4*x + 1)
-

Square root

is_squareMethod
is_square(f::PolyRingElem{T}) where T <: RingElement

Return true if $f$ is a perfect square.

is_square(a::FracElem{T}) where T <: RingElem

Return true if $a$ is a square.

sqrtMethod
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement

Return the square root of the given Puiseux series $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Base.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement

Return the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.

Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Examples

julia> R, x = RationalFunctionField(QQ, "x")
-(Rational function field over rationals, x)
-
-julia> a = (21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
-(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
-
-julia> sqrt(a^2)
-(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
-
-julia> is_square(a^2)
-true

Univariate function fields

Univariate function fields in AbstractAlgebra are algebraic extensions $K/k(x)$ of a rational function field $k(x)$ over a field $k$.

These are implemented in a module implemented in src/generic/FunctionField.jl.

Generic function field types

Function field objects $K/k(x)$ in AbstractAlgebra have type Generic.FunctionField{T} where T is the type of elements of the field k.

Corresponding function field elements have type Generic.FunctionFieldElement{T}. See the file src/generic/GenericTypes.jl for details.

Abstract types

Function field types belong to the abstract type Field and their elements to the abstract type FieldElem.

Function field constructors

In order to construct function fields in AbstractAlgebra.jl, one first constructs the rational function field they are an extension of, then supplies a polynomial over this field to the following constructor:

FunctionField(p::Poly{RationalFunctionFieldElem{T, U}}, s::AbstractString; cached::Bool=true) where {T <: FieldElement, U <: PolyRingElem{T}}

Given an irreducible polynomial p over a rational function field return a tuple (S, z) consisting of the parent object of the function field defined by that polynomial over $k(x)$ and the generator z. By default the parent object S will depend only on p and s and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Here are some examples of creating function fields and making use of the resulting parent objects to coerce various elements into the function field.

Examples

julia> R1, x1 = RationalFunctionField(QQ, "x1") # characteristic 0
-(Rational function field over rationals, x1)
-
-julia> U1, z1 = R1["z1"]
-(Univariate polynomial ring in z1 over rational function field, z1)
-
-julia> f = (x1^2 + 1)//(x1 + 1)*z1^3 + 4*z1 + 1//(x1 + 1)
-(x1^2 + 1)//(x1 + 1)*z1^3 + 4*z1 + 1//(x1 + 1)
-
-julia> S1, y1 = FunctionField(f, "y1")
-(Function Field over Rationals with defining polynomial (x1^2 + 1)*y1^3 + (4*x1 + 4)*y1 + 1, y1)
-
-julia> a = S1()
-0
-
-julia> b = S1((x1 + 1)//(x1 + 2))
-(x1 + 1)//(x1 + 2)
-
-julia> c = S1(1//3)
-1//3
-
-julia> R2, x2 = RationalFunctionField(GF(23), "x1") # characteristic p
-(Rational function field over finite field F_23, x1)
-
-julia> U2, z2 = R2["z2"]
-(Univariate polynomial ring in z2 over rational function field, z2)
-
-julia> g = z2^2 + 3z2 + 1
-z2^2 + 3*z2 + 1
-
-julia> S2, y2 = FunctionField(g, "y2")
-(Function Field over Finite field F_23 with defining polynomial y2^2 + 3*y2 + 1, y2)
-
-julia> d = S2(R2(5))
-5
-
-julia> e = S2(y2)
-y2

Basic function field functionality

Function fields implement the full Ring and Field interfaces. We give some examples of such functionality.

Examples

julia> R, x = RationalFunctionField(GF(23), "x") # characteristic p
-(Rational function field over finite field F_23, x)
-
-julia> U, z = R["z"]
-(Univariate polynomial ring in z over rational function field, z)
-
-julia> g = z^2 + 3z + 1
-z^2 + 3*z + 1
-
-julia> S, y = FunctionField(g, "y")
-(Function Field over Finite field F_23 with defining polynomial y^2 + 3*y + 1, y)
-
-julia> f = (x + 1)*y + 1
-(x + 1)*y + 1
-
-julia> base_ring(f)
-Rational function field
-  over finite field F_23
-
-julia> f^2
-(20*x^2 + 19*x + 22)*y + 22*x^2 + 21*x
-
-julia> f*inv(f)
-1

Function field functionality provided by AbstractAlgebra.jl

The following functionality is provided for function fields.

Basic manipulation

base_fieldMethod
base_field(R::FunctionField)

Return the rational function field that the field R is an extension of. Synonymous with base_ring.

varMethod
var(R::FunctionField)

Return the variable name of the generator of the function field R as a symbol.

characteristicMethod
characteristic(R::FunctionField)

Return the characteristic of the underlying rational function field.

defining_polynomialMethod
defining_polynomial(R::FunctionField)
-modulus(R::FunctionField)

Return the original polynomial that was used to define the function field R.

numeratorMethod
Base.numerator(R::FunctionField{T}, canonicalise::Bool=true) where T <: FieldElement
-Base.denominator(R::FunctionField{T}, canonicalise::Bool=true) where T <: FieldElement

Thinking of elements of the rational function field as fractions, put the defining polynomial of the function field over a common denominator and return the numerator/denominator respectively. Note that the resulting polynomials belong to a different ring than the original defining polynomial. The canonicalise is ignored, but exists for compatibility with the Generic interface.

numeratorMethod
Base.numerator(a::FunctionFieldElem{T}, canonicalise::Bool=true) where T <: FieldElement
-Base.denominator(a::FunctionFieldElem{T}, canonicalise::Bool=true) where T <: FieldElement

Return the numerator and denominator of the function field element a. Note that elements are stored in fraction free form so that the denominator is a common denominator for the coefficients of the element a. If canonicalise is set to true the fraction is first canonicalised.

degreeMethod
degree(S::FunctionField)

Return the degree of the defining polynomial of the function field, i.e. the degree of the extension that the function field makes of the underlying rational function field.

genMethod
gen(S::FunctionField{T}) where T <: FieldElement

Return the generator of the function field returned by the function field constructor.

is_genMethod
is_gen(a::FunctionFieldElem)

Return true if a is the generator of the function field returned by the function field constructor.

coeffMethod
coeff(a::FunctionFieldElem, n::Int)

Return the degree n coefficient of the element a in its polynomial representation in terms of the generator of the function field. The coefficient is returned as an element of the underlying rational function field.

num_coeffMethod
num_coeff(a::FunctionFieldElem, n::Int)

Return the degree n coefficient of the numerator of the element a (in its polynomial representation in terms of the generator of the function field, rationalised as per numerator/denominator described above). The coefficient will be an polynomial over the base_ring of the underlying rational function field.

Examples

julia> R, x = RationalFunctionField(QQ, "x")
-(Rational function field over rationals, x)
-
-julia> U, z = R["z"]
-(Univariate polynomial ring in z over rational function field, z)
-
-julia> g = z^2 + 3*(x + 1)//(x + 2)*z + 1
-z^2 + (3*x + 3)//(x + 2)*z + 1
-
-julia> S, y = FunctionField(g, "y")
-(Function Field over Rationals with defining polynomial (x + 2)*y^2 + (3*x + 3)*y + x + 2, y)
-
-julia> base_field(S)
-Rational function field
-  over rationals
-
-julia> var(S)
-:y
-
-julia> characteristic(S)
-0
-
-julia> defining_polynomial(S)
-z^2 + (3*x + 3)//(x + 2)*z + 1
-
-julia> numerator(S)
-(x + 2)*y^2 + (3*x + 3)*y + x + 2
-
-julia> denominator(S)
-x + 2
-
-julia> a = (x + 1)//(x^2 + 1)*y + 3x + 2
-((x + 1)*y + 3*x^3 + 2*x^2 + 3*x + 2)//(x^2 + 1)
-
-julia> numerator(a, false)
-(x + 1)*y + 3*x^3 + 2*x^2 + 3*x + 2
-
-julia> denominator(a, false)
-x^2 + 1
-
-julia> degree(S)
-2
-
-julia> gen(S)
-y
-
-julia> is_gen(y)
-true
-
-julia> coeff(a, 1)
-(x + 1)//(x^2 + 1)
-
-julia> num_coeff(a, 1)
-x + 1

Trace and norm

normMethod
norm(a::FunctionFieldElem)

Return the absolute norm of a as an element of the underlying rational function field.

julia> R, x = RationalFunctionField(QQ, "x")
-(Rational function field over rationals, x)
-
-julia> U, z = R["z"]
-(Univariate polynomial ring in z over rational function field, z)
-
-julia> g = z^2 + 3*(x + 1)//(x + 2)*z + 1
-z^2 + (3*x + 3)//(x + 2)*z + 1
-
-julia> S, y = FunctionField(g, "y")
-(Function Field over Rationals with defining polynomial (x + 2)*y^2 + (3*x + 3)*y + x + 2, y)
-
-julia> f = (-3*x - 5//3)//(x - 2)*y + (x^3 + 1//9*x^2 + 5)//(x - 2)
-((-3*x - 5//3)*y + x^3 + 1//9*x^2 + 5)//(x - 2)
-
-julia> norm(f)
-(x^7 + 20//9*x^6 + 766//81*x^5 + 2027//81*x^4 + 110//3*x^3 + 682//9*x^2 + 1060//9*x + 725//9)//(x^3 - 2*x^2 - 4*x + 8)
-
-julia> tr(f)
-(2*x^4 + 38//9*x^3 + 85//9*x^2 + 24*x + 25)//(x^2 - 4)
diff --git a/previews/PR2578/AbstractAlgebra/functional_map/index.html b/previews/PR2578/AbstractAlgebra/functional_map/index.html deleted file mode 100644 index 14e0ded6b258..000000000000 --- a/previews/PR2578/AbstractAlgebra/functional_map/index.html +++ /dev/null @@ -1,17 +0,0 @@ - -Functional maps · Oscar.jl

Functional maps

A functional map in AbstractAlgebra is a map which can be applied by evaluating a Julia function or closure. It is represented by a map object that contains such a function/closure, usually in a field called image_fn.

All functional maps belong to the map class FunctionalMap.

A generic concrete type Generic.FunctionalMap is provided by the Generic module to implement a generic functional map type. This allows for functional maps that contain no extra data, other than a Julia function/closure.

Custom map types can also be defined which have map class FunctionalMap.

Functional map interface

All functional map types must define their supertypes as in the following example:

mutable struct MyFunctionalMap{D, C} <: Map{D, C, FunctionalMap, MyFunctionalMap}
-   # some fields
-   image_fn::Function
-end

Of course MyFunctionalMap need not be parameterised if the types D and C of the domain and codomain objects are known.

Required functions for functional maps

The following functions must be defined for all functional map types or classes:

image_fn(M::Map(MyFunctionalMap))

Return the Julia function or closure that corresponds to application of the map $M$. This function only needs to be provided if this function is not stored in an image_fn field of the MyFunctionalMap type.

Generic functional maps

The Generic module provides a concrete type FunctionalMap which merely keeps track of a Julia function/closure implementing the map.

Such maps can be constructed using the following function:

map_from_func(f::Function, R, S)

Construct the generic functional map with domain and codomain given by the parent objects $R$ and $S$ corresponding to the Julia function $f$.

Examples

julia> f = map_from_func(x -> x + 1, ZZ, ZZ)
-Map with the following data
-
-Domain:
-=======
-Integers
-
-Codomain:
-========
-Integers
-
-julia> f(ZZ(2))
-3
diff --git a/previews/PR2578/AbstractAlgebra/ideal/index.html b/previews/PR2578/AbstractAlgebra/ideal/index.html deleted file mode 100644 index 24cfabf95c1e..000000000000 --- a/previews/PR2578/AbstractAlgebra/ideal/index.html +++ /dev/null @@ -1,75 +0,0 @@ - -Ideal functionality · Oscar.jl

Ideal functionality

AbstractAlgebra.jl provides a module, implemented in src/generic/Ideal.jl for ideals of a Euclidean domain (assuming the existence of a gcdx function) or of a univariate or multivariate polynomial ring over the integers. Univariate and multivariate polynomial rings over other domains (other than fields) are not supported at this time.

Info

A more complete implementation for ideals defined over other rings is provided by Hecke and Oscar.

Generic ideal types

AbstractAlgebra.jl provides a generic ideal type based on Julia arrays which is implemented in src/generic/Ideal.jl.

These generic ideals have type Generic.Ideal{T} where T is the type of elements of the ring the ideals belong to. Internally they consist of a Julia array of generators and some additional fields for a parent object, etc. See the file src/generic/GenericTypes.jl for details.

Parent objects of ideals have type Generic.IdealSet{T}.

Abstract types

All ideal types belong to the abstract type Ideal{T} and their parents belong to the abstract type Set. This enables one to write generic functions that can accept any AbstractAlgebra ideal type.

Note

Both the generic ideal type Generic.Ideal{T} and the abstract type it belongs to, Ideal{T}, are called Ideal. The former is a (parameterised) concrete type for an ideal in the ring whose elements have type T. The latter is an abstract type representing all ideal types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).

Ideal constructors

One may construct ideals in AbstractAlgebra.jl with the following constructor.

Generic.Ideal(R::Ring, V::Vector{T}) where T <: RingElement

Given a set of elements V in the ring R, construct the ideal of R generated by the elements V. Note that V may be arbitrary, e.g. it can contain duplicates, zero entries or be empty.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]; ordering=:degrevlex)
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> V = [3*x^2*y - 3*y^2, 9*x^2*y + 7*x*y]
-2-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:
- 3*x^2*y - 3*y^2
- 9*x^2*y + 7*x*y
-
-julia> I = Generic.Ideal(R, V)
-AbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.MPoly{BigInt}}(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[7*x*y + 9*y^2, 243*y^3 - 147*y^2, x*y^2 + 36*y^3 - 21*y^2, x^2*y + 162*y^3 - 99*y^2])
-
-julia> W = map(ZZ, [2, 5, 7])
-3-element Vector{BigInt}:
- 2
- 5
- 7
-
-julia> J = Generic.Ideal(ZZ, W)
-AbstractAlgebra.Generic.Ideal{BigInt}(Integers, BigInt[1])

Ideal functions

Basic functionality

gensMethod
gens(I::Ideal{T}) where T <: RingElement

Return a list of generators of the ideal I in reduced form and canonicalised.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> V = [1 + 2x^2 + 3x^3, 5x^4 + 1, 2x - 1]
-3-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:
- 3*x^3 + 2*x^2 + 1
- 5*x^4 + 1
- 2*x - 1
-
-julia> I = Generic.Ideal(R, V)
-AbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.Poly{BigInt}}(Univariate polynomial ring in x over integers, AbstractAlgebra.Generic.Poly{BigInt}[3, x + 1])
-
-julia> gens(I)
-2-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:
- 3
- x + 1

Arithmetic of Ideals

Ideals support addition, multiplication, scalar multiplication and equality testing of ideals.

Containment

containsMethod
Base.contains(I::Ideal{T}, J::Ideal{T}) where T <: RingElement

Return true if the ideal J is contained in the ideal I.

intersectionMethod
intersection(I::Ideal{T}, J::Ideal{T}) where T <: RingElement

Return the intersection of the ideals I and J.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> V = [1 + 2x^2 + 3x^3, 5x^4 + 1, 2x - 1]
-3-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:
- 3*x^3 + 2*x^2 + 1
- 5*x^4 + 1
- 2*x - 1
-
-julia> W = [1 + 2x^2 + 3x^3, 5x^4 + 1]
-2-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:
- 3*x^3 + 2*x^2 + 1
- 5*x^4 + 1
-
-julia> I = Generic.Ideal(R, V)
-AbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.Poly{BigInt}}(Univariate polynomial ring in x over integers, AbstractAlgebra.Generic.Poly{BigInt}[3, x + 1])
-
-julia> J = Generic.Ideal(R, W)
-AbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.Poly{BigInt}}(Univariate polynomial ring in x over integers, AbstractAlgebra.Generic.Poly{BigInt}[282, 3*x + 255, x^2 + 107])
-
-julia> contains(J, I)
-false
-
-julia> contains(I, J)
-true
-
-julia> intersection(I, J) == J
-true

Normal form

For ideal of polynomial rings it is possible to return the normal form of a polynomial with respect to an ideal.

normal_formMethod
normal_form(p::U, I::Ideal{U}) where {T <: RingElement, U <: Union{AbstractAlgebra.PolyRingElem{T}, AbstractAlgebra.MPolyRingElem{T}}}

Return the normal form of the polynomial p with respect to the ideal I.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]; ordering=:degrevlex)
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> V = [3*x^2*y - 3*y^2, 9*x^2*y + 7*x*y]
-2-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:
- 3*x^2*y - 3*y^2
- 9*x^2*y + 7*x*y
-
-julia> I = Generic.Ideal(R, V)
-AbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.MPoly{BigInt}}(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[7*x*y + 9*y^2, 243*y^3 - 147*y^2, x*y^2 + 36*y^3 - 21*y^2, x^2*y + 162*y^3 - 99*y^2])
-
-
-julia> normal_form(30x^5*y + 2x + 1, I)
-135*y^4 + 138*y^3 - 147*y^2 + 2*x + 1
diff --git a/previews/PR2578/AbstractAlgebra/img/types.dia b/previews/PR2578/AbstractAlgebra/img/types.dia deleted file mode 100644 index 484b473f460165ff3a5127b078da4782257ee42d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2988 zcmV;d3sdwTiwFP!000023+-K9bKAHTeb2AZXkWcBaPhrbXQw;Uv=5!OlWdMTUvE~E`@Gr|>+)hs5S~u* za=u;^?spWim~WID`|e_TUDvliou7aC@&&CPHd(!{ z(5kpYoBaHL*=m)Yn?~o;_wOc?=N&AvI$`F> z^{twA^Yv<7P42VR#q@{I?lnDcx;fwK=Y_s+vt@o&<=OAuU1Rgo`k1b7^J=%-o7?rK zFiq-*+r1_o{n&q>wP{*yOrvu7{)fM?AN(OTA3XKdcA%X`>YJ=u7UjMjb8c4tL;z9% zU`__tN@K|+c|0etH+MCxxz(`ds$tC)o6FmERaaS2@0+|@uUC0idaHGHmmhCuGtX8A zVlTNB;Kk>nuGil={?FNJbBF`}<8OD{Ywz4;RV-el_{yD(5+W{qV57D;D|YJ22aB)6vs) z)9n0vXMMNbp(n`~E&Lo@H#r@;EXXj*n_1}D6H_m>l zvvQGDi^-3ZU)Nu!PaMQBkYaH${TJRoS-b9;&P*KKJ6pHwZ;--B^D{t{@1BDF0McdP z>T0+D%6O2K%T@l(hBYzc2=gpCx%*LAlsVqC$`U*tGro9p$L%NE-B{V}oq{yl#J>jCKfE&p0SgD+{|OG4pG5SJEH zM8*WLw*rV$K4XYdW02xwE!Or_d?#A(wCTE}j^1vy+hM~0%x~7{Q(kxQ;THyxE=IC0 z>o$Y-^U3GzrdU0go6OEN}Am>zS8#H_f>`&`RsT`MNvf-W}5Jz43G?wBMNY zkD|<5hExcRNfrheV#XteG}FXJBrO@?Gl>Ys%E6DA-^W>=ugmf>FBi^}SNXT!MEa2) zi{lQ(T=Dts?h&-H;FmhJ{+QEduI*+o+CKhea&6GiM5%i1_|)X-ujWMWIoa}E(tMY0 zf0yo)%AEsxC0^SZAPt49yHhCKoyk(hPreJ38YAGzepm1$B{r5 zj$le`xB(Fp!OjRE0W)Iwg><7m)i4$o_&0OKZxauU%>&!8m}uY#X&?_yO-UFDIxI8A zb{G{Q3I2)0@e!VGcd68({52~F2Rl+IK;y95mt&c#2%O4 z=wKjAlWByo`on-M?G<3(TIS{Z?NX^^P4swyP$6w=GgKZ5s=@g$oWmzlrioh z1aszUG&F7qwpI)`)H47i2{>vfMpH2SP~@vc;)c<=VH+9~H5?x`B%}u|mN+9ANgY>= zMVt|4^;pIpn5-nSAS=kLRC*aykpRTM!*TRFn8oIu3SIZu|y9CrH4FR zti?Q2iyDN#S;550wRl4g)flQTPN|jX;V^2g7BD7u_?Fq>zt^jWE`}H`ejy>G=wQVb z)2yL~%qh08t-~042>i(TtXp$ZE)S4v?RwYJ1|FH=p#$=9ERKb+IC&Zt7cNVIhV7`x z+A7DWxYbs95(iOdegnNq3~o>cr+N@qnGC^=nh;rCr(tB!*5auTId593rhq|ogvJq)h=U! zjbVxe#WHH8?@)@U?a>@sbvyx=JI$UNK>Ofw+VU!;B6B&*tHAOq$K{MohCoFpb78)v zieD5m*8yhM2bh%wmXeXNOq~^QP&O6?0vQ|0L5?LL4+&)62au(OmBz87GFUT;`>1Se zD!UdhHkQMDOJE)}#TGrJ*vcj~6iE^{#cs@CX;W-B3qz4&W5}^>5|L8ufl}-iG^P~$ zEvMLBp-J|!#M0K4ITAYZI`_s7wnHr-uE4!jFpgy)RgrH}d>U$!LLy6d+Fa}m z;dZ^?*pxdEvVl6p-cqIux@0uaZRQiH7HS4I>uKf_1($CIy2{NdYX0ZKu09cVp{Lm$ zZnvR{JR43a_}OsfcJjhZIKw9HM&HS+)ydv<0Vf1+_sZtiFQ{QdftQX&$3dlEJ4Jvv ztOys|=+_(fdfm{|T$W%Cr9hKNn=a7?jj zjIl}d5SswJ${^~*@{=86CzchGuFj%IF|GWeDAU@KA>&gUBvXJI>EaS9$Fns)*3>@) z)~zlfSgXvk$kW zH1e7=V*`|1ac0wRNn@`#3vntfoE)+o+sh(geZ~+Yk=FogX6LU2Z(z*rMj5ej9OPJ9 zIXP(gRreE(?So`^f3b3pxz+(U4dxb^x^=EB9_FjoT9gSczfCk5|+;-^sIPO8u zXICU}1T3za&st$fSScT&&LWjCA}wFi@eQEk+lOLO@r_Vs%t;?%3ER;IaAcLSH3NtX zCo*PMNJ>rqAxE+TB88^GLeoARQ*0VzZ0cjOTib2q%|OK?%i|hLhBtY693ZOPyoUL8 zEa4w|_fPvAwiKZTSU}ni$`qu=7^G+)kN>f?0f~rGv4fPeBoOyfM?iv8FqSFcF$5{U z31|vaLp=wm6_zPXjWJC1u?vT0*iJnH#OG4hl0sZHTndN+W0~?%aH)?eMh!=$S}~bo i)JbEMf4|Be^6LFN|Hk|*tL*0eyZ-~^duTf%zyJWvio9$9 diff --git a/previews/PR2578/AbstractAlgebra/img/types.png b/previews/PR2578/AbstractAlgebra/img/types.png deleted file mode 100644 index 96eb037d5a2f9bcbb01c8c92fd330adbf1adda07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17647 zcmaic1yq%5yX{g`N&x{uNohq&K)OU40YRig5$Wy@U5GS_fUxKk>Fy9kKJqm)?)seQ)dc2-aZg0T6EWm#6WKso znNl6b6rIZvfgkNy*vy6_Ej^V@g$Y!jsQ+Ypg1n?z>T)|J>Ba~x_g&&w*R>?X#FBBa zpW!LrDS49DV?H5DhQ^RE=E5i;;?vhK+5!yS1+w-0KZEyKPx7*&J`Qs+-~MaBiqKe1*MSVCgfXn!&5uI-D9iZDJiA`AIp!o4*}Ddf_H zL4LV%a~8YBf~WV5X8vID$@lFVm8>0&s|if2l0KLn$$FubjzXQJq@>m5Ur2=AP;qfa zoeA-gk*|akDX%d`1hn73dDS7~>vN8n#}=^!289|!%md9KO$K-G-t9IkwFosS$KjO@ z6OEMXm-ALwowjDDL7wXB)O<2q9dqP}_z`OS{`+@{=`s`7ZpNH!%YI`GS+rB~}Ryd9zcK`yxGnai zH$KCnX`~W*@r*^htg5~JJvn4sj^In*F=;Q=G*7Ty;N}jB_E{1jHd?` zDpV`T$#VxL9gLV%da;FQH@pLYBD?~ zA7Z6i(x)d}(@&!dFB+Sbp~BR`nD#m0i=*Y%?1UQCPL>^x+3NWnBpNj?nmP_+ksL_;WAkvuQ zrYiG|Ze*&ZMKIJvlj9cso*NDQ|q`%9Xco-}Wqab#*l~hzU^M zx|Q|h4i=42nY+u>(nC$%}N;~WGhHs@u2$6N^9Bh+=QFN?Vf~TU28SuTy&^{=u@+IY%u=Z#sefr{$%v)a?oVJuAp--$t5>fIFQl8) z3!lF3wIYmYmDq0$zQwihxVxmuAlaKzEBGurmx11*5(o2}V}Wvak5p+&#tq>m3gRig z&;;X_-A>8<;$5x1FLo!n*Y)OjWV!s=i>xvQMO-!S-Mw4LZ~4^C%}q+`?Z()6U%O`N zORWBZ0lg}RfR0MHUFPG9?p{bWB`^0?%}P6l_#|Pfj=@LYk}l_jJ!hw;8{2&o!~MsF z2i49T$;`tu5K}Los(;OFz9SwPZa?2)Ib75fvz0J^7=%D=Q(Ba`&Oe#He2<1+NN8;G zyffm9c=Eg8V8bA!dbWg(q&(K<{ysiFzHyMaxcKYWuNQV+U&f8S9=W~18*jvz(d}i5 zf{ck(CpUGnOYtW|sb%+HdE@IP{^sj*&sB?B0oIs=1U4ajGw#@lT6be(W7yN_m=QzH z!evhsicV4I_B)NRI=4SRBh3f%x);BE`EqpRW;gTT42tGZ`tLu#qRq|B7IqG|=NGA^ zT&CG;)M{Ne4Rm!W3;W*^tPzEIy5HTa!$4Jc9J;OKHfc=iUoVsPLn8Xrdy<<>)Iss1jDPY?YZb1fvzx{-STXz!Ef;Eu*w?acW*T5}#}?otm{QK7U++lj}YY@Xy<^$0Twtp5Jm zHd-mkB$Oao9S`>|>fdfQtSjd9obRB8xY?H4bLV}p`!9x$N&A%E9eGR7H`4iofr;o|Lb{(5 z@yruT)`siaGqW$+y4)2d8o5eUYk2rKsSfutGBS!%rAt!om=5Rod$|u+MwSa)B0sHR zRrr#Lp%oj^8ZejnEL+X>c3K7_Q>Xr=p`4$Q_IFrqW?SAX#tU2*|M201nYnrVsCGNe zw{5Pl*;!%K-bQ&esm{IO>|s6OMt=;y*4C=DH=UzB9(VZ*m0oa@`9%}crbH3ZNF+a* z{qx85c8yd-MA!@eowL*9MbG7CYVVr5y1H~;rhDz)TKHo@q;Zp_TDcpECn1?$-4v)^ zx%3`4)^0AD#l^)G?WBRxBF!)kp%>Q_YNs(fW-h&yX?`&(lpn{E}i)mQ}- zukKXoa*trUzH;kHh#^c%tBA>8@(Q@|q3Wr4%$n9#URWdR% zDzAfS%h57f@=y5kGBO&qZl#HdliB%oRS@P`-!|{cC{8g`VMM$7qc6kMIO(z7PA45& z0&l6S^ZNeox}eiaI1dkX6kwUN<8^zA{YG4NkBzUGD*iKqfHORr8+o*R0XuG)`$+Oq0>g$WTZp|v7cw{L<*~RQGZcxg~%38EE zZ*6Tw-cxs49#{qNMngkWT3U*MiFY#XPn{Oh<$t=YfBv(j<#Se+tfHdRX1lD|Q0goZ zlj27nJj6aTJA1T}^uXp!^YD)F{@C_v`Q#N$Om%g2bb(L^WbR~ zQV~#&v9Y6HN=tX>!((HQ;3_@7)ZXW(`%rm8sYOM2c%0TJYWK(Nm7sCJ#k@~8o2i7| zD$IlY{=U|}L+^C( zUWeS?2zWFnbk2xpEhg=HAuJ#$NYG}g0Uq*fyHk`%90vzy=$9-SDs`JcHh%l|4WC+s zC8L z_oc(AUdh*=?u~wZgE`pWFDW5WaN+USRd}5J1`K=(0f*1t=V$t!yOHhAbv_s_TKElv zLWi>vIDRR4d7&Z;s%mO#s;b|k@W{A77Zh}LcIHD5P|w$!?@WwlQ_&x&^K>66E{D6h z|MCZ)%OJ-P5~9=mA_m5y=K&_#y{W^NHRawmPn^hm_7^zFwImcJuMhv5zx0Ha3(*PgVPnmod@F`9wwr zYqhI)dDo$21@>F(oZ0o{VAFgcXPR%VFY76DB+g-$-_H7^_vz8@*RNl#VVUFj?bGlw z9nq<#Fw-2yg#7sNc@IG89ZDvF7T z85tR=sYUfomt1uDNYTI>FYI3SvN;qP{`>cDeecuA2|odcg(vxXwK=%;`xEX^5QI9j zRloG~sCawV&{a!%94%&|t6=B$@bK{YL9=KYUUN1L|Am8`g@uKunTmjkAP*f^hBjA* zi{D(iHd1My+1>~P+ggcfuS>!@OmwEES>nD{ktCZPg6oe_JnfyG>%Fibzx2;&9r-43 zA;gTKmaN7*PXq)93wfWNK*^D=-o>L9v9N9^_roRa@pXl}-CG@s}wd` zCnX>tAR(EPy9UXH5_WeI6KgoyU4|x5eR2CfdaIVd2M|GK;nEmFCfnNDDl02TMn>*W zde^@pEk8e=Joh^M6OB!?xw+}Sw_^LGvenQam9{ldE&Bmk2%8$G{ahPd`z;blOhST3 zB{Za0`19vaR_(Hiid;1u;a>=mZ0&L@Nf(R`-6?XM16z&m9#8|UbdBH!Af}+;kH5Q4r!#3_UI?A)=TEst z44-uYj{}a=#^}h%O(9X|H63xR(-#plHxj+iT&sRVk+UF4Vlv59TRuywjT{xVQ&3Pa zFrcMLgU_lzJIZ#vFj7oLO}(DST80D5d8yw1;)Z2mVIkxy1Cm9fz=wbnmbk0yNy5D4 z*_^CNcZy_5TZRIP%58xLAIbda!i5X^9-B=V_(C=i!q9hnGnM2i-;=_eykQIQj1Flr zRN#ANf3&lRBuMRc*;~@~S5EnT=v1jtGh)4wfW#Nf< zi}%@fVsP-)!AHL@ag&8CN7_&@#Z8iJYlcw?!x|FbxDkm$2|6yRPAJrGUteVik(zNi z*NA3PSy6#XI?3yCurW3DJYoLY6^!_o95LAqmA-IGDtK7Ur2W7)BQAN#Us0^v`}_I1xt`O0 zq;dI~X=#QHJ{Kgy=XD@!`m3F-#ox)LbCQJ!b&`ijManU-aM}L;9v4R;5TBT6E&N#t zs&G5Cb!1f3mXI|MO4Hgtg1ctINVl8TCW24X&goz2!3iPg=Y zm|@dxbzMQ7)+n>MMe}`E8&|wBB7Wh!G?uKK+|Sn5!r@Hm>NJaqi?%g4 z*rPvupmoIJ!P4e$+*b~8GtdPXahuc|O8@D}$qJ_wI9$uCTYbMVT=;GqrnF(%k$xk3A@^q`C z+G`dwPzwwAz@A34mHg0TiGqbz*4O7Mpgsvq$VKG8hGn7i_4VD+c}#8mTrE$h)piUn zwd+dq2bsOSY$v8nTqjR(4nDQ(&&^JGzC^e zeF97ablB>_<_vl6m$I_5qN1WE+Fdrqx=+`~F2Xj3N`+CyL-Flb*AJL$ZfY8Losaj& zqjX!VoR5=L)Go6K2n;lfxjC%_%{s*#Yf_5c8E$5FAw62}XGaIn$|r~OiGbalrc(eK zKJQ9;$fOw8(%GpbCs(BY2yhu(TuVeHp9mn#G;363q-L1o@;0B)BK~b902M;+dlpb1 zc9+$laiTlfr%#_!rNiW|lbvMcArAg}|ZX*FII5cT8x_miz(?9ihD_eaqRgbNDE;oW{( z>$V#h988by*$r-YDLvK!?!&OT;b4e>zG5eZNvB`$Rl7?YuQ*t0t}fnkemZ&XD!_t( zpx}4^i>8>A65!r*c2!1P1fUuL92KU#)j|b*(_?piQk0wfBf%EHRxNf)E~B<~-pR*U zhs~mA(~B))d*~+$sk=+Z#MC^e5?cazPhCrEsk=aIZ=;0DC+EhE8zB_@A7(0m*h7i3 zr;GZNahr6($RSKk)k31Bh$xB*4<{fd{=R(zGk_(@!G8U@0@mT)sC5_x|L@^0v4JjF zit6L_dT#(|@T35I!`m2|%&hd3{ecSZ{W%dL72z`ab0Yk>Fg++s;bD zyM1s=-e-sNFnl;k&+M~F_LLo%?EUbqZ%JCeIP=FS5#EM z(3`JO*l1)&i>x{L9h6_Q^>Yv~J3N8&+E`4x(&NW*g3fuFjUP3Pj2J&eG*9_rA#N)P zZC;|8^{4hSF)=C7oca^3k9Y0bA6Ke+*NdGnKp?ih6Db`W9`+9odILn+`)O!sNFe^0 zF`|8%9x(=B9PzHc-W%otEE>p?yjo7{noTJg8JS0q9%*UCVm`u%f$EG9$8v?q7@G!y zvrt_u`AOHq=iA%cor$9Bl`UdXu#r9l;u%Vbc~9<`nVDJOsVK7QRB-U|RU{|B0J=CK z_?jUWTnUSYo`a(Rpf8fZ{gEVrI5AGsFMez?N7#Zl`OUF#btg8KwNtH^R5#XJj)IOJfd7&5j>t0 zq-7c`0`Z}x5jo49fXNjUN)z<8wB(kP!&->M(JIEDo3?%A5Kax}^h``d;%6|x2;3ne zB;+Yo=BaiN>=Mnc$B^3-?WDr5yb`Vcj>AnW@T49Vh zuyQQ6cjo9g_KPkaPbWv+nfm(L@d77r2#;3iJ!r(ujX8N$G-p*b^@VYD{ z`(x1nhZP!hjap>vP=J*rXhZpOL~EK_Hjue$+0U~3SKeQG^L1+K{w0(jJPImRB}*cg zdLYkiXYoqxya|~-XUxMO2v;BSwgh1mfr_&7^bhq(=E$Fr?L}1l@rum}1NYe2I$Bzi zw(afgC`6Ymbv3g4i}>MJjua!|&T8L<%rOlJe@aYT|LK3Zyx|@fV(JQ{r8PiLfb%45 zItM`CRA*~V7thcRC^ZMnVVw_~yjbQ3+OdT0eS5hk%_>z|@2_a~a#B{8D^R3v^VrSG zh`0O*Ay3Eqo~qGIx9s?lhbrdLFKonjJs3zIm=DB>cpd@H0hk{pK+$`d(X?Pe_zd-fMhdVUIN)J< zMXA(o6K*#?=5P%3eV9YWLt9QyPX|uz?2I>#4QeJ8ihXn26{gV$flHcG8}?iXo7+$e z%F6b}ohM7ZFa*SYeZ{zrm}=2=9*5wX!74y>pdV8@LoptZN4W=dxQ@d?*?%B+_cZUNTtkrLV)dWj5&>ZZ6P zCMMODi-`!Su=^vYp>eZw`|{<>0`ZDVHew{uEPSM36#f4FJAwF)TWw#Vj}EMv*bJjW ztOOQNlJ8-maUGW7Z-Bf4(d*Z?hpp{>%3O*h$>cwm5FtVD-Ytxj-g`eBH2P2+W_h2d zP!Z1tw5=tjqj8`m^m@FAryESvi5^?n@prS0kQU@YAJA)M%)rP9 zM6*9AZ3gyzW~Cmn*I|f~vfH{TL~sGo5&OWLgk~04oBETjAb7ek^u>)^EnXb|mlq&Q z^~>kacf?yj{7DPF>_Gt=&HYeZ{34AZ%;YMV7e(+O(__&sh7lPj;P@pYLuyH*AsQk{ zjA+bpPH>GzY9mp2u@b?cUcqMRH~F2%PpSJ7ZtGzA{dqn-Tv zvsi-PKe^nQBLfw0hDhbA$zv62us~&nFh>&nE%Q*0SdDm4rrx?vPGzVYb45Y5}s4_=Nr7CCk1{@vb zs9O_HNc0CLK~S~dx0`KgY!n|%6yf-n&=*zem2*5+qQx3-${FJz5MSW4yM#BTP?w7Z z)uxLA7(}Zq{|CV=Btid_%)`r|(iLhzKl@j`oL&m$l_(~)bSa!8bzy}y3jYLp-tsOK zL4!h=M2rm$yQpelkc9{9Hyfsilq-d7!ORw%AXujQIFI_QMG9Hqb4kL}8LA$h4fkPD#Mpoe zJ6wifBSV)ggdXtEV4=W+z(crD!mS}T1OSI3rW`l!@FTeO)zk)-`m@tR8y^8}&+3T9 z3G)V`-9K41+0Vvhf*KKC?@uM+lz*e|Jbod@7+kjyDN4>b*RHk`pfD51kPzW6l3P zt&nHfHTf8DsTYFB71IDFvK{g-KGEFfK|epr0yrOLv5rn3?51tp2nVjaaTG!(|%1%O+RUBZ!!QY@4f~KMu6x z<-B>7?d`Pu)higITwr2Z-F-Q)O|(iheUdSEV?~d*sPdfhT-oOC6qk;i;=fET4;Gsr z85PImeo9DKle<~>{W%A~)&k*P0P9f)887CwUmi>R+xKGO^lYeBJf%c|y+)^%p#m>F z&^Qkfn;6GJA}=c&pqBm0J}@X~m|M^Qa)1U&^$r5PmD(s!Ez@2jqVYKgl#xk6T2>Ny z(BX$IjO-yK7hB)2;W+79gD-}SuuNLAHzj_~@aERo;bUMyQAX8$a|y&}H{#B#0-f@6 z_HsEadwV6fd+OV9Y$+RtYVd62pCt&fpc3Og%B5@NmK_!X!TjF<&`#L8n=Y$6Hdj3p zs?NX7FXJm=Q{2;V+bi*FNP;PA4>~%IYGyp-o*Euyc1q@_?HxTbw&AV9m`1||klgZ?014)J3 z{zr%tyz7LXX2rv8dy%zYOe`%%=GGXj1PV~RAEtq!ioM@53*tgwuqD4#ualcwRg-~o zmTHPeXB1(ke^ZeLkjqp<(rgQlsz92pxDML${fub442RFy`!R41PUoJ`w>vzfKg%W(Niv!aG)rAuEFWngL;_u|n3l>)` z8@0#w_n>SfwX{aI{`?Avrv#*GsVI1xWv(?|Nz`vY^%yx*0X=c(*ADI8UJZS-6Hu;N zDO&r48J5$PotrmuZL;3r2-}B@=Ie`M%JYYskCx@mU^_(`2~W?@lU~36l`)i3aKJ=J zLEK$`fg44@Xbqcp#uiF#ld83V<6}3vAqh3OF_ex}|KpVJK1(oY1rCMZLaE;S`1lkQ za4a8Mj+9{I;guz@SLJ2K9m<2+1ANdCLu&{6Rpw0l*NL*~6Vddp+F3;K!h^q_8sGN( z?CffnP1@sm&`R@kDjU!4nneOFUYU{c_Vj5VPp!?g_@hS{@lLjP93YZZvJ76njBi!y zSXW6V5h%NXBME9LNbIpCQJ-a((xAz6=Wq7al(5#|E=S?$UI#IUoE-S}XS56E*A)wr zwS@V-Dj%Q*FXZg|5w20YEwSCb`{LCQulg6gyg4SOpe6vpO(H(6hAI22BXNC9^153%RRe#@Z@lNW@ctwFITvOo+(`=1_t*JAAVPaeL6c_WFvIigf>*= zpDWnq*F-V6vKMc?eWviscGDvb(qK?JwfRfIqy9NzLR7ZKx}JK<4KouHtgBbYK%4~B zHTEo17z9ekF&`5uchk{L-F_q0g+NfJfXGMNuHa`p|;8QD#-k3yzx*eKX+hY1Z$p7;X@G#ufUDo^K|CN6&HKt%cS!DE zA9F3%(=F+nD~ZrKY-u;D4O)32_;aFpK7T)6#X_XI_Mtg}uC>1GYC0m^Gmodw1?48FQ2Vs7RJ=#Q>btVWS!w(J)7;|53 z6BWjQXGK^SczUp#5HuzriVmes&HV5(D8DOV-Qu^Sr;$ikIo)igRyaCn@2WX%<1I5j zSguwsc}KO;q0aE-`y4YHWzUDWtn@#BT3c($EzRbf)(5oZ?d*OzrH}Npa9zH1i9q}c z9)-rUXZP(ZBZO-6~_ z+7Fye(4r^E%iQy>^Ilfm{F|?-$X?XVU-l=GS4^n6NH7qv&wqiNn&~DQhH{P{N4bNX4kH>u{H6=v^BzPDZ+#Y@FU;^zWGb!md3(E>< zgI>G+>gjmRgD~G5yaq@iB`MkMRnyki29wCmkRKpm-?*ptT%s?E%cLvmACC(}51Uqr z3|tTgeL-+t{WGv9Cnq28ue0B|bCb^|snrnY+BMJR+;RZ+bdEkE=HOicp?h#LYri(j8P#iBBf3eq7+`M@JG*Pv=y>VxP zC2Q)Dn;0kz)ZQoe;R&RvJ-LO1PQGGNe-ubjTko8upFY%LG%zqo!+R)IckmlG>ruFv zjSY|+?X9hgllAAY0bE>Mz}8^VfLG?8T8@mYY|Q3czLt^(AOiV7#|xcN%hlQ)tUr6!^W2l9b6W{w0oE7?}aQ0~06F4kFLP8$viMA-Rt8YOz6cw!po?;4o z2Bsz^pM+euK)M4`Q7pnDN8W_M7%izeDdjs&~#@*J|R%AE~IY)QKp@93z>$|U(#&8)A^z{W( zi=Ne=pXSqFKdON=g+>HSUqw!i1rX#tb&dtQ;^kC6O8nku9#Ek{;K8Th>#FxYhpBfB zMs1hn*Yk&v5NO*^=(~4!n3>5qp8FuXj|$M@D>=^!5UbRDHd6p^Eb0`Re2_W;P?FeJ``ioovugV!T?zD zeTacI4SWf}n>mCZFeSKLELV>6N4sYP9GBAm`hIY6Z~&zI0i_WX3ThD#4ON!gx1WOu zjkd6$c|WKZAYscA=5{{KQiTEt80`FDChR^|{x%Fe9t6w7K>-0VLauh6o~J+!W?3Z}8Te&UA*w8v|1h!C?he$S?XqWmGo?h6`S=3hPhc${Bc!0v(bEG8 zt$xz$cooO*H@Fka$DL4))37CgTnwN&L9rYLPZv~RVd?@3Fapr<^H=8OS+#y(fB_vW zZ>vDnY&_Jhc1rJjk9rI=EB}i|By?hMR*bMv+`0vG@mkGx2c)ho)F1E|?c0=a-gnzs zfT9M*A8_q>wZ}d{e-Qfdh?a-xkdTMc$xqOZvf0)M9$e>zu4&M<*M^Jdfv5q_fnB$1 zwp-)XOt&;On6FHM9G8=md-%||Z`$Pn48sSEK}{(tS&iSmb;j|7IXVtr(b2q~M-DK1 zTStQFZ48nVoD<7n!~o@&fP%szf7TZR^DQ3b2&b=m=|2-#f0LY^_vtQLs|U<>mxaZU zZhOQ5%nyempJ}JNWD#8{YgNl^f7wLW1hkQiKNJ@a&q-(mHEgjqR>?&(3j}UnR#u_9 z1uUdWVpZC8aA`z|wu8+?8Y|%4yCI-5?IR2k)YsFaT>Nn>w6ux(1m&I4I7`GIdu|RnM#$AtXZ-^M_6d|!-Zh> zRm&bPvm6B@)O3;!=w?;U>uY%m?&xzAgs-EBeAbWP&ah~pV1S_h$JOhvO&QGMV9?;x zvxU|VRhbT%mX_8xIH*mU#LDFSfKKajx%Vt^eP9wK60dSvJ%TM6VR@vjn3a{aHe!-3 z_LP|F9b!Wh0%j3*3OW?rffUv)P>CR{*!Ambz=PR*??+P;hy`G<%hjp0gI}e>R&xSi zDgr(W5U3M`Tsff+>@4;|7tuur#4wmPT6c~2uxP;1z=#AlTuJwQ6SyKL;9W4SoS)2# z?p(pH(0%@V3i5st6(k)(_DoaruA_wBB}m=qLd>7!WMo)0kAR{TaDt>*wlD+7wp)EoG?f&gXaOv4AJcRQ3ABqXmjQ-FqjO&@`;`uyqT~8 zMQH2iJ!ClSjZTeAVRt`V6F`6&OjG>!b1(~*TIAUELl{95nRFVpgyI#)ZK?uRfxhdm zm(jT5hi%+vV{52h7+0=-{`}cxf804f3sURwbbnI)4l!(mgWZktDYW)dqT`xRNJ*)y zs@eyO8bZ#i7{lquWB&^1zlP?*1mQgjVoRag!#R|Co{nwCTToA+7i)3E&4 zDVmkXW}GoK#r+Td7gB0@DEq>Vjg4&%ZGI8ZPax=7U=A(a*#+^%XFXNe9cHRm_Mi$3 z0;K`{!4nY6l(;_PT?VZPE*kHEch> zE9TM4&8K|$xSiN|Z4i@n|DHZ#gYdzF2Oy3j!yozM6~<(%<pB9Yth;Ty7jlWl-4I2$J!*+01w*lDz)T1Z zV|YS8@#zC6&!>?eKMuuZ0O*G!YH=&QsYqjiSZVE4aEn+%GeL#}XR(~#NL0o3CVKRq zl0EjaAJMA!@^_!r{cpo81xcj1vo?3+HTGP`%)ha+IU zBYdI1AZ`Bma`W57bu3P#l3wFUj5IOx>p*)2aF-K=#akxN&-P&?0kCwJoxKy|{ze&< zz8Z7n3NwoJh9b3)3&-8NvKj#dmdXJG=?h%F1M-%NzoKRwthmV_>Y8n#t~DOAdV2aq zU%S}i2MkDWMmtDIiokAyFe<=x=gxv3sh$h;4?x8c5fP}JiUMN|v@zwwfcx@i1`W{< zx8q(4Tk1}HWlrJO%8gPeMm@_@9Ws%{VP!&8!U+#@m_<9cmk0AnJAkRF1&7Pt`lSAo zC%2zj;6eEdINA}zL$AFdj8n*Pz_{4Pz$kU`^0>~s-v>%B-j(c{$5mLq;9x3Y0S*ou zz!zZOyxxIU#RVM}3LqgB#6C* z>&*J?tpp?ha)1*|<(8v+aJU5Op>^6j+^H)N%3GXHD;iLn!9EJ!XPkLyDJex1Pe{_{ zrHKn*HqnC_E$J^f%S~)|2YC!&B%CN4>U@Jpdp!vb0!2H!Ew}?adwa+u<>?bJB4nng zqf0KBdL|2AJWAbNnXFI5b7I2;q^e?BRa4^u)Ut}DE^}Nhwb%upd^G5-a$F|)3%Jl4io&WYt&-2M4WP9N zb%M7*Kd=jd_3#(ASQ#jdcocjEwliR3k?2kV?+$?OEg^5P`@nz55mL2Kz&&$HPA1Wi z8HWY_7g`l2Q@VWvWCp_}IG+Hm)CyEwK!wxm>|Q*eb&UNF2ugqbbsXpux1T}-nMcpa z0H|Q9(qw!t3AJZdl))0Be1{lJO4G1L!sMg~bc7W? zd=3C0CwgzGA3YWTVG7Za(fkOb@|!Ri3;|7pbw(d-B+1<-InisN`iY2$+`02PCnpE$ ze*!+fAugQ+qD4zZrRM{KJOqIyW9EONGqe%4T@>xbc-bs;Go$=pXJ^wx#nCEecquH` zG1yr^dStzK4^Ev{H9#(2xkg4zMs@_z?65NQzT@NSCu_h_F2*&+=)E!r!om8V9y|zg z@5CI36>JiPh{pjqnM*+lhR%dT+6sEa=#LatbfPIFKYeNZ4x0XBLjA`p?dFgfEKHfw}4yl@HhcJ zWYT?ISn0HAo&K1d0}`5;}aT?1MYIjQ2Y;DiiZ%|mLfO*i%1+?rK4(aCMaUyvNc+0 zLK39(E&_+@ygCBs7O>r4fgk3tD}ym2s~ZOdiT_kD%zqbrS>TSBwX)#XBsF4)w+HN6`j^Zxz&#Kg{w_$(qV5`09%Hhid7 zX&?bi0|d=YFgaql?R^q(G)r~-(r@Nemc01gf(N%#2%5Xo>3j0yKMSIkBpFt4e#?H*M>OO=D{&>1^pzVZAQy1iYo2IoE+%1wztDBP z^5$W>%I081MEgUd++h|_EJCE{%n`Rjq()p#cu2sU*(gu@xh04>lQyamEkNX zd;Lkz!$RP@j-nd1tty)ie=ZW?tnhr;Ak%cw|H-)A2rcI9>8JEqEo>LGOng9Xj4tLd zz$S7JkO1Cml)eFy2-r25BjI1UYQ_F|SFgNzBmKjYga^({hsvcB?okNn2h2PZb7LK| z#6slCy1G_^lM0-El9GOJ3=}7PuBTs{rsa7GZ{{D^kE0+qGP&O!6C!ffWx`M~KU-?k ziMGuE*aCOT1Pr`jB?Az+WMJ87+$`ym?LZq#cVe9CXW3z@!VoI|dOjH*(Q3-DlS=F# zk4rG6pjz@1IIQs3tF9qd2U$6F1x^q_;?}tBe&PBihA1I`ha-5@NhO1p?!W(laUE;8 z!uF-3V<|WQ9-}=VLvYxQjFi+F48{@<%zh#emx9sX3y@!TB)6m?mH{8ya7Ew>5{^({ zl-z+&EAX9gIsz*p7{Ecdoy8Juyo?|RI?@r07bjp{hwLX8@u+C$1cCxc@m-teD*Rq2 z6<{2}MH@%p44V*~WEvaOac>2v0k6()%D#{Px>H#Ap|@z`G+ir4fWz@7H8uOQ=Y(cG zVk=WPc&RcMe1yR&dgtD~(ZZMh?W7|YODNF32B#28!KkUhireTZry%Is4PQ2r4Gy$I ztqUUq&>UcE?}IKe>l%Tb2BRoqDE-Nuu42r;mI-N-&Iy>|((x|MUIth=CFAMo303gd zuV46-0)5%)Kww;`1YQV1f#xt_RL1@>jM0g<7)ed-Do(jB3}E<3=~O%Af-!@XO{YME z1#U51fFk@dTJpaRvmOj}mqM5}ZlnL-7AhrJTgm^iF)oVMAFl~!y@4CC+k$eI2IZS$ z;~s*04QR%zaO*&K0e=Ziyv(#W1Ddlu<;P1vIflmxVZdgRk%AQr*eDp@VNeu>Y1SbF zMBgGy7CE%%Eshh468sF1P~j{${2rh})6}g`a2}eTNvRR-wfP9;5EByavW3f@Wv!;Sdh#o zcN7zZ77c_!^PLA9$gZ0w*A|g>{QTk0jsxkN3x6xEf(`KL_;7+OFRw%QMvwCG%>gRT zn8yxiyB-&u&yCCKts)$0F!-k;>Y<%^u|ULC%B!i795dvDNojdks1qC+@ru&uk?ybg zE-tI9ittNG$;S>*R>7`o+-r5hGNmYl5PMoc4iJ~sT<==r)9`MSG%onUf{kD>qe1c$-!gH!s={Q9-jFXmqV0U^Z*Xm=L;IzW0Xp%+CnT?Kts z?b0{x2f_dC{BXQr-tqAQyFbJDz$S)&_`fY5mH*rFQ57YZUbHXBv@Dl)pfSaaPN~d*s&Vie4qHd&xX;GL z(8Vsg+-PQi@(ad}|A%`6_W6GsEvTn2ig7`S06VoTrJw)GNU8i1!7Ms*W3vj-uO~}) d8hB4dbHzieymlQj(ch^dE2$`vC;t5P{{c$LNHhQd diff --git a/previews/PR2578/AbstractAlgebra/index.html b/previews/PR2578/AbstractAlgebra/index.html deleted file mode 100644 index a9ce10f7ba53..000000000000 --- a/previews/PR2578/AbstractAlgebra/index.html +++ /dev/null @@ -1,44 +0,0 @@ - -AbstractAlgebra.jl · Oscar.jl

AbstractAlgebra.jl

Introduction

AbstractAlgebra.jl is a computer algebra package for the Julia programming language, maintained by William Hart, Tommy Hofmann, Claus Fieker and Fredrik Johansson and other interested contributors.

AbstractAlgebra.jl grew out of the Nemo project after a number of requests from the community for the pure Julia part of Nemo to be split off into a separate project. See the Nemo repository for more details about Nemo.

Features

The features of AbstractAlgebra.jl include:

  • Use of Julia multiprecision integers and rationals
  • Finite fields (prime order, naive implementation only)
  • Number fields (naive implementation only)
  • Univariate polynomials
  • Multivariate polynomials
  • Relative and absolute power series
  • Laurent series
  • Fraction fields
  • Residue rings, including $\mathbb{Z}/n\mathbb{Z}$
  • Matrices and linear algebra

All implementations are fully recursive and generic, so that one can build matrices over polynomial rings, over a finite field, for example.

AbstractAlgebra.jl also provides a set of abstract types for Groups, Rings, Fields, Modules and elements thereof, which allow external types to be made part of the AbstractAlgebra.jl type hierarchy.

Installation

To use AbstractAlgebra we require Julia 1.6 or higher. Please see https://julialang.org/downloads/ for instructions on how to obtain Julia for your system.

At the Julia prompt simply type

julia> using Pkg; Pkg.add("AbstractAlgebra")

Quick start

Here are some examples of using AbstractAlgebra.jl.

This example makes use of multivariate polynomials.

using AbstractAlgebra
-
-R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"])
-
-f = x + y + z + 1
-
-p = f^20;
-
-@time q = p*(p+1);

Here is an example using generic recursive ring constructions.

using AbstractAlgebra
-
-R = GF(7)
-
-S, y = polynomial_ring(R, "y")
-
-T = residue_ring(S, y^3 + 3y + 1)
-
-U, z = polynomial_ring(T, "z")
-
-f = (3y^2 + y + 2)*z^2 + (2*y^2 + 1)*z + 4y + 3;
-
-g = (7y^2 - y + 7)*z^2 + (3y^2 + 1)*z + 2y + 1;
-
-s = f^4;
-
-t = (s + g)^4;
-
-@time resultant(s, t)

Here is an example using matrices.

using AbstractAlgebra
-
-R, x = polynomial_ring(ZZ, "x")
-
-S = matrix_space(R, 10, 10)
-
-M = rand(S, 0:3, -10:10);
-
-@time det(M)

And here is an example with power series.

using AbstractAlgebra
-
-R, x = QQ["x"]
-
-S, t = power_series_ring(R, 30, "t")
-
-u = t + O(t^100)
-
-@time divexact((u*exp(x*u)), (exp(u)-1));
diff --git a/previews/PR2578/AbstractAlgebra/integer/index.html b/previews/PR2578/AbstractAlgebra/integer/index.html deleted file mode 100644 index 48aca431e7b5..000000000000 --- a/previews/PR2578/AbstractAlgebra/integer/index.html +++ /dev/null @@ -1,60 +0,0 @@ - -Integer ring · Oscar.jl

Integer ring

AbstractAlgebra.jl provides a module, implemented in src/julia/Integer.jl for making Julia BigInts conform to the AbstractAlgebra.jl Ring interface.

In addition to providing a parent object ZZ for Julia BigInts, we implement any additional functionality required by AbstractAlgebra.jl.

Because BigInt cannot be directly included in the AbstractAlgebra.jl abstract type hierarchy, we achieve integration of Julia BigInts by introducing a type union, called RingElement, which is a union of RingElem and a number of Julia types, including BigInt. Everywhere that RingElem is notionally used in AbstractAlgebra.jl, we are in fact using RingElement, with additional care being taken to avoid ambiguities.

The details of how this is done are technical, and we refer the reader to the implementation for details. For most intents and purposes, one can think of the Julia BigInt type as belonging to RingElem.

One other technicality is that Julia defines certain functions for BigInt, such as sqrt and exp differently to what AbstractAlgebra.jl requires. To get around this, we redefine these functions internally to AbstractAlgebra.jl, without redefining them for users of AbstractAlgebra.jl. This allows the internals of AbstractAlgebra.jl to function correctly, without broadcasting pirate definitions of already defined Julia functions to the world.

To access the internal definitions, one can use AbstractAlgebra.sqrt and AbstractAlgebra.exp, etc.

Types and parent objects

Integers have type BigInt, as in Julia itself. We simply supplement the functionality for this type as required for computer algebra.

The parent objects of such integers has type Integers{BigInt}.

For convenience, we also make Int a part of the AbstractAlgebra.jl type hierarchy and its parent object (accessible as zz) has type Integers{Int}. But we caution that this type is not particularly useful as a model of the integers and may not function as expected within AbstractAlgebra.jl.

Integer constructors

In order to construct integers in AbstractAlgebra.jl, one can first construct the integer ring itself. This is accomplished using the following constructor.

Integers{BigInt}()

This gives the unique object of type Integers{BigInt} representing the ring of integers in AbstractAlgebra.jl.

In practice, one simply uses ZZ which is assigned to be the return value of the above constructor. There is no need to call the constructor in practice.

Here are some examples of creating the integer ring and making use of the resulting parent object to coerce various elements into the ring.

Examples

julia> f = ZZ()
-0
-
-julia> g = ZZ(123)
-123
-
-julia> h = ZZ(BigInt(1234))
-1234
-

Basic ring functionality

The integer ring in AbstractAlgebra.jl implements the full Ring interface and the Euclidean Ring interface.

We give some examples of such functionality.

Examples

julia> f = ZZ(12)
-12
-
-julia> h = zero(ZZ)
-0
-
-julia> k = one(ZZ)
-1
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> T = parent(f)
-Integers
-
-julia> f == deepcopy(f)
-true
-
-julia> g = f + 12
-24
-
-julia> h = powermod(f, 12, ZZ(17))
-4
-
-julia> flag, q = divides(f, ZZ(3))
-(true, 4)
-

Integer functionality provided by AbstractAlgebra.jl

The functionality below supplements that provided by Julia itself for its BigInt type.

Basic functionality

Examples

julia> r = ZZ(-1)
--1
-
-julia> is_unit(r)
-true
-

Divisibility testing

is_divisible_byMethod
is_divisible_by(a::Integer, b::Integer)

Return true if $a$ is divisible by $b$, i.e. if there exists $c$ such that $a = bc$.

** Examples **

julia> r = ZZ(6)
-6
-
-julia> s = ZZ(3)
-3
-
-julia> is_divisible_by(r, s)
-true

Square root

sqrtMethod
sqrt(a::T; check::Bool=true) where T <: Integer

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

is_squareMethod
is_square(f::PolyRingElem{T}) where T <: RingElement

Return true if $f$ is a perfect square.

is_square(a::ResFieldElem{T}) where T <: Integer

Return true if $a$ is a square.

is_square(a::T) where T <: Integer

Return true if $a$ is a square.

is_square_with_sqrtMethod
is_square_with_sqrt(a::T) where T <: Integer

Return (true, s) if $a$ is a perfect square, where $s^2 = a$. Otherwise return (false, 0).

rootMethod
root(a::T, n::Int; check::Bool=true) where T <: Integer

Return the $n$-th root of $a$. If check=true the function will test if the input was a perfect $n$-th power, otherwise an exception will be raised. We require $n > 0$.

irootMethod
iroot(a::T, n::Int) where T <: Integer

Return the truncated integer part of the $n$-th root of $a$ (round towards zero). We require $n > 0$ and also $a \geq 0$ if $n$ is even.

is_powerMethod
is_power(a::T, n::Int) where T <: Integer

Return true if $a$ is a perfect $n$-th power, i.e. if there is a $b$ such that $a = b^n$. We require $n > 0$.

is_power_with_rootMethod
is_power_with_root(a::T, n::Int) where T <: Integer

Return true, q if $a$ is a perfect $n$-th power with $a = q^n$. Otherwise return false, 0. We require $n > 0$.

expMethod
exp(a::T) where T <: Integer

Return $1$ if $a = 0$, otherwise throw an exception. This function is not generally of use to the user, but is used internally in AbstractAlgebra.jl.

exp(a::Rational{T}) where T <: Integer

Return $1$ if $a = 0$, otherwise throw an exception.

Examples

julia> d = AbstractAlgebra.sqrt(ZZ(36))
-6
-
-julia> is_square(ZZ(9))
-true
-
-julia> m = AbstractAlgebra.exp(ZZ(0))
-1

Coprime bases

ppioMethod
ppio(a::T, b::T)

Split $a$ into $c*d$ where $c = gcd(a, b^\infty)$.

Examples

julia> c, n = ppio(ZZ(12), ZZ(26))
-(4, 3)
-
diff --git a/previews/PR2578/AbstractAlgebra/interface_introduction/index.html b/previews/PR2578/AbstractAlgebra/interface_introduction/index.html deleted file mode 100644 index 040aaa77a860..000000000000 --- a/previews/PR2578/AbstractAlgebra/interface_introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

AbstractAlgebra defines a series of interfaces that can be extended with new types that implement those interfaces. For example, if one were implementing a new polynomial ring type, one would implement all of the required functionality described in this chapter for the relevant AbstractAlgebra interfaces. This would include the Ring Interface and the Univariate Polynomial Ring Interface.

Once a new type implements all the required functionality, all the corresponding generic functionality would then function automatically for the new type.

One may then go on to implement some of the optional functionality for performance if the provided generic functionality is insufficient.

AbstractAlgebra tries to provide all generic constructions recursively so that one can have towers of generic constructions. This means that new interfaces should generally only be added if they cooperate with all the existing interfaces, at least so far as the theory exists to do so.

diff --git a/previews/PR2578/AbstractAlgebra/laurent_mpolynomial/index.html b/previews/PR2578/AbstractAlgebra/laurent_mpolynomial/index.html deleted file mode 100644 index 000831571ecb..000000000000 --- a/previews/PR2578/AbstractAlgebra/laurent_mpolynomial/index.html +++ /dev/null @@ -1,27 +0,0 @@ - -Sparse distributed multivariate Laurent polynomials · Oscar.jl

Sparse distributed multivariate Laurent polynomials

Every element of the multivariate Laurent polynomial ring $R[x_1, x_1^{-1}, \dots, x_n, x_n^{-1}]$ can be presented as a sum of products of powers of the $x_i$ where the power can be any integer. Therefore, the interface for sparse multivarate polynomials carries over with the additional feature that exponents can be negative.

Generic multivariate Laurent polynomial types

AbstractAlgebra.jl provides a generic implementation of multivariate Laurent polynomials, built in terms of regular multivariate polynomials, in the file src/generic/LaurentMPoly.jl.

The type LaurentMPolyWrap{T, ...} <: LaurentMPolyRingElem{T} implements generic multivariate Laurent polynomials by wrapping regular polynomials: a Laurent polynomial l wraps a polynomial p and a vector of integers $n_i$ such that $l = \prod_i x_i^{n_i} * p$. The representation is said to be normalized when each $n_i$ is as large as possible (or zero when l is zero), but the representation of a given element is not required to be normalized internally.

The corresponding parent type is LaurentMPolyWrapRing{T, ...} <: LaurentMPolyRing{T}.

Abstract types

Two abstract types LaurentMPolyRingElem{T} and LaurentMPolyRing{T} are defined to represent Laurent polynomials and rings thereof, parameterized on a base ring T.

Multivate Laurent polynomial operations

Since, from the point of view of the interface, Laurent polynomials are simply regular polynomials with possibly negative exponents, the following functions from the polynomial interface are completely analogous. As with regular polynomials, an implementation must provide access to the elements as a sum of individual terms in some order. This order currently cannot be specified in the constructor.

LaurentPolynomialRing(R::Ring, S::Vector{<:VarName}; cached::Bool = true)
-LaurentPolynomialRing(R::Ring, n::Int, s::VarName; cached::Bool = false)
(S::LaurentMPolyRing{T})(A::Vector{T}, m::Vector{Vector{Int}})
MPolyBuildCtx(R::LaurentMPolyRing)
-push_term!(M::LaurentMPolyBuildCtx, c::RingElem, v::Vector{Int})
-finish(M::LaurentMPolyBuildCtx)
symbols(S::LaurentMPolyRing)
-nvars(f::LaurentMPolyRing)
-gens(S::LaurentMPolyRing)
-gen(S::LaurentMPolyRing, i::Int)
-is_gen(x::LaurentMPolyRingElem)
-var_index(p::LaurentMPolyRingElem)
-length(f::LaurentMPolyRingElem)
coefficients(p::LaurentMPolyRingElem)
-monomials(p::LaurentMPolyRingElem)
-terms(p::LaurentMPolyRingElem)
-exponent_vectors(p::LaurentMPolyRingElem)
-leading_coefficient(p::LaurentMPolyRingElem)
-leading_monomial(p::LaurentMPolyRingElem)
-leading_term(p::LaurentMPolyRingElem)
-leading_exponent_vector(p::LaurentMPolyRingElem)
change_base_ring(::Ring, p::LaurentMPolyRingElem)
-change_coefficient_ring(::Ring, p::LaurentMPolyRingElem)
-map_coefficients(::Any, p::LaurentMPolyRingElem)
evaluate(p::LaurentMPolyRingElem, ::Vector)
derivative(p::LaurentMPolyRingElem, x::LaurentMPolyRingElem)
-derivative(p::LaurentMPolyRingElem, i::Int)
rand(R::LaurentMPolyRingElem, length_range::UnitRange{Int}, exp_range::UnitRange{Int}, v...)

The choice of canonical unit for Laurent polynomials includes the product $\prod_i x_i^{n_i}$ from the normalized representation. In particular, this means that the output of gcd will not have any negative exponents.

julia> R, (x, y) = LaurentPolynomialRing(ZZ, ["x", "y"]);
-
-julia> canonical_unit(2*x^-5 - 3*x + 4*y^-4 + 5*y^2)
--x^-5*y^-4
-
-julia> gcd(x^-3 - y^3, x^-2 - y^2)
-x*y - 1
diff --git a/previews/PR2578/AbstractAlgebra/laurent_polynomial/index.html b/previews/PR2578/AbstractAlgebra/laurent_polynomial/index.html deleted file mode 100644 index ec092f69f6b4..000000000000 --- a/previews/PR2578/AbstractAlgebra/laurent_polynomial/index.html +++ /dev/null @@ -1,49 +0,0 @@ - -Generic Laurent polynomials · Oscar.jl

Generic Laurent polynomials

Laurent polynomials are similar to polynomials but can have terms of negative degrees, and form a ring denoted by $R[x, x^{-1}]$ where R is the coefficient ring.

Generic Laurent polynomial types

AbstractAlgebra.jl provides a generic implementation of Laurent polynomials, built in terms of regular polynomials in the file src/generic/LaurentPoly.jl.

The type LaurentPolyWrap{T, ...} <: LaurentPolyRingElem{T} implements generic Laurent polynomials by wrapping regular polynomials: a Laurent polynomial l wraps a polynomial p and an integer n such that $l = x^{-n} * p$.

The corresponding parent type is LaurentPolyWrapRing{T, ...} <: LaurentPolynomialRing{T}.

Abstract types

Two abstract types LaurentPolyRingElem{T} and LaurentPolynomialRing{T} are defined to represent Laurent polynomials and rings thereof, parameterized on a base ring T.

Laurent polynomials ring constructor

In order to instantiate Laurent polynomials, one must first construct the parent ring:

LaurentPolynomialRingType
LaurentPolynomialRing(R::Ring, s::VarName)

Given a base ring R and string s specifying how the generator (variable) should be printed, return a tuple S, x representing the new Laurent polynomial ring $S = R[x, 1/x]$ and the generator $x$ of the ring.

Examples

julia> R, x = LaurentPolynomialRing(ZZ, "x")
-(Univariate Laurent Polynomial Ring in x over Integers, x)
-
-julia> 2x^-3 + x^2
-x^2 + 2*x^-3
-
-julia> rand(R, -3:3, -9:9)
--3*x^2 - 8*x + 4 + 3*x^-1 - 6*x^-2 + 9*x^-3
LaurentPolynomialRing(R::AbstractAlgebra.Ring, s::Vector{T}; cached::Bool = true) where T <: VarName

Given a base ring R and an array of strings s specifying how the generators (variables) should be printed, return a tuple T, (x1, x2, ...) representing the new ring $T = R[x1, 1/x1, x2, 1/x2, ...]$ and the generators $x1, x2, ...$ of the ring. By default the parent object T will depend only on R and x1, x2, ... and will be cached. Setting the optional argument cached to false will prevent the parent object T from being cached.

Basic functionality

Laurent polynomials implement the ring interface, and some methods from the polynomial interface, for example:

julia> R, x = LaurentPolynomialRing(ZZ, "x")
-(Univariate Laurent polynomial ring in x over integers, x)
-
-julia> var(R)
-:x
-
-julia> symbols(R)
-1-element Vector{Symbol}:
- :x
-
-julia> nvars(R)
-1
-
-julia> f = x^-2 + 2x
-2*x + x^-2
-
-julia> coeff.(f, -2:2)
-5-element Vector{BigInt}:
- 1
- 0
- 0
- 2
- 0
-
-julia> set_coefficient!(f, 3, ZZ(5))
-5*x^3 + 2*x + x^-2
-
-julia> is_gen(f)
-false
-
-julia> shift_left(f,2)
-5*x^5 + 2*x^3 + 1
-
-julia> map_coefficients(x->2x, f)
-10*x^3 + 4*x + 2*x^-2
-
-julia> change_base_ring(RealField, f)
-5.0*x^3 + 2.0*x + x^-2
-
-julia> leading_coefficient(f), trailing_coefficient(f)
-(5, 1)
diff --git a/previews/PR2578/AbstractAlgebra/map_cache/index.html b/previews/PR2578/AbstractAlgebra/map_cache/index.html deleted file mode 100644 index dd3742456bf2..000000000000 --- a/previews/PR2578/AbstractAlgebra/map_cache/index.html +++ /dev/null @@ -1,36 +0,0 @@ - -Cached maps · Oscar.jl

Cached maps

All basic map (i.e. those not built up from other maps) in AbstractAlgebra can be cached.

A cache is a dictionary that can be switched on and off at run time that keeps a cache of previous evaluations of the map. This can be useful if the map is extremely difficult to evaluate, e.g. a discrete logarithm map. Rather than evaluate the map afresh each time, the map first looks up the dictionary of previous known values of the map.

To facilitate caching of maps, the Generic module provides a type Generic.MapCache, which can be used to wrap any existing map object with a dictionary.

Importantly, the supertype of the resulting Generic.MapCache object is identical to that of the map being cached. This means that any functions that would accept the original map will also accept the cached version.

Note

Caching of maps only works for maps that correctly abstract access to their fields using accessor functions, as described in the map interface.

Cached map constructors

To construct a cached map from an existing map object, we have the following function:

cached(M::Map; enabled=true, limit=100)

Return a cached map with the same supertype as $M$, caching up to limit values of the map M in a dictionary, assuming that the cache is enabled.

Caches can be disabled by setting the value of the parameter enabled to false. This allows for the user to quickly go through code and completely disable caches of maps that were previously enabled, for testing purposes, etc.

Caches can also be turned on and off at run time (see below).

Examples

julia> f = map_from_func(x -> x + 1, ZZ, ZZ)
-Map with the following data
-
-Domain:
-=======
-Integers
-
-Codomain:
-========
-Integers
-
-julia> g = cached(f);
-
-julia> f(ZZ(1)) == g(ZZ(1))
-true

Functionality for cached maps

The following functions are provided for cached maps.

enable_cache!(M::MapCache)
-disable_cache!(M::MapCache)

Temporarily enable or disable the cache for the given map. The values stored in the cache are not lost when it is disabled.

set_limit!(M::MapCache, limit::Int)

Set the limit on the number of values that can be cached in the dictionary, to the given value. Setting the value to 0 will effectively disable further caching for this map.

Examples

julia> f = cached(map_from_func(x -> x + 1, ZZ, ZZ));
-
-julia> a = f(ZZ(1))
-2
-
-julia> disable_cache!(f)
-
-julia> b = f(ZZ(1))
-2
-
-julia> enable_cache!(f)
-
-julia> c = f(ZZ(1))
-2
-
-julia> set_limit!(f, 200)
-200
-
-julia> d = f(ZZ(1))
-2
diff --git a/previews/PR2578/AbstractAlgebra/map_interface/index.html b/previews/PR2578/AbstractAlgebra/map_interface/index.html deleted file mode 100644 index 8060585a6ef6..000000000000 --- a/previews/PR2578/AbstractAlgebra/map_interface/index.html +++ /dev/null @@ -1,8 +0,0 @@ - -Map Interface · Oscar.jl

Map Interface

Maps in AbstractAlgebra can be constructed from Julia functions, or they can be represented by some other kind of data, e.g. a matrix, or built up from other maps.

In the following, we will always use the word "function" to mean a Julia function, and reserve the word "map" for a map on sets, whether mathematically, or as an object in the system.

Parent objects

Maps in AbstractAlgebra currently don't have parents. This will change later when AbstractAlgebra has a category system, so that the parent of a map can be some sort of Hom set.

Map classes

All maps in AbstractAlgebra belong to a class of maps. The classes are modeled as abstract types that lie in a hierarchy, inheriting from SetMap at the top of the hierarchy. Other classes that inherit from SetMap are FunctionalMap for maps that are constructed from a Julia function (or closure), and IdentityMap for the class of the identity maps within the system.

One might naturally assume that map types belong directly to these classes in the way that types of other objects in the system belong to abstract types in the AbstractAlgebra type hierarchy. However, in order to provide an extensible system, this is not the case.

Instead, a map type MyMap will belong to an abstract type of the form Map{D, C, T, MyMap}, where D is the type of the object representing the domain of the map type (this can also be an abstract type, such as Group), C is the type of the object representing the codomain of the map type and T is the map class that MyMap belongs to, e.g. SetMap or FunctionalMap.

Because a four parameter type system becomes quite cumbersome to use, we provide a number of functions for referring to collections of map types.

If writing a function that accepts any map type, one makes the type of its argument belong to Map. For example f(M::Map) = 1.

If writing a function that accepts any map from a domain of type D to a codomain of type C, one makes writes for example f(M::Map{D, C}) = 2. Note that D and C can be abstract types, such as Group, but otherwise must be the types of the parent objects representing the domain and codomain.

A function that accepts any map belonging to a given map class might be written as f(M::Map(FunctionalMap)) = 3 or f(M::Map(FunctionalMap){D, C}) = 4 for example, where D and C are the types of the parent objects for the domain and codomain.

Finally, if a function should only work for a map of a given map type MyMap, say, one writes this f(M::Map(MyMap)) or f(M::Map(MyMap){D, C}, where as usual D and C are the types of the domain and codomain parent objects.

Implementing new map types

There are two common kinds of map type that developers will need to write. The first has a fixed domain and codomain, and the second is a type parameterised by the types of the domain and codomain. We give two simple examples here of how this might look.

In the case of fixed domain and codomain, e.g. Integers{BigInt}, we would write it as follows:

mutable struct MyMap <: Map{Integers{BigInt}, Integers{BigInt}, SetMap, MyMap}
-   # some data fields
-end

In the case of parameterisation by the type of the domain and codomain:

mutable struct MyMap{D, C} <: Map{D, C, SetMap, MyMap}
-   # some data fields
-end

As mentioned above, to write a function that only accepts maps of type MyMap, one writes the functions as follows:

function my_fun(M::Map(MyMap))

The Map function then computes the correct type to use, which is actually not MyMap if all features of the generic Map infrastructure are required. It is bad practice to write functions for MyMap directly instead of Map(MyMap), since other users will be unable to use generic constructions over the map type MyMap.

Required functionality for maps

All map types must implement a standard interface, which we specify here.

We will define this interface for a custom map type MyMap belonging to Map(SetMap), SetMap being the map class that all maps types belong to.

Note that map types do not need to contain any specific fields, but must provide accessor functions (getters and setters) in the manner described above.

The required accessors for map types of class SetMap are as follows.

domain(M::Map(MyMap))
-codomain(M::Map(MyMap))

Return the domain and codomain parent objects respectively, for the map $M$. It is only necessary to define these functions if the map type MyMap does not contain fields domain and codomain containing these parent objects.

It is also necessary to be able to apply a map. This amounts to overloading the call method for objects belonging to Map(MyMap).

(M::Map(MyMap)(a))

Apply the map M to the element a of the domain of M. Note that it is usual to add a type assertion to the return value of this function, asserting that the return value has type elem_type(C) where C is the type of the codomain parent object.

Optional functionality for maps

The Generic module in AbstractAlgebra automatically provides certain functionality for map types, assuming that they satisfy the full interface described above.

However, certain map types or map classes might like to provide their own implementation of this functionality, overriding the generic functionality.

We describe this optional functionality here.

Show method

Custom map types may like to provide a custom show method if the default of displaying the domain and codomain of the map is not sufficient.

show(io::IO, M::Map(MyMap))

Identity maps

There is a concrete map type Generic.IdentityMap{D} for the identity map on a given domain. Here D is the type of the object representing that domain.

Generic.IdentityMap belongs to the supertype Map{D, C, AbstractAlgebra.IdentityMap, IdentityMap}.

Note that the map class is also called IdentityMap. It is an abstract type, whereas Generic.IdentityMap is a concrete type in the Generic module.

An identity map has the property that when composed with any map whose domain or codomain is compatible, that map will be returned as the composition. Identity maps can therefore serve as a starting point when building up a composition of maps, starting an identity map.

We do not cached identity maps in the system, so that if more than one is created on the same domain, there will be more than one such map in the system. This underscores the fact that there is in general no way for the system to know if two maps compose to give an identity map, and therefore the only two maps that can be composed to give an identity map are identity maps on the same domain.

To construct an identity map for a given domain, specified by a parent object R, say, we have the following function.

identity_map(R::Set)

Return an identity map on the domain $R$.

Of course there is nothing stopping a map type or class from implementing its own identity map type, and defining composition of maps of the same kind with such an identity map. In such a case, the class of such an identity map type must belong to IdentityMap so that composition with other map types still works.

Composition of maps

Any two compatible maps in AbstractAlgebra can be composed and any composition can be applied.

In order to facilitate this, the Generic module provides a type Generic.CompositeMap{D, C}, which contains two maps map1 and map2, corresponding to the two maps to be applied in a composition, in the order they should be applied.

To construct a composition map from two existing maps, we have the following function:

compose(f::Map{D, U}, g::Map{U, C}) where {D, U, C}

Compose the two maps $f$ and $g$, i.e. return the map $h$ such that $h(x) = g(f(x))$.

As a shortcut for this function we have the following operator:

*(f::Map{D, U}, g::Map{U, C}) where {D, U, C} = compose(f, g)

Note the order of composition. If we have maps $f : X \to Y$, $g : Y \to Z$ the correct order of the maps in this operator is f*g, so that (f*g)(x) = g(f(x)).

This is chosen so that for left $R$-module morphisms represented by a matrix, the order of matrix multiplication will match the order of composition of the corresponding morphisms.

Of course, a custom map type or class of maps can implement its own composition type and compose function.

This is the case with the FunctionalMap class for example, which caches the Julia function/closure corresponding to the composition of two functional maps. As this cached function needs to be stored inside the composition, a special type is necessary for the composition of two functional maps.

By default, compose will check that the two maps are composable, i.e. the codomain of the first map matches the domain of the second map. This is implemented by the following function:

check_composable(f::Map{D, U}, g::Map{U, C})

Raise an exception if the codomain of $f$ doesn't match the domain of $g$.

Note that composite maps should keep track of the two maps they were constructed from. To access these maps, the following functions are provided:

map1(f::CompositeMap)
-map2(f::CompositeMap)

Any custom composite map type must also provide these functions for that map type, even if there exist fields with those names. This is because there is no common map class for all composite map types. Therefore the Generic system cannot provide fallbacks for all such composite map types.

diff --git a/previews/PR2578/AbstractAlgebra/map_introduction/index.html b/previews/PR2578/AbstractAlgebra/map_introduction/index.html deleted file mode 100644 index 630d579a6451..000000000000 --- a/previews/PR2578/AbstractAlgebra/map_introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Maps in AbstractAlgebra model maps on sets $f : D \to C$ for some domain $D$ and codomain $C$, which have no real limitations except that elements of the codomain and domain be represented by element objects in the system.

Maps $f : D \to C$ in AbstractAlgebra are modeled by Julia objects that are able to be called on a single element $d \in D$ of the domain to yield an element $f(d) \in C$ of the codomain. We say that the map is being applied.

Maps can be constructed from Julia functions, or they can be represented by some other kind of data, e.g. a matrix, or built up from other maps.

Maps in AbstractAlgebra have a domain and codomain, can be applied, composed with other maps. Various special kinds of map provide more functionality.

For details please refer to the Map Interface documentation.

For example, there are functional maps which wrap a Julia function, cached maps which cache values so they do not have to be recomputed each time they are applied to the same inputs and various kinds of maps with inverses, e.g. maps with sections, retractions and full inverses.

The map system uses a complex four parameter Map type, however various helper functions are provided to make it easier to work with.

diff --git a/previews/PR2578/AbstractAlgebra/map_with_inverse/index.html b/previews/PR2578/AbstractAlgebra/map_with_inverse/index.html deleted file mode 100644 index d77c92aca051..000000000000 --- a/previews/PR2578/AbstractAlgebra/map_with_inverse/index.html +++ /dev/null @@ -1,51 +0,0 @@ - -Map with inverse · Oscar.jl

Map with inverse

It is not possible to provide generic functionality to invert a map. However, sometimes one knows an inverse map explicitly and would like to keep track of this.

Recall that as map composition is not commutative, there is a notion of a left inverse and a right inverse for maps.

To keep track of such inverse maps, AbstractAlgebra provides data types Generic.MapWithRetraction and Generic.MapWithSection.

Given a map $f : X \to Y$, a retraction of $f$ is a map $g : Y \to X$ such that $g(f(x)) = x$ for all $x \in X$.

Given a map $f : X \to Y$, a section of $f$ is a map $g : Y \to X$ such that $f(g(x)) = x$ for all $y \in Y$.

In AbstractAlgebra, a map with retraction/section is an object containing a pair of maps, the second of which is a retraction/section of the first.

Maps with retraction/section can be composed, and we also define the inverse of such a pair to be the map with the pair swapped. Thus the inverse of a map with retraction is a map with section.

Map with inverse constructors

To construct a map with retraction/section from a pair of maps, we have the following functions:

map_with_retraction(m::Map{D, C}, r::Map{C, D}) where {D, C}
-map_with_section(m::Map{D, C}, s::Map{C, D}) where {D, C}

Construct the map with retraction/section given a known retraction/section $r$ or $s$ respectively, of $m$.

For convenience we allow construction of maps with retraction/section from a pair of Julia functions/closures.

map_with_retraction_from_func(f::Function, r::Function, R, S)
-map_with_section_from_func(f::Function, s::Function, R, S)

Construct the map with retraction/section such that the map is given by the function $f$ and the retraction/section is given by the function $r$ or $s$ respectively. Here $R$ is the parent object representing the domain and $S$ is the parent object representing the codomain of $f$.

Examples

julia> f = map_with_retraction_from_func(x -> x + 1, x -> x - 1, ZZ, ZZ)
-Map with retraction with the following data
-
-Domain:
-=======
-Integers
-
-Codomain:
-========
-Integers
-
-julia> a = f(ZZ(1))
-2

Functionality for maps with inverses

The following functionality is provided for maps with inverses.

inv(M::Generic.MapWithRetraction)
-inv(M::Generic.MapWithSection)

Return the map with the two maps contained in $M$ swapped. In the first case, a MapWithSection is returned. In the second case a MapWithRetraction is returned.

To access the two maps stored in a map with retraction/section, we have the following:

image_map(M::Generic.MapWithRetraction)
-image_map(M::Generic.MapWithSection)
-retraction_map(M::Generic.MapWithRetraction)
-section_map(M::Generic.MapWithSection)

The first two of these functions return the first map in a map with retraction/section, the second two functions return the corresponding second maps.

Examples

julia> f = map_with_retraction_from_func(x -> x + 1, x -> x - 1, ZZ, ZZ)
-Map with retraction with the following data
-
-Domain:
-=======
-Integers
-
-Codomain:
-========
-Integers
-
-julia> g = inv(f)
-Map with section with the following data
-
-Domain:
-=======
-Integers
-
-Codomain:
-========
-Integers
-
-julia> h = f*g
-Composite map consisting of the following
-
-Integers -> Integers
-then
-Integers -> Integers
-
-julia> a = h(ZZ(1))
-1
-
diff --git a/previews/PR2578/AbstractAlgebra/mathjaxhelper.js b/previews/PR2578/AbstractAlgebra/mathjaxhelper.js deleted file mode 100644 index 1bd5394af59d..000000000000 --- a/previews/PR2578/AbstractAlgebra/mathjaxhelper.js +++ /dev/null @@ -1,10 +0,0 @@ -MathJax.Hub.Config({ - extensions: ["tex2jax.js"], - jax: ["input/TeX", "output/HTML-CSS"], - tex2jax: { - inlineMath: [ ['$','$'], ["\\(","\\)"] ], - displayMath: [ ['$$','$$'], ["\\[","\\]"] ], - processEscapes: true - }, -}); - diff --git a/previews/PR2578/AbstractAlgebra/matrix/index.html b/previews/PR2578/AbstractAlgebra/matrix/index.html deleted file mode 100644 index 4588e930d351..000000000000 --- a/previews/PR2578/AbstractAlgebra/matrix/index.html +++ /dev/null @@ -1,928 +0,0 @@ - -Matrix functionality · Oscar.jl

Matrix functionality

AbstractAlgebra.jl provides a module, implemented in src/Matrix.jl for matrices over any ring belonging to the AbstractAlgebra abstract type hierarchy. This functionality will work for any matrix type which follows the Matrix interface.

Similarly, AbstractAlgebra.jl provides a module in src/MatrixAlgebra.jl for matrix algebras over a ring.

Generic matrix types

AbstractAlgebra.jl allows the creation of dense matrices over any computable ring $R$. Generic matrices over a ring are implemented in src/generic/Matrix.jl.

Generic matrix algebras of $m\times m$ matrices are implemented in src/generic/MatrixAlgebra.jl.

Generic matrices in AbstractAlgebra.jl have type Generic.MatSpaceElem{T} for matrices in a matrix space, or Generic.MatAlgElem{T} for matrices in a matrix algebra, where T is the type of elements of the matrix. Internally, generic matrices are implemented using an object wrapping a Julia two dimensional array, though they are not themselves Julia arrays. See the file src/generic/GenericTypes.jl for details.

For the most part, one doesn't want to work directly with the MatSpaceElem type though, but with an abstract type called Generic.Mat which includes MatSpaceElem and views thereof.

Parents of generic matrices (matrix spaces) have type Generic.MatSpace{T}. Parents of matrices in a matrix algebra have type Generic.MatAlgebra{T}.

The dimensions and base ring $R$ of a generic matrix are stored in its parent object, however to allow creation of matrices without first creating the matrix space parent, generic matrices in Julia do not contain a reference to their parent. They contain the row and column numbers (or degree, in the case of matrix algebras) and the base ring on a per matrix basis. The parent object can then be reconstructed from this data on demand.

Abstract types

The generic matrix types (matrix spaces) belong to the abstract type MatElem{T} and the matrix space parent types belong to MatSpace{T}. Similarly the generic matrix algebra matrix types belong to the abstract type MatAlgElem{T} and the parent types belong to MatAlgebra{T} Note that both the concrete type of a matrix space parent object and the abstract class it belongs to have the name MatElem, therefore disambiguation is required to specify which is intended. The same is true for the abstract types for matrix spaces and their elements.

Matrix space constructors

A matrix space in AbstractAlgebra.jl represents a collection of all matrices with given dimensions and base ring.

In order to construct matrices in AbstractAlgebra.jl, one can first construct the matrix space itself. This is accomplished with the following constructor. We discuss creation of matrix algebras separately in a dedicated section elsewhere in the documentation.

matrix_space(R::Ring, rows::Int, cols::Int)

Construct the space of matrices with the given number of rows and columns over the given base ring.

Here are some examples of creating matrix spaces and making use of the resulting parent objects to coerce various elements into the matrix space.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> A = S()
-[0   0   0]
-[0   0   0]
-[0   0   0]
-
-julia> B = S(12)
-[12    0    0]
-[ 0   12    0]
-[ 0    0   12]
-
-julia> C = S(R(11))
-[11    0    0]
-[ 0   11    0]
-[ 0    0   11]
-

Matrix element constructors

There are a few ways to construct matrices other than by coercing elements as shown above. The first method is from an array of elements.

This can be done with either two or one dimensional arrays.

(S::MatSpace{T})(A::Matrix{S}) where {S <: RingElement, T <: RingElement}
-(S::MatAlgebra{T})(A::Matrix{S}) where {S <: RingElement, T <: RingElement}

Create the matrix in the given space/algebra whose $(i, j)$ entry is given by A[i, j], where S is the type of elements that can be coerced into the base ring of the matrix.

(S::MyMatSpace{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}
-(S::MyMatAlgebra{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}

Create the matrix in the given space/algebra of matrices (with dimensions $m\times n$ say), whose $(i, j)$ entry is given by A[i*(n - 1) + j] and where S is the type of elements that can be coerced into the base ring of the matrix.

We also provide the following syntax for constructing literal matrices (similar to how Julia arrays can be be constructed).

R[a b c...;...]

Create the matrix over the base ring $R$ consisting of the given rows (separated by semicolons). Each entry is coerced into $R$ automatically. Note that parentheses may be placed around individual entries if the lists would otherwise be ambiguous, e.g. R[1 2; 2 (- 3)].

Also see the Matrix interface for a list of other ways to create matrices.

Examples

julia> S = matrix_space(QQ, 2, 3)
-Matrix space of 2 rows and 3 columns
-  over rationals
-
-julia> T = MatrixAlgebra(QQ, 2)
-Matrix algebra of degree 2
-  over rationals
-
-julia> M1 = S(Rational{BigInt}[2 3 1; 1 0 4])
-[2//1   3//1   1//1]
-[1//1   0//1   4//1]
-
-julia> M2 = S(BigInt[2 3 1; 1 0 4])
-[2//1   3//1   1//1]
-[1//1   0//1   4//1]
-
-julia> M3 = S(BigInt[2, 3, 1, 1, 0, 4])
-[2//1   3//1   1//1]
-[1//1   0//1   4//1]
-
-julia> N1 = T(Rational{BigInt}[2 3; 1 0])
-[2//1   3//1]
-[1//1   0//1]
-
-julia> N2 = T(BigInt[2 3; 1 0])
-[2//1   3//1]
-[1//1   0//1]
-
-julia> N3 = T(BigInt[2, 3, 1, 1])
-[2//1   3//1]
-[1//1   1//1]
-
-julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> M = R[t + 1 1; t^2 0]
-[t + 1   1]
-[  t^2   0]
-
-julia> N = R[t + 1 2 t] # create a row vector
-[t + 1   2   t]
-
-julia> P = R[1; 2; t] # create a column vector
-[1]
-[2]
-[t]

It is also possible to create matrices (in a matrix space only) directly, without first creating the corresponding matrix space (the inner constructor being called directly).

matrix(R::Ring, arr::Matrix{T}) where T <: RingElement

Given an $m\times n$ Julia matrix of entries, construct the corresponding AbstractAlgebra.jl matrix over the given ring R, assuming all the entries can be coerced into R.

matrix(R::Ring, r::Int, c::Int, A::Vector{T}) where T <: RingElement

Construct the given $r\times c$ AbstractAlgebra.jl matrix over the ring R whose $(i, j)$ entry is given by A[c*(i - 1) + j], assuming that all the entries can be coerced into R.

zero_matrix(R::Ring, r::Int, c::Int)

Construct the $r\times c$ AbstractAlgebra.jl zero matrix over the ring R.

Examples

julia> M = matrix(ZZ, BigInt[3 1 2; 2 0 1])
-[3   1   2]
-[2   0   1]
-
-julia> N = matrix(ZZ, 3, 2, BigInt[3, 1, 2, 2, 0, 1])
-[3   1]
-[2   2]
-[0   1]
-
-julia> P = zero_matrix(ZZ, 3, 2)
-[0   0]
-[0   0]
-[0   0]
-
-julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> M = R()
-[0   0]
-[0   0]

Block diagonal matrix constructors

It is also possible to create block diagonal matrices from a vector of existing matrices. It is also possible to construct them from Julia matrices if one supplies the base ring.

Note that if the input matrices are not square, the output matrix may not be square.

block_diagonal_matrixMethod
block_diagonal_matrix(V::Vector{<:MatElem{T}}) where T <: NCRingElement

Create the block diagonal matrix whose blocks are given by the matrices in V. There must be at least one matrix in V.

block_diagonal_matrixMethod
block_diagonal_matrix(R::NCRing, V::Vector{<:Matrix{T}}) where T <: NCRingElement

Create the block diagonal matrix over the ring R whose blocks are given by the matrices in V. Entries are coerced into R upon creation.

Examples

julia> block_diagonal_matrix(ZZ, [[1 2; 3 4], [4 5 6; 7 8 9]])
-[1   2   0   0   0]
-[3   4   0   0   0]
-[0   0   4   5   6]
-[0   0   7   8   9]
-
-julia> M = matrix(ZZ, [1 2; 3 4])
-[1   2]
-[3   4]
-
-julia> N = matrix(ZZ, [4 5 6; 7 8 9])
-[4   5   6]
-[7   8   9]
-
-julia> block_diagonal_matrix([M, N])
-[1   2   0   0   0]
-[3   4   0   0   0]
-[0   0   4   5   6]
-[0   0   7   8   9]

Conversion to Julia matrices and iteration

While AbstractAlgebra matrices are not instances of AbstractArray, they are closely related to Julia matrices. For convenience, a Matrix and an Array constructors taking an AbstractAlgebra matrix as input are provided:

MatrixMethod
Matrix(A::MatrixElem{T}) where T <: RingElement

Convert A to a Julia Matrix of the same dimensions with the same elements.

Examples

julia> A = ZZ[1 2 3; 4 5 6]
-[1   2   3]
-[4   5   6]
-
-julia> Matrix(A)
-2×3 Matrix{BigInt}:
- 1  2  3
- 4  5  6
ArrayMethod
Array(A::MatrixElem{T}) where T <: RingElement

Convert A to a Julia Matrix of the same dimensions with the same elements.

Examples

julia> R, x = ZZ["x"]; A = R[x^0 x^1; x^2 x^3]
-[  1     x]
-[x^2   x^3]
-
-julia> Array(A)
-2×2 Matrix{AbstractAlgebra.Generic.Poly{BigInt}}:
- 1    x
- x^2  x^3

Matrices also support iteration, and therefore functions accepting an iterator can be called on them, e.g.:

julia> M = matrix_space(ZZ, 2, 3); x = M(1:6)
-[1   2   3]
-[4   5   6]
-
-julia> collect(x)
-2×3 Matrix{BigInt}:
- 1  2  3
- 4  5  6
-
-julia> Set(x)
-Set{BigInt} with 6 elements:
-  5
-  4
-  6
-  2
-  3
-  1

Views

As per Julia, AbstractAlgebra supports the construction of matrix views. These allow one to work with a submatrix of a given matrix. Modifying the submatrix also modifies the original matrix.

The syntax for views is as for Julia's own views.

Examples

julia> M = matrix(ZZ, 3, 3, BigInt[1, 2, 3, 2, 3, 4, 3, 4, 5])
-[1   2   3]
-[2   3   4]
-[3   4   5]
-
-julia> N1 = @view M[1:2, :]
-[1   2   3]
-[2   3   4]
-
-julia> N2 = @view M[:, 1:2]
-[1   2]
-[2   3]
-[3   4]
-
-julia> R = N1*N2
-[14   20]
-[20   29]

Matrix functionality provided by AbstractAlgebra.jl

Most of the following generic functionality is available for both matrix spaces and matrix algebras. Exceptions include functions that do not return or accept square matrices or which cannot specify a parent. Such functions include solve, kernel, and nullspace which can't be provided for matrix algebras.

For details on functionality that is provided for matrix algebras only, see the dedicated section of the documentation.

Basic matrix functionality

As well as the Ring and Matrix interfaces, the following functions are provided to manipulate matrices and to set and retrieve entries and other basic data associated with the matrices.

dense_matrix_typeMethod
dense_matrix_type(::Type{T}) where T<:NCRingElement
-dense_matrix_type(::T) where T<:NCRingElement
-dense_matrix_type(::Type{S}) where S<:NCRing
-dense_matrix_type(::S) where S<:NCRing

Return the type of matrices with coefficients of type T respectively elem_type(S).

nrowsMethod
nrows(a::MatSpace)

Return the number of rows of the given matrix space.

ncolsMethod
ncols(a::MatSpace)

Return the number of columns of the given matrix space.

nrowsMethod
nrows(a::MatrixElem{T}) where T <: NCRingElement

Return the number of rows of the given matrix.

ncolsMethod
ncols(a::MatrixElem{T}) where T <: NCRingElement

Return the number of columns of the given matrix.

lengthMethod
length(a::MatrixElem{T}) where T <: NCRingElement

Return the number of entries in the given matrix.

isemptyMethod
isempty(a::MatrixElem{T}) where T <: NCRingElement

Return true if a does not contain any entry (i.e. length(a) == 0), and false otherwise.

identity_matrixMethod
identity_matrix(R::NCRing, n::Int)

Return the $n \times n$ identity matrix over $R$.

identity_matrixMethod
identity_matrix(M::MatElem{T}) where T <: NCRingElement

Construct the identity matrix in the same matrix space as M, i.e. with ones down the diagonal and zeroes elsewhere. M must be square. This is an alias for one(M).

diagonal_matrixMethod
diagonal_matrix(x::RingElement, m::Int, [n::Int])

Return the $m \times n$ matrix over $R$ with x along the main diagonal and zeroes elsewhere. If n is not specified, it defaults to m.

Examples

julia> diagonal_matrix(ZZ(2), 2, 3)
-[2   0   0]
-[0   2   0]
-
-julia> diagonal_matrix(QQ(-1), 3)
-[-1//1    0//1    0//1]
-[ 0//1   -1//1    0//1]
-[ 0//1    0//1   -1//1]
zeroMethod
zero(a::MatSpace)

Return the zero matrix in the given matrix space.

zeroMethod
zero(x::MatrixElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement
-zero(x::MatrixElem{T}, R::NCRing=base_ring(x)) where T <: NCRingElement
-zero(x::MatrixElem{T}, r::Int, c::Int) where T <: NCRingElement

Return a zero matrix similar to the given matrix, with optionally different base ring or dimensions.

oneMethod
one(a::MatSpace)

Return the identity matrix of given matrix space. The matrix space must contain square matrices or else an error is thrown.

oneMethod
one(a::MatrixElem{T}) where T <: NCRingElement

Return the identity matrix in the same matrix space as $a$. If the space does not contain square matrices, an error is thrown.

lower_triangular_matrixMethod
lower_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}

Return the $n$ by $n$ matrix whose entries on and below the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $n(n+1)/2$.

An exception is thrown if there is no integer $n$ with this property.

Examples

julia> lower_triangular_matrix([1, 2, 3])
-[1   0]
-[2   3]
upper_triangular_matrixMethod
upper_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}

Return the $n$ by $n$ matrix whose entries on and above the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $n(n+1)/2$.

An exception is thrown if there is no integer $n$ with this property.

Examples

julia> upper_triangular_matrix([1, 2, 3])
-[1   2]
-[0   3]
strictly_lower_triangular_matrixMethod
strictly_lower_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}

Return the $n$ by $n$ matrix whose entries below the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $(n-1)n/2$.

An exception is thrown if there is no integer $n$ with this property.

Examples

julia> strictly_lower_triangular_matrix([1, 2, 3])
-[0   0   0]
-[1   0   0]
-[2   3   0]
strictly_upper_triangular_matrixMethod
strictly_upper_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}

Return the $n$ by $n$ matrix whose entries above the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $(n-1)n/2$.

An exception is thrown if there is no integer $n$ with this property.

Examples

julia> strictly_upper_triangular_matrix([1, 2, 3])
-[0   1   2]
-[0   0   3]
-[0   0   0]
is_upper_triangularMethod
is_upper_triangular(A::MatrixElem{T}) where T <: RingElement

Return true if $A$ is an upper triangular matrix.

Alias for LinearAlgebra.istriu.

change_base_ringMethod
change_base_ring(R::NCRing, M::MatrixElem{T}) where T <: NCRingElement

Return the matrix obtained by coercing each entry into R.

mapMethod
map(f, a::MatrixElem{T}) where T <: NCRingElement

Transform matrix a by applying f on each element. This is equivalent to map_entries(f, a).

map!Method
map!(f, dst::MatrixElem{T}, src::MatrixElem{U}) where {T <: NCRingElement, U <: NCRingElement}

Like map, but stores the result in dst rather than a new matrix. This is equivalent to map_entries!(f, dst, src).

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> B = S([R(2) R(3) R(1); t t + 1 t + 2; R(-1) t^2 t^3])
-[ 2       3       1]
-[ t   t + 1   t + 2]
-[-1     t^2     t^3]
-
-julia> T = dense_matrix_type(R)
-AbstractAlgebra.Generic.MatSpaceElem{AbstractAlgebra.Generic.Poly{Rational{BigInt}}}
-
-julia> r = nrows(B)
-3
-
-julia> c = ncols(B)
-3
-
-julia> length(B)
-9
-
-julia> isempty(B)
-false
-
-julia> M = A + B
-[  t + 3         t + 3                   2]
-[t^2 + t       2*t + 1             2*t + 2]
-[     -3   t^2 + t + 2   t^3 + t^2 + t + 1]
-
-julia> N = 2 + A
-[t + 3       t             1]
-[  t^2   t + 2             t]
-[   -2   t + 2   t^2 + t + 3]
-
-julia> M1 = deepcopy(A)
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> A != B
-true
-
-julia> isone(one(S))
-true
-
-julia> V = A[1:2, :]
-[t + 1   t   1]
-[  t^2   t   t]
-
-julia> W = A^3
-[    3*t^4 + 4*t^3 + t^2 - 3*t - 5            t^4 + 5*t^3 + 10*t^2 + 7*t + 4                 2*t^4 + 7*t^3 + 9*t^2 + 8*t + 1]
-[t^5 + 4*t^4 + 3*t^3 - 7*t^2 - 4*t               4*t^4 + 8*t^3 + 7*t^2 + 2*t                 t^5 + 5*t^4 + 9*t^3 + 7*t^2 - t]
-[  t^5 + 3*t^4 - 10*t^2 - 16*t - 2   t^5 + 6*t^4 + 12*t^3 + 11*t^2 + 5*t - 2   t^6 + 3*t^5 + 8*t^4 + 15*t^3 + 10*t^2 + t - 5]
-
-julia> Z = divexact(2*A, 2)
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> M = matrix(ZZ, BigInt[2 3 0; 1 1 1])
-[2   3   0]
-[1   1   1]
-
-julia> M[1, 2] = BigInt(4)
-4
-
-julia> c = M[1, 1]
-2
-

Transpose

transposeMethod
transpose(x::MatrixElem{T}) where T <: RingElement

Return the transpose of the given matrix.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> B = transpose(A)
-[t + 1   t^2            -2]
-[    t     t         t + 2]
-[    1     t   t^2 + t + 1]
-

Submatrices

Submatrices are only available for matrix spaces, not for matrix algebras and generally only available for generic matrices built on Julia arrays.

Submatrices return a new matrix with the same entries as the submatrix with the given range of rows and columns. They are best illustrated with examples.

Examples

julia> M = matrix(ZZ, BigInt[1 2 3; 2 3 4; 3 4 5])
-[1   2   3]
-[2   3   4]
-[3   4   5]
-
-julia> N1 = M[1:2, :]
-[1   2   3]
-[2   3   4]
-
-julia> N2 = M[:, :]
-[1   2   3]
-[2   3   4]
-[3   4   5]
-
-julia> N3 = M[2:3, 2:3]
-[3   4]
-[4   5]
-

Elementary row and column operations

add_columnMethod
add_column(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, rows = 1:nrows(a)) where T <: RingElement

Create a copy of $a$ and add $s$ times the $i$-th row to the $j$-th row of $a$.

By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.

add_column!Method
add_column!(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, rows = 1:nrows(a)) where T <: RingElement

Add $s$ times the $i$-th row to the $j$-th row of $a$.

By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.

add_rowMethod
add_row(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, cols = 1:ncols(a)) where T <: RingElement

Create a copy of $a$ and add $s$ times the $i$-th row to the $j$-th row of $a$.

By default, the transformation is applied to all columns of $a$. This can be changed using the optional cols argument.

add_row!Method
add_row!(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, cols = 1:ncols(a)) where T <: RingElement

Add $s$ times the $i$-th row to the $j$-th row of $a$.

By default, the transformation is applied to all columns of $a$. This can be changed using the optional cols argument.

multiply_columnMethod
multiply_column(a::MatrixElem{T}, s::RingElement, i::Int, rows = 1:nrows(a)) where T <: RingElement

Create a copy of $a$ and multiply the $i$th column of $a$ with $s$.

By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.

multiply_column!Method
multiply_column!(a::MatrixElem{T}, s::RingElement, i::Int, rows = 1:nrows(a)) where T <: RingElement

Multiply the $i$th column of $a$ with $s$.

By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.

multiply_rowMethod
multiply_row(a::MatrixElem{T}, s::RingElement, i::Int, cols = 1:ncols(a)) where T <: RingElement

Create a copy of $a$ and multiply the $i$th row of $a$ with $s$.

By default, the transformation is applied to all columns of $a$. This can be changed using the optional cols argument.

multiply_row!Method
multiply_row!(a::MatrixElem{T}, s::RingElement, i::Int, cols = 1:ncols(a)) where T <: RingElement

Multiply the $i$th row of $a$ with $s$.

By default, the transformation is applied to all columns of $a$. This can be changed using the optional cols argument.

Examples

julia> M = ZZ[1 2 3; 2 3 4; 4 5 5]
-[1   2   3]
-[2   3   4]
-[4   5   5]
-
-julia> add_column(M, 2, 3, 1)
-[ 7   2   3]
-[10   3   4]
-[14   5   5]
-
-julia> add_row(M, 1, 2, 3)
-[1   2   3]
-[2   3   4]
-[6   8   9]
-
-julia> multiply_column(M, 2, 3)
-[1   2    6]
-[2   3    8]
-[4   5   10]
-
-julia> multiply_row(M, 2, 3)
-[1    2    3]
-[2    3    4]
-[8   10   10]

Swapping rows and columns

swap_rowsMethod
swap_rows(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement

Return a matrix $b$ with the entries of $a$, where the $i$th and $j$th row are swapped.

Examples

julia> M = identity_matrix(ZZ, 3)
-[1   0   0]
-[0   1   0]
-[0   0   1]
-
-julia> swap_rows(M, 1, 2)
-[0   1   0]
-[1   0   0]
-[0   0   1]
-
-julia> M  # was not modified
-[1   0   0]
-[0   1   0]
-[0   0   1]
swap_rows!Method
swap_rows!(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement

Swap the $i$th and $j$th row of $a$ in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).

Examples

julia> M = identity_matrix(ZZ, 3)
-[1   0   0]
-[0   1   0]
-[0   0   1]
-
-julia> swap_rows!(M, 1, 2)
-[0   1   0]
-[1   0   0]
-[0   0   1]
-
-julia> M  # was modified
-[0   1   0]
-[1   0   0]
-[0   0   1]
swap_colsMethod
swap_cols(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement

Return a matrix $b$ with the entries of $a$, where the $i$th and $j$th row are swapped.

swap_cols!Method
swap_cols!(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement

Swap the $i$th and $j$th column of $a$ in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).

Swap the rows of M in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).

Concatenation

The following are only available for matrix spaces, not for matrix algebras.

hcat(M::T, N::T) where T <: MatElem

Return the horizontal concatenation of $M$ and $N$. It is assumed that the number of rows of $M$ and $N$ are the same.

vcat(M::T, N::T) where T <: MatElem

Return the vertical concatenation of $M$ and $N$. It is assumed that the number of columns of $M$ and $N$ are the same.

Examples

julia> M = matrix(ZZ, BigInt[1 2 3; 2 3 4; 3 4 5])
-[1   2   3]
-[2   3   4]
-[3   4   5]
-
-julia> N = matrix(ZZ, BigInt[1 0 1; 0 1 0; 1 0 1])
-[1   0   1]
-[0   1   0]
-[1   0   1]
-
-julia> P = hcat(M, N)
-[1   2   3   1   0   1]
-[2   3   4   0   1   0]
-[3   4   5   1   0   1]
-
-julia> Q = vcat(M, N)
-[1   2   3]
-[2   3   4]
-[3   4   5]
-[1   0   1]
-[0   1   0]
-[1   0   1]
-

Similar and zero

Both similar and zero construct new matrices, but the entries are either undefined with similar or zero-initialized with zero.

similar(x::MatElem, R::Ring=base_ring(x))
-zero(x::MatElem, R::Ring=base_ring(x))

Construct the matrix with the same dimensions as the given matrix, and the same base ring unless explicitly specified.

similar(x::MatElem, R::Ring, r::Int, c::Int)
-similar(x::MatElem, r::Int, c::Int)
-zero(x::MatElem, R::Ring, r::Int, c::Int)
-zero(x::MatElem, r::Int, c::Int)

Construct the $r\times c$ matrix with R as base ring (which defaults to the base ring of the the given matrix). If $x$ belongs to a matrix algebra and $r \neq c$, an exception is raised, and it's also possible to specify only one Int as the order (e.g. similar(x, n)).

Base.isassigned(M::MatElem, i, j)

Test whether the given matrix has a value associated with indices i and j.

Examples

julia> M = matrix(ZZ, BigInt[3 1 2; 2 0 1])
-[3   1   2]
-[2   0   1]
-
-julia> isassigned(M, 1, 2)
-true
-
-julia> isassigned(M, 4, 4)
-false
-
-julia> A = similar(M)
-[#undef   #undef   #undef]
-[#undef   #undef   #undef]
-
-julia> isassigned(A, 1, 2)
-false
-
-julia> B = zero(M)
-[0   0   0]
-[0   0   0]
-
-julia> C = similar(M, 4, 5)
-[#undef   #undef   #undef   #undef   #undef]
-[#undef   #undef   #undef   #undef   #undef]
-[#undef   #undef   #undef   #undef   #undef]
-[#undef   #undef   #undef   #undef   #undef]
-
-julia> base_ring(B)
-Integers
-
-julia> D = zero(M, QQ, 2, 2)
-[0//1   0//1]
-[0//1   0//1]
-
-julia> base_ring(D)
-Rationals

Symmetry testing

is_symmetricMethod
is_symmetric(a::MatrixElem{T}) where T <: RingElement

Return true if the given matrix is symmetric with respect to its main diagonal, i.e., tr(M) == M, otherwise return false.

Alias for LinearAlgebra.issymmetric.

Examples

julia> M = matrix(ZZ, [1 2 3; 2 4 5; 3 5 6])
-[1   2   3]
-[2   4   5]
-[3   5   6]
-
-julia> is_symmetric(M)
-true
-
-julia> N = matrix(ZZ, [1 2 3; 4 5 6; 7 8 9])
-[1   2   3]
-[4   5   6]
-[7   8   9]
-
-julia> is_symmetric(N)
-false
is_skew_symmetricMethod
is_skew_symmetric(M::MatElem)

Return true if the given matrix is skew symmetric with respect to its main diagonal, i.e., tr(M) == -M, otherwise return false.

Examples

julia> M = matrix(ZZ, [0 -1 -2; 1 0 -3; 2 3 0])
-[0   -1   -2]
-[1    0   -3]
-[2    3    0]
-
-julia> is_skew_symmetric(M)
-true
-

Powering

powersMethod
powers(a::Union{NCRingElement, MatElem}, d::Int)

Return an array $M$ of "powers" of a where $M[i + 1] = a^i$ for $i = 0..d$.

Examples

julia> M = ZZ[1 2 3; 2 3 4; 4 5 5]
-[1   2   3]
-[2   3   4]
-[4   5   5]
-
-julia> A = powers(M, 4)
-5-element Vector{AbstractAlgebra.Generic.MatSpaceElem{BigInt}}:
- [1 0 0; 0 1 0; 0 0 1]
- [1 2 3; 2 3 4; 4 5 5]
- [17 23 26; 24 33 38; 34 48 57]
- [167 233 273; 242 337 394; 358 497 579]
- [1725 2398 2798; 2492 3465 4044; 3668 5102 5957]
-

Gram matrix

gramMethod
gram(x::MatElem)

Return the Gram matrix of $x$, i.e. if $x$ is an $r\times c$ matrix return the $r\times r$ matrix whose entries $i, j$ are the dot products of the $i$-th and $j$-th rows, respectively.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> B = gram(A)
-[2*t^2 + 2*t + 2   t^3 + 2*t^2 + t                   2*t^2 + t - 1]
-[t^3 + 2*t^2 + t       t^4 + 2*t^2                       t^3 + 3*t]
-[  2*t^2 + t - 1         t^3 + 3*t   t^4 + 2*t^3 + 4*t^2 + 6*t + 9]
-

Trace

trMethod
tr(x::AbsAlgAssElem{T}) where T -> T

Returns the trace of $x$.

tr(x::MatrixElem{T}) where T <: RingElement

Return the trace of the matrix $a$, i.e. the sum of the diagonal elements. We require the matrix to be square.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> b = tr(A)
-t^2 + 3*t + 2
-

Content

contentMethod
content(x::MatrixElem{T}) where T <: RingElement

Return the content of the matrix $a$, i.e. the greatest common divisor of all its entries, assuming it exists.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> b = content(A)
-1
-

Permutation

*Method
*(P::perm, x::MatrixElem{T}) where T <: RingElement

Apply the pemutation $P$ to the rows of the matrix $x$ and return the result.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in t over rationals
-
-julia> G = SymmetricGroup(3)
-Full symmetric group over 3 elements
-
-julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> P = G([1, 3, 2])
-(2,3)
-
-julia> B = P*A
-[t + 1       t             1]
-[   -2   t + 2   t^2 + t + 1]
-[  t^2       t             t]
-

LU factorisation

luMethod
lu(A::MatrixElem{T}, P = SymmetricGroup(nrows(A))) where {T <: FieldElement}

Return a tuple $r, p, L, U$ consisting of the rank of $A$, a permutation $p$ of $A$ belonging to $P$, a lower triangular matrix $L$ and an upper triangular matrix $U$ such that $p(A) = LU$, where $p(A)$ stands for the matrix whose rows are the given permutation $p$ of the rows of $A$.

ffluMethod
fflu(A::MatrixElem{T}, P = SymmetricGroup(nrows(A))) where {T <: RingElement}

Return a tuple $r, d, p, L, U$ consisting of the rank of $A$, a denominator $d$, a permutation $p$ of $A$ belonging to $P$, a lower triangular matrix $L$ and an upper triangular matrix $U$ such that $p(A) = LDU$, where $p(A)$ stands for the matrix whose rows are the given permutation $p$ of the rows of $A$ and such that $D$ is the diagonal matrix diag$(p_1, p_1p_2, \ldots, p_{n-2}p_{n-1}, p_{n-1}p_n)$ where the $p_i$ are the inverses of the diagonal entries of $L$. The denominator $d$ is set to $\pm \mathrm{det}(S)$ where $S$ is an appropriate submatrix of $A$ ($S = A$ if $A$ is square and nonsingular) and the sign is decided by the parity of the permutation.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)
-
-julia> S = matrix_space(K, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 - 2 a - 1 2a])
-[      0   2*x + 3   x^2 + 1]
-[x^2 - 2     x - 1       2*x]
-[x^2 - 2     x - 1       2*x]
-
-julia> r, P, L, U = lu(A)
-(2, (1,2), [1 0 0; 0 1 0; 1 0 1], [x^2-2 x-1 2*x; 0 2*x+3 x^2+1; 0 0 0])
-
-julia> r, d, P, L, U = fflu(A)
-(2, 3*x^2 - 10*x - 8, (1,2), [x^2-2 0 0; 0 3*x^2-10*x-8 0; x^2-2 0 1], [x^2-2 x-1 2*x; 0 3*x^2-10*x-8 -4*x^2-x-2; 0 0 0])
-

Reduced row-echelon form

rref_rationalMethod
rref_rational(M::MatrixElem{T}) where {T <: RingElement}

Return a tuple $(r, A, d)$ consisting of the rank $r$ of $M$ and a denominator $d$ in the base ring of $M$ and a matrix $A$ such that $A/d$ is the reduced row echelon form of $M$. Note that the denominator is not usually minimal.

rrefMethod
rref(M::MatrixElem{T}) where {T <: FieldElement}

Return a tuple $(r, A)$ consisting of the rank $r$ of $M$ and a reduced row echelon form $A$ of $M$.

is_rrefMethod
is_rref(M::MatrixElem{T}) where {T <: RingElement}

Return true if $M$ is in reduced row echelon form, otherwise return false.

is_rrefMethod
is_rref(M::MatrixElem{T}) where {T <: RingElement}

Return true if $M$ is in reduced row echelon form, otherwise return false.

is_rref(M::MatrixElem{T}) where {T <: FieldElement}

Return true if $M$ is in reduced row echelon form, otherwise return false.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)
-
-julia> S = matrix_space(K, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> M = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> r, A = rref(M)
-(3, [1 0 0; 0 1 0; 0 0 1])
-
-julia> is_rref(A)
-true
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in x over integers
-
-julia> M = S([R(0) 2x + 3 x^2 + 1; x^2 - 2 x - 1 2x; x^2 + 3x + 1 2x R(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> r, A, d = rref_rational(M)
-(3, [-x^5-2*x^4-15*x^3-18*x^2-8*x-7 0 0; 0 -x^5-2*x^4-15*x^3-18*x^2-8*x-7 0; 0 0 -x^5-2*x^4-15*x^3-18*x^2-8*x-7], -x^5 - 2*x^4 - 15*x^3 - 18*x^2 - 8*x - 7)
-
-julia> is_rref(A)
-true

Determinant

detMethod
det(M::MatrixElem{T}) where {T <: RingElement}

Return the determinant of the matrix $M$. We assume $M$ is square.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)
-
-julia> S = matrix_space(K, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> d = det(A)
-11*x^2 - 30*x - 5
-

Rank

rankMethod
rank(M::MatrixElem{T}) where {T <: RingElement}

Return the rank of the matrix $M$.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)
-
-julia> S = matrix_space(K, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> d = rank(A)
-3
-

Minors

minorsMethod
minors(A::MatElem, k::Int)

Return an array consisting of the k-minors of A.

Examples

julia> A = ZZ[1 2 3; 4 5 6]
-[1   2   3]
-[4   5   6]
-
-julia> minors(A, 2)
-3-element Vector{BigInt}:
- -3
- -6
- -3
-

Exterior power

exterior_powerMethod
exterior_power(A::MatElem, k::Int) -> MatElem

Return the k-th exterior power of A.

Examples

julia> A = matrix(ZZ, 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
-
-julia> exterior_power(A, 2)
-[-3    -6   -3]
-[-6   -12   -6]
-[-3    -6   -3]

Pfaffian

pfaffianMethod
pfaffian(M::MatElem)

Return the Pfaffian of a skew-symmetric matrix M.

pfaffiansMethod
pfaffians(M::MatElem, k::Int)

Return a vector consisting of the k-Pfaffians of a skew-symmetric matrix M.

Examples

julia> R, x = polynomial_ring(QQ, ["x$i" for i in 1:6])
-(Multivariate polynomial ring in 6 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x1, x2, x3, x4, x5, x6])
-
-julia> M = R[0 x[1] x[2] x[3]; -x[1] 0 x[4] x[5]; -x[2] -x[4] 0 x[6]; -x[3] -x[5] -x[6] 0]
-[  0    x1    x2   x3]
-[-x1     0    x4   x5]
-[-x2   -x4     0   x6]
-[-x3   -x5   -x6    0]
-
-julia> pfaffian(M)
-x1*x6 - x2*x5 + x3*x4
-
-julia> pfaffians(M, 2)
-6-element Vector{AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}:
- x1
- x2
- x4
- x3
- x5
- x6
- 

Linear solving

solveMethod
solve(a::MatElem{S}, b::MatElem{S}) where {S <: RingElement}

Given an $m\times r$ matrix $a$ over a ring and an $m\times n$ matrix $b$ over the same ring, return an $r\times n$ matrix $x$ such that $ax = b$. If no such matrix exists, an exception is raised. See also solve_left.

solve_rationalMethod
solve_rational(M::MatElem{T}, b::MatElem{T}) where T <: RingElement

Given a non-singular $n\times n$ matrix over a ring and an $n\times m$ matrix over the same ring, return a tuple $x, d$ consisting of an $n\times m$ matrix $x$ and a denominator $d$ such that $Ax = db$. The denominator will be the determinant of $A$ up to sign. If $A$ is singular an exception is raised.

can_solve_with_solutionMethod
can_solve_with_solution(a::MatElem{S}, b::MatElem{S}; side::Symbol = :right) where S <: RingElement

Given two matrices $a$ and $b$ over the same ring, try to solve $ax = b$ if side is :right or $xa = b$ if side is :left. In either case, return a tuple (flag, x). If a solution exists, flag is set to true and x is a solution. If no solution exists, flag is set to false and x is arbitrary. If the dimensions of $a$ and $b$ are incompatible, an exception is raised.

can_solveMethod
can_solve(a::MatElem{S}, b::MatElem{S}; side::Symbol = :right) where S <: RingElement

Given two matrices $a$ and $b$ over the same ring, check the solubility of $ax = b$ if side is :right or $xa = b$ if side is :left. Return true if a solution exists, false otherwise. If the dimensions of $a$ and $b$ are incompatible, an exception is raised. If a solution should be computed as well, use can_solve_with_solution instead.

solve_leftMethod
solve_left(a::MatElem{S}, b::MatElem{S}) where S <: RingElement

Given an $r\times n$ matrix $a$ over a ring and an $m\times n$ matrix $b$ over the same ring, return an $m\times r$ matrix $x$ such that $xa = b$. If no such matrix exists, an exception is raised. See also solve.

solve_triuMethod
solve_triu(U::MatElem{T}, b::MatElem{T}, unit::Bool = false) where {T <: FieldElement}

Given a non-singular $n\times n$ matrix over a field which is upper triangular, and an $n\times m$ matrix over the same field, return an $n\times m$ matrix $x$ such that $Ax = b$. If $A$ is singular an exception is raised. If unit is true then $U$ is assumed to have ones on its diagonal, and the diagonal will not be read.

can_solve_left_reduced_triuMethod
can_solve_left_reduced_triu(r::MatElem{T},
-                      M::MatElem{T}) where T <: RingElement

Return a tuple flag, x where flag is set to true if $xM = r$ has a solution, where $M$ is an $m\times n$ matrix in (upper triangular) Hermite normal form or reduced row echelon form and $r$ and $x$ are row vectors with $m$ columns. If there is no solution, flag is set to false and $x$ is set to the zero row.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)
-
-julia> S = matrix_space(K, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> U = matrix_space(K, 3, 1)
-Matrix space of 3 rows and 1 column
-  over residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> b = U([2a, a + 1, (-a - 1)])
-[   2*x]
-[ x + 1]
-[-x - 1]
-
-julia> x = solve(A, b)
-[  1984//7817*x^2 + 1573//7817*x - 937//7817]
-[ -2085//7817*x^2 + 1692//7817*x + 965//7817]
-[-3198//7817*x^2 + 3540//7817*x - 3525//7817]
-
-julia> A = matrix(ZZ, 2, 2, [1, 2, 0, 2])
-[1   2]
-[0   2]
-
-julia> b = matrix(ZZ, 2, 1, [2, 1])
-[2]
-[1]
-
-julia> can_solve(A, b, side = :right)
-false
-
-julia> A = matrix(QQ, 2, 2, [3, 4, 5, 6])
-[3//1   4//1]
-[5//1   6//1]
-
-julia> b = matrix(QQ, 1, 2, [2, 1])
-[2//1   1//1]
-
-julia> can_solve_with_solution(A, b; side = :left)
-(true, [-7//2 5//2])
-
-julia> A = S([a + 1 2a + 3 a^2 + 1; K(0) a^2 - 1 2a; K(0) K(0) a])
-[x + 1   2*x + 3   x^2 + 1]
-[    0   x^2 - 1       2*x]
-[    0         0         x]
-
-julia> bb = U([2a, a + 1, (-a - 1)])
-[   2*x]
-[ x + 1]
-[-x - 1]
-
-julia> x = solve_triu(A, bb, false)
-[ 1//3*x^2 + 8//3*x + 13//3]
-[-3//5*x^2 - 3//5*x - 12//5]
-[                   x^2 + 2]
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in x over integers
-
-julia> U = matrix_space(R, 3, 2)
-Matrix space of 3 rows and 2 columns
-  over univariate polynomial ring in x over integers
-
-julia> A = S([R(0) 2x + 3 x^2 + 1; x^2 - 2 x - 1 2x; x^2 + 3x + 1 2x R(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> bbb = U(transpose([2x x + 1 (-x - 1); x + 1 (-x) x^2]))
-[   2*x   x + 1]
-[ x + 1      -x]
-[-x - 1     x^2]
-
-julia> x, d = solve_rational(A, bbb)
-([3*x^4-10*x^3-8*x^2-11*x-4 -x^5+3*x^4+x^3-2*x^2+3*x-1; -2*x^5-x^4+6*x^3+2*x+1 x^6+x^5+4*x^4+9*x^3+8*x^2+5*x+2; 6*x^4+12*x^3+15*x^2+6*x-3 -2*x^5-4*x^4-6*x^3-9*x^2-4*x+1], x^5 + 2*x^4 + 15*x^3 + 18*x^2 + 8*x + 7)
-
-julia> S = matrix_space(ZZ, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over integers
-
-julia> T = matrix_space(ZZ, 3, 1)
-Matrix space of 3 rows and 1 column
-  over integers
-
-julia> A = S([BigInt(2) 3 5; 1 4 7; 9 2 2])
-[2   3   5]
-[1   4   7]
-[9   2   2]
-
-julia> B = T([BigInt(4), 5, 7])
-[4]
-[5]
-[7]

Inverse

invMethod
inv(M::MatrixElem{T}) where {T <: RingElement}

Given a non-singular $n\times n$ matrix over a ring, return an $n\times n$ matrix $X$ such that $MX = I_n$, where $I_n$ is the $n\times n$ identity matrix. If $M$ is not invertible over the base ring an exception is raised.

is_invertible_with_inverseMethod
is_invertible_with_inverse(A::MatrixElem{T}; side::Symbol = :left) where {T <: RingElement}

Given an $n\times m$ matrix $A$ over a ring, return a tuple (flag, B). If side is :right and flag is true, $B$ is the right inverse of $A$ i.e. $AB$ is the $n\times n$ unit matrix. If side is :left and flag is true, $B$ is the left inverse of $A$ i.e. $BA$ is the $m\times m$ unit matrix. If flag is false, no right or left inverse exists.

is_invertibleMethod
is_invertible(A::MatrixElem{T}) where {T <: RingElement}

Return true if a given square matrix is invertible, false otherwise. If the inverse should also be computed, use is_invertible_with_inverse.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)
-
-julia> S = matrix_space(K, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> X = inv(A)
-[-343//7817*x^2 + 717//7817*x - 2072//7817   -4964//23451*x^2 + 2195//23451*x - 11162//23451    -232//23451*x^2 - 4187//23451*x - 1561//23451]
-[ 128//7817*x^2 - 655//7817*x + 2209//7817      599//23451*x^2 - 2027//23451*x - 1327//23451   -1805//23451*x^2 + 2702//23451*x - 7394//23451]
-[ 545//7817*x^2 + 570//7817*x + 2016//7817     -1297//23451*x^2 - 5516//23451*x - 337//23451   8254//23451*x^2 - 2053//23451*x + 16519//23451]
-
-julia> is_invertible(A)
-true
-
-julia> is_invertible_with_inverse(A)
-(true, [-343//7817*x^2+717//7817*x-2072//7817 -4964//23451*x^2+2195//23451*x-11162//23451 -232//23451*x^2-4187//23451*x-1561//23451; 128//7817*x^2-655//7817*x+2209//7817 599//23451*x^2-2027//23451*x-1327//23451 -1805//23451*x^2+2702//23451*x-7394//23451; 545//7817*x^2+570//7817*x+2016//7817 -1297//23451*x^2-5516//23451*x-337//23451 8254//23451*x^2-2053//23451*x+16519//23451])
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = matrix_space(R, 3, 3)
-Matrix space of 3 rows and 3 columns
-  over univariate polynomial ring in x over integers
-
-julia> A = S([R(0) 2x + 3 x^2 + 1; x^2 - 2 x - 1 2x; x^2 + 3x + 1 2x R(1)])
-[            0   2*x + 3   x^2 + 1]
-[      x^2 - 2     x - 1       2*x]
-[x^2 + 3*x + 1       2*x         1]
-
-julia> X, d = pseudo_inv(A)
-([4*x^2-x+1 -2*x^3+3 x^3-5*x^2-5*x-1; -2*x^3-5*x^2-2*x-2 x^4+3*x^3+2*x^2+3*x+1 -x^4+x^2+2; -x^3+2*x^2+2*x-1 -2*x^3-9*x^2-11*x-3 2*x^3+3*x^2-4*x-6], -x^5 - 2*x^4 - 15*x^3 - 18*x^2 - 8*x - 7)
-

Nullspace

nullspaceMethod
nullspace(M::MatElem{T}) where {T <: RingElement}

Return a tuple $(\nu, N)$ consisting of the nullity $\nu$ of $M$ and a basis $N$ (consisting of column vectors) for the right nullspace of $M$, i.e. such that $MN$ is the zero matrix. If $M$ is an $m\times n$ matrix $N$ will be an $n\times \nu$ matrix. Note that the nullspace is taken to be the vector space kernel over the fraction field of the base ring if the latter is not a field. In AbstractAlgebra we use the name "kernel" for a function to compute an integral kernel.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = matrix_space(R, 4, 4)
-Matrix space of 4 rows and 4 columns
-  over univariate polynomial ring in x over integers
-
-julia> M = S([-6*x^2+6*x+12 -12*x^2-21*x-15 -15*x^2+21*x+33 -21*x^2-9*x-9;
-              -8*x^2+8*x+16 -16*x^2+38*x-20 90*x^2-82*x-44 60*x^2+54*x-34;
-              -4*x^2+4*x+8 -8*x^2+13*x-10 35*x^2-31*x-14 22*x^2+21*x-15;
-              -10*x^2+10*x+20 -20*x^2+70*x-25 150*x^2-140*x-85 105*x^2+90*x-50])
-[  -6*x^2 + 6*x + 12   -12*x^2 - 21*x - 15    -15*x^2 + 21*x + 33     -21*x^2 - 9*x - 9]
-[  -8*x^2 + 8*x + 16   -16*x^2 + 38*x - 20     90*x^2 - 82*x - 44    60*x^2 + 54*x - 34]
-[   -4*x^2 + 4*x + 8    -8*x^2 + 13*x - 10     35*x^2 - 31*x - 14    22*x^2 + 21*x - 15]
-[-10*x^2 + 10*x + 20   -20*x^2 + 70*x - 25   150*x^2 - 140*x - 85   105*x^2 + 90*x - 50]
-
-julia> n, N = nullspace(M)
-(2, [1320*x^4-330*x^2-1320*x-1320 1056*x^4+1254*x^3+1848*x^2-66*x-330; -660*x^4+1320*x^3+1188*x^2-1848*x-1056 -528*x^4+132*x^3+1584*x^2+660*x-264; 396*x^3-396*x^2-792*x 0; 0 396*x^3-396*x^2-792*x])
nullspace(M::MatElem{T}) where {T <: FieldElement}

Return a tuple $(\nu, N)$ consisting of the nullity $\nu$ of $M$ and a basis $N$ (consisting of column vectors) for the right nullspace of $M$, i.e. such that $MN$ is the zero matrix. If $M$ is an $m\times n$ matrix $N$ will be an $n\times \nu$ matrix.

Kernel

kernelMethod
kernel(a::MatElem{T}; side::Symbol = :right) where T <: RingElement

Return a tuple $(n, M)$, where $n$ is the rank of the kernel of $a$ and $M$ is a basis for it. If side is :right or not specified, the right kernel is computed, i.e. the matrix of columns whose span gives the right kernel space. If side is :left, the left kernel is computed, i.e. the matrix of rows whose span is the left kernel space.

left_kernelMethod
left_kernel(a::MatElem{T}) where T <: RingElement

Return a tuple n, M where $M$ is a matrix whose rows generate the kernel of $M$ and $n$ is the rank of the kernel. The transpose of the output of this function is guaranteed to be in flipped upper triangular format (i.e. upper triangular format if columns and rows are reversed).

right_kernelMethod
right_kernel(a::MatElem{T}) where T <: RingElement

Return a tuple n, M where $M$ is a matrix whose columns generate the kernel of $a$ and $n$ is the rank of the kernel.

Examples

julia> S = matrix_space(ZZ, 4, 4)
-Matrix space of 4 rows and 4 columns
-  over integers
-
-julia> M = S([1 2 0 4;
-              2 0 1 1;
-              0 1 1 -1;
-              2 -1 0 2])
-[1    2   0    4]
-[2    0   1    1]
-[0    1   1   -1]
-[2   -1   0    2]
-
-julia> nr, Nr = kernel(M)
-(1, [-8; -6; 11; 5])
-
-julia> nl, Nl = left_kernel(M)
-(1, [0 -1 1 1])
-

Hessenberg form

hessenbergMethod
hessenberg(A::MatrixElem{T}) where {T <: RingElement}

Return the Hessenberg form of $M$, i.e. an upper Hessenberg matrix which is similar to $M$. The upper Hessenberg form has nonzero entries above and on the diagonal and in the diagonal line immediately below the diagonal.

is_hessenbergMethod
is_hessenberg(A::MatrixElem{T}) where {T <: RingElement}

Return true if $M$ is in Hessenberg form, otherwise returns false.

Examples

julia> R = residue_ring(ZZ, 7)
-Residue ring of integers modulo 7
-
-julia> S = matrix_space(R, 4, 4)
-Matrix space of 4 rows and 4 columns
-  over residue ring of integers modulo 7
-
-julia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);
-              R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])
-[1   2   4   3]
-[2   5   1   0]
-[6   1   3   2]
-[1   1   3   5]
-
-julia> A = hessenberg(M)
-[1   5   5   3]
-[2   1   1   0]
-[0   1   3   2]
-[0   0   2   2]
-
-julia> is_hessenberg(A)
-true
-

Characteristic polynomial

charpolyMethod
charpoly(V::Ring, Y::MatrixElem{T}) where {T <: RingElement}

Return the characteristic polynomial $p$ of the matrix $M$. The polynomial ring $R$ of the resulting polynomial must be supplied and the matrix is assumed to be square.

Examples

julia> R = residue_ring(ZZ, 7)
-Residue ring of integers modulo 7
-
-julia> S = matrix_space(R, 4, 4)
-Matrix space of 4 rows and 4 columns
-  over residue ring of integers modulo 7
-
-julia> T, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over residue ring, x)
-
-julia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);
-              R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])
-[1   2   4   3]
-[2   5   1   0]
-[6   1   3   2]
-[1   1   3   5]
-
-julia> A = charpoly(T, M)
-x^4 + 2*x^2 + 6*x + 2
-

Minimal polynomial

minpolyMethod
minpoly(S::Ring, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}

Return the minimal polynomial $p$ of the matrix $M$. The polynomial ring $S$ of the resulting polynomial must be supplied and the matrix must be square.

Examples

julia> R = GF(13)
-Finite field F_13
-
-julia> T, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over finite field F_13, y)
-
-julia> M = R[7 6 1;
-             7 7 5;
-             8 12 5]
-[7    6   1]
-[7    7   5]
-[8   12   5]
-
-julia> A = minpoly(T, M)
-y^2 + 10*y
-

Transforms

similarity!Method
similarity!(A::MatrixElem{T}, r::Int, d::T) where {T <: RingElement}

Applies a similarity transform to the $n\times n$ matrix $M$ in-place. Let $P$ be the $n\times n$ identity matrix that has had all zero entries of row $r$ replaced with $d$, then the transform applied is equivalent to $M = P^{-1}MP$. We require $M$ to be a square matrix. A similarity transform preserves the minimal and characteristic polynomials of a matrix.

Examples

julia> R = residue_ring(ZZ, 7)
-Residue ring of integers modulo 7
-
-julia> S = matrix_space(R, 4, 4)
-Matrix space of 4 rows and 4 columns
-  over residue ring of integers modulo 7
-
-julia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);
-              R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])
-[1   2   4   3]
-[2   5   1   0]
-[6   1   3   2]
-[1   1   3   5]
-
-julia> similarity!(M, 1, R(3))
-

Hermite normal form

hnfMethod
hnf(A::MatrixElem{T}) where {T <: RingElement}

Return the upper right row Hermite normal form of $A$.

hnf_with_transformMethod
hnf_with_transform(A)

Return the tuple $H, U$ consisting of the upper right row Hermite normal form $H$ of $A$ together with invertible matrix $U$ such that $UA = H$.

is_hnfMethod
is_hnf(M::MatrixElem{T}) where T <: RingElement

Return true if the matrix is in Hermite normal form.

Examples

julia> A = matrix(ZZ, [2 3 -1; 3 5 7; 11 1 12])
-[ 2   3   -1]
-[ 3   5    7]
-[11   1   12]
-
-julia> H = hnf(A)
-[1   0   255]
-[0   1    17]
-[0   0   281]
-
-julia> is_hnf(H)
-true
-
-julia> H, U = hnf_with_transform(A)
-([1 0 255; 0 1 17; 0 0 281], [-47 28 1; -3 2 0; -52 31 1])
-
-julia> U*A
-[1   0   255]
-[0   1    17]
-[0   0   281]

Smith normal form

is_snfMethod
is_snf(A::MatrixElem{T}) where T <: RingElement

Return true if $A$ is in Smith Normal Form.

snfMethod
snf(A::MatrixElem{T}) where {T <: RingElement}

Return the Smith normal form of $A$.

snf_with_transformMethod
snf_with_transform(A)

Return the tuple $S, T, U$ consisting of the Smith normal form $S$ of $A$ together with invertible matrices $T$ and $U$ such that $TAU = S$.

Examples

julia> A = matrix(ZZ, [2 3 -1; 3 5 7; 11 1 12])
-[ 2   3   -1]
-[ 3   5    7]
-[11   1   12]
-
-julia> S = snf(A)
-[1   0     0]
-[0   1     0]
-[0   0   281]
-
-julia> S, T, U = snf_with_transform(A)
-([1 0 0; 0 1 0; 0 0 281], [1 0 0; 7 1 0; 229 31 1], [0 -3 26; 0 2 -17; -1 0 1])
-
-julia> T*A*U
-[1   0     0]
-[0   1     0]
-[0   0   281]

(Weak) Popov form

AbstractAlgebra.jl provides algorithms for computing the (weak) Popov of a matrix with entries in a univariate polynomial ring over a field.

is_weak_popovMethod
is_weak_popov(P::MatrixElem{T}, rank::Int) where T <: PolyRingElem

Return true if $P$ is a matrix in weak Popov form of the given rank.

weak_popovMethod
weak_popov(A::MatElem{T}) where {T <: PolyRingElem}

Return the weak Popov form of $A$.

weak_popov_with_transformMethod
weak_popov_with_transform(A::MatElem{T}) where {T <: PolyRingElem}

Compute a tuple $(P, U)$ where $P$ is the weak Popov form of $A$ and $U$ is a transformation matrix so that $P = UA$.

popovMethod
popov(A::MatElem{T}) where {T <: PolyRingElem}

Return the Popov form of $A$.

popov_with_transformMethod
popov_with_transform(A::MatElem{T}) where {T <: PolyRingElem}

Compute a tuple $(P, U)$ where $P$ is the Popov form of $A$ and $U$ is a transformation matrix so that $P = UA$.

Examples

julia> R, x = polynomial_ring(QQ, "x");
-
-julia> A = matrix(R, map(R, Any[1 2 3 x; x 2*x 3*x x^2; x x^2+1 x^3+x^2 x^4+x^2+1]))
-[1         2           3               x]
-[x       2*x         3*x             x^2]
-[x   x^2 + 1   x^3 + x^2   x^4 + x^2 + 1]
-
-julia> P = weak_popov(A)
-[   1                        2                    3   x]
-[   0                        0                    0   0]
-[-x^3   -2*x^3 + x^2 - 2*x + 1   -2*x^3 + x^2 - 3*x   1]
-
-julia> P, U = weak_popov_with_transform(A)
-([1 2 3 x; 0 0 0 0; -x^3 -2*x^3+x^2-2*x+1 -2*x^3+x^2-3*x 1], [1 0 0; -x 1 0; -x^3-x 0 1])
-
-julia> U*A
-[   1                        2                    3   x]
-[   0                        0                    0   0]
-[-x^3   -2*x^3 + x^2 - 2*x + 1   -2*x^3 + x^2 - 3*x   1]
diff --git a/previews/PR2578/AbstractAlgebra/matrix_algebras/index.html b/previews/PR2578/AbstractAlgebra/matrix_algebras/index.html deleted file mode 100644 index 1dd0c2be63df..000000000000 --- a/previews/PR2578/AbstractAlgebra/matrix_algebras/index.html +++ /dev/null @@ -1,40 +0,0 @@ - -Generic matrix algebras · Oscar.jl

Generic matrix algebras

AbstractAlgebra.jl allows the creation of an algebra (ring) of $m\times m$ matrices over a computable, commutative ring.

Functions specific to generic matrix algebras of $m\times m$ matrices are implemented in src/generic/MatrixAlgebra.jl. The remaining functionality is in the file src/generic/Matrix.jl.

As well as implementing the entire Matrix interface, including the optional functionality, there are many additional generic algorithms implemented for matrix algebras.

Almost all of the functionality specified for generic matrices is available for matrix algebras. The exceptions are functions such as solve and nullspace which may return non-square matrices, or which don't accept square matrices.

All of the generic functionality is part of the Generic submodule of AbstractAlgebra.jl. This is exported by default, so it is not necessary to qualify names of functions.

Types and parent objects

Generic matrices in AbstractAlgebra.jl have type Generic.MatAlgElem{T} for matrices in a matrix algebra, where T is the type of elements of the matrix. Internally, generic matrices are implemented using an object wrapping a Julia two dimensional array, though they are not themselves Julia arrays. See the file src/generic/GenericTypes.jl for details.

Parents of generic matrices in a matrix algebra have type Generic.MatAlgebra{T}.

Note that matrix algebras are noncommutative rings. Thus their types belong to NCRing and NCRingElem. They cannot be used in constructions which require a commutative ring (Ring and RingElem respectively).

The generic matrix algebra matrix types belong to the abstract type MatAlgElem{T} and the parent types belong to MatAlgebra{T} Note that both of these require disambiguation from the concrete types in Generic of the same name.

The degree and base ring $R$ of a generic matrix are stored in its parent object, however to allow creation of matrices without first creating the matrix space parent, generic matrices in Julia do not contain a reference to their parent. They contain the row and column numbers (or degree, in the case of matrix algebras) and the base ring on a per matrix basis. The parent object can then be reconstructed from this data on demand.

Matrix algebra constructors

A matrix algebra in AbstractAlgebra.jl represents a collection of all matrices with given degree and base ring.

In order to construct matrices in AbstractAlgebra.jl, one must construct the matrix algebra itself. This is accomplished with the following constructor.

MatrixAlgebra(R::Ring, degree::Int)

Construct the algebra of matrices with the given degree over the given base ring.

Here are some examples of creating matrix algebras and making use of the resulting parent objects to coerce various elements into the matrix algebra.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = MatrixAlgebra(R, 3)
-Matrix algebra of degree 3
-  over univariate polynomial ring in t over rationals
-
-julia> A = S()
-[0   0   0]
-[0   0   0]
-[0   0   0]
-
-julia> B = S(12)
-[12    0    0]
-[ 0   12    0]
-[ 0    0   12]
-
-julia> C = S(R(11))
-[11    0    0]
-[ 0   11    0]
-[ 0    0   11]
-

Matrix algebra element constructors

The following additional constructors are provided for constructing various kinds of matrices in a matrix algebra.

identity_matrixMethod
identity_matrix(M::MatElem{T}) where T <: NCRingElement

Construct the identity matrix in the same matrix space as M, i.e. with ones down the diagonal and zeroes elsewhere. M must be square. This is an alias for one(M).

identity_matrix(M::MatAlgElem{T}) where T <: RingElement

Return the identity matrix over the same base ring as $M$ and with the same dimensions.

Examples

S = MatrixAlgebra(ZZ, 2)
-M = zero(S)
-
-P = identity_matrix(M)

Matrix algebra functionality provided by AbstractAlgebra.jl

Most of the generic matrix functionality described in the generic matrix section of the documentation is available for both matrix spaces and matrix algebras. Exceptions include functions that do not return or accept square matrices or which cannot specify a parent. Such functions include solve and nullspace which can't be provided for matrix algebras.

In addition to the functionality described for matrix spaces, matrix algebras support all noncommutative ring operations, and matrix algebras can be used as a base ring for other generic constructs that accept a noncommutative base ring (NCRing).

In this section we describe functionality provided for matrix algebras only.

Basic matrix functionality

As well as the Ring and Matrix interfaces, the following functions are provided to manipulate matrices.

degreeMethod
degree(a::MatAlgElem{T}) where T <: RingElement

Return the degree $n$ of the given matrix algebra.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = MatrixAlgebra(R, 3)
-Matrix algebra of degree 3
-  over univariate polynomial ring in t over rationals
-
-julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
-[t + 1       t             1]
-[  t^2       t             t]
-[   -2   t + 2   t^2 + t + 1]
-
-julia> n = degree(A)
-3
-
diff --git a/previews/PR2578/AbstractAlgebra/matrix_interface/index.html b/previews/PR2578/AbstractAlgebra/matrix_interface/index.html deleted file mode 100644 index 1d5a2cb844a1..000000000000 --- a/previews/PR2578/AbstractAlgebra/matrix_interface/index.html +++ /dev/null @@ -1,16 +0,0 @@ - -Matrix Interface · Oscar.jl

Matrix Interface

Generic matrices are supported in AbstractAlgebra.jl. Both the space of $m\times n$ matrices and the algebra (ring) of $m\times m$ matrices are supported.

As the space of $m\times n$ matrices over a commutative ring is not itself a commutative ring, not all of the Ring interface needs to be implemented for such matrices in.

In particular, the following functions do not need to be implemented: is_domain_type, and divexact. The canonical_unit function should be implemented, but simply needs to return the corresponding value for entry $[1, 1]$ (the function is never called on empty matrices).

For matrix algebras, all of the ring interface must be implemented.

Note

AbstractAlgebra.jl matrices are not the same as Julia matrices. We store a base ring in our matrix and matrices are row major instead of column major in order to support the numerous large C libraries that use this convention.

All AbstractAlgebra.jl matrices are assumed to be mutable. This is usually critical to performance.

Types and parents

AbstractAlgebra provides two abstract types for matrix spaces and their elements:

  • MatSpace{T} is the abstract type for matrix space parent types
  • MatElem{T} is the abstract type for matrix types belonging to a matrix space

It also provides two abstract types for matrix algebras and their elements:

  • MatAlgebra{T} is the abstract type for matrix algebra parent types
  • MatAlgElem{T} is the abstract type for matrix types belonging to a matrix algebra

Note that these abstract types are parameterised. The type T should usually be the type of elements of the matrices.

Matrix spaces and matrix algebras should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Matrix spaces and algebras should at least be distinguished based on their base (coefficient) ring and the dimensions of the matrices in the space.

See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).

Required functionality for matrices

In addition to the required (relevant) functionality for the Ring interface (see above), the following functionality is required for the Matrix interface.

We suppose that R is a fictitious base ring (coefficient ring) and that S is a space of $m\times n$ matrices over R, or algebra of $m\times m$ matrices with parent object S of type MyMatSpace{T} or MyMatAlgebra{T}, respectively. We also assume the matrices in the space have type MyMat{T}, where T is the type of elements of the base (element) ring.

Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.

Note that the type T must (transitively) belong to the abstract type RingElem.

Currently only matrices over commutative rings are supported.

Constructors

In addition to the standard constructors, the following constructors, taking an array of elements, must be available.

(S::MyMatSpace{T})(A::Matrix{T}) where T <: RingElem
-(S::MyMatAlgebra{T})(A::Matrix{T}) where T <: RingElem

Create the matrix in the given space/algebra whose $(i, j)$ entry is given by A[i, j].

(S::MyMatSpace{T})(A::Matrix{S}) where {S <: RingElem, T <: RingElem}
-(S::MyMatAlgebra{T})(A::Matrix{S}) where {S <: RingElem, T <: RingElem}

Create the matrix in the given space/algebra whose $(i, j)$ entry is given by A[i, j], where S is the type of elements that can be coerced into the base ring of the matrix.

(S::MyMatSpace{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}
-(S::MyMatAlgebra{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}

Create the matrix in the given space/algebra of matrices (with dimensions $m\times n$ say), whose $(i, j)$ entry is given by A[i*(n - 1) + j] and where S is the type of elements that can be coerced into the base ring of the matrix.

It is also possible to create matrices (in a matrix space only) directly, without first creating the corresponding matrix space (the inner constructor being called directly). Note that to support this, matrix space parent objects don't contain a reference to their parent. Instead, parents are constructed on-the-fly if requested. (The same strategy is used for matrix algebras.)

matrix(R::Ring, arr::Matrix{T}) where T <: RingElem

Given an $m\times n$ Julia matrix of entries, construct the corresponding AbstractAlgebra.jl matrix over the given ring R, assuming all the entries can be coerced into R.

matrix(R::Ring, r::Int, c::Int, A::Vector{T}) where T <: RingElem

Construct the given $r\times c$ AbstractAlgebra.jl matrix over the ring R whose $(i, j)$ entry is given by A[c*(i - 1) + j], assuming that all the entries can be coerced into R.

zero_matrix(R::Ring, r::Int, c::Int)

Construct the $r\times c$ AbstractAlgebra.jl zero matrix over the ring R.

Views

Just as Julia supports views of matrices, AbstractAlgebra requires all matrix types to support views. These allow one to work with a submatrix of a given matrix. Modifying the submatrix also modifies the original matrix.

Note that deepcopy of a view type must return the same type, but it should return a view into a deepcopy of the original matrix. Julia enforces this for consistency.

To support views, generic matrices in AbstractAlgebra of type Generic.MatSpaceElem have an associated Generic.MatSpaceView type. Both belong to the Generic.Mat abstract type, so that one can work with that in functions that can accept both views and actual matrices.

The syntax for views is as for Julia's own views.

Note that the parent_type function returns the same type for a view as for the original matrix type. This could potentially cause a problem if the elem_type function is applied to the return value of parent_type and then used in a type assertion. For this reason, there may be some limitations on the use of views.

The similar function also returns a matrix of type MatSpaceElem when applied to a view, rather than another view.

Basic manipulation of matrices

dense_matrix_type(::Type{T}) where T<:NCRingElement
-dense_matrix_type(::T) where T<:NCRingElement
-dense_matrix_type(::Type{S}) where S<:NCRing
-dense_matrix_type(::S) where S<:NCRing

Return the type of dense matrices whose entries have type T respectively elem_type(S). It suffices to provide a method with the first signature. For the other three signatures, the default methods dispatch to the first. E.g. in Nemo, which depends on AbstractAlgebra, we define dense_matrix_type(::Type{ZZRingElem}) = ZZMatrix.

nrows(M::MyMatSpace{T}) where T <: RingElem
-nrows(M::MyMatAlgebra{T}) where T <: RingElem

Return the number of rows of matrices in the matrix space.

ncols(M:MyMatSpace{T}) where T <: RingElem
-ncols(M:MyMatAlgebra{T}) where T <: RingElem

Return the number of columns of matrices in the matrix space.

nrows(f::MyMat{T}) where T <: RingElem

Return the number of rows of the given matrix.

ncols(f::MyMat{T}) where T <: RingElem

Return the number of columns of the given matrix.

getindex(M::MyMat{T}, r::Int, c::Int) where T <: RingElem

Return the $(i, j)$-th entry of the matrix $M$.

setindex!(M::MyMat{T}, d::T, r::Int, c::Int) where T <: RingElem

Set the $(i, j)$-th entry of the matrix $M$ to $d$, which is assumed to be in the base ring of the matrix. The matrix must have such an entry and the matrix is mutated in place and not returned from the function.

Transpose

transpose(::MyMat{T}) where T <: RingElem

Return the transpose of the given matrix.

Optional functionality for matrices

Especially when wrapping C libraries, some functions are best implemented directly, rather than relying on the generic functionality. The following are all provided by the AbstractAlgebra.jl generic code, but can optionally be implemented directly for performance reasons.

Optional submatrices

The following are only available for matrix spaces, not for matrix algebras.

Base.getindex(M::MyMat, rows::AbstractVector{Int}, cols::AbstractVector{Int})

Return a new matrix with the same entries as the submatrix with the given range of rows and columns.

Optional row swapping

swap_rows!(M::MyMat{T}, i::Int, j::Int) where T <: RingElem

Swap the rows of M in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).

Optional concatenation

The following are only available for matrix spaces, not for matrix algebras.

hcat(M::MyMat{T}, N::MyMat{T}) where T <: RingElem

Return the horizontal concatenation of $M$ and $N$. It is assumed that the number of rows of $M$ and $N$ are the same.

vcat(M::MyMat{T}, N::MyMat{T}) where T <: RingElem

Return the vertical concatenation of $M$ and $N$. It is assumed that the number of columns of $M$ and $N$ are the same.

Optional zero tests

The following functions are available for matrices in both matrix algebras and matrix spaces.

is_zero_entry(M::MatrixElem{T}, i::Int, j::Int) where T <: NCRingElement
-is_zero_row(M::MatrixElem{T}, i::Int) where T <: NCRingElement
-is_zero_column(M::MatrixElem{T}, j::Int) where T <: NCRingElement

Optional similar and zero

The following functions are available for matrices in both matrix algebras and matrix spaces. Both similar and zero construct new matrices, with the same methods, but the entries are either undefined with similar or zero-initialized with zero.

similar(x::MyMat{T}, R::Ring=base_ring(x)) where T <: RingElem
-zero(x::MyMat{T}, R::Ring=base_ring(x)) where T <: RingElem

Construct the matrix with the same dimensions as the given matrix, and the same base ring unless explicitly specified.

similar(x::MyMat{T}, R::Ring, r::Int, c::Int) where T <: RingElem
-similar(x::MyMat{T}, r::Int, c::Int) where T <: RingElem
-zero(x::MyMat{T}, R::Ring, r::Int, c::Int) where T <: RingElem
-zero(x::MyMat{T}, r::Int, c::Int) where T <: RingElem

Construct the $r\times c$ matrix with R as base ring (which defaults to the base ring of the the given matrix). If $x$ belongs to a matrix algebra and $r \neq c$, an exception is raised, and it's also possible to specify only one Int as the order (e.g. similar(x, n)).

Custom matrices and rings may choose which specific matrix type is best-suited to return for the given ring and dimensionality. If they do not specialize these functions, the default is a Generic.MatSpaceElem matrix, or Generic.MatAlgElem for matrix algebras. The default implementation of zero calls out to similar, so it's generally sufficient to specialize only similar. For both similar and zero, only the most general method has to be implemented (e.g. similar(x::MyMat, R::Ring, r::Int, c::Int), as all other methods (which have defaults) call out to this more general method.

Base.isassigned(M::MyMat, i, j)

Test whether the given matrix has a value associated with indices i and j. It is recommended to overload this method for custom matrices.

Optional symmetry test

is_symmetric(a::MatrixElem)

Return true if the given matrix is symmetric with respect to its main diagonal, otherwise return false.

diff --git a/previews/PR2578/AbstractAlgebra/matrix_introduction/index.html b/previews/PR2578/AbstractAlgebra/matrix_introduction/index.html deleted file mode 100644 index 9ed2de714824..000000000000 --- a/previews/PR2578/AbstractAlgebra/matrix_introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

AbstractAlgebra provides matrix spaces (mxn matrices) and matrix algebras (nxn matrices) over a ring. Whilst both types of matrix provide matrix multiplication for matrices whose dimensions are compatible for multiplication, only the latter kind of matrices form rings in the system.

Matrix spaces provide a large number of linear algebra operations, including linear solving, elementary row operations, various canonical forms. The system also provides characteristic and minimal polynomial computations, LU decomposition, determinant, matrix inverse, kernel computations.

There is also code for computation of the Hermite and Smith normal forms over Euclidean domains and Popov form for matrices over polynomial rings over a field.

Most of this generic functionality is provided for arbitrary matrix types that satisfy the AbstractAlgebra matrix interface.

diff --git a/previews/PR2578/AbstractAlgebra/misc/index.html b/previews/PR2578/AbstractAlgebra/misc/index.html deleted file mode 100644 index 2147bd29d3c5..000000000000 --- a/previews/PR2578/AbstractAlgebra/misc/index.html +++ /dev/null @@ -1,102 +0,0 @@ - -Miscellaneous · Oscar.jl

Miscellaneous

Printing options

AbstractAlgebra supports printing to LaTeX using the MIME type "text/latex". To enable LaTeX rendering in Jupyter notebooks and query for the current state, use the following functions:

set_html_as_latexFunction
set_html_as_latex(fl::Bool)

Toggles whether MIME type text/html should be printed as text/latex. Note that this is a global option. The return value is the old value.

get_html_as_latexFunction
get_html_as_latex()

Returns whether MIME type text/html is printed as text/latex.

Updating the type diagrams

Updating the diagrams of the documentation can be done by modifying and running the script docs/create_type_diagrams.jl. Note that this requires the package Kroki.

Attributes

Often it is desirable to have a flexible way to attach additional data to mathematical structures such as groups, rings, fields, etc. beyond what the original implementation covers. To facilitate this, we provide an attributes system: for objects of suitable types, one may use set_attribute! to attach key-value pairs to the object, and query them using has_attribute, get_attribute and get_attribute!.

Attributes are supported for all singletons (i.e., instances of an empty struct type), as well as for instances of mutable struct type for which attribute storage was enabled. There are two ways to enable attribute storage for such types:

  1. By applying @attributes to a mutable struct declaration, storage is reserved inside that struct type itself (this increases the size of each struct by 8 bytes if no attributes are set).
  2. By applying @attributes to the name of a mutable struct type, methods are installed which store attributes to instances of the type in a WeakKeyDict outside the struct.
@attributesMacro
@attributes typedef

This is a helper macro that ensures that there is storage for attributes in the type declared in the expression typedef, which must be either a mutable struct definition expression, or the name of a mutable struct type.

The latter variant is useful to enable attribute storage for types defined in other packages. Note that @attributes is idempotent: when applied to a type for which attribute storage is already available, it does nothing.

For singleton types, attribute storage is also supported, and in fact always enabled. Thus it is not necessary to apply this macro to such a type.

Note

When applied to a struct definition this macro adds a new field to the struct. For structs without constructor, this will change the signature of the default inner constructor, which requires explicit values for every field, including the attribute storage field this macro adds. Usually it is thus preferable to add an explicit default constructor, as in the example below.

Examples

Applying the macro to a struct definition results in internal storage of the attributes:

julia> @attributes mutable struct MyGroup
-           order::Int
-           MyGroup(order::Int) = new(order)
-       end
-
-julia> G = MyGroup(5)
-MyGroup(5, #undef)
-
-julia> set_attribute!(G, :isfinite, :true)
-
-julia> get_attribute(G, :isfinite)
-true

Applying the macro to a typename results in external storage of the attributes:

julia> mutable struct MyOtherGroup
-           order::Int
-           MyOtherGroup(order::Int) = new(order)
-       end
-
-julia> @attributes MyOtherGroup
-
-julia> G = MyOtherGroup(5)
-MyOtherGroup(5)
-
-julia> set_attribute!(G, :isfinite, :true)
-
-julia> get_attribute(G, :isfinite)
-true
@attrMacro
@attr [RetType] funcdef

This macro is applied to the definition of a unary function, and enables caching ("memoization") of its return values based on the argument. This assumes the argument supports attribute storing (see @attributes) via get_attribute!.

The name of the function is used as name for the underlying attribute.

Effectively, this turns code like this:

@attr RetType function myattr(obj::Foo)
-   # ... expensive computation
-   return result
-end

into something essentially equivalent to this:

function myattr(obj::Foo)
-  return get_attribute!(obj, :myattr) do
-    # ... expensive computation
-    return result
-  end::RetType
-end

Examples

julia> @attributes mutable struct Foo
-           x::Int
-           Foo(x::Int) = new(x)
-       end;
-
-julia> @attr Int function myattr(obj::Foo)
-                println("Performing expensive computation")
-                return factorial(obj.x)
-             end;
-
-julia> obj = Foo(5);
-
-julia> myattr(obj)
-Performing expensive computation
-120
-
-julia> myattr(obj) # second time uses the cached result
-120
-
has_attributeFunction
has_attribute(G::Any, attr::Symbol)

Return a boolean indicating whether G has a value stored for the attribute attr.

get_attributeFunction
get_attribute(f::Function, G::Any, attr::Symbol)

Return the value stored for the attribute attr, or if no value has been set, return f().

This is intended to be called using do block syntax.

get_attribute(obj, attr) do
-    # default value calculated here if needed
-    ...
-end
get_attribute(G::Any, attr::Symbol, default::Any = nothing)

Return the value stored for the attribute attr, or if no value has been set, return default.

get_attribute!Function
get_attribute!(f::Function, G::Any, attr::Symbol)

Return the value stored for the attribute attr of G, or if no value has been set, store key => f() and return f().

This is intended to be called using do block syntax.

get_attribute!(obj, attr) do
-    # default value calculated here if needed
-    ...
-end
get_attribute!(G::Any, attr::Symbol, default::Any)

Return the value stored for the attribute attr of G, or if no value has been set, store key => default, and return default.

set_attribute!Function
set_attribute!(G::Any, data::Pair{Symbol, <:Any}...)

Attach the given sequence of key=>value pairs as attributes of G.

set_attribute!(G::Any, attr::Symbol, value::Any)

Attach the given value as attribute attr of G.

The attributes system can be utilized to change the way certain objects are printed. We provide macros @show_special and @show_name for this purpose, both are called with the same argument as show: an IO-object and the object itself. Both are supposed to be used within the usual show function:

function show(io::IO, A::MyObj)
-   @show_name(io, A)
-   @show_special(io, A)
-
-   ... usual stuff

@show_special checks if an attribute :show_special is present. If so, it has to be a function taking IO and the object. This is then called instead of the usual show function.

@show_name will check if there is a variable in global (Main module) namespace with value bound to the object. In compact printing mode, the name is then shown instead of the object.

Note: if the object is stored in several variable, the first one will be used. Also the name, once used for printing, is stored in the object - hence will not change anymore.

Advanced printing

To facilitate printing of nested mathematical structures, we provide a modified IOCustom object, that supports indentation and decapitalization.

Example

We illustrate this with an example

struct A{T}
-  x::T
-end
-
-function Base.show(io::IO, a::A)
-  io = AbstractAlgebra.pretty(io)
-  println(io, "Something of type A")
-  print(io, AbstractAlgebra.Indent(), "over ", AbstractAlgebra.Lowercase(), a.x)
-  print(io, AbstractAlgebra.Dedent()) # don't forget to undo the indentation!
-end
-
-struct B
-end
-
-function Base.show(io::IO, b::B)
-  io = AbstractAlgebra.pretty(io)
-  print(io, LowercaseOff(), "Hilbert thing")
-end

At the REPL, this will then be printed as follows:

julia> A(2)
-Something of type A
-  over 2
-
-julia> A(A(2))
-Something of type A
-  over something of type A
-    over 2
-
-julia> A(B())
-Something of type A
-  over Hilbert thing

Documentation

prettyFunction
pretty(io::IO) -> IOCustom

Wrap io into an IOCustom object.

Examples

julia> io = AbstractAlgebra.pretty(stdout);
IndentType
Indent

When printed to an IOCustom object, increases the indentation level by one.

Examples

julia> io = AbstractAlgebra.pretty(stdout);
-
-julia> print(io, AbstractAlgebra.Indent(), "This is indented")
-  This is indented
DedentType
Dedent

When printed to an IOCustom object, decreases the indentation level by one.

Examples

julia> io = AbstractAlgebra.pretty(stdout);
-
-julia> print(io, AbstractAlgebra.Indent(), AbstractAlgebra.Dedent(), "This is indented")
-This is indented
LowercaseType
Lowercase

When printed to an IOCustom object, the next letter printed will be lowercase.

Examples

julia> io = AbstractAlgebra.pretty(stdout);
-
-julia> print(io, AbstractAlgebra.Lowercase(), "Foo")
-foo
LowercaseOffType
LowercaseOff

When printed to an IOCustom object, the case of the next letter will not be changed when printed.

Examples

julia> io = AbstractAlgebra.pretty(stdout);
-
-julia> print(io, AbstractAlgebra.Lowercase(), AbstractAlgebra.LowercaseOff(), "Foo")
-Foo
diff --git a/previews/PR2578/AbstractAlgebra/module/index.html b/previews/PR2578/AbstractAlgebra/module/index.html deleted file mode 100644 index 97931a431e8d..000000000000 --- a/previews/PR2578/AbstractAlgebra/module/index.html +++ /dev/null @@ -1,96 +0,0 @@ - -Finitely presented modules · Oscar.jl

Finitely presented modules

AbstractAlgebra allows the construction of finitely presented modules (i.e. with finitely many generators and relations), starting from free modules.

The generic code provided by AbstractAlgebra will only work for modules over euclidean domains.

Free modules can be built over both commutative and noncommutative rings. Other types of module are restricted to fields and euclidean rings.

Abstract types

AbstractAlgebra provides two abstract types for finitely presented modules and their elements:

  • FPModule{T} is the abstract type for finitely presented module parent

types

  • FPModuleElem{T} is the abstract type for finitely presented module

element types

Note that the abstract types are parameterised. The type T should usually be the type of elements of the ring the module is over.

Module functions

All finitely presented modules over a Euclidean domain implement the following functions.

Basic functions

zero(M::FPModule)
iszero(m::FPModuleElem{T}) where T <: RingElement

Return true if the given module element is zero.

ngens(M::FPModule{T}) where T <: RingElement

Return the number of generators of the module $M$ in its current representation.

gen(M::FPModule{T}, i::Int) where T <: RingElement

Return the $i$-th generator (indexed from $1$) of the module $M$.

gens(M::FPModule{T}) where T <: RingElement

Return a Julia array of the generators of the module $M$.

rels(M::FPModule{T}) where T <: RingElement

Return a Julia vector of all the relations between the generators of M. Each relation is given as an AbstractAlgebra row matrix.

Examples

julia> M = FreeModule(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> n = ngens(M)
-2
-
-julia> G = gens(M)
-2-element Vector{AbstractAlgebra.Generic.FreeModuleElem{Rational{BigInt}}}:
- (1//1, 0//1)
- (0//1, 1//1)
-
-julia> R = rels(M)
-AbstractAlgebra.Generic.MatSpaceElem{Rational{BigInt}}[]
-
-julia> g1 = gen(M, 1)
-(1//1, 0//1)
-
-julia> !iszero(g1)
-true
-
-julia> M = FreeModule(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> z = zero(M)
-(0//1, 0//1)
-
-julia> iszero(z)
-true

Element constructors

We can construct elements of a module $M$ by specifying linear combinations of the generators of $M$. This is done by passing a vector of ring elements.

(M::FPModule{T})(v::Vector{T}) where T <: RingElement

Construct the element of the module $M$ corresponding to $\sum_i g[i]v[i]$ where $g[i]$ are the generators of the module $M$. The resulting element will lie in the module $M$.

Coercions

Given a module $M$ and an element $n$ of a module $N$, it is possible to coerce $n$ into $M$ using the notation $M(n)$ in certain circumstances.

In particular the element $n$ will be automatically coerced along any canonical injection of a submodule map and along any canonical projection of a quotient map. There must be a path from $N$ to $M$ along such maps.

Examples

F = FreeModule(ZZ, 3)
-
-S1, f = sub(F, [rand(F, -10:10)])
-
-S, g = sub(F, [rand(F, -10:10)])
-Q, h = quo(F, S)
-
-m = rand(S1, -10:10)
-n = Q(m)

Arithmetic operators

Elements of a module can be added, subtracted or multiplied by an element of the ring the module is defined over and compared for equality.

In the case of a noncommutative ring, both left and right scalar multiplication are defined.

Basic manipulation

zero(M::FPModule)

Examples

julia> M = FreeModule(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> z = zero(M)
-(0//1, 0//1)

Element indexing

getindexMethod
getindex(A::SMat, i::Int, j::Int)

Given a sparse matrix $A = (a_{ij})_{i, j}$, return the entry $a_{ij}$.

getindex(A::SMat, i::Int) -> SRow

Given a sparse matrix $A$ and an index $i$, return the $i$-th row of $A$.

getindex(a::Fac, b) -> Int

If $b$ is a factor of $a$, the corresponding exponent is returned. Otherwise an error is thrown.

Examples

julia> F = FreeModule(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> m = F(BigInt[2, -5, 4])
-(2, -5, 4)
-
-julia> m[1]
-2

Module comparison

==Method
==(M::FPModule{T}, N::FPModule{T}) where T <: RingElement

Return true if the modules are (constructed to be) the same module elementwise. This is not object equality and it is not isomorphism. In fact, each method of constructing modules (submodules, quotient modules, products, etc.) must extend this notion of equality to the modules they create.

Examples

julia> M = FreeModule(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> M == M
-true
-

Isomorphism

is_isomorphicMethod
is_isomorphic(M::FPModule{T}, N::FPModule{T}) where T <: RingElement

Return true if the modules $M$ and $N$ are isomorphic.

Note

Note that this function relies on the Smith normal form over the base ring of the modules being able to be made unique. This is true for Euclidean domains for which divrem has a fixed choice of quotient and remainder, but it will not in general be true for Euclidean rings that are not domains.

Examples

julia> M = FreeModule(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> m1 = rand(M, -10:10)
-(3, -1, 0)
-
-julia> m2 = rand(M, -10:10)
-(4, 4, -7)
-
-julia> S, f = sub(M, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 3 over integers)
-
-julia> I, g = image(f)
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 3 over integers)
-
-julia> is_isomorphic(S, I)
-true
-

Invariant Factor Decomposition

For modules over a euclidean domain one can take the invariant factor decomposition to determine the structure of the module. The invariant factors are unique up to multiplication by a unit, and even unique if a canonical_unit is available for the ring that canonicalises elements.

snfMethod
snf(m::FPModule{T}) where T <: RingElement

Return a pair M, f consisting of the invariant factor decomposition $M$ of the module m and a module homomorphism (isomorphisms) $f : M \to m$. The module M is itself a module which can be manipulated as any other module in the system.

invariant_factorsMethod
invariant_factors(m::FPModule{T}) where T <: RingElement

Return a vector of the invariant factors of the module $M$.

Examples

julia> M = FreeModule(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> m1 = rand(M, -10:10)
-(3, -1, 0)
-
-julia> m2 = rand(M, -10:10)
-(4, 4, -7)
-
-julia> S, f = sub(M, [m1, m2])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 3 over integers)
-
-julia> Q, g = quo(M, S)
-(Quotient module over Integers with 2 generators and relations:
-[16 -21], Hom: Free module of rank 3 over integers -> Quotient module over Integers with 2 generators and relations:
-[16 -21])
-
-julia> I, f = snf(Q)
-(Invariant factor decomposed module over Integers with invariant factors BigInt[0], Module isomorphism with
-Domain: Invariant factor decomposed module over Integers with invariant factors BigInt[0]
-Codomain: Quotient module over Integers with 2 generators and relations:
-[16 -21])
-
-julia> invs = invariant_factors(Q)
-1-element Vector{BigInt}:
- 0
-
diff --git a/previews/PR2578/AbstractAlgebra/module_homomorphism/index.html b/previews/PR2578/AbstractAlgebra/module_homomorphism/index.html deleted file mode 100644 index 2d1ce48ad1d9..000000000000 --- a/previews/PR2578/AbstractAlgebra/module_homomorphism/index.html +++ /dev/null @@ -1,54 +0,0 @@ - -Module Homomorphisms · Oscar.jl

Module Homomorphisms

Abstract Algebra provides homomorphisms of finitely presented modules.

Generic module homomorphism types

AbstractAlgebra defines two module homomorphism types, namely Generic.ModuleHomomorphism and Generic.ModuleIsomorphism. Functionality for these is implemented in src/generic/ModuleHomomorphism.jl.

Abstract types

The Generic.ModuleHomomorphism and Generic.ModuleIsomorphism types inherit from Map(FPModuleHomomorphism).

Generic functionality

The following generic functionality is provided for module homomorphisms.

Constructors

Homomorphisms of AbstractAlgebra modules, $f : R^s \to R^t$, can be represented by $s\times t$ matrices over $R$.

ModuleHomomorphismMethod
ModuleHomomorphism(M1::FPModule{T},
-                   M2::FPModule{T}, m::MatElem{T}) where T <: RingElement

Create the homomorphism $f : M_1 \to M_2$ represented by the matrix $m$.

ModuleIsomorphismMethod
ModuleIsomorphism(M1::FPModule{T}, M2::FPModule{T}, M::MatElem{T},
-                  minv::MatElem{T}) where T <: RingElement

Create the isomorphism $f : M_1 \to M_2$ represented by the matrix $M$. The inverse morphism is automatically computed.

Examples

julia> M = FreeModule(ZZ, 2)
-Free module of rank 2 over integers
-
-julia> f = ModuleHomomorphism(M, M, matrix(ZZ, 2, 2, [1, 2, 3, 4]))
-Module homomorphism
-  from free module of rank 2 over integers
-  to free module of rank 2 over integers
-
-julia> m = M([ZZ(1), ZZ(2)])
-(1, 2)
-
-julia> f(m)
-(7, 10)
-

They can also be created by giving images (in the codomain) of the generators of the domain:

ModuleHomomorphism(M1::FPModule{T}, M2::FPModule{T}, v::Vector{<:FPModuleElem{T}}) where T <: RingElement

Kernels

kernelMethod
kernel(f::ModuleHomomorphism{T}) where T <: RingElement

Return a pair K, g consisting of the kernel object $K$ of the given module homomorphism $f$ (as a submodule of its domain) and the canonical injection from the kernel into the domain of $f$

Examples

julia> M = FreeModule(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> m = M([ZZ(1), ZZ(2), ZZ(3)])
-(1, 2, 3)
-
-julia> S, f = sub(M, [m])
-(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 3 over integers)
-
-julia> Q, g = quo(M, S)
-(Quotient module over Integers with 2 generators and no relations, Hom: Free module of rank 3 over integers -> Quotient module over Integers with 2 generators and no relations)
-
-julia> kernel(g)
-(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 3 over integers)
-

Images

imageMethod
image(f::Map(FPModuleHomomorphism))

Return a pair I, g consisting of the image object $I$ of the given module homomorphism $f$ (as a submodule of its codomain) and the canonical injection from the image into the codomain of $f$

M = FreeModule(ZZ, 3)
-
-m = M([ZZ(1), ZZ(2), ZZ(3)])
-
-S, f = sub(M, [m])
-Q, g = quo(M, S)
-K, k = kernel(g)
-
-image(compose(k, g))

Preimages

preimageMethod
preimage(f::Map(FPModuleHomomorphism),
-         v::FPModuleElem{T}) where T <: RingElement

Return a preimage of $v$ under the homomorphism $f$, i.e. an element of the domain of $f$ that maps to $v$ under $f$. Note that this has no special mathematical properties. It is an element of the set theoretical preimage of the map $f$ as a map of sets, if one exists. The preimage is neither unique nor chosen in a canonical way in general. When no such element exists, an exception is raised.

M = FreeModule(ZZ, 3)
-
-m = M([ZZ(1), ZZ(2), ZZ(3)])
-
-S, f = sub(M, [m])
-Q, g = quo(M, S)
-
-m = rand(M, -10:10)
-n = g(m)
-
-p = preimage(g, n)

Inverses

Module isomorphisms can be cheaply inverted.

invMethod
Base.inv(f::Map(ModuleIsomorphism))

Return the inverse map of the given module isomorphism. This is computed cheaply.

M = FreeModule(ZZ, 2)
-N = matrix(ZZ, 2, 2, BigInt[1, 0, 0, 1])
-f = ModuleIsomorphism(M, M, N)
-
-g = inv(f)
diff --git a/previews/PR2578/AbstractAlgebra/module_interface/index.html b/previews/PR2578/AbstractAlgebra/module_interface/index.html deleted file mode 100644 index 1050de0b0356..000000000000 --- a/previews/PR2578/AbstractAlgebra/module_interface/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Module Interface · Oscar.jl

Module Interface

Note

The module infrastructure in AbstractAlgebra should be considered experimental at this stage. This means that the interface may change in the future.

AbstractAlgebra allows the construction of finitely presented modules (i.e. with finitely many generators and relations), starting from free modules. The generic code provided by AbstractAlgebra will only work for modules over euclidean domains, however there is nothing preventing a library from implementing more general modules using the same interface.

All finitely presented module types in AbstractAlgebra follow the following interface which is a loose interface of functions, without much generic infrastructure built on top.

Free modules can be built over both commutative and noncommutative rings. Other types of module are restricted to fields and euclidean rings.

Abstract types

AbstractAlgebra provides two abstract types for finitely presented modules and their elements:

  • FPModule{T} is the abstract type for finitely presented module parent

types

  • FPModuleElem{T} is the abstract type for finitely presented module

element types

Note that the abstract types are parameterised. The type T should usually be the type of elements of the ring the module is over.

Required functionality for modules

We suppose that R is a fictitious base ring and that S is a module over R with parent object S of type MyModule{T}. We also assume the elements in the module have type MyModuleElem{T}, where T is the type of elements of the ring the module is over.

Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.

Note that the type T must (transitively) belong to the abstract type RingElement or NCRingElem.

We describe the functionality below for modules over commutative rings, i.e. with element type belonging to RingElement, however similar constructors should be available for element types belonging to NCRingElem instead, for free modules over a noncommutative ring.

Although not part of the module interface, implementations of modules that wish to follow our interface should use the same function names for submodules, quotient modules, direct sums and module homomorphisms if they wish to remain compatible with our module generics in the future.

Basic manipulation

iszero(m::MyModuleElem{T}) where T <: RingElement

Return true if the given module element is zero.

ngens(M::MyModule{T}) where T <: RingElement

Return the number of generators of the module $M$ in its current representation.

gen(M::MyModule{T}, i::Int) where T <: RingElement

Return the $i$-th generator (indexed from $1$) of the module $M$.

gens(M::MyModule{T}) where T <: RingElement

Return a Julia array of the generators of the module $M$.

rels(M::MyModule{T}) where T <: RingElement

Return a Julia vector of all the relations between the generators of M. Each relation is given as an AbstractAlgebra row matrix.

Element constructors

We can construct elements of a module $M$ by specifying linear combinations of the generators of $M$. This is done by passing a vector of ring elements.

(M::Module{T})(v::Vector{T}) where T <: RingElement

Construct the element of the module $M$ corresponding to $\sum_i g[i]v[i]$ where $g[i]$ are the generators of the module $M$. The resulting element will lie in the module $M$.

Coercions

Given a module $M$ and an element $n$ of a module $N$, it is possible to coerce $n$ into $M$ using the notation $M(n)$ in certain circumstances.

In particular the element $n$ will be automatically coerced along any canonical injection of a submodule map and along any canonical projection of a quotient map. There must be a path from $N$ to $M$ along such maps.

Arithmetic operators

Elements of a module can be added, subtracted or multiplied by an element of the ring the module is defined over and compared for equality.

In the case of a noncommutative ring, both left and right scalar multiplication are defined.

diff --git a/previews/PR2578/AbstractAlgebra/module_introduction/index.html b/previews/PR2578/AbstractAlgebra/module_introduction/index.html deleted file mode 100644 index 5193a5b01446..000000000000 --- a/previews/PR2578/AbstractAlgebra/module_introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

As with many generic constructions in AbstractAlgebra, the modules that are provided in AbstractAlgebra itself work over a Euclidean domain. Moreover, they are limited to finitely presented modules.

Free modules and vector spaces are provided over Euclidean domains and fields respectively and then submodule, quotient module and direct sum module constructions are possible recursively over these.

It's also possible to compute an invariant decomposition using the Smith Normal Form.

The system also provides module homomorphisms and isomorphisms, building on top of the map interface.

As for rings and fields, modules follow an interface which other modules are expected to follow. However, very little generic functionality is provided automatically once this interface is implemented by a new module type.

The purpose of the module interface is simply to encourage uniformity in the module interfaces of systems that build on AbstractAlgebra. Of course modules are so diverse that this is a very loosely defined interface to accommodate the diversity of possible representations and implementations.

diff --git a/previews/PR2578/AbstractAlgebra/mpoly_interface/index.html b/previews/PR2578/AbstractAlgebra/mpoly_interface/index.html deleted file mode 100644 index fe52d585a4ef..000000000000 --- a/previews/PR2578/AbstractAlgebra/mpoly_interface/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Multivariate Polynomial Ring Interface · Oscar.jl

Multivariate Polynomial Ring Interface

Multivariate polynomial rings are supported in AbstractAlgebra.jl, and in addition to the standard Ring interface, numerous additional functions are provided.

Unlike other kinds of rings, even complex operations such as GCD depend heavily on the multivariate representation. Therefore AbstractAlgebra.jl cannot provide much in the way of additional functionality to external multivariate implementations.

This means that external libraries must be able to implement their multivariate formats in whatever way they see fit. The required interface here should be implemented, even if it is not optimal. But it can be extended, either by implementing one of the optional interfaces, or by extending the required interface in some other way.

Naturally, any multivariate polynomial ring implementation provides the full Ring interface, in order to be treated as a ring for the sake of AbstractAlgebra.jl.

Considerations which make it impossible for AbstractAlgebra.jl to provide generic functionality on top of an arbitrary multivariate module include:

  • orderings (lexical, degree, weighted, block, arbitrary)
  • sparse or dense representation
  • distributed or recursive representation
  • packed or unpacked exponents
  • exponent bounds (and whether adaptive or not)
  • random access or iterators
  • whether monomials and polynomials have the same type
  • whether special cache aware data structures such as Geobuckets are used

Types and parents

AbstractAlgebra.jl provides two abstract types for multivariate polynomial rings and their elements:

  • MPolyRing{T} is the abstract type for multivariate polynomial ring parent types
  • MPolyRingElem{T} is the abstract type for multivariate polynomial types

We have that MPolyRing{T} <: Ring and MPolyRingElem{T} <: RingElem.

Note that both abstract types are parameterised. The type T should usually be the type of elements of the coefficient ring of the polynomial ring. For example, in the case of $\mathbb{Z}[x, y]$ the type T would be the type of an integer, e.g. BigInt.

Multivariate polynomial rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Multivariate polynomial rings should at least be distinguished based on their base (coefficient) ring and number of variables. But if they have the same base ring, symbols (for their variables/generators) and ordering, they should certainly have the same parent object.

See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).

Required functionality for multivariate polynomials

In addition to the required functionality for the Ring interface, the Multivariate Polynomial interface has the following required functions.

We suppose that R is a fictitious base ring (coefficient ring) and that S is a multivariate polynomial ring over R (i.e. $S = R[x, y, \ldots]$) with parent object S of type MyMPolyRing{T}. We also assume the polynomials in the ring have type MyMPoly{T}, where T is the type of elements of the base (coefficient) ring.

Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.

Note that the type T must (transitively) belong to the abstract type RingElem or more generally the union type RingElement which includes the Julia integer, rational and floating point types.

Constructors

To construct a multivariate polynomial ring, there is the following constructor.

polynomial_ring(R::Ring, s::Vector{<:VarName}; ordering=:lex, cached::Bool=true)

Return a tuple, S, vars consisting of a polynomial ring $S$ and an array of generators (variables) which print according to the strings in the supplied vector $s$. The ordering can at present be :lex, :deglex or :degrevlex. By default, the polynomial ring is cached, and creating a polynomial ring with the same data will return the same ring object $S$. If this caching is not desired, it can be switched off by setting cached=false.

Polynomials in a given ring can be constructed using the generators and basic polynomial arithmetic. However, this is inefficient and the following build context is provided for building polynomials term-by-term. It assumes the polynomial data type is random access, and so the constructor functions must be reimplemented for all other types of polynomials.

MPolyBuildCtx(R::MPolyRing)

Return a build context for creating polynomials in the given polynomial ring.

push_term!(M::MPolyBuildCtx, c::RingElem, v::Vector{Int})

Add the term with coefficient $c$ and exponent vector $v$ to the polynomial under construction in the build context $M$.

finish(M::MPolyBuildCtx)

Finish construction of the polynomial, sort the terms, remove duplicate and zero terms and return the created polynomial.

Data type and parent object methods

symbols(S::MyMPolyRing{T}) where T <: RingElem

Return an array of Symbols representing the variables (generators) of the polynomial ring. Note that these are Symbols not Strings, though their string values will usually be used when printing polynomials.

nvars(f::MyMPolyRing{T}) where T <: RingElem

Return the number of variables of the polynomial ring.

gens(S::MyMPolyRing{T}) where T <: RingElem

Return an array of all the generators (variables) of the given polynomial ring (as polynomials).

The first entry in the array will be the variable with most significance with respect to the ordering.

gen(S::MyMPolyRing{T}, i::Int) where T <: RingElem

Return the $i$-th generator (variable) of the given polynomial ring (as a polynomial).

ordering(S::MyMPolyRing{T})

Return the ordering of the given polynomial ring as a symbol. Supported values currently include :lex, :deglex and :degrevlex.

Basic manipulation of rings and elements

length(f::MyMPoly{T}) where T <: RingElem

Return the number of nonzero terms of the given polynomial. The length of the zero polynomial is defined to be $0$. The return value should be of type Int.

degrees(f::MyMPoly{T}) where T <: RingElem

Return an array of the degrees of the polynomial $f$ in each of the variables.

total_degree(f::MyMPoly{T}) where T <: RingElem

Return the total degree of the polynomial $f$, i.e. the highest sum of exponents occurring in any term of $f$.

is_gen(x::MyMPoly{T}) where T <: RingElem

Return true if $x$ is a generator of the polynomial ring.

coefficients(p::MyMPoly{T}) where T <: RingElem

Return an iterator for the coefficients of the polynomial $p$, starting with the coefficient of the most significant term with respect to the ordering. Generic code will provide this function automatically for random access polynomials that implement the coeff function.

monomials(p::MyMPoly{T}) where T <: RingElem

Return an iterator for the monomials of the polynomial $p$, starting with the monomial of the most significant term with respect to the ordering. Monomials in AbstractAlgebra are defined to have coefficient $1$. See the function terms if you also require the coefficients, however note that only monomials can be compared. Generic code will provide this function automatically for random access polynomials that implement the monomial function.

terms(p::MyMPoly{T}) where T <: RingElem

Return an iterator for the terms of the polynomial $p$, starting with the most significant term with respect to the ordering. Terms in AbstractAlgebra include the coefficient. Generic code will provide this function automatically for random access polynomials that implement the term function.

exponent_vectors(a::MyMPoly{T}) where T <: RingElement

Return an iterator for the exponent vectors for each of the terms of the polynomial starting with the most significant term with respect to the ordering. Each exponent vector is an array of Ints, one for each variable, in the order given when the polynomial ring was created. Generic code will provide this function automatically for random access polynomials that implement the exponent_vector function.

Exact division

For any ring that implements exact division, the following can be implemented.

divexact(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem

Return the exact quotient of $f$ by $g$ if it exists, otherwise throw an error.

divides(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem

Return a tuple (flag, q) where flag is true if $g$ divides $f$, in which case $q$ will be the exact quotient, or flag is false and $q$ is set to zero.

remove(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem

Return a tuple $(v, q)$ such that the highest power of $g$ that divides $f$ is $g^v$ and the cofactor is $q$.

valuation(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem

Return $v$ such that the highest power of $g$ that divides $f$ is $g^v$.

Ad hoc exact division

For any ring that implements exact division, the following can be implemented.

divexact(f::MyMPoly{T}, c::Integer) where T <: RingElem
-divexact(f::MyMPoly{T}, c::Rational) where T <: RingElem
-divexact(f::MyMPoly{T}, c::T) where T <: RingElem

Divide the polynomial exactly by the constant $c$.

Euclidean division

Although multivariate polynomial rings are not in general Euclidean, it is possible to define a quotient with remainder function that depends on the polynomial ordering in the case that the quotient ring is a field or a Euclidean domain. In the case that a polynomial $g$ divides a polynomial $f$, the result no longer depends on the ordering and the remainder is zero, with the quotient agreeing with the exact quotient.

divrem(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem

Return a tuple $(q, r)$ such that $f = qg + r$, where the coefficients of terms of $r$ whose monomials are divisible by the leading monomial of $g$ are reduced modulo the leading coefficient of $g$ (according to the Euclidean function on the coefficients).

Note that the result of this function depends on the ordering of the polynomial ring.

div(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem

As per the divrem function, but returning the quotient only. Especially when the quotient happens to be exact, this function can be exceedingly fast.

GCD

In cases where there is a meaningful Euclidean structure on the coefficient ring, it is possible to compute the GCD of multivariate polynomials.

gcd(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem

Return a greatest common divisor of $f$ and $g$.

Square root

Over rings for which an exact square root is available, it is possible to take the square root of a polynomial or test whether it is a square.

sqrt(f::MyMPoly{T}, check::Bool=true) where T <: RingElem

Return the square root of the polynomial $f$ and raise an exception if it is not a square. If check is set to false, the input is assumed to be a perfect square and this assumption is not fully checked. This can be significantly faster.

is_square(::MyMPoly{T}) where T <: RingElem

Return true if $f$ is a square.

Interface for sparse distributed, random access multivariates

The following additional functions should be implemented by libraries that provide a sparse distributed polynomial format, stored in a representation for which terms can be accessed in constant time (e.g. where arrays are used to store coefficients and exponent vectors).

Sparse distributed, random access constructors

In addition to the standard constructors, the following constructor, taking arrays of coefficients and exponent vectors, should be provided.

(S::MyMPolyRing{T})(A::Vector{T}, m::Vector{Vector{Int}}) where T <: RingElem

Create the polynomial in the given ring with nonzero coefficients specified by the elements of $A$ and corresponding exponent vectors given by the elements of $m$.

There is no assumption about coefficients being nonzero or terms being in order or unique. Zero terms are removed by the function, duplicate terms are combined (added) and the terms are sorted so that they are in the correct order.

Each exponent vector uses a separate integer for each exponent field, the first of which should be the exponent for the most significant variable with respect to the ordering. All exponents must be non-negative.

A library may also optionally provide an interface that makes use of BigInt (or any other big integer type) for exponents instead of Int.

Sparse distributed, random access basic manipulation

coeff(f::MyMPoly{T}, n::Int) where T <: RingElem

Return the coefficient of the $n$-th term of $f$. The first term should be the most significant term with respect to the ordering.

coeff(a::MyMPoly{T}, exps::Vector{Int}) where T <: RingElement

Return the coefficient of the term with the given exponent vector, or zero if there is no such term.

monomial(f::MyMPoly{T}, n::Int) where T <: RingElem
-monomial!(m::MyMPoly{T}, f::MyMPoly{T}, n::Int) where T <: RingElem

Return the $n$-th monomial of $f$ or set $m$ to the $n$-th monomial of $f$, respectively. The first monomial should be the most significant term with respect to the ordering. Monomials have coefficient $1$ in AbstractAlgebra. See the function term if you also require the coefficient, however, note that only monomials can be compared.

term(f::MyMPoly{T}, n::Int) where T <: RingElem

Return the $n$-th term of $f$. The first term should be the one whose monomial is most significant with respect to the ordering.

exponent(f::MyMPoly{T}, i::Int, j::Int) where T <: RingElem

Return the exponent of the $j$-th variable in the $i$-th term of the polynomial $f$. The first term is the one with whose monomial is most significant with respect to the ordering.

exponent_vector(a::MyMPoly{T}, i::Int) where T <: RingElement

Return a vector of exponents, corresponding to the exponent vector of the i-th term of the polynomial. Term numbering begins at $1$ and the exponents are given in the order of the variables for the ring, as supplied when the ring was created.

setcoeff!(a::MyMPoly, exps::Vector{Int}, c::S) where S <: RingElement

Set the coefficient of the term with the given exponent vector to the given value $c$. If no such term exists (and $c \neq 0$), one will be inserted. This function takes $O(\log n)$ operations if a term with the given exponent already exists and $c \neq 0$, or if the term is inserted at the end of the polynomial. Otherwise it can take $O(n)$ operations in the worst case. This function must return the modified polynomial.

Unsafe functions

The following functions must be provided, but are considered unsafe, as they may leave the polynomials in an inconsistent state and they mutate their inputs. As usual, such functions should only be applied on polynomials that have no references elsewhere in the system and are mainly intended to be used in carefully written library code, rather than by users.

Users should instead build polynomials using the constructors described above.

fit!(f::MyMPoly{T}, n::Int) where T <: RingElem

Ensure that the polynomial $f$ internally has space for $n$ nonzero terms. This function must mutate the function in-place if it is mutable. It does not return the mutated polynomial. Immutable types can still be supported by defining this function to do nothing.

setcoeff!(a::MyMPoly{T}, i::Int, c::T) where T <: RingElement
-setcoeff!(a::MyMPoly{T}, i::Int, c::U) where {T <: RingElement, U <: Integer}

Set the $i$-th coefficient of the polynomial $a$ to $c$. No check is performed on the index $i$ or for $c = 0$. It may be necessary to call combine_like_terms after calls to this function, to remove zero terms. The function must return the modified polynomial.

combine_like_terms!(a::MyMPoly{T}) where T <: RingElement

Remove zero terms and combine any adjacent terms with the same exponent vector (by adding them). It is assumed that all the exponent vectors are already in the correct order with respect to the ordering. The function must return the resulting polynomial.

set_exponent_vector!(a::MyMPoly{T}, i::Int, exps::Vector{Int}) where T <: RingElement

Set the $i$-th exponent vector to the given exponent vector. No check is performed on the index $i$, which is assumed to be valid (or that the polynomial has enough space allocated). No sorting of exponents is performed by this function. To sort the terms after setting any number of exponents with this function, run the sort_terms! function. The function must return the modified polynomial.

sort_terms!(a::MyMPoly{T}) where {T <: RingElement}

Sort the terms of the given polynomial according to the polynomial ring ordering. Zero terms and duplicate exponents are ignored. To deal with those call combine_like_terms. The sorted polynomial must be returned by the function.

Optional functionality for multivariate polynomials

The following functions can optionally be implemented for multivariate polynomial types.

Reduction by an ideal

divrem(f::MyMPoly{T}, G::Vector{MyMPoly{T}}) where T <: RingElem

As per the divrem function above, except that each term of $r$ starting with the most significant term, is reduced modulo the leading terms of each of the polynomials in the array $G$ for which the leading monomial is a divisor.

A tuple $(Q, r)$ is returned from the function, where $Q$ is an array of polynomials of the same length as $G$, and such that $f = r + \sum Q[i]G[i]$.

The result is again dependent on the ordering in general, but if the polynomials in $G$ are over a field and the reduced generators of a Groebner basis, then the result is unique.

Evaluation

evaluate(a::MyMPoly{T}, A::Vector{T}) where T <: RingElem

Evaluate the polynomial at the given values in the coefficient ring of the polynomial. The result should be an element of the coefficient ring.

evaluate(f::MyMPoly{T}, A::Vector{U}) where {T <: RingElem, U <: Integer}

Evaluate the polynomial $f$ at the values specified by the entries of the array $A$.

(a::MyMPoly{T})(vals::Union{NCRingElem, RingElement}...) where T <: RingElement

Evaluate the polynomial at the given arguments. This provides functional notation for polynomial evaluation, i.e. $f(a, b, c)$. It must be defined for each supported polynomial type (Julia does not allow functional notation to be defined for an abstract type).

The code for this function in MPoly.jl can be used when implementing this as it provides the most general possible evaluation, which is much more general than the case of evaluation at elements of the same ring.

The evaluation should succeed for any set of values for which a multiplication is defined with the product of a coefficient and all the values before it.

Note

The values at which a polynomial is evaluated may be in non-commutative rings. Products are performed in the order of the variables in the polynomial ring that the polynomial belongs to, preceded by a multiplication by the coefficient on the left.

Derivations

The following function allows to compute derivations of multivariate polynomials of type MPoly.

derivative(f::MyMPoly{T}, j::Int) where T <: RingElem

Compute the derivative of $f$ with respect to the $j$-th variable of the polynomial ring.

diff --git a/previews/PR2578/AbstractAlgebra/mpolynomial/index.html b/previews/PR2578/AbstractAlgebra/mpolynomial/index.html deleted file mode 100644 index 2ff6a9cfc73d..000000000000 --- a/previews/PR2578/AbstractAlgebra/mpolynomial/index.html +++ /dev/null @@ -1,424 +0,0 @@ - -Sparse distributed multivariate polynomials · Oscar.jl

Sparse distributed multivariate polynomials

AbstractAlgebra.jl provides a module, implemented in src/MPoly.jl for sparse distributed multivariate polynomials over any commutative ring belonging to the AbstractAlgebra abstract type hierarchy.

Generic sparse distributed multivariable polynomial types

AbstractAlgebra provides a generic multivariate polynomial type Generic.MPoly{T} where T is the type of elements of the coefficient ring.

The polynomials are implemented using a Julia array of coefficients and a 2-dimensional Julia array of UInts for the exponent vectors. Note that exponent $n$ is represented by the $n$-th column of the exponent array, not the $n$-th row. This is because Julia uses a column major representation. See the file src/generic/GenericTypes.jl for details.

The top bit of each UInt is reserved for overflow detection.

Parent objects of such polynomials have type Generic.MPolyRing{T}.

The string representation of the variables of the polynomial ring and the base/coefficient ring $R$ and the ordering are stored in the parent object.

Abstract types

The polynomial element types belong to the abstract type MPolyRingElem{T} and the polynomial ring types belong to the abstract type MPolyRing{T}.

Note

Note that both the generic polynomial ring type Generic.MPolyRing{T} and the abstract type it belongs to, MPolyRing{T} are both called MPolyRing. The former is a (parameterised) concrete type for a polynomial ring over a given base ring whose elements have type T. The latter is an abstract type representing all multivariate polynomial ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).

Polynomial ring constructors

In order to construct multivariate polynomials in AbstractAlgebra.jl, one must first construct the polynomial ring itself. This is accomplished with one of the following constructors.

polynomial_ringMethod
polynomial_ring(R::Ring, s::Vector{T}; cached::Bool = true, ordering::Symbol = :lex) where T <: VarName

Given a base ring R and a vector s of variable names $x1, x2, \dots$ specifying how the generators (variables) should be printed, return a tuple S, [x1, x2, ...] representing the new polynomial ring $S = R[x1, x2, ...]$ and the generators $x1, x2, \dots$ of the polynomial ring.

Mathematically the object S depends only on R and x1, x2, ... and by default it will be cached, i.e., if polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting the optional argument cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.

The ordering of the polynomial ring can be one of :lex, :deglex or :degrevlex.

polynomial_ringMethod
polynomial_ring(R::Ring, n::Int, s::VarName = :x; cached, ordering)

Given a symbol, string or character s and a number of variables n will do the same as the first constructor except that the variables will be automatically numbered. For example if s is the string x and n = 3 then the variables will print as x1, x2, x3.

Like for univariate polynomials, a shorthand constructor is provided when the number of generators is greater than 1: given a base ring R, we abbreviate the constructor as follows:

R["x", "y", ...]

Here are some examples of creating multivariate polynomial rings and making use of the resulting parent objects to coerce various elements into the polynomial ring.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]; ordering=:deglex)
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> T, (z, t) = QQ["z", "t"]
-(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[z, t])
-
-julia> f = R()
-0
-
-julia> g = R(123)
-123
-
-julia> h = R(BigInt(1234))
-1234
-
-julia> k = R(x + 1)
-x + 1
-
-julia> m = R(x + y + 1)
-x + y + 1
-
-julia> derivative(k, 1)
-1
-
-julia> derivative(k, 2)
-0
-

Polynomial constructors

Multivariate polynomials can be constructed from the generators in the usual way using arithmetic operations.

Also, all of the standard ring element constructors may be used to construct multivariate polynomials.

(R::MPolyRing{T})() where T <: RingElement
-(R::MPolyRing{T})(c::Integer) where T <: RingElement
-(R::MPolyRing{T})(a::elem_type(R)) where T <: RingElement
-(R::MPolyRing{T})(a::T) where T <: RingElement

For more efficient construction of multivariate polynomial, one can use the MPoly build context, where terms (coefficient followed by an exponent vector) are pushed onto a context one at a time and then the polynomial constructed from those terms in one go using the finish function.

MPolyBuildCtxMethod
MPolyBuildCtx(R::MPolyRing)

Return a build context for creating polynomials in the given ring.

push_term!Method
push_term!(M::MPolyBuildCtx, c::RingElem, v::Vector{Int})

Add the term with coefficient c and exponent vector v to the polynomial under construction in the build context M.

finishMethod
finish(M::MPolyBuildCtx)

Finish construction of the polynomial, sort the terms, remove duplicate and zero terms and return the created polynomial.

Note that the finish function resets the build context so that it can be used to construct multiple polynomials..

When a multivariate polynomial type has a representation that allows constant time access (e.g. it is represented internally by arrays), the following additional constructor is available. It takes and array of coefficients and and array of exponent vectors.

(S::MPolyRing{T})(A::Vector{T}, m::Vector{Vector{Int}}) where T <: RingElem

Create the polynomial in the given ring with nonzero coefficients specified by the elements of $A$ and corresponding exponent vectors given by the elements of $m$.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> C = MPolyBuildCtx(R)
-Builder for an element of Multivariate polynomial ring in 2 variables over integers
-
-julia> push_term!(C, ZZ(3), [1, 2]);
-
-
-julia> push_term!(C, ZZ(2), [1, 1]);
-
-
-julia> push_term!(C, ZZ(4), [0, 0]);
-
-
-julia> f = finish(C)
-3*x*y^2 + 2*x*y + 4
-
-julia> push_term!(C, ZZ(4), [1, 1]);
-
-
-julia> f = finish(C)
-4*x*y
-
-julia> S, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])
-
-julia> f = S(Rational{BigInt}[2, 3, 1], [[3, 2], [1, 0], [0, 1]])
-2*x^3*y^2 + 3*x + y

Functions for types and parents of multivariate polynomial rings

base_ring(R::MPolyRing)
-base_ring(a::MPolyRingElem)

Return the coefficient ring of the given polynomial ring or polynomial, respectively.

parent(a::MPolyRingElem)

Return the polynomial ring of the given polynomial.

characteristic(R::MPolyRing)

Return the characteristic of the given polynomial ring. If the characteristic is not known, an exception is raised.

Polynomial functions

Basic manipulation

All the standard ring functions are available, including the following.

zero(R::MPolyRing)
-one(R::MPolyRing)
-iszero(a::MPolyRingElem)
-isone(a::MPolyRingElem)
divexact(a::T, b::T) where T <: MPolyRingElem

All basic functions from the Multivariate Polynomial interface are provided.

symbols(S::MPolyRing)
-nvars(f::MPolyRing)
-gens(S::MPolyRing)
-gen(S::MPolyRing, i::Int)
ordering(S::MPolyRing{T})

Note that the currently supported orderings are :lex, :deglex and :degrevlex.

length(f::MPolyRingElem)
-degrees(f::MPolyRingElem)
-total_degree(f::MPolyRingElem)
is_gen(x::MPolyRingElem)
divexact(f::T, g::T) where T <: MPolyRingElem

For multivariate polynomial types that allow constant time access to coefficients, the following are also available, allowing access to the given coefficient, monomial or term. Terms are numbered from the most significant first.

coeff(f::MPolyRingElem, n::Int)
-coeff(a::MPolyRingElem, exps::Vector{Int})

Access a coefficient by term number or exponent vector.

monomial(f::MPolyRingElem, n::Int)
-monomial!(m::T, f::T, n::Int) where T <: MPolyRingElem

The second version writes the result into a preexisting polynomial object to save an allocation.

term(f::MPolyRingElem, n::Int)
exponent(f::MyMPolyRingElem, i::Int, j::Int)

Return the exponent of the $j$-th variable in the $i$-th term of the polynomial $f$.

exponent_vector(a::MPolyRingElem, i::Int)
setcoeff!(a::MPolyRingElem{T}, exps::Vector{Int}, c::T) where T <: RingElement

Although multivariate polynomial rings are not usually Euclidean, the following functions from the Euclidean interface are often provided.

divides(f::T, g::T) where T <: MPolyRingElem
-remove(f::T, g::T) where T <: MPolyRingElem
-valuation(f::T, g::T) where T <: MPolyRingElem
divrem(f::T, g::T) where T <: MPolyRingElem
-div(f::T, g::T) where T <: MPolyRingElem

Compute a tuple $(q, r)$ such that $f = qg + r$, where the coefficients of terms of $r$ whose monomials are divisible by the leading monomial of $g$ are reduced modulo the leading coefficient of $g$ (according to the Euclidean function on the coefficients). The divrem version returns both quotient and remainder whilst the div version only returns the quotient.

Note that the result of these functions depend on the ordering of the polynomial ring.

gcd(f::T, g::T) where T <: MPolyRingElem

The following functionality is also provided for all multivariate polynomials.

is_univariateMethod
is_univariate(R::AbstractAlgebra.MPolyRing)

Returns true if $R$ is a univariate polynomial ring, i.e. has exactly one variable, and false otherwise.

varsMethod
vars(p::AbstractAlgebra.MPolyRingElem{T}) where {T <: RingElement}

Return the variables actually occurring in $p$.

var_indexMethod
var_index(p::AbstractAlgebra.MPolyRingElem{T}) where {T <: RingElement}

Return the index of the given variable $x$. If $x$ is not a variable in a multivariate polynomial ring, an exception is raised.

degreeMethod
degree(f::AbstractAlgebra.MPolyRingElem{T}, i::Int) where T <: RingElement

Return the degree of the polynomial $f$ in terms of the i-th variable.

degreeMethod
degree(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return the degree of the polynomial $f$ in terms of the variable $x$.

degreesMethod
degrees(f::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return an array of the degrees of the polynomial $f$ in terms of each variable.

is_constantMethod
is_constant(x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return true if x is a degree zero polynomial or the zero polynomial, i.e. a constant polynomial.

is_termMethod
is_term(x::MPoly)

Return true if the given polynomial has precisely one term.

is_monomialMethod
is_monomial(x::AbstractAlgebra.MPolyRingElem)

Return true if the given polynomial has precisely one term whose coefficient is one.

is_univariateMethod
is_univariate(p::AbstractAlgebra.MPolyRingElem)

Returns true if $p$ is a univariate polynomial, i.e. involves at most one variable (thus constant polynomials are considered univariate), and false otherwise. The result depends on the terms of the polynomial, not simply on the number of variables in the polynomial ring.

coeffMethod
coeff(f::AbstractAlgebra.MPolyRingElem{T}, m::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return the coefficient of the monomial $m$ of the polynomial $f$. If there is no such monomial, zero is returned.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = x^2 + 2x + 1
-x^2 + 2*x + 1
-
-julia> V = vars(f)
-1-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:
- x
-
-julia> var_index(y) == 2
-true
-
-julia> degree(f, x) == 2
-true
-
-julia> degree(f, 2) == 0
-true
-
-julia> d = degrees(f)
-2-element Vector{Int64}:
- 2
- 0
-
-julia> is_constant(R(1))
-true
-
-julia> is_term(2x)
-true
-
-julia> is_monomial(y)
-true
-
-julia> is_unit(R(1))
-true
-
-julia> S, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = x^3*y + 3x*y^2 + 1
-x^3*y + 3*x*y^2 + 1
-
-julia> c1 = coeff(f, 1)
-1
-
-julia> c2 = coeff(f, x^3*y)
-1
-
-julia> m = monomial(f, 2)
-x*y^2
-
-julia> e1 = exponent(f, 1, 1)
-3
-
-julia> v1 = exponent_vector(f, 1)
-2-element Vector{Int64}:
- 3
- 1
-
-julia> t1 = term(f, 1)
-x^3*y
-
-julia> setcoeff!(f, [3, 1], 12)
-12*x^3*y + 3*x*y^2 + 1
-
-julia> S, (x, y) = polynomial_ring(QQ, ["x", "y"]; ordering=:deglex)
-(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])
-
-julia> V = symbols(S)
-2-element Vector{Symbol}:
- :x
- :y
-
-julia> X = gens(S)
-2-element Vector{AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}:
- x
- y
-
-julia> ord = ordering(S)
-:deglex
-
-julia> S, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = x^3*y + 3x*y^2 + 1
-x^3*y + 3*x*y^2 + 1
-
-julia> n = length(f)
-3
-
-julia> is_gen(y)
-true
-
-julia> nvars(S) == 2
-true
-
-julia> d = total_degree(f)
-4
-
-julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = 2x^2*y + 2x + y + 1
-2*x^2*y + 2*x + y + 1
-
-julia> g = x^2*y^2 + 1
-x^2*y^2 + 1
-
-julia> flag, q = divides(f*g, f)
-(true, x^2*y^2 + 1)
-
-julia> d = divexact(f*g, f)
-x^2*y^2 + 1
-
-julia> v, q = remove(f*g^3, g)
-(3, 2*x^2*y + 2*x + y + 1)
-
-julia> n = valuation(f*g^3, g)
-3
-
-julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])
-
-julia> f = 3x^2*y^2 + 2x + 1
-3*x^2*y^2 + 2*x + 1
-
-julia> f1 = divexact(f, 5)
-3//5*x^2*y^2 + 2//5*x + 1//5
-
-julia> f2 = divexact(f, QQ(2, 3))
-9//2*x^2*y^2 + 3*x + 3//2

Square root

Over rings for which an exact square root is available, it is possible to take the square root of a polynomial or test whether it is a square.

sqrt(f::MPolyRingElem, check::bool=true)
-is_square(::MPolyRingElem)

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = -4*x^5*y^4 + 5*x^5*y^3 + 4*x^4 - x^3*y^4
--4*x^5*y^4 + 5*x^5*y^3 + 4*x^4 - x^3*y^4
-
-julia> sqrt(f^2)
-4*x^5*y^4 - 5*x^5*y^3 - 4*x^4 + x^3*y^4
-
-julia> is_square(f)
-false

Iterators

The following iterators are provided for multivariate polynomials.

coefficients(p::MPoly)
-monomials(p::MPoly)
-terms(p::MPoly)
-exponent_vectors(a::MPoly)

Examples

julia> S, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = x^3*y + 3x*y^2 + 1
-x^3*y + 3*x*y^2 + 1
-
-julia> C = collect(coefficients(f))
-3-element Vector{BigInt}:
- 1
- 3
- 1
-
-julia> M = collect(monomials(f))
-3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:
- x^3*y
- x*y^2
- 1
-
-julia> T = collect(terms(f))
-3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:
- x^3*y
- 3*x*y^2
- 1
-
-julia> V = collect(exponent_vectors(f))
-3-element Vector{Vector{Int64}}:
- [3, 1]
- [1, 2]
- [0, 0]

Changing base (coefficient) rings

In order to substitute the variables of a polynomial $f$ over a ring $T$ by elements in a $T$-algebra $S$, you first have to change the base ring of $f$ using the following function, where $g$ is a function representing the structure homomorphism of the $T$-algebra $S$.

change_base_ringMethod
change_base_ring(R::Ring, p::MPolyRingElem{<: RingElement}; parent::MPolyRing, cached::Bool=true)

Return the polynomial obtained by coercing the non-zero coefficients of p into R.

If the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

change_coefficient_ringMethod
change_coefficient_ring(R::Ring, p::MPolyRingElem{<: RingElement}; parent::MPolyRing, cached::Bool=true)

Return the polynomial obtained by coercing the non-zero coefficients of p into R.

If the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

map_coefficientsMethod
map_coefficients(f, p::MPolyRingElem{<: RingElement}; parent::MPolyRing)

Transform the polynomial p by applying f on each non-zero coefficient.

If the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> fz = x^2*y^2 + x + 1
-x^2*y^2 + x + 1
-
-julia> fq = change_base_ring(QQ, fz)
-x^2*y^2 + x + 1
-
-julia> fq = change_coefficient_ring(QQ, fz)
-x^2*y^2 + x + 1
-

In case a specific parent ring is constructed, it can also be passed to the function.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> S,  = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])
-
-julia> fz = x^5 + y^3 + 1
-x^5 + y^3 + 1
-
-julia> fq = change_base_ring(QQ, fz, parent=S)
-x^5 + y^3 + 1

Multivariate coefficients

In order to return the "coefficient" (as a multivariate polynomial in the same ring), of a given monomial (in which some of the variables may not appear and others may be required to appear to exponent zero), we can use the following function.

coeffMethod
coeff(a::AbstractAlgebra.MPolyRingElem{T}, vars::Vector{Int}, exps::Vector{Int}) where T <: RingElement

Return the "coefficient" of $a$ (as a multivariate polynomial in the same ring) of the monomial consisting of the product of the variables of the given indices raised to the given exponents (note that not all variables need to appear and the exponents can be zero). E.g. coeff(f, [1, 3], [0, 2]) returns the coefficient of $x^0*z^2$ in the polynomial $f$ (assuming variables $x, y, z$ in that order).

coeffMethod
coeff(a::T, vars::Vector{T}, exps::Vector{Int}) where T <: AbstractAlgebra.MPolyRingElem

Return the "coefficient" of $a$ (as a multivariate polynomial in the same ring) of the monomial consisting of the product of the given variables to the given exponents (note that not all variables need to appear and the exponents can be zero). E.g. coeff(f, [x, z], [0, 2]) returns the coefficient of $x^0*z^2$ in the polynomial $f$.

Examples

julia> R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])
-
-julia> f = x^4*y^2*z^2 - 2x^4*y*z^2 + 4x^4*z^2 + 2x^2*y^2 + x + 1
-x^4*y^2*z^2 - 2*x^4*y*z^2 + 4*x^4*z^2 + 2*x^2*y^2 + x + 1
-
-julia> coeff(f, [1, 3], [4, 2]) == coeff(f, [x, z], [4, 2])
-true
-

Inflation/deflation

deflationMethod
deflation(f::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Compute deflation parameters for the exponents of the polynomial $f$. This is a pair of arrays of integers, the first array of which (the shift) gives the minimum exponent for each variable of the polynomial, and the second of which (the deflation) gives the gcds of all the exponents after subtracting the shift, again per variable. This functionality is used by gcd (and can be used by factorisation algorithms).

deflateMethod
deflate(f::AbstractAlgebra.MPolyRingElem{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: RingElement

Return a polynomial with the same coefficients as $f$ but whose exponents have been reduced by the given shifts (supplied as an array of shifts, one for each variable), then deflated (divided) by the given exponents (again supplied as an array of deflation factors, one for each variable). The algorithm automatically replaces a deflation of $0$ by $1$, to avoid division by $0$.

deflateMethod
deflate(f::AbstractAlgebra.MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement

Return a polynomial with the same coefficients as $f$ but whose exponents have been deflated (divided) by the given exponents (supplied as an array of deflation factors, one for each variable).

The algorithm automatically replaces a deflation of $0$ by $1$, to avoid division by $0$.

deflateMethod
deflate(f::AbstractAlgebra.MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement

Return a polynomial with the same coefficients as $f$ but whose exponents have been deflated maximally, i.e. with each exponent divide by the largest integer which divides the degrees of all exponents of that variable in $f$.

deflateMethod
deflate(f::AbstractAlgebra.MPolyRingElem, vars::Vector{Int}, shift::Vector{Int}, defl::Vector{Int})

Return a polynomial with the same coefficients as $f$ but where exponents of some variables (supplied as an array of variable indices) have been reduced by the given shifts (supplied as an array of shifts), then deflated (divided) by the given exponents (again supplied as an array of deflation factors). The algorithm automatically replaces a deflation of $0$ by $1$, to avoid division by $0$.

deflateMethod
deflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: AbstractAlgebra.MPolyRingElem

Return a polynomial with the same coefficients as $f$ but where the exponents of the given variables have been reduced by the given shifts (supplied as an array of shifts), then deflated (divided) by the given exponents (again supplied as an array of deflation factors). The algorithm automatically replaces a deflation of $0$ by $1$, to avoid division by $0$.

inflateMethod
inflate(f::AbstractAlgebra.MPolyRingElem{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: RingElement

Return a polynomial with the same coefficients as $f$ but whose exponents have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors, one for each variable) and then increased by the given shifts (again supplied as an array of shifts, one for each variable).

inflateMethod
inflate(f::AbstractAlgebra.MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement

Return a polynomial with the same coefficients as $f$ but whose exponents have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors, one for each variable).

inflateMethod
inflate(f::AbstractAlgebra.MPolyRingElem, vars::Vector{Int}, shift::Vector{Int}, defl::Vector{Int})

Return a polynomial with the same coefficients as $f$ but where exponents of some variables (supplied as an array of variable indices) have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors) and then increased by the given shifts (again supplied as an array of shifts).

inflateMethod
inflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: AbstractAlgebra.MPolyRingElem

Return a polynomial with the same coefficients as $f$ but where the exponents of the given variables have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors) and then increased by the given shifts (again supplied as an array of shifts).

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = x^7*y^8 + 3*x^4*y^8 - x^4*y^2 + 5x*y^5 - x*y^2
-x^7*y^8 + 3*x^4*y^8 - x^4*y^2 + 5*x*y^5 - x*y^2
-
-julia> def, shift = deflation(f)
-([1, 2], [3, 3])
-
-julia> f1 = deflate(f, def, shift)
-x^2*y^2 + 3*x*y^2 - x + 5*y - 1
-
-julia> f2 = inflate(f1, def, shift)
-x^7*y^8 + 3*x^4*y^8 - x^4*y^2 + 5*x*y^5 - x*y^2
-
-julia> f2 == f
-true
-
-julia> g = (x+y+1)^2
-x^2 + 2*x*y + 2*x + y^2 + 2*y + 1
-
-julia> g0 = coeff(g, [y], [0])
-x^2 + 2*x + 1
-
-julia> g1 = deflate(g - g0, [y], [1], [1])
-2*x + y + 2
-
-julia> g == g0 + y * g1
-true
-

Conversions

to_univariateMethod
to_univariate(R::AbstractAlgebra.PolyRing{T}, p::AbstractAlgebra.MPolyRingElem{T}) where T <: AbstractAlgebra.RingElement

Assuming the polynomial $p$ is actually a univariate polynomial, convert the polynomial to a univariate polynomial in the given univariate polynomial ring $R$. An exception is raised if the polynomial $p$ involves more than one variable.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> S, z = polynomial_ring(ZZ, "z")
-(Univariate polynomial ring in z over integers, z)
-
-julia> f = 2x^5 + 3x^4 - 2x^2 - 1
-2*x^5 + 3*x^4 - 2*x^2 - 1
-
-julia> g = to_univariate(S, f)
-2*z^5 + 3*z^4 - 2*z^2 - 1
-

Evaluation

The following function allows evaluation of a polynomial at all its variables. The result is always in the ring that a product of a coefficient and one of the values belongs to, i.e. if all the values are in the coefficient ring, the result of the evaluation will be too.

evaluateMethod
evaluate(a::AbstractAlgebra.MPolyRingElem{T}, vals::Vector{U}) where {T <: RingElement, U <: RingElement}

Evaluate the polynomial expression by substituting in the array of values for each of the variables. The evaluation will succeed if multiplication is defined between elements of the coefficient ring of $a$ and elements of the supplied vector.

The following functions allow evaluation of a polynomial at some of its variables. Note that the result will be a product of values and an element of the polynomial ring, i.e. even if all the values are in the coefficient ring and all variables are given values, the result will be a constant polynomial, not a coefficient.

evaluateMethod
evaluate(a::AbstractAlgebra.MPolyRingElem{T}, vars::Vector{Int}, vals::Vector{U}) where {T <: RingElement, U <: RingElement}

Evaluate the polynomial expression by substituting in the supplied values in the array vals for the corresponding variables with indices given by the array vars. The evaluation will succeed if multiplication is defined between elements of the coefficient ring of $a$ and elements of vals.

evaluateMethod
evaluate(a::S, vars::Vector{S}, vals::Vector{U}) where {S <: AbstractAlgebra.MPolyRingElem{T}, U <: RingElement} where T <: RingElement

Evaluate the polynomial expression by substituting in the supplied values in the array vals for the corresponding variables (supplied as polynomials) given by the array vars. The evaluation will succeed if multiplication is defined between elements of the coefficient ring of $a$ and elements of vals.

The following function allows evaluation of a polynomial at values in a not necessarily commutative ring, e.g. elements of a matrix algebra.

evaluateMethod
evaluate(a::AbstractAlgebra.MPolyRingElem{T}, vals::Vector{U}) where {T <: RingElement, U <: NCRingElem}

Evaluate the polynomial expression at the supplied values, which may be any ring elements, commutative or non-commutative, but in the same ring. Evaluation always proceeds in the order of the variables as supplied when creating the polynomial ring to which $a$ belongs. The evaluation will succeed if a product of a coefficient of the polynomial by one of the values is defined.

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = 2x^2*y^2 + 3x + y + 1
-2*x^2*y^2 + 3*x + y + 1
-
-julia> evaluate(f, BigInt[1, 2])
-14
-
-julia> evaluate(f, [QQ(1), QQ(2)])
-14//1
-
-julia> evaluate(f, [1, 2])
-14
-
-julia> f(1, 2) == 14
-true
-
-julia> evaluate(f, [x + y, 2y - x])
-2*x^4 - 4*x^3*y - 6*x^2*y^2 + 8*x*y^3 + 2*x + 8*y^4 + 5*y + 1
-
-julia> f(x + y, 2y - x)
-2*x^4 - 4*x^3*y - 6*x^2*y^2 + 8*x*y^3 + 2*x + 8*y^4 + 5*y + 1
-
-julia> R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])
-
-julia> f = x^2*y^2 + 2x*z + 3y*z + z + 1
-x^2*y^2 + 2*x*z + 3*y*z + z + 1
-
-julia> evaluate(f, [1, 3], [3, 4])
-9*y^2 + 12*y + 29
-
-julia> evaluate(f, [x, z], [3, 4])
-9*y^2 + 12*y + 29
-
-julia> evaluate(f, [1, 2], [x + z, x - z])
-x^4 - 2*x^2*z^2 + 5*x*z + z^4 - z^2 + z + 1
-
-julia> S = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> M1 = S([1 2; 3 4])
-[1   2]
-[3   4]
-
-julia> M2 = S([2 3; 1 -1])
-[2    3]
-[1   -1]
-
-julia> M3 = S([-1 1; 1 1])
-[-1   1]
-[ 1   1]
-
-julia> evaluate(f, [M1, M2, M3])
-[ 64    83]
-[124   149]

Leading and constant coefficients, leading monomials and leading terms

The leading and trailing coefficient, constant coefficient, leading monomial and leading term of a polynomial p are returned by the following functions:

leading_coefficientMethod
leading_coefficient(p::MPolyRingElem)

Return the leading coefficient of the polynomial $p$.

trailing_coefficientMethod
trailing_coefficient(p::MPolyRingElem)

Return the trailing coefficient of the polynomial $p$, i.e. the coefficient of the last nonzero term, or zero if the polynomial is zero.

leading_monomialMethod
leading_monomial(p::MPolyRingElem)

Return the leading monomial of $p$. This function throws an ArgumentError if $p$ is zero.

leading_termMethod
leading_term(p::MPolyRingElem)

Return the leading term of the polynomial p. This function throws an ArgumentError if $p$ is zero.

constant_coefficientMethod
constant_coefficient(p::MPolyRingElem)

Return the constant coefficient of the polynomial $p$ or zero if it doesn't have one.

tailMethod
tail(p::MPolyRingElem)

Return the tail of the polynomial $p$, i.e. the polynomial without its leading term (if any).

Examples

using AbstractAlgebra
-R,(x,y) = polynomial_ring(ZZ, ["x", "y"], ordering=:deglex)
-p = 2*x*y + 3*y^3 + 1
-leading_term(p)
-leading_monomial(p)
-leading_coefficient(p)
-leading_term(p) == leading_coefficient(p) * leading_monomial(p)
-constant_coefficient(p)
-tail(p)

Least common multiple, greatest common divisor

The greatest common divisor of two polynomials a and b is returned by

gcdMethod
gcd(a::MPoly{T}, a::MPoly{T}) where {T <: RingElement}

Return the greatest common divisor of a and b in parent(a).

Note that this functionality is currently only provided for AbstractAlgebra generic polynomials. It is not automatically provided for all multivariate rings that implement the multivariate interface.

However, if such a gcd is provided, the least common multiple of two polynomials a and b is returned by

lcmMethod
lcm(a::AbstractAlgebra.MPolyRingElem{T}, a::AbstractAlgebra.MPolyRingElem{T}) where {T <: RingElement}

Return the least common multiple of a and b in parent(a).

Examples

julia> using AbstractAlgebra
-
-julia> R,(x,y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> a = x*y + 2*y
-x*y + 2*y
-
-julia> b = x^3*y + y
-x^3*y + y
-
-julia> gcd(a,b)
-y
-
-julia> lcm(a,b)
-x^4*y + 2*x^3*y + x*y + 2*y
-
-julia> lcm(a,b) == a * b // gcd(a,b)
-true
-

Derivations

derivativeMethod
derivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.

Examples

julia> R, (x, y) = AbstractAlgebra.polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = x*y + x + y + 1
-x*y + x + y + 1
-
-julia> derivative(f, x)
-y + 1
-
-julia> derivative(f, y)
-x + 1
-
-julia> derivative(f, 1)
-y + 1
-
-julia> derivative(f, 2)
-x + 1

Homogeneous polynomials

It is possible to test whether a polynomial is homogeneous with respect to the standard grading using the function

is_homogeneousMethod
is_homogeneous(x::MPoly{T}) where {T <: RingElement}

Return true if the given polynomial is homogeneous with respect to the standard grading and false otherwise.

Random generation

Random multivariate polynomials in a given ring can be constructed by passing a range of degrees for the variables and a range on the number of terms. Additional parameters are used to generate the coefficients of the polynomial.

Note that zero coefficients may currently be generated, leading to less than the requested number of terms.

rand(R::MPolyRing, exp_range::UnitRange{Int}, term_range::UnitRange{Int}, v...)

Examples

julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])
-
-julia> f = rand(R, -1:2, 3:5, -10:10)
-4*x^4*y^4
-
-julia> S, (s, t) = polynomial_ring(GF(7), ["x", "y"])
-(Multivariate polynomial ring in 2 variables over finite field F_7, AbstractAlgebra.Generic.MPoly{AbstractAlgebra.GFElem{Int64}}[x, y])
-
-julia> g = rand(S, -1:2, 3:5)
-4*x^3*y^4
diff --git a/previews/PR2578/AbstractAlgebra/mseries/index.html b/previews/PR2578/AbstractAlgebra/mseries/index.html deleted file mode 100644 index 94e9ff345240..000000000000 --- a/previews/PR2578/AbstractAlgebra/mseries/index.html +++ /dev/null @@ -1,78 +0,0 @@ - -Multivariate series · Oscar.jl

Multivariate series

AbstractAlgebra.jl provide multivariate series over a commutative ring.

Series with capped absolute precision are provided with and without weights.

For the unweighted case precision in each variable can be set per series, but is capped at some maximum precision which is set when defining the ring.

For the weighted case, a single precision is set on the ring only. Terms are truncated at that precision (after applying weights).

Generic multivariate series

Generic multivariate series over a commutative ring, AbsMSeries{T} is implemented in src/generic/AbsMSeries.jl.

Such series are capped absolute series and have type Generic.AbsMSeries{T} where T is the type of elements of the coefficient ring.

Internally they consist of a multivariate polynomial. For unweighted series they also contain a vector of precisions, one for each variable.

For weighted series weights and a precision are stored on the ring only. The vector of precisions in the series objects is ignored.

See the file src/generic/GenericTypes.jl for details of the type.

The series are implemented in terms of multivariate polynomials which are used internally to keep track of the coefficients of the series.

Only lex ordering is provided at present both weighted and unweighted, though series print in reverse order to what multivariate polynomials would print, i.e. least significant term first, as would be expected for series.

Parent objects of such series have type Generic.AbsMSeriesRing{T}.

The symbol representation of the variables and the multivariate polynomial ring is stored in the parent object.

Abstract types

Multivariate series element types belong to the abstract type MSeriesElem{T} and the multivariate series ring types belong to the abstract type MSeriesRing{T}. This enables one to write generic functions that can accept any AbstractAlgebra multivariate series type.

Multivariate series ring constructors

In order to construct multivariate series in AbstractAlgebra.jl, one must first construct the series ring itself. This is accomplished with the following constructors.

For the unweighted case:

power_series_ring(R::Ring, prec::Vector{Int}, s::AbstractVector{<:VarName}; cached::Bool = true)

Given a base ring R and a vector of strings s specifying how the generators (variables) should be printed, along with a vector of precisions, one for each variable, return a tuple U, (x, y, ...) representing the new series ring $S$ and the generators $x, y, \ldots$ of the ring as a tuple. By default the parent object S will depend on R, the precision vector and the variable names x, y, ... and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

In the weighted case:

power_series_ring(R::Ring, weights::Vector{Int}, s::AbstractVector{<:VarName}, prec::Int; cached::Bool = true)

Given a base ring R and a vector of strings s specifying how the generators (variables) should be printed, along with a vector of weights, one for each variable and a bound on the (weighted) precision, return a tuple U, (x, y, ...) representing the new series ring $S$ and the generators $x, y, \ldots$ of the ring as a tuple. By default the parent object S will depend on R, the precision, the vector of weights and the variable names x, y, ... and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Here are some examples of creating multivariate series rings and making use of the resulting parent objects to coerce various elements into the series ring.

Note that one can also use the function call O(x^n) with unweighted series to specify the precision in the variable x of a given series expression should be precision n.

Note

It is not possible to use x^0 in the O() function, since there is no distinction between x^0 and y^0 as far as the system is concerned. If one wishes to set the precision of a variable to precision 0, one must use the set_precision! function described below.

If one wants a series with the same precision in all variables, one can use O(R, n) where R is the series ring and n is the desired precision.

If all the precisions are to be the same, the vector of integers for the precisions can be replaced by a single integer in the constructor.

Examples

julia> R, (x, y) = power_series_ring(ZZ, [2, 3], ["x", "y"])
-(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(y^3) + O(x^2), y + O(y^3) + O(x^2)])
-
-julia> f = R()
-O(y^3) + O(x^2)
-
-julia> g = R(123)
-123 + O(y^3) + O(x^2)
-
-julia> h = R(BigInt(1234))
-1234 + O(y^3) + O(x^2)
-
-julia> k = R(x + 1)
-1 + x + O(y^3) + O(x^2)
-
-julia> m = x + y + O(y^2)
-y + x + O(y^2) + O(x^2)
-
-julia> R, (x, y) = power_series_ring(ZZ, 3, ["x", "y"])
-(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(y^3) + O(x^3), y + O(y^3) + O(x^3)])
-
-julia> n = x + y + O(R, 2)
-y + x + O(y^2) + O(x^2)
-
-julia> R, (x, y) = power_series_ring(ZZ, [2, 3], 10, ["x", "y"])
-(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(10), y + O(10)])
-
-julia> R()
-O(10)
-
-julia> R(x)
-x + O(10)

Basic ring functionality

Once a multivariate series ring is constructed, there are various ways to construct series in that ring.

The easiest way is simply using the generators returned by the power_series_ring constructor and build up the power series using basic arithmetic, as described in the Ring interface.

The power series rings in AbstractAlgebra.jl implement the full Ring interface.

We give some examples of such functionality.

Note

The divexact function can currently only divide by unit series (i.e. whose constant coefficient is invertible).

Examples

julia> R, (x,) = power_series_ring(ZZ, [5], ["x"])
-(Multivariate power series ring in 1 variable over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(x^5)])
-
-julia> f = x^3 + 3x + 21
-21 + 3*x + x^3 + O(x^5)
-
-julia> h = zero(R)
-O(x^5)
-
-julia> k = one(R)
-1 + O(x^5)
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> n = length(f)
-3
-
-julia> U = base_ring(R)
-Integers
-
-julia> v = symbols(R)
-1-element Vector{Symbol}:
- :x
-
-julia> T = parent(x + 1)
-Multivariate power series ringin 1 variable x
-  over integers
-
-julia> f == deepcopy(f)
-true
-
-julia> t = divexact(f*x, 1 + x)
-21*x - 18*x^2 + 18*x^3 - 17*x^4 + O(x^5)
-
-julia> R, (x, y) = power_series_ring(ZZ, [2, 3], 10, ["x", "y"])
-(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(10), y + O(10)])
-
-julia> f = 3x^2*y + 1
-1 + 3*y*x^2 + O(10)
-
-julia> one(R)
-1 + O(10)

Power series functionality provided by AbstractAlgebra.jl

The functionality listed below is automatically provided by AbstractAlgebra.jl for absolute series over any commutative ring.

Basic functionality

The following are provided for weighted and unweighted series:

nvarsMethod
nvars(R::AbsMSeriesRing)

Return the number of variables in the series ring.

symbolsMethod
symbols(R::MSeriesRing)

Return a vector of symbols, one for each of the variables of the series ring $R$.

precisionMethod
precision(a::AbsMSeries)

Return a vector of precisions, one for each variable in the series ring. If the ring is weighted the weighted precision is returned instead.

coeffMethod
coeff(a::AbsMSeries, n::Int)

Return the coefficient of the $n$-th nonzero term of the series (or zero if there are fewer than $n$ nonzero terms). Terms are numbered from the least significant term, i.e. the first term displayed when the series is printed.

characteristicMethod
characteristic(R::FracField{T}) where T <: RingElem

Return the characteristic of the given field.

genMethod
gen(R::AbsMSeriesRing, i::Int)

Return the $i$-th generator (variable) of the series ring $R$. Numbering starts from $1$ for the most significant variable.

gensMethod
gens(R::AbsMSeriesRing)

Return a vector of the generators (variables) of the series ring $R$, starting with the most significant.

is_genMethod
is_gen(a::AbsMSeries)

Return true if the series $a$ is a generator of its parent series ring.

is_unitMethod
is_unit(a::AbsMSeries)

Return true if the series is a unit in its series ring, i.e. if its constant term is a unit in the base ring.

lengthMethod
length(a::AbsMSeries)

Return the number of nonzero terms in the series $a$.

The following are only available for unweighted series.

max_precisionMethod
max_precision(R::AbsMSeriesRing)

Return a vector of precision caps, one for each variable in the ring. Arithmetic operations will be performed to precisions not exceeding these values.

valuationMethod
valuation(a::AbsMSeries)

Return the valuation of $a$ as a vector of integers, one for each variable.

Iteration

coefficientsMethod
coefficients(a::AbsMSeries)

Return an array of the nonzero coefficients of the series, in the order they would be displayed, i.e. least significant term first.

exponent_vectorsMethod
exponent_vectors(a::AbsMSeries)

Return an array of the exponent vectors of the nonzero terms of the series, in the order they would be displayed, i.e. least significant term first.

Truncation

truncateMethod
truncate(a::AbstractAlgebra.AbsMSeries, prec::Vector{Int})

Return $a$ truncated to (absolute) precisions given by the vector prec.

truncateMethod
truncate(a::AbstractAlgebra.AbsMSeries, prec::Int)

Return $a$ truncated to precision prec. This either truncates by weight in the weighted cases or truncates each variable to precision prec in the unweighted case.

Exact division

divexactMethod
divexact(x::AbsMSeries{T}, y::AbsMSeries{T}; check::Bool=true) where T <: RingElement

Return the exact quotient of the series $x$ by the series $y$. This function currently assumes $y$ is an invertible series.

Evaluation

evaluateMethod
evaluate(a::U, vars::Vector{Int}, vals::Vector{U}) where {T <: RingElement, U <: AbsMSeries{T}}

Evaluate the series expression by substituting in the supplied values in the array vals for the corresponding variables with indices given by the array vars. The values must be in the same ring as $a$.

evaluateMethod
evaluate(a::U, vars::Vector{U}, vals::Vector{U}) where {T <: RingElement, U <: AbsMSeries{T}}

Evaluate the series expression by substituting in the supplied values in the array vals for the corresponding variables given by the array vars. The values must be in the same ring as $a$.

evaluateMethod
evaluate(a::U, vals::Vector{U}) where {T <: RingElement, U <: AbsMSeries{T}}

Evaluate the series expression by substituting in the supplied values in the array vals for the variables the series ring to which $a$ belongs. The values must be in the same ring as $a$.

Random generation

randMethod
rand(S::MSeriesRing, term_range, v...)

Return a random element of the series ring $S$ with number of terms in the range given by term_range and where coefficients of the series are randomly generated in the base ring using the data given by v. The exponents of the variable in the terms will be less than the precision caps for the Ring $S$ when it was created.

diff --git a/previews/PR2578/AbstractAlgebra/ncpolynomial/index.html b/previews/PR2578/AbstractAlgebra/ncpolynomial/index.html deleted file mode 100644 index 9a041bd78f04..000000000000 --- a/previews/PR2578/AbstractAlgebra/ncpolynomial/index.html +++ /dev/null @@ -1,213 +0,0 @@ - -Univariate polynomials over a noncommutative ring · Oscar.jl

Univariate polynomials over a noncommutative ring

AbstractAlgebra.jl provides a module, implemented in src/NCPoly.jl for univariate polynomials over any noncommutative ring in the AbstractAlgebra type hierarchy.

Generic type for univariate polynomials over a noncommutative ring

AbstractAlgebra.jl implements a generic univariate polynomial type over noncommutative rings in src/generic/NCPoly.jl.

These generic polynomials have type Generic.NCPoly{T} where T is the type of elements of the coefficient ring. Internally they consist of a Julia array of coefficients and some additional fields for length and a parent object, etc. See the file src/generic/GenericTypes.jl for details.

Parent objects of such polynomials have type Generic.NCPolyRing{T}.

The string representation of the variable of the polynomial ring and the base/coefficient ring $R$ is stored in the parent object.

Abstract types

The polynomial element types belong to the abstract type NCPolyRingElem{T} and the polynomial ring types belong to the abstract type NCPolyRing{T}. This enables one to write generic functions that can accept any AbstractAlgebra polynomial type.

Note

Note that both the generic polynomial ring type Generic.NCPolyRing{T} and the abstract type it belongs to, NCPolyRing{T} are both called NCPolyRing. The former is a (parameterised) concrete type for a polynomial ring over a given base ring whose elements have type T. The latter is an abstract type representing all polynomial ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).

Polynomial ring constructors

In order to construct polynomials in AbstractAlgebra.jl, one must first construct the polynomial ring itself. This is accomplished with the following constructor.

polynomial_ringMethod
polynomial_ring(R::NCRing, s::VarName; cached::Bool = true)

Given a base ring R and symbol/string s specifying how the generator (variable) should be printed, return a tuple S, x representing the new polynomial ring $S = R[x]$ and the generator $x$ of the ring.

By default the parent object S depends only on R and x and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Examples

julia> R, x = polynomial_ring(ZZ, :x)
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, :y)
-(Univariate polynomial ring in y over univariate polynomial ring, y)

A shorthand version of this function is provided: given a base ring R, we abbreviate the constructor as follows.

R["x"]

Here are some examples of creating polynomial rings and making use of the resulting parent objects to coerce various elements into the polynomial ring.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-julia> U, z = R["z"]
-(Univariate polynomial ring in z over matrix algebra of degree 2 over integers, z)
-
-julia> f = S()
-0
-
-julia> g = S(123)
-[123 0; 0 123]
-
-julia> h = T(BigInt(1234))
-[1234 0; 0 1234]
-
-julia> k = T(x + 1)
-x + 1
-
-julia> m = U(z + 1)
-z + 1
-

All of the examples here are generic polynomial rings, but specialised implementations of polynomial rings provided by external modules will also usually provide a polynomial_ring constructor to allow creation of their polynomial rings.

Basic ring functionality

Once a polynomial ring is constructed, there are various ways to construct polynomials in that ring.

The easiest way is simply using the generator returned by the polynomial_ring constructor and build up the polynomial using basic arithmetic, as described in the Ring interface.

The Julia language also has special syntax for the construction of polynomials in terms of a generator, e.g. we can write 2x instead of 2*x.

The polynomial rings in AbstractAlgebra.jl implement the full Ring interface. Of course the entire Univariate Polynomial Ring interface is also implemented.

We give some examples of such functionality.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-julia> f = x^3 + 3x + 21
-x^3 + [3 0; 0 3]*x + [21 0; 0 21]
-
-julia> g = (x + 1)*y^2 + 2x + 1
-(x + 1)*y^2 + [2 0; 0 2]*x + 1
-
-julia> h = zero(T)
-0
-
-julia> k = one(S)
-1
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> n = length(g)
-3
-
-julia> U = base_ring(T)
-Univariate polynomial ring in x over matrix algebra of degree 2 over integers
-
-julia> V = base_ring(y + 1)
-Univariate polynomial ring in x over matrix algebra of degree 2 over integers
-
-julia> v = var(T)
-:y
-
-julia> U = parent(y + 1)
-Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers
-
-julia> g == deepcopy(g)
-true

Polynomial functionality provided by AbstractAlgebra.jl

The functionality listed below is automatically provided by AbstractAlgebra.jl for any polynomial module that implements the full Univariate Polynomial Ring interface over a noncommutative ring. This includes AbstractAlgebra.jl's own generic polynomial rings.

But if a C library provides all the functionality documented in the Univariate Polynomial Ring interface over a noncommutative ring, then all the functions described here will also be automatically supplied by AbstractAlgebra.jl for that polynomial type.

Of course, modules are free to provide specific implementations of the functions described here, that override the generic implementation.

Basic functionality

leading_coefficientMethod
leading_coefficient(a::PolynomialElem)

Return the leading coefficient of the given polynomial. This will be the nonzero coefficient of the term with highest degree unless the polynomial in the zero polynomial, in which case a zero coefficient is returned.

trailing_coefficientMethod
trailing_coefficient(a::PolynomialElem)

Return the trailing coefficient of the given polynomial. This will be the nonzero coefficient of the term with lowest degree unless the polynomial is the zero polynomial, in which case a zero coefficient is returned.

genMethod
gen(R::NCPolyRing)

Return the generator of the given polynomial ring.

is_genMethod
is_gen(a::PolynomialElem)

Return true if the given polynomial is the constant generator of its polynomial ring, otherwise return false.

is_monomialMethod
is_monomial(a::PolynomialElem)

Return true if the given polynomial is a monomial.

is_termMethod
is_term(a::PolynomialElem)

Return true if the given polynomial has one term.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-julia> a = zero(T)
-0
-
-julia> b = one(T)
-1
-
-julia> c = BigInt(1)*y^2 + BigInt(1)
-y^2 + 1
-
-julia> d = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + [3 0; 0 3]
-
-julia> f = leading_coefficient(d)
-x
-
-julia> y = gen(T)
-y
-
-julia> g = is_gen(y)
-true
-
-julia> m = is_unit(b)
-true
-
-julia> n = degree(d)
-2
-
-julia> is_term(2y^2)
-true
-
-julia> is_monomial(y^2)
-true
-

Truncation

truncateMethod
truncate(a::PolynomialElem, n::Int)

Return $a$ truncated to $n$ terms, i.e. the remainder upon division by $x^n$.

mullowMethod
mullow(a::NCPolyRingElem{T}, b::NCPolyRingElem{T}, n::Int) where T <: NCRingElem

Return $a\times b$ truncated to $n$ terms.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + [3 0; 0 3]
-
-julia> g = (x + 1)*y + (x^3 + 2x + 2)
-(x + 1)*y + x^3 + [2 0; 0 2]*x + [2 0; 0 2]
-
-julia> h = truncate(f, 1)
-[3 0; 0 3]
-
-julia> k = mullow(f, g, 4)
-(x^2 + x)*y^3 + (x^4 + [3 0; 0 3]*x^2 + [4 0; 0 4]*x + 1)*y^2 + (x^4 + x^3 + [2 0; 0 2]*x^2 + [7 0; 0 7]*x + [5 0; 0 5])*y + [3 0; 0 3]*x^3 + [6 0; 0 6]*x + [6 0; 0 6]
-

Reversal

reverseMethod
reverse(x::PolynomialElem, len::Int)

Return the reverse of the polynomial $x$, thought of as a polynomial of the given length (the polynomial will be notionally truncated or padded with zeroes before the leading term if necessary to match the specified length). The resulting polynomial is normalised. If len is negative we throw a DomainError().

reverseMethod
reverse(x::PolynomialElem)

Return the reverse of the polynomial $x$, i.e. the leading coefficient of $x$ becomes the constant coefficient of the result, etc. The resulting polynomial is normalised.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + [3 0; 0 3]
-
-julia> g = reverse(f, 7)
-[3 0; 0 3]*y^6 + (x + 1)*y^5 + x*y^4
-
-julia> h = reverse(f)
-[3 0; 0 3]*y^2 + (x + 1)*y + x
-

Shifting

shift_leftMethod
shift_left(f::PolynomialElem, n::Int)

Return the polynomial $f$ shifted left by $n$ terms, i.e. multiplied by $x^n$.

shift_rightMethod
shift_right(f::PolynomialElem, n::Int)

Return the polynomial $f$ shifted right by $n$ terms, i.e. divided by $x^n$.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + [3 0; 0 3]
-
-julia> g = shift_left(f, 7)
-x*y^9 + (x + 1)*y^8 + [3 0; 0 3]*y^7
-
-julia> h = shift_right(f, 2)
-x
-

Evaluation

evaluateMethod
evaluate(a::NCPolyRingElem, b::T) where T <: NCRingElem

Evaluate the polynomial $a$ at the value $b$ and return the result.

evaluateMethod
evaluate(a::NCPolyRingElem, b::Union{Integer, Rational, AbstractFloat})

Evaluate the polynomial $a$ at the value $b$ and return the result.

We also overload the functional notation so that the polynomial $f$ can be evaluated at $a$ by writing $f(a)$.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + [3 0; 0 3]
-
-julia> k = evaluate(f, 3)
-[12 0; 0 12]*x + [6 0; 0 6]
-
-julia> m = evaluate(f, x^2 + 2x + 1)
-x^5 + [4 0; 0 4]*x^4 + [7 0; 0 7]*x^3 + [7 0; 0 7]*x^2 + [4 0; 0 4]*x + [4 0; 0 4]
-
-julia> r = f(23)
-[552 0; 0 552]*x + [26 0; 0 26]
-

Derivative

derivativeMethod
derivative(a::PolynomialElem)

Return the derivative of the polynomial $a$.

Examples

julia> R = MatrixAlgebra(ZZ, 2)
-Matrix algebra of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + [3 0; 0 3]
-
-julia> h = derivative(f)
-[2 0; 0 2]*x*y + x + 1
-
diff --git a/previews/PR2578/AbstractAlgebra/ncring_interface/index.html b/previews/PR2578/AbstractAlgebra/ncring_interface/index.html deleted file mode 100644 index 9574c1fd2430..000000000000 --- a/previews/PR2578/AbstractAlgebra/ncring_interface/index.html +++ /dev/null @@ -1,3 +0,0 @@ - -Noncommutative ring Interface · Oscar.jl

Noncommutative ring Interface

AbstractAlgebra.jl supports commutative rings through its Ring interface. In this section we describe the corresponding interface for noncommutative rings. The two interfaces are very similar in terms of required functionality, and so we mainly document the differences here.

Noncommutative rings can be supported through the abstract types NCRing and NCRingElem. Note that we have Ring <: NCRing, etc., so the interface here should more correctly be called the Not-necessarily-Commutative-ring interface.

However, the fact remains that if one wishes to implement a noncommutative ring, one should make its type belong to NCRing but not to Ring. Therefore it is not too much of a mistake to think of the NCRing interface as being for noncommutative rings.

Types

As for the Ring interface, most noncommutative rings must supply two types:

  • a type for the parent object (representing the ring itself)
  • a type for elements of that ring

The parent type must belong to NCRing and the element type must belong to NCRingElem. Of course, the types may belong to these abstract types transitively via an intermediate abstract type.

Also as for the Ring interface, it is advised to make the types of generic parameterised rings that belong to NCRing and NCRingElem depend on the type of the elements of that parameter ring.

NCRingElement type union

As for the Ring interface, the NCRing interface provides a union type NCRingElement in src/julia/JuliaTypes.jl which is a union of NCRingElem and the Julia types Integer, Rational and AbstractFloat.

Most of the generic code in AbstractAlgebra for general rings makes use of the union type NCRingElement instead of NCRingElem so that the generic functions also accept the Julia Base ring types.

As per usual, one may need to implement one ad hoc binary operation for each concrete type belonging to NCRingElement to avoid ambiguity warnings.

Parent object caches

Parent object caches for the NCRing interface operate as per the Ring interface.

Required functions for all rings

Generic functions may only rely on required functionality for the NCRing interface, which must be implemented by all noncommutative rings.

Most of this required functionality is the same as for the Ring interface, so we refer the reader there for details, with the following modifications.

We give this interface for fictitious types MyParent for the type of the ring parent object R and MyElem for the type of the elements of the ring.

Exact division

divexact_left(f::MyElem, g::MyElem)
-divexact_right(f::MyElem, g::MyElem)

If $f = ga$ for some $a$ in the ring, the function divexact_left(f, g) returns a. If $f = ag$ then divexact_right(f, g) returns a. A DivideError() should be thrown if division is by zero. If no exact quotient exists or an impossible inverse is unavoidably encountered, an error should be thrown.

diff --git a/previews/PR2578/AbstractAlgebra/numberfield/index.html b/previews/PR2578/AbstractAlgebra/numberfield/index.html deleted file mode 100644 index 2881bccf4e72..000000000000 --- a/previews/PR2578/AbstractAlgebra/numberfield/index.html +++ /dev/null @@ -1,10 +0,0 @@ - -Number fields · Oscar.jl

Number fields

AbstractAlgebra.jl provides a very naive implementation of number fields. This allows arithmetic in algebraic number fields, which are currently modeled as $\mathbb{Q}[x]$ modulo an irreducible polynomial, i.e. as a residue field.

The definition of the number field constructor is given in src/generic/NumberField.jl but no type is defined for a number field. The definition mainly exists for testing purposes. It may later be replaced by a more standard implementation. For a more fully fleshed out number field implementation (based on a very high performance C library), see Nemo.jl.

Number field constructors

In order to construct number fields in AbstractAlgebra.jl, one must first construct the field itself. This is accomplished with the following constructor.

number_field(f::Generic.Poly{Rational{BigInt}}, s::VarName, t = "\$"; cached::Bool = true)

Given an irreducible defining polynomial $f$ in $\mathbb{Q}[x]$, return a tuple $(K, x)$ consisting of the number field defined by that polynomial and a generator. The string fields are currently ignored, but are reserved for future use.

Currently the generator of the number field prints the same way as the variable in $\mathbb{Q}[x]$.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)
-
-julia> f = a^2 + 2a + 7
-x^2 + 2*x + 7
-

Basic field functionality

The number field module in AbstractAlgebra.jl implements the full Field and residue_ring interfaces.

diff --git a/previews/PR2578/AbstractAlgebra/perm/index.html b/previews/PR2578/AbstractAlgebra/perm/index.html deleted file mode 100644 index cceadb97fe57..000000000000 --- a/previews/PR2578/AbstractAlgebra/perm/index.html +++ /dev/null @@ -1,188 +0,0 @@ - -Permutations and Symmetric groups · Oscar.jl

Permutations and Symmetric groups

AbstractAlgebra.jl provides rudimentary native support for permutation groups (implemented in src/generic/PermGroups.jl). All functionality of permutations is accessible in the Generic submodule.

Permutations are represented internally via vector of integers, wrapped in type Perm{T}, where T<:Integer carries the information on the type of elements of a permutation. Symmetric groups are singleton parent objects of type SymmetricGroup{T} and are used mostly to store the length of a permutation, since it is not included in the permutation type.

Symmetric groups are created using the SymmetricGroup (inner) constructor.

Both SymmetricGroup and Perm and can be parametrized by any type T<:Integer . By default the parameter is the Int-type native to the systems architecture. However, if you are sure that your permutations are small enough to fit into smaller integer type (such as Int32, UInt16, or even Int8), you may choose to change the parametrizing type accordingly. In practice this may result in decreased memory footprint (when storing multiple permutations) and noticeable faster performance, if your workload is heavy in operations on permutations, which e.g. does not fit into cache of your cpu.

All the permutation group types belong to the Group abstract type and the corresponding permutation element types belong to the GroupElem abstract type.

setpermstyleFunction
setpermstyle(format::Symbol)

Select the style in which permutations are displayed (in the REPL or in general as strings). This can be either

  • :array - as vector of integers whose $n$-th position represents the value at $n$), or
  • :cycles - as, more familiar for mathematicians, decomposition into disjoint cycles, where the value at $n$ is represented by the entry immediately following $n$ in a cycle (the default).

The difference is purely esthetical.

Examples

julia> setpermstyle(:array)
-:array
-
-julia> Perm([2,3,1,5,4])
-[2, 3, 1, 5, 4]
-
-julia> setpermstyle(:cycles)
-:cycles
-
-julia> Perm([2,3,1,5,4])
-(1,2,3)(4,5)

Permutations constructors

There are several methods to construct permutations in AbstractAlgebra.jl.

  • The easiest way is to directly call to the Perm (inner) constructor:
PermType
Perm{T<:Integer}

The type of permutations. Fieldnames:

  • d::Vector{T} - vector representing the permutation
  • modified::Bool - bit to check the validity of cycle decomposition
  • cycles::CycleDec{T} - (cached) cycle decomposition

A permutation $p$ consists of a vector (p.d) of $n$ integers from $1$ to $n$. If the $i$-th entry of the vector is $j$, this corresponds to $p$ sending $i \to j$. The cycle decomposition (p.cycles) is computed on demand and should never be accessed directly. Use cycles(p) instead.

There are two inner constructors of Perm:

  • Perm(n::T) constructs the trivial Perm{T}-permutation of length $n$.
  • Perm(v::AbstractVector{<:Integer} [,check=true]) constructs a permutation represented by v. By default Perm constructor checks if the vector constitutes a valid permutation. To skip the check call Perm(v, false).

Examples

julia> Perm([1,2,3])
-()
-   
-julia> g = Perm(Int32[2,3,1])
-(1,2,3)
-
-julia> typeof(g)
-Perm{Int32}

Since the parent object can be reconstructed from the permutation itself, you can work with permutations without explicitly constructing the parent object.

  • The other way is to first construct the permutation group they belong to. This is accomplished with the inner constructor SymmetricGroup(n::Integer) which constructs the permutation group on $n$ symbols and returns the parent object representing the group.
SymmetricGroupType
SymmetricGroup{T<:Integer}

The full symmetric group singleton type. SymmetricGroup(n) constructs the full symmetric group $S_n$ on $n$-symbols. The type of elements of the group is inferred from the type of n.

Examples

julia> G = SymmetricGroup(5)
-Full symmetric group over 5 elements
-
-julia> elem_type(G)
-Perm{Int64}
-
-julia> H = SymmetricGroup(UInt16(5))
-Full symmetric group over 5 elements
-
-julia> elem_type(H)
-Perm{UInt16}

A vector of integers can be then coerced to a permutation by calling a parent permutation group on it. The advantage is that the vector is automatically converted to the integer type fixed at the creation of the parent object.

Examples:

julia> G = SymmetricGroup(BigInt(5)); p = G([2,3,1,5,4])
-(1,2,3)(4,5)
-
-julia> typeof(p)
-Perm{BigInt}
-
-julia> H = SymmetricGroup(UInt16(5)); r = H([2,3,1,5,4])
-(1,2,3)(4,5)
-
-julia> typeof(r)
-Perm{UInt16}
-
-julia> one(H)
-()

By default the coercion checks for non-unique values in the vector, but this can be switched off with G([2,3,1,5,4], false).

  • Finally there is a perm"..." string macro to construct a permutation from a string input.
@perm_strMacro
perm"..."

String macro to parse disjoint cycles into Perm{Int}.

Strings for the output of GAP could be copied directly into perm"...". Cycles of length $1$ are not necessary, but can be included. A permutation of the minimal support is constructed, i.e. the maximal $n$ in the decomposition determines the parent group $S_n$.

Examples

julia> p = perm"(1,3)(2,4)"
-(1,3)(2,4)
-
-julia> typeof(p)
-Perm{Int64}
-
-julia> parent(p) == SymmetricGroup(4)
-true
-
-julia> p = perm"(1,3)(2,4)(10)"
-(1,3)(2,4)
-
-julia> parent(p) == SymmetricGroup(10)
-true

Permutation interface

The following basic functionality is provided by the default permutation group implementation in AbstractAlgebra.jl, to support construction of other generic constructions over permutation groups. Any custom permutation group implementation in AbstractAlgebra.jl should provide the group element arithmetic and comparison.

A custom implementation also needs to implement hash(::Perm, ::UInt) and (possibly) deepcopy_internal(::Perm, ::IdDict).

Note

Permutation group elements are mutable and so returning shallow copies is not sufficient.

getindex(a::Perm, n::Integer)

Allow access to entry $n$ of the given permutation via the syntax a[n]. Note that entries are $1$-indexed.

setindex!(a::Perm, d::Integer, n::Integer)

Set the $n$-th entry of the given permutation to $d$. This allows Julia to provide the syntax a[n] = d for setting entries of a permutation. Entries are $1$-indexed.

Note

Using setindex! invalidates the cycle decomposition cached in a permutation, which will be computed the next time it is needed.

Given the parent object G for a permutation group, the following coercion functions are provided to coerce various arguments into the permutation group. Developers provide these by overloading the permutation group parent objects.

one(G)

Return the identity permutation.

G(A::Vector{<:Integer})

Return the permutation whose entries are given by the elements of the supplied vector.

G(p::Perm)

Take a permutation that is already in the permutation group and simply return it. A copy of the original is not made if not necessary.

Basic manipulation

Numerous functions are provided to manipulate permutation group elements.

cyclesMethod
cycles(g::Perm)

Decompose permutation g into disjoint cycles.

Return a CycleDec object which iterates over disjoint cycles of g. The ordering of cycles is not guaranteed, and the order within each cycle is computed up to a cyclic permutation. The cycle decomposition is cached in g and used in future computation of permtype, parity, sign, order and ^ (powering).

Examples

julia> g = Perm([3,4,5,2,1,6])
-(1,3,5)(2,4)
-
-julia> collect(cycles(g))
-3-element Vector{Vector{Int64}}:
- [1, 3, 5]
- [2, 4]
- [6]

Cycle structure is cached in a permutation, since once available, it provides a convenient shortcut in many other algorithms.

parityMethod
parity(g::Perm)

Return the parity of the given permutation, i.e. the parity of the number of transpositions in any decomposition of g into transpositions.

parity returns $1$ if the number is odd and $0$ otherwise. parity uses cycle decomposition of g if already available, but will not compute it on demand. Since cycle structure is cached in g you may call cycles(g) before calling parity.

Examples

julia> g = Perm([3,4,1,2,5])
-(1,3)(2,4)
-
-julia> parity(g)
-0
-
-julia> g = Perm([3,4,5,2,1,6])
-(1,3,5)(2,4)
-
-julia> parity(g)
-1
signMethod
sign(g::Perm)

Return the sign of a permutation.

sign returns $1$ if g is even and $-1$ if g is odd. sign represents the homomorphism from the permutation group to the unit group of $\mathbb{Z}$ whose kernel is the alternating group.

Examples

julia> g = Perm([3,4,1,2,5])
-(1,3)(2,4)
-
-julia> sign(g)
-1
-
-julia> g = Perm([3,4,5,2,1,6])
-(1,3,5)(2,4)
-
-julia> sign(g)
--1
permtypeMethod
permtype(g::Perm)

Return the type of permutation g, i.e. lengths of disjoint cycles in cycle decomposition of g.

The lengths are sorted in decreasing order by default. permtype(g) fully determines the conjugacy class of g.

Examples

julia> g = Perm([3,4,5,2,1,6])
-(1,3,5)(2,4)
-
-julia> permtype(g)
-3-element Vector{Int64}:
- 3
- 2
- 1
-
-julia> e = one(g)
-()
-
-julia> permtype(e)
-6-element Vector{Int64}:
- 1
- 1
- 1
- 1
- 1
- 1

Additionally GroupsCore.jl package provides more functionality, notably functions gens and order. You may consult its documentation. Note that even an Int64 can be easily overflowed when computing with symmetric groups. Thus, by default, order returns (always correct) BigInts. If you are sure that the computation will not overflow, you may use order(::Type{T}, ...) to perform computations with machine integers. Julia's standard promotion rules apply for the returned value.

Since SymmetricGroup implements the iterator protocol, you may iterate over all permutations via a simple loop:

for p in SymmetricGroup(n)
-   ...
-end

Iteration over all permutations in reasonable time, (i.e. in terms of minutes) is possible when $n ≤ 13$.

You may also use the non-allocating Generic.elements! function for $n ≤ 14$ (or even $15$ if you are patient enough), which is an order of magnitude faster.

elements!Method
Generic.elements!(G::SymmetricGroup)

Return an unsafe iterator over all permutations in G. Only one permutation is allocated and then modified in-place using the non-recursive Heaps algorithm.

Note: you need to explicitly copy permutations intended to be stored or modified.

Examples

julia> elts = Generic.elements!(SymmetricGroup(5));
-
-
-julia> length(elts)
-120
-
-julia> for p in Generic.elements!(SymmetricGroup(3))
-         println(p)
-       end
-()
-(1,2)
-(1,3,2)
-(2,3)
-(1,2,3)
-(1,3)
-
-julia> A = collect(Generic.elements!(SymmetricGroup(3))); A
-6-element Vector{Perm{Int64}}:
- (1,3)
- (1,3)
- (1,3)
- (1,3)
- (1,3)
- (1,3)
-
-julia> unique(A)
-1-element Vector{Perm{Int64}}:
- (1,3)

However, since all permutations yielded by elements! are aliased (modified "in-place"), collect(Generic.elements!(SymmetricGroup(n))) returns a vector of identical permutations.

Note

If you intend to use or store elements yielded by elements! you need to deepcopy them explicitly.

Arithmetic operators

*Method
*(g::Perm, h::Perm)

Return the composition $h ∘ g$ of two permutations.

This corresponds to the action of permutation group on the set [1..n] on the right and follows the convention of GAP.

If g and h are parametrized by different types, the result is promoted accordingly.

Examples

julia> Perm([2,3,1,4])*Perm([1,3,4,2]) # (1,2,3)*(2,3,4)
-(1,3)(2,4)
^Method
^(g::Perm, n::Integer)

Return the $n$-th power of a permutation g.

By default g^n is computed by cycle decomposition of g if n > 3. Generic.power_by_squaring provides a different method for powering which may or may not be faster, depending on the particular case. Due to caching of the cycle structure, repeated powering of g will be faster with the default method.

Examples

julia> g = Perm([2,3,4,5,1])
-(1,2,3,4,5)
-
-julia> g^3
-(1,4,2,5,3)
-
-julia> g^5
-()
invMethod
Base.inv(g::Perm)

Return the inverse of the given permutation, i.e. the permutation $g^{-1}$ such that $g ∘ g^{-1} = g^{-1} ∘ g$ is the identity permutation.

Permutations parametrized by different types can be multiplied, and follow the standard julia integer promotion rules:

g = rand(SymmetricGroup(Int8(5)));
-h = rand(SymmetricGroup(UInt32(5)));
-typeof(g*h)
-
-# output
-Perm{UInt32}

Coercion

The following coercions are available for G::SymmetricGroup parent objects. Each of the methods perform basic sanity checks on the input which can be switched off by the second argument.

Examples

(G::SymmetricGroup)(::AbstractVector{<:Integer}[, check=true])

Turn a vector of integers into a permutation (performing conversion, if necessary).

(G::SymmetricGroup)(::Perm[, check=true])

Coerce a permutation p into group G (performing the conversion, if necessary). If p is already an element of G no copy is performed.

(G::SymmetricGroup)(::String[, check=true])

Parse the string input e.g. copied from the output of GAP. The method uses the same logic as the perm"..." macro. The string is sanitized and checked for disjoint cycles. Both string(p::Perm) (if setpermstyle(:cycles)) and string(cycles(p::Perm)) are valid input for this method.

(G::SymmetricGroup{T})(::CycleDec{T}[, check=true]) where T

Turn a cycle decomposition object into a permutation.

Comparison

==Method
==(g::Perm, h::Perm)

Return true if permutations are equal, otherwise return false.

Permutations parametrized by different integer types are considered equal if they define the same permutation in the abstract permutation group.

Examples

julia> g = Perm(Int8[2,3,1])
-(1,2,3)
-
-julia> h = perm"(3,1,2)"
-(1,2,3)
-
-julia> g == h
-true
==Method
==(G::SymmetricGroup, H::SymmetricGroup)

Return true if permutation groups are equal, otherwise return false.

Permutation groups on the same number of letters, but parametrized by different integer types are considered different.

Examples

julia> G = SymmetricGroup(UInt(5))
-Permutation group over 5 elements
-
-julia> H = SymmetricGroup(5)
-Permutation group over 5 elements
-
-julia> G == H
-false

Misc

randMethod
rand([rng=GLOBAL_RNG,] G::SymmetricGroup)

Return a random permutation from G.

matrix_reprMethod
matrix_repr(a::Perm)

Return the permutation matrix as a sparse matrix representing a via natural embedding of the permutation group into the general linear group over $\mathbb{Z}$.

Examples

julia> p = Perm([2,3,1])
-(1,2,3)
-
-julia> matrix_repr(p)
-3×3 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
- ⋅  1  ⋅
- ⋅  ⋅  1
- 1  ⋅  ⋅
-
-julia> Array(ans)
-3×3 Matrix{Int64}:
- 0  1  0
- 0  0  1
- 1  0  0
matrix_repr(Y::YoungTableau)

Construct sparse integer matrix representing the tableau.

Examples

julia> y = YoungTableau([4,3,1]);
-
-
-julia> matrix_repr(y)
-3×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 8 stored entries:
- 1  2  3  4
- 5  6  7  ⋅
- 8  ⋅  ⋅  ⋅
embMethod
emb(G::SymmetricGroup, V::Vector{Int}, check::Bool=true)

Return the natural embedding of a permutation group into G as the subgroup permuting points indexed by V.

Examples

julia> p = Perm([2,3,1])
-(1,2,3)
-
-julia> f = Generic.emb(SymmetricGroup(5), [3,2,5]);
-
-
-julia> f(p)
-(2,5,3)
emb!Method
emb!(result::Perm, p::Perm, V)

Embed permutation p into permutation result on the indices given by V.

This corresponds to the natural embedding of $S_k$ into $S_n$ as the subgroup permuting points indexed by V.

Examples

julia> p = Perm([2,1,4,3])
-(1,2)(3,4)
-
-julia> Generic.emb!(Perm(collect(1:5)), p, [3,1,4,5])
-(1,3)(4,5)
diff --git a/previews/PR2578/AbstractAlgebra/poly_interface/index.html b/previews/PR2578/AbstractAlgebra/poly_interface/index.html deleted file mode 100644 index 179a97432cf3..000000000000 --- a/previews/PR2578/AbstractAlgebra/poly_interface/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Univariate Polynomial Ring Interface · Oscar.jl

Univariate Polynomial Ring Interface

Univariate polynomial rings are supported in AbstractAlgebra, and in addition to the standard Ring interface, numerous additional functions are required to be present for univariate polynomial rings.

Univariate polynomial rings can be built over both commutative and noncommutative rings.

Univariate polynomial rings over a field are also Euclidean and therefore such rings must implement the Euclidean interface.

Since a sparse distributed multivariate format can generally also handle sparse univariate polynomials, the univariate polynomial interface is designed around the assumption that they are dense. This is not a requirement, but it may be easier to use the multivariate interface for sparse univariate types.

Types and parents

AbstractAlgebra provides two abstract types for polynomial rings and their elements over a commutative ring:

  • PolyRing{T} is the abstract type for univariate polynomial ring parent types
  • PolyRingElem{T} is the abstract type for univariate polynomial types

Similarly there are two abstract types for polynomial rings and their elements over a noncommutative ring:

  • NCPolyRing{T} is the abstract type for univariate polynomial ring parent types
  • NCPolyRingElem{T} is the abstract type for univariate polynomial types

We have that PolyRing{T} <: Ring and PolyRingElem{T} <: RingElem. Similarly we have that NCPolyRing{T} <: NCRing and NCPolyRingElem{T} <: NCRingElem.

Note that the abstract types are parameterised. The type T should usually be the type of elements of the coefficient ring of the polynomial ring. For example, in the case of $\mathbb{Z}[x]$ the type T would be the type of an integer, e.g. BigInt.

If the parent object for such a ring has type MyZX and polynomials in that ring have type MyZXPoly then one would have:

  • MyZX <: PolyRing{BigInt}
  • MyZXPoly <: PolyRingElem{BigInt}

Polynomial rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Polynomial rings should at least be distinguished based on their base (coefficient) ring. But if they have the same base ring and symbol (for their variable/generator), they should certainly have the same parent object.

See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).

Required functionality for univariate polynomials

In addition to the required functionality for the Ring/NCRing interface (and in the case of polynomials over a field, the Euclidean Ring interface), the Polynomial Ring interface has the following required functions.

We suppose that R is a fictitious base ring (coefficient ring) and that S is a univariate polynomial ring over R (i.e. $S = R[x]$) with parent object S of type MyPolyRing{T}. We also assume the polynomials in the ring have type MyPoly{T}, where T is the type of elements of the base (coefficient) ring.

Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.

Note that the type T must (transitively) belong to the abstract type RingElem or NCRingElem.

We describe the functionality below for polynomials over commutative rings, i.e. with element type belonging to RingElem, however similar constructors should be available for element types belonging to NCRingElem instead, if the coefficient ring is noncommutative.

Constructors

In addition to the standard constructors, the following constructors, taking an array of coefficients, must be available.

(S::MyPolyRing{T})(A::Vector{T}) where T <: RingElem
-(S::MyPolyRing{T})(A::Vector{U}) where T <: RingElem, U <: RingElem
-(S::MyPolyRing{T})(A::Vector{U}) where T <: RingElem, U <: Integer

Create the polynomial in the given ring whose degree $i$ coefficient is given by A[1 + i]. The elements of the array are assumed to be able to be coerced into the base ring R. If the argument is an empty vector, the zero polynomial shall be returned.

It may be desirable to have a additional version of the function that accepts an array of Julia Int values if this can be done more efficiently.

It is also possible to create polynomials directly without first creating the corresponding polynomial ring.

polynomial(R::Ring, arr::Vector{T}, var::VarName=:x; cached::Bool=true)

Given an array of coefficients construct the polynomial with those coefficients over the given ring and with the given variable.

Note

If cached is set to false then the parent ring of the created polynomial is not cached. However, this means that subsequent polynomials created in the same way will not be compatible. Instead, one should use the parent object of the first polynomial to create subsequent polynomials instead of calling this function repeatedly with cached=false.

Data type and parent object methods

var(S::MyPolyRing{T}) where T <: RingElem

Return a Symbol representing the variable (generator) of the polynomial ring. Note that this is a Symbol not a String, though its string value will usually be used when printing polynomials.

symbols(S::MyPolyRing{T}) where T <: RingElem

Return the array [s] where s is a Symbol representing the variable of the given polynomial ring. This is provided for uniformity with the multivariate interface, where there is more than one variable and hence an array of symbols.

dense_poly_type(::Type{T}) where T <: RingElement

Return the type of a polynomial whose coefficients have the given type. In our example MyPoly{T}.

This function is defined for generic polynomials and only needs to be defined for custom polynomial rings, e.g. ones defined by a C implementation.

The default implementation figures out the appropriate polynomial ring type via dense_poly_type and calls its constructor with R, s, cached as arguments. In our example, this would be

MyPolyRing{T}(R, s, cached)

Accordingly, polynomial_ring_only only needs to be defined, if such a constructor does not exist or other behaviour is wanted.

Basic manipulation of rings and elements

length(f::MyPoly{T}) where T <: RingElem

Return the length of the given polynomial. The length of the zero polynomial is defined to be $0$, otherwise the length is the degree plus $1$. The return value should be of type Int.

set_length!(f::MyPoly{T}, n::Int) where T <: RingElem

This function must zero any coefficients beyond the requested length $n$ and then set the length of the polynomial to $n$. This function does not need to normalise the polynomial and is not useful to the user, but is used extensively by the AbstractAlgebra generic functionality.

This function returns the resulting polynomial.

coeff(f::MyPoly{T}, n::Int) where T <: RingElem

Return the coefficient of the polynomial f of degree n. If n is larger than the degree of the polynomial, it should return zero in the coefficient ring.

setcoeff!(f::MyPoly{T}, n::Int, a::T) where T <: RingElem

Set the degree $n$ coefficient of $f$ to $a$. This mutates the polynomial in-place if possible and returns the mutated polynomial (so that immutable types can also be supported). The function must not assume that the polynomial already has space for $n + 1$ coefficients. The polynomial must be resized if this is not the case.

Note that this function is not required to normalise the polynomial and is not necessarily useful to the user, but is used extensively by the generic functionality in AbstractAlgebra.jl. It is for setting raw coefficients in the representation.

normalise(f::MyPoly{T}, n::Int) where T <: RingElem

Given a polynomial whose length is currently $n$, including any leading zero coefficients, return the length of the normalised polynomial (either zero or the length of the polynomial with nonzero leading coefficient). Note that the function does not actually perform the normalisation.

fit!(f::MyPoly{T}, n::Int) where T <: RingElem

Ensure that the polynomial $f$ internally has space for $n$ coefficients. This function must mutate the function in-place if it is mutable. It does not return the mutated polynomial. Immutable types can still be supported by defining this function to do nothing.

Some interfaces for C polynomial types automatically manage the internal allocation of polynomials in every function that can be called on them. Explicit adjustment by the generic code in AbstractAlgebra.jl is not required. In such cases, this function can also be defined to do nothing.

Optional functionality for polynomial rings

Sometimes parts of the Euclidean Ring interface can and should be implemented for polynomials over a ring that is not necessarily a field.

When divisibility testing can be implemented for a polynomial ring over a field, it should be possible to implement the following functions from the Euclidean Ring interface:

  • divides
  • remove
  • valuation

When the given polynomial ring is a GCD domain, with an effective GCD algorithm, it may be possible to implement the following functions:

  • gcd
  • lcm

Polynomial rings can optionally implement any part of the generic univariate polynomial functionality provided by AbstractAlgebra.jl, using the same interface.

Obviously additional functionality can also be added to that provided by AbstractAlgebra.jl on an ad hoc basis.

Similar

The similar function is available for all univariate polynomial types, but new polynomial rings can define a specialised version of it if required.

similar(x::MyPoly{T}, R::Ring=base_ring(x), var::VarName=var(parent(x))) where T <: RingElem

Construct the zero polynomial with the given variable and coefficients in the given ring, if specified, and with the defaults shown if not.

Custom polynomial rings may choose which polynomial type is best-suited to return for any given arguments. If they don't specialise the function the default polynomial type returned is a Generic.Poly.

diff --git a/previews/PR2578/AbstractAlgebra/polynomial/index.html b/previews/PR2578/AbstractAlgebra/polynomial/index.html deleted file mode 100644 index 9172409e2c9e..000000000000 --- a/previews/PR2578/AbstractAlgebra/polynomial/index.html +++ /dev/null @@ -1,508 +0,0 @@ - -Univariate polynomial functionality · Oscar.jl

Univariate polynomial functionality

AbstractAlgebra.jl provides a module, implemented in src/Poly.jl for polynomials over any commutative ring belonging to the AbstractAlgebra abstract type hierarchy. This functionality will work for any univariate polynomial type which follows the Univariate Polynomial Ring interface.

Generic univariate polynomial types

AbstractAlgebra.jl provides a generic polynomial type based on Julia arrays which is implemented in src/generic/Poly.jl.

These generic polynomials have type Generic.Poly{T} where T is the type of elements of the coefficient ring. Internally they consist of a Julia array of coefficients and some additional fields for length and a parent object, etc. See the file src/generic/GenericTypes.jl for details.

Parent objects of such polynomials have type Generic.PolyRing{T}.

The string representation of the variable of the polynomial ring and the base/coefficient ring $R$ is stored in the parent object.

Abstract types

All univariate polynomial element types belong to the abstract type PolyRingElem{T} and the polynomial ring types belong to the abstract type PolyRing{T}. This enables one to write generic functions that can accept any AbstractAlgebra polynomial type.

Note

Both the generic polynomial ring type Generic.PolyRing{T} and the abstract type it belongs to, PolyRing{T}, are called PolyRing. The former is a (parameterised) concrete type for a polynomial ring over a given base ring whose elements have type T. The latter is an abstract type representing all polynomial ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).

Polynomial ring constructors

In order to construct polynomials in AbstractAlgebra.jl, one must first construct the polynomial ring itself. This is accomplished with the following constructor.

polynomial_ringMethod
polynomial_ring(R::NCRing, s::VarName; cached::Bool = true)

Given a base ring R and symbol/string s specifying how the generator (variable) should be printed, return a tuple S, x representing the new polynomial ring $S = R[x]$ and the generator $x$ of the ring.

By default the parent object S depends only on R and x and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Examples

julia> R, x = polynomial_ring(ZZ, :x)
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, :y)
-(Univariate polynomial ring in y over univariate polynomial ring, y)

A shorthand version of this function is provided: given a base ring R, we abbreviate the constructor as follows.

R[:x]

It is also possible to create a polynomial ring with default symbol as follows. This is a lightweight constructor and should be used in generic algorithms wherever possible when creating polynomial rings where the symbol does not matter.

PolyRing(R::Ring)

Given a base ring R return the polynomial ring $S = R[x]$. Note that unlike the constructors above, the return type is not a tuple. Only the ring is returned and not the generator. The polynomial ring is not cached.

Here are some examples of creating polynomial rings and their associated generators.

Examples

julia> T, z = QQ["z"]
-(Univariate polynomial ring in z over rationals, z)
-
-julia> U = PolyRing(ZZ)
-Univariate polynomial ring in x over integers

All of the examples here are generic polynomial rings, but specialised implementations of polynomial rings provided by external modules will also usually provide a polynomial_ring constructor to allow creation of their polynomial rings.

Polynomial constructors

Once a polynomial ring is constructed, there are various ways to construct polynomials in that ring.

The easiest way is simply using the generator returned by the polynomial_ring constructor and build up the polynomial using basic arithmetic.

The Julia language has special syntax for the construction of polynomials in terms of a generator, e.g. we can write 2x instead of 2*x.

A second way is to use the polynomial ring to construct a polynomial. There are the usual ways of constructing an element of a ring.

(R::PolyRing)() # constructs zero
-(R::PolyRing)(c::Integer)
-(R::PolyRing)(c::elem_type(R))
-(R::PolyRing{T})(a::T) where T <: RingElement

For polynommials there is also the following more general constructor accepting an array of coefficients.

(S::PolyRing{T})(A::Vector{T}) where T <: RingElem
-(S::PolyRing{T})(A::Vector{U}) where T <: RingElem, U <: RingElem
-(S::PolyRing{T})(A::Vector{U}) where T <: RingElem, U <: Integer

Construct the polynomial in the ring S with the given array of coefficients, i.e. where A[1] is the constant coefficient.

A third way of constructing polynomials is to construct them directly without creating the polynomial ring.

polynomial(R::Ring, arr::Vector{T}, var::VarName=:x; cached::Bool=true)

Given an array of coefficients construct the polynomial with those coefficients over the given ring and with the given variable.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = x^3 + 3x + 21
-x^3 + 3*x + 21
-
-julia> g = (x + 1)*y^2 + 2x + 1
-(x + 1)*y^2 + 2*x + 1
-
-julia> R()
-0
-
-julia> S(1)
-1
-
-julia> S(y)
-y
-
-julia> S(x)
-x
-
-julia> S, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> f = S(Rational{BigInt}[2, 3, 1])
-x^2 + 3*x + 2
-
-julia> g = S(BigInt[1, 0, 4])
-4*x^2 + 1
-
-julia> h = S([4, 7, 2, 9])
-9*x^3 + 2*x^2 + 7*x + 4
-
-julia> p = polynomial(ZZ, [1, 2, 3])
-3*x^2 + 2*x + 1
-
-julia> f = polynomial(ZZ, [1, 2, 3], "y")
-3*y^2 + 2*y + 1

Similar and zero

Another way of constructing polynomials is to construct one similar to an existing polynomial using either similar or zero.

similar(x::MyPoly{T}, R::Ring=base_ring(x)) where T <: RingElem
-zero(x::MyPoly{T}, R::Ring=base_ring(x)) where T <: RingElem

Construct the zero polynomial with the same variable as the given polynomial with coefficients in the given ring. Both functions behave the same way for polynomials.

similar(x::MyPoly{T}, R::Ring, var::VarName=var(parent(x))) where T <: RingElem
-similar(x::MyPoly{T}, var::VarName=var(parent(x))) where T <: RingElem
-zero(x::MyPoly{T}, R::Ring, var::VarName=var(parent(x))) where T <: RingElem
-zero(x::MyPoly{T}, var::VarName=var(parent(x))) where T <: RingElem

Construct the zero polynomial with the given variable and coefficients in the given ring, if specified, and in the coefficient ring of the given polynomial otherwise.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> f = 1 + 2x + 3x^2
-3*x^2 + 2*x + 1
-
-julia> g = similar(f)
-0
-
-julia> h = similar(f, QQ)
-0
-
-julia> k = similar(f, QQ, "y")
-0

Functions for types and parents of polynomial rings

base_ring(R::PolyRing)
-base_ring(a::PolyRingElem)

Return the coefficient ring of the given polynomial ring or polynomial.

parent(a::NCRingElement)

Return the polynomial ring of the given polynomial..

characteristic(R::NCRing)

Return the characteristic of the given polynomial ring. If the characteristic is not known, an exception is raised.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> U = base_ring(S)
-Univariate polynomial ring in x over integers
-
-julia> V = base_ring(y + 1)
-Univariate polynomial ring in x over integers
-
-julia> T = parent(y + 1)
-Univariate polynomial ring in y over univariate polynomial ring

Euclidean polynomial rings

For polynomials over a field, the Euclidean Ring Interface is implemented.

mod(f::PolyRingElem, g::PolyRingElem)
-divrem(f::PolyRingElem, g::PolyRingElem)
-div(f::PolyRingElem, g::PolyRingElem)
mulmod(f::PolyRingElem, g::PolyRingElem, m::PolyRingElem)
-powermod(f::PolyRingElem, e::Int, m::PolyRingElem)
-invmod(f::PolyRingElem, m::PolyRingElem)
divides(f::PolyRingElem, g::PolyRingElem)
-remove(f::PolyRingElem, p::PolyRingElem)
-valuation(f::PolyRingElem, p::PolyRingElem)
gcd(f::PolyRingElem, g::PolyRingElem)
-lcm(f::PolyRingElem, g::PolyRingElem)
-gcdx(f::PolyRingElem, g::PolyRingElem)
-gcdinv(f::PolyRingElem, g::PolyRingElem)

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = residue_ring(R, x^3 + 3x + 1)
-Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> T, y = polynomial_ring(S, "y")
-(Univariate polynomial ring in y over residue ring, y)
-
-julia> f = (3*x^2 + x + 2)*y + x^2 + 1
-(3*x^2 + x + 2)*y + x^2 + 1
-
-julia> g = (5*x^2 + 2*x + 1)*y^2 + 2x*y + x + 1
-(5*x^2 + 2*x + 1)*y^2 + 2*x*y + x + 1
-
-julia> h = (3*x^3 + 2*x^2 + x + 7)*y^5 + 2x*y + 1
-(2*x^2 - 8*x + 4)*y^5 + 2*x*y + 1
-
-julia> invmod(f, g)
-(707//3530*x^2 + 2151//1765*x + 123//3530)*y - 178//1765*x^2 - 551//3530*x + 698//1765
-
-julia> mulmod(f, g, h)
-(-30*x^2 - 43*x - 9)*y^3 + (-7*x^2 - 23*x - 7)*y^2 + (4*x^2 - 10*x - 3)*y + x^2 - 2*x
-
-julia> powermod(f, 3, h)
-(69*x^2 + 243*x + 79)*y^3 + (78*x^2 + 180*x + 63)*y^2 + (27*x^2 + 42*x + 18)*y + 3*x^2 + 3*x + 2
-
-julia> h = mod(f, g)
-(3*x^2 + x + 2)*y + x^2 + 1
-
-julia> q, r = divrem(f, g)
-(0, (3*x^2 + x + 2)*y + x^2 + 1)
-
-julia> div(g, f)
-(-5//11*x^2 + 2//11*x + 6//11)*y - 13//121*x^2 - 3//11*x - 78//121
-
-julia> d = gcd(f*h, g*h)
-y + 1//11*x^2 + 6//11
-
-julia> k = gcdinv(f, h)
-(y + 1//11*x^2 + 6//11, 0)
-
-julia> m = lcm(f, h)
-(-14*x^2 - 23*x - 2)*y - 4*x^2 - 5*x + 1
-
-julia> flag, q = divides(g^2, g)
-(true, (5*x^2 + 2*x + 1)*y^2 + 2*x*y + x + 1)
-
-julia> valuation(3g^3, g) == 3
-true
-
-julia> val, q = remove(5g^3, g)
-(3, 5)
-
-julia> r, s, t = gcdx(g, h)
-(1, 311//3530*x^2 - 2419//3530*x + 947//1765, (707//3530*x^2 + 2151//1765*x + 123//3530)*y - 178//1765*x^2 - 551//3530*x + 698//1765)
-

Functions in the Euclidean Ring interface are supported over residue rings that are not fields, except that if an impossible inverse is encountered during the computation an error is thrown.

Polynomial functions

Basic functionality

All basic ring functionality is provided for polynomials. The most important such functions are the following.

zero(R::PolyRing)
-one(R::PolyRing)
-iszero(a::PolyRingElem)
-isone(a::PolyRingElem)
divexact(a::T, b::T) where T <: PolyRingElem

All functions in the polynomial interface are provided. The most important are the following.

var(S::PolyRing)
-symbols(S::PolyRing{T}) where T <: RingElem

Return a symbol or length 1 array of symbols, respectively, specifying the variable of the polynomial ring. This symbol is converted to a string when printing polynomials in that ring.

In addition, the following basic functions are provided.

modulusMethod
modulus(a::PolyRingElem{T}) where {T <: ResElem}

Return the modulus of the coefficients of the given polynomial.

leading_coefficientMethod
leading_coefficient(a::PolynomialElem)

Return the leading coefficient of the given polynomial. This will be the nonzero coefficient of the term with highest degree unless the polynomial in the zero polynomial, in which case a zero coefficient is returned.

leading_coefficient(p::MPolyRingElem)

Return the leading coefficient of the polynomial $p$.

trailing_coefficientMethod
trailing_coefficient(a::PolynomialElem)

Return the trailing coefficient of the given polynomial. This will be the nonzero coefficient of the term with lowest degree unless the polynomial is the zero polynomial, in which case a zero coefficient is returned.

trailing_coefficient(p::MPolyRingElem)

Return the trailing coefficient of the polynomial $p$, i.e. the coefficient of the last nonzero term, or zero if the polynomial is zero.

constant_coefficientMethod
constant_coefficient(a::PolynomialElem)

Return the constant coefficient of the given polynomial. If the polynomial is the zero polynomial, the function will return zero.

set_coefficient!Method
set_coefficient!(c::PolynomialElem{T}, n::Int, a::T) where T <: RingElement
-set_coefficient!(c::PolynomialElem{T}, n::Int, a::U) where {T <: RingElement, U <: Integer}

Set the coefficient of degree $n$ to $a$.

tailMethod
tail(a::PolynomialElem)

Return the tail of the given polynomial, i.e. the polynomial without its leading term (if any).

genMethod
gen(M::SubquoModule{T}, i::Int) where T

Return the ith generator of M.

source
gen(a::MPolyRing{T}, i::Int) where {T <: RingElement}

Return the $i$-th generator (variable) of the given polynomial ring.

gen(R::AbsPowerSeriesRing{T}) where T <: RingElement

Return the generator of the power series ring, i.e. $x + O(x^n)$ where $n$ is the precision of the power series ring $R$.

is_genMethod
is_gen(x::MPoly{T}) where {T <: RingElement}

Return true if the given polynomial is a generator (variable) of the polynomial ring it belongs to.

is_gen(a::PolynomialElem)

Return true if the given polynomial is the constant generator of its polynomial ring, otherwise return false.

is_monicMethod
is_monic(a::PolynomialElem)

Return true if the given polynomial is monic, i.e. has leading coefficient equal to one, otherwise return false.

is_squareMethod
is_square(f::PolyRingElem{T}) where T <: RingElement

Return true if $f$ is a perfect square.

is_square(a::FracElem{T}) where T <: RingElem

Return true if $a$ is a square.

lengthMethod
length(a::PolynomialElem)

Return the length of the polynomial. The length of a univariate polynomial is defined to be the number of coefficients in its dense representation, including zero coefficients. Thus naturally the zero polynomial has length zero and additionally for nonzero polynomials the length is one more than the degree. (Note that the leading coefficient will always be nonzero.)

degreeMethod
degree(a::PolynomialElem)

Return the degree of the given polynomial. This is defined to be one less than the length, even for constant polynomials.

is_monomialMethod
is_monomial(a::PolynomialElem)

Return true if the given polynomial is a monomial.

is_monomial(x::AbstractAlgebra.MPolyRingElem)

Return true if the given polynomial has precisely one term whose coefficient is one.

is_monomial_recursiveMethod
is_monomial_recursive(a::PolynomialElem)

Return true if the given polynomial is a monomial. This function is recursive, with all scalar types returning true.

is_termMethod
is_term(a::PolynomialElem)

Return true if the given polynomial has one term.

is_term(x::MPoly)

Return true if the given polynomial has precisely one term.

is_term_recursiveMethod
is_term_recursive(a::PolynomialElem)

Return true if the given polynomial has one term. This function is recursive, with all scalar types returning true.

is_constantMethod
is_constant(a::PolynomialElem)

Return true if a is a degree zero polynomial or the zero polynomial, i.e. a constant polynomial.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> T, z = polynomial_ring(QQ, "z")
-(Univariate polynomial ring in z over rationals, z)
-
-julia> U = residue_ring(ZZ, 17)
-Residue ring of integers modulo 17
-
-julia> V, w = polynomial_ring(U, "w")
-(Univariate polynomial ring in w over residue ring, w)
-
-julia> var(R)
-:x
-
-julia> symbols(R)
-1-element Vector{Symbol}:
- :x
-
-julia> a = zero(S)
-0
-
-julia> b = one(S)
-1
-
-julia> isone(b)
-true
-
-julia> c = BigInt(1)//2*z^2 + BigInt(1)//3
-1//2*z^2 + 1//3
-
-julia> d = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + 3
-
-julia> f = leading_coefficient(d)
-x
-
-julia> y = gen(S)
-y
-
-julia> g = is_gen(w)
-true
-
-julia> divexact((2x + 1)*(x + 1), (x + 1))
-2*x + 1
-
-julia> m = is_unit(b)
-true
-
-julia> n = degree(d)
-2
-
-julia> r = modulus(w)
-17
-
-julia> is_term(2y^2)
-true
-
-julia> is_monomial(y^2)
-true
-
-julia> is_monomial_recursive(x*y^2)
-true
-
-julia> is_monomial(x*y^2)
-false
-
-julia> S, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> f = x^3 + 3x + 1
-x^3 + 3*x + 1
-
-julia> g = S(BigInt[1, 2, 0, 1, 0, 0, 0]);
-
-julia> n = length(f)
-4
-
-julia> c = coeff(f, 1)
-3
-
-julia> g = set_coefficient!(g, 2, ZZ(11))
-x^3 + 11*x^2 + 2*x + 1
-
-julia> g = set_coefficient!(g, 7, ZZ(4))
-4*x^7 + x^3 + 11*x^2 + 2*x + 1

Iterators

An iterator is provided to return the coefficients of a univariate polynomial. The iterator is called coefficients and allows iteration over the coefficients, starting with the term of degree zero (if there is one). Note that coefficients of each degree are given, even if they are zero. This is best illustrated by example.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> f = x^2 + 2
-x^2 + 2
-
-julia> C = collect(coefficients(f))
-3-element Vector{BigInt}:
- 2
- 0
- 1
-
-julia> for c in coefficients(f)
-          println(c)
-       end
-2
-0
-1

Truncation

truncateMethod
truncate(a::PolynomialElem, n::Int)

Return $a$ truncated to $n$ terms, i.e. the remainder upon division by $x^n$.

mullowMethod
mullow(a::PolyRingElem{T}, b::PolyRingElem{T}, n::Int) where T <: RingElement

Return $a\times b$ truncated to $n$ terms.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + 3
-
-julia> g = (x + 1)*y + (x^3 + 2x + 2)
-(x + 1)*y + x^3 + 2*x + 2
-
-julia> h = truncate(f, 1)
-3
-
-julia> k = mullow(f, g, 4)
-(x^2 + x)*y^3 + (x^4 + 3*x^2 + 4*x + 1)*y^2 + (x^4 + x^3 + 2*x^2 + 7*x + 5)*y + 3*x^3 + 6*x + 6
-

Reversal

reverseMethod
reverse(x::PolynomialElem, len::Int)

Return the reverse of the polynomial $x$, thought of as a polynomial of the given length (the polynomial will be notionally truncated or padded with zeroes before the leading term if necessary to match the specified length). The resulting polynomial is normalised. If len is negative we throw a DomainError().

reverseMethod
reverse(x::PolynomialElem)

Return the reverse of the polynomial $x$, i.e. the leading coefficient of $x$ becomes the constant coefficient of the result, etc. The resulting polynomial is normalised.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + 3
-
-julia> g = reverse(f, 7)
-3*y^6 + (x + 1)*y^5 + x*y^4
-
-julia> h = reverse(f)
-3*y^2 + (x + 1)*y + x
-

Shifting

shift_leftMethod
shift_left(f::PolynomialElem, n::Int)

Return the polynomial $f$ shifted left by $n$ terms, i.e. multiplied by $x^n$.

shift_rightMethod
shift_right(f::PolynomialElem, n::Int)

Return the polynomial $f$ shifted right by $n$ terms, i.e. divided by $x^n$.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + 3
-
-julia> g = shift_left(f, 7)
-x*y^9 + (x + 1)*y^8 + 3*y^7
-
-julia> h = shift_right(f, 2)
-x
-

Inflation and deflation

deflationMethod
deflation(p::PolyRingElem)

Return a tuple (shift, defl) where shift is the exponent of the trailing term of $p$ and defl is the gcd of the distance between the exponents of the nonzero terms of $p$. If $p = 0$, both shift and defl will be zero.

inflateMethod
inflate(f::PolyRingElem, shift::Int64, n::Int64) -> PolyRingElem

Given a polynomial $f$ in $x$, return $f(x^n)*x^j$, i.e. multiply all exponents by $n$ and shift $f$ left by $j$.

inflateMethod
inflate(f::PolyRingElem, n::Int64) -> PolyRingElem

Given a polynomial $f$ in $x$, return $f(x^n)$, i.e. multiply all exponents by $n$.

deflateMethod
deflate(f::PolyRingElem, shift::Int64, n::Int64) -> PolyRingElem

Given a polynomial $g$ in $x^n$ such that f = g(x)*x^{shift}, write $f$ as a polynomial in $x$, i.e. divide all exponents of $g$ by $n$.

deflateMethod
deflate(f::PolyRingElem, n::Int64) -> PolyRingElem

Given a polynomial $f$ in $x^n$, write it as a polynomial in $x$, i.e. divide all exponents by $n$.

deflateMethod
deflate(x::PolyRingElem) -> PolyRingElem, Int

Deflate the polynomial $f$ maximally, i.e. find the largest $n$ s.th. $f$ can be deflated by $n$, i.e. $f$ is actually a polynomial in $x^n$. Return $g, n$ where $g$ is the deflation of $f$.

Square root

sqrtMethod
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement

Return the square root of the given Puiseux series $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Base.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement

Return the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.

Examples

R, x = polynomial_ring(ZZ, "x")
-g = x^2+6*x+1
-sqrt(g^2)

Change of base ring

change_base_ringMethod
change_base_ring(R::Ring, p::PolyRingElem{<: RingElement}; parent::PolyRing)

Return the polynomial obtained by coercing the non-zero coefficients of p into R.

If the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

change_coefficient_ringMethod
change_coefficient_ring(R::Ring, p::PolyRingElem{<: RingElement}; parent::PolyRing)

Return the polynomial obtained by coercing the non-zero coefficients of p into R.

If the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

map_coefficientsMethod
map_coefficients(f, p::PolyRingElem{<: RingElement}; cached::Bool=true, parent::PolyRing)

Transform the polynomial p by applying f on each non-zero coefficient.

If the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

Examples

R, x = polynomial_ring(ZZ, "x")
-g = x^3+6*x + 1
-change_base_ring(GF(2), g)
-change_coefficient_ring(GF(2), g)

Pseudodivision

Given two polynomials $a, b$, pseudodivision computes polynomials $q$ and $r$ with length$(r) <$ length$(b)$ such that $L^d a = bq + r,$ where $d =$ length$(a) -$ length$(b) + 1$ and $L$ is the leading coefficient of $b$.

We call $q$ the pseudoquotient and $r$ the pseudoremainder.

pseudoremMethod
pseudorem(f::PolyRingElem{T}, g::PolyRingElem{T}) where T <: RingElement

Return the pseudoremainder of $f$ divided by $g$. If $g = 0$ we throw a DivideError().

pseudodivremMethod
pseudodivrem(f::PolyRingElem{T}, g::PolyRingElem{T}) where T <: RingElement

Return a tuple $(q, r)$ consisting of the pseudoquotient and pseudoremainder of $f$ divided by $g$. If $g = 0$ we throw a DivideError().

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + 3
-
-julia> g = (x + 1)*y + (x^3 + 2x + 2)
-(x + 1)*y + x^3 + 2*x + 2
-
-julia> h = pseudorem(f, g)
-x^7 + 3*x^5 + 2*x^4 + x^3 + 5*x^2 + 4*x + 1
-
-julia> q, r = pseudodivrem(f, g)
-((x^2 + x)*y - x^4 - x^2 + 1, x^7 + 3*x^5 + 2*x^4 + x^3 + 5*x^2 + 4*x + 1)
-

Content and primitive part

contentMethod
content(a::PolyRingElem)

Return the content of $a$, i.e. the greatest common divisor of its coefficients.

primpartMethod
primpart(a::PolyRingElem)

Return the primitive part of $a$, i.e. the polynomial divided by its content.

Examples

R, x = polynomial_ring(ZZ, "x")
-S, y = polynomial_ring(R, "y")
-
-k = x*y^2 + (x + 1)*y + 3
-
-n = content(k)
-p = primpart(k*(x^2 + 1))

Evaluation, composition and substitution

evaluateMethod
evaluate(a::PolyRingElem, b::T) where T <: RingElement

Evaluate the polynomial expression $a$ at the value $b$ and return the result.

evaluateMethod
evaluate(a::PolyRingElem, b::T) where T <: RingElement

Evaluate the polynomial expression $a$ at the value $b$ and return the result.

composeMethod
compose(a::PolyRingElem, b::PolyRingElem)

Compose the polynomial $a$ with the polynomial $b$ and return the result, i.e. return $a\circ b$.

substMethod
subst(f::PolyRingElem{T}, a::Any) where T <: RingElement

Evaluate the polynomial $f$ at $a$. Note that $a$ can be anything, whether a ring element or not.

We also overload the functional notation so that the polynomial $f$ can be evaluated at $a$ by writing $f(a)$.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + 3
-
-julia> g = (x + 1)*y + (x^3 + 2x + 2)
-(x + 1)*y + x^3 + 2*x + 2
-
-julia> M = R[x + 1 2x; x - 3 2x - 1]
-[x + 1       2*x]
-[x - 3   2*x - 1]
-
-julia> k = evaluate(f, 3)
-12*x + 6
-
-julia> m = evaluate(f, x^2 + 2x + 1)
-x^5 + 4*x^4 + 7*x^3 + 7*x^2 + 4*x + 4
-
-julia> n = compose(f, g)
-(x^3 + 2*x^2 + x)*y^2 + (2*x^5 + 2*x^4 + 4*x^3 + 9*x^2 + 6*x + 1)*y + x^7 + 4*x^5 + 5*x^4 + 5*x^3 + 10*x^2 + 8*x + 5
-
-julia> p = subst(f, M)
-[3*x^3 - 3*x^2 + 3*x + 4       6*x^3 + 2*x^2 + 2*x]
-[3*x^3 - 8*x^2 - 2*x - 3   6*x^3 - 8*x^2 + 2*x + 2]
-
-julia> q = f(M)
-[3*x^3 - 3*x^2 + 3*x + 4       6*x^3 + 2*x^2 + 2*x]
-[3*x^3 - 8*x^2 - 2*x - 3   6*x^3 - 8*x^2 + 2*x + 2]
-
-julia> r = f(23)
-552*x + 26
-

Derivative and integral

derivativeMethod
derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the derivative of the given Puiseux series $a$.

derivative(a::PolynomialElem)

Return the derivative of the polynomial $a$.

derivative(f::AbsPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

derivative(f::RelPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

julia> R, x = power_series_ring(QQ, 10, "x")
-(Univariate power series ring in x over Rationals, x + O(x^11))
-
-julia> f = 2 + x + 3x^3
-2 + x + 3*x^3 + O(x^10)
-
-julia> derivative(f)
-1 + 9*x^2 + O(x^9)
derivative(f::AbstractAlgebra.MPolyRingElem{T}, j::Int) where {T <: RingElement}

Return the partial derivative of f with respect to $j$-th variable of the polynomial ring.

derivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.

derivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable of index $n$.

derivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable $v$.

integralMethod
integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the integral of the given Puiseux series $a$.

integral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem

Return the integral of the power series $f$.

integral(x::PolyRingElem{T}) where {T <: Union{ResElem, FieldElement}}

Return the integral of the polynomial $x$.

integral(f::AbsPowerSeriesRingElem{T})

Return the integral of the power series $f$.

integral(f::RelPowerSeriesRingElem{T})

Return the integral of the power series $f$.

julia> R, x = power_series_ring(QQ, 10, "x")
-(Univariate power series ring in x over Rationals, x + O(x^11))
-
-julia> f = 2 + x + 3x^3
-2 + x + 3*x^3 + O(x^10)
-
-julia> integral(f)
-2*x + 1//2*x^2 + 3//4*x^4 + O(x^11)

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> T, z = polynomial_ring(QQ, "z")
-(Univariate polynomial ring in z over rationals, z)
-
-julia> U = residue_ring(T, z^3 + 3z + 1)
-Residue ring of univariate polynomial ring modulo z^3 + 3*z + 1
-
-julia> V, w = polynomial_ring(U, "w")
-(Univariate polynomial ring in w over residue ring, w)
-
-julia> f = x*y^2 + (x + 1)*y + 3
-x*y^2 + (x + 1)*y + 3
-
-julia> g = (z^2 + 2z + 1)*w^2 + (z + 1)*w - 2z + 4
-(z^2 + 2*z + 1)*w^2 + (z + 1)*w - 2*z + 4
-
-julia> h = derivative(f)
-2*x*y + x + 1
-
-julia> k = integral(g)
-(1//3*z^2 + 2//3*z + 1//3)*w^3 + (1//2*z + 1//2)*w^2 + (-2*z + 4)*w
-

Resultant and discriminant

sylvester_matrixMethod
sylvester_matrix(p::PolyRingElem, q::PolyRingElem)

Return the sylvester matrix of the given polynomials.

resultantMethod
resultant(p::PolyRingElem{T}, q::PolyRingElem{T}) where T <: RingElement

Return the resultant of the given polynomials.

resxMethod
resx(a::PolyRingElem{T}, b::PolyRingElem{T}) where T <: RingElement

Return a tuple $(r, s, t)$ such that $r$ is the resultant of $a$ and $b$ and such that $r = a\times s + b\times t$.

discriminantMethod
discriminant(a::PolyRingElem)

Return the discriminant of the given polynomial.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = 3x*y^2 + (x + 1)*y + 3
-3*x*y^2 + (x + 1)*y + 3
-
-julia> g = 6(x + 1)*y + (x^3 + 2x + 2)
-(6*x + 6)*y + x^3 + 2*x + 2
-
-julia> S = sylvester_matrix(f, g)
-[    3*x           x + 1               3]
-[6*x + 6   x^3 + 2*x + 2               0]
-[      0         6*x + 6   x^3 + 2*x + 2]
-
-julia> h = resultant(f, g)
-3*x^7 + 6*x^5 - 6*x^3 + 96*x^2 + 192*x + 96
-
-julia> k = discriminant(f)
-x^2 - 34*x + 1
-

Newton representation

monomial_to_newton!Method
monomial_to_newton!(P::Vector{T}, roots::Vector{T}) where T <: RingElement

Converts a polynomial $p$, given as an array of coefficients, in-place from its coefficients given in the standard monomial basis to the Newton basis for the roots $r_0, r_1, \ldots, r_{n-2}$. In other words, this determines output coefficients $c_i$ such that $c_0 + c_1(x-r_0) + c_2(x-r_0)(x-r_1) + \ldots + c_{n-1}(x-r_0)(x-r_1)\cdots(x-r_{n-2})$ is equal to the input polynomial.

newton_to_monomial!Method
newton_to_monomial!(P::Vector{T}, roots::Vector{T}) where T <: RingElement

Converts a polynomial $p$, given as an array of coefficients, in-place from its coefficients given in the Newton basis for the roots $r_0, r_1, \ldots, r_{n-2}$ to the standard monomial basis. In other words, this evaluates $c_0 + c_1(x-r_0) + c_2(x-r_0)(x-r_1) + \ldots + c_{n-1}(x-r_0)(x-r_1)\cdots(x-r_{n-2})$ where $c_i$ are the input coefficients given by $p$.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = 3x*y^2 + (x + 1)*y + 3
-3*x*y^2 + (x + 1)*y + 3
-
-julia> g = deepcopy(f)
-3*x*y^2 + (x + 1)*y + 3
-
-julia> roots = [R(1), R(2), R(3)]
-3-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:
- 1
- 2
- 3
-
-julia> monomial_to_newton!(g.coeffs, roots)
-
-julia> newton_to_monomial!(g.coeffs, roots)

Roots

rootsMethod
roots(f::PolyRingElem)

Returns the roots of the polynomial f in the base ring of f as an array.

rootsMethod
roots(R::Field, f::PolyRingElem)

Returns the roots of the polynomial f in the field R as an array.

Interpolation

interpolateMethod
interpolate(S::PolyRing, x::Vector{T}, y::Vector{T}) where T <: RingElement

Given two arrays of values $xs$ and $ys$ of the same length $n$, find the polynomial $f$ in the polynomial ring $R$ of length at most $n$ such that $f$ has the value $ys$ at the points $xs$. The values in the arrays $xs$ and $ys$ must belong to the base ring of the polynomial ring $R$. If no such polynomial exists, an exception is raised.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> xs = [R(1), R(2), R(3), R(4)]
-4-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:
- 1
- 2
- 3
- 4
-
-julia> ys = [R(1), R(4), R(9), R(16)]
-4-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:
- 1
- 4
- 9
- 16
-
-julia> f = interpolate(S, xs, ys)
-y^2
-

Power sums

polynomial_to_power_sumsMethod
polynomial_to_power_sums(f::PolyRingElem{T}, n::Int=degree(f)) where T <: RingElement -> Vector{T}

Uses Newton (or Newton-Girard) formulas to compute the first $n$ sums of powers of the roots of $f$ from the coefficients of $f$, starting with the sum of (first powers of) the roots. The input polynomial must be monic, at least degree $1$ and have nonzero constant coefficient.

power_sums_to_polynomialMethod
power_sums_to_polynomial(P::Vector{T};
-                 parent::AbstractAlgebra.PolyRing{T}=

AbstractAlgebra.PolyRing(parent(P[1])) where T <: RingElement -> PolyRingElem{T}

Uses the Newton (or Newton-Girard) identities to obtain the polynomial with given sums of powers of roots. The list must be nonempty and contain degree(f) entries where $f$ is the polynomial to be recovered. The list must start with the sum of first powers of the roots.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> f = x^4 - 2*x^3 + 10*x^2 + 7*x - 5
-x^4 - 2*x^3 + 10*x^2 + 7*x - 5
-
-julia> V = polynomial_to_power_sums(f)
-4-element Vector{BigInt}:
-   2
- -16
- -73
-  20
-
-julia> power_sums_to_polynomial(V)
-x^4 - 2*x^3 + 10*x^2 + 7*x - 5

Special functions

The following special functions can be computed for any polynomial ring. Typically one uses the generator $x$ of a polynomial ring to get the respective special polynomials expressed in terms of that generator.

chebyshev_tMethod
chebyshev_t(n::Int, x::PolyRingElem)

Return the Chebyshev polynomial of the first kind $T_n(x)$, defined by $T_n(x) = \cos(n \cos^{-1}(x))$.

chebyshev_uMethod
chebyshev_u(n::Int, x::PolyRingElem)

Return the Chebyshev polynomial of the first kind $U_n(x)$, defined by $(n+1) U_n(x) = T'_{n+1}(x)$.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> f = chebyshev_t(20, y)
-524288*y^20 - 2621440*y^18 + 5570560*y^16 - 6553600*y^14 + 4659200*y^12 - 2050048*y^10 + 549120*y^8 - 84480*y^6 + 6600*y^4 - 200*y^2 + 1
-
-julia> g = chebyshev_u(15, y)
-32768*y^15 - 114688*y^13 + 159744*y^11 - 112640*y^9 + 42240*y^7 - 8064*y^5 + 672*y^3 - 16*y
-

Random generation

One may generate random polynomials with degrees in a given range. Additional parameters are used to construct coefficients as elements of the coefficient ring.

rand(R::PolyRing, deg_range::UnitRange{Int}, v...)
-rand(R::PolyRing, deg::Int, v...)

Examples

R, x = polynomial_ring(ZZ, "x")
-f = rand(R, -1:3, -10:10)
-
-S, y = polynomial_ring(GF(7), "y")
-g = rand(S, 2:2)
-
-U, z = polynomial_ring(R, "z")
-h = rand(U, 3:3, -1:2, -10:10)
diff --git a/previews/PR2578/AbstractAlgebra/puiseux/index.html b/previews/PR2578/AbstractAlgebra/puiseux/index.html deleted file mode 100644 index 872dbf52901c..000000000000 --- a/previews/PR2578/AbstractAlgebra/puiseux/index.html +++ /dev/null @@ -1,157 +0,0 @@ - -Generic Puiseux series · Oscar.jl

Generic Puiseux series

AbstractAlgebra.jl allows the creation of Puiseux series over any computable commutative ring $R$.

Puiseux series are power series of the form $a_jx^{j/m} + a_{j+1}x^{(j+1)/m} + \cdots + a_{k-1}x^{(k-1)/m} + O(x^{k/m})$ for some integer $m > 0$ where $i \geq 0$, $a_i \in R$ and the relative precision $k - j$ is at most equal to some specified precision $n$.

The generic Puiseux series module is implemented in src/generic/PuiseuxSeries.jl.

As well as implementing the Series Ring interface, the Puiseux series module in AbstractAlgebra.jl implements the generic algorithms described below.

All of the generic functionality is part of the Generic submodule of AbstractAlgebra.jl. This is exported by default so that it is not necessary to qualify function names.

Types and parent objects

The types of generic Puiseux series implemented by AbstractAlgebra.jl are Generic.PuiseuxSeriesRingElem{T} and Generic.PuiseuxSeriesFieldElem{T}.

Both series element types belong to the union type Generic.PuiseuxSeriesElem.

Puiseux series elements belong directly to either RingElem or FieldElem since it is more useful to be able to distinguish whether they belong to a ring or field than it is to distinguish that they are Puiseux series.

The parent types for Puiseux series, Generic.PuiseuxSeriesRing{T} and Generic.PuiseuxSeriesField{T} respectively, belong to Ring and Field respectively.

The default precision, string representation of the variable and base ring $R$ of a generic Puiseux series are stored in its parent object.

Puiseux series ring constructors

In order to construct Puiseux series in AbstractAlgebra.jl, one must first construct the ring itself. This is accomplished with any of the following constructors.

PuiseuxSeriesRing(R::Ring, prec_max::Int, s::VarName; cached::Bool = true)
PuiseuxSeriesRing(R::Field, prec_max::Int, s::VarName; cached::Bool = true)
PuiseuxSeriesField(R::Field, prec_max::Int, s::VarName; cached::Bool = true)

Given a base ring R, a maximum relative precision and a string s specifying how the generator (variable) should be printed, return a tuple S, x representing the Puiseux series ring and its generator.

By default, S will depend only on S, x and the maximum precision and will be cached. Setting the optional argument cached to false will prevent this.

Here are some examples of constructing various kinds of Puiseux series rings and coercing various elements into those rings.

Examples

julia> R, x = PuiseuxSeriesRing(ZZ, 10, "x")
-(Puiseux series ring in x over integers, x + O(x^11))
-
-julia> S, y = PuiseuxSeriesField(QQ, 10, "y")
-(Puiseux series field in y over rationals, y + O(y^11))
-
-julia> f = R()
-O(x^10)
-
-julia> g = S(123)
-123 + O(y^10)
-
-julia> h = R(BigInt(1234))
-1234 + O(x^10)
-
-julia> k = S(y + 1)
-1 + y + O(y^10)
-

Big-oh notation

Series elements can be given a precision using the big-oh notation. This is provided by a function of the following form, (or something equivalent for Laurent series):

O(x::SeriesElem)

Examples

julia> R, x = PuiseuxSeriesRing(ZZ, 10, "x")
-(Puiseux series ring in x over integers, x + O(x^11))
-
-julia> f = 1 + 2x + O(x^5)
-1 + 2*x + O(x^5)
-
-julia> g = 2x^(1//3) + 7x^(2//3) + O(x^(7//3))
-2*x^(1//3) + 7*x^(2//3) + O(x^(7//3))

What is happening here in practice is that O(x^n) is creating the series 0 + O(x^n) and the rules for addition of series dictate that if this is added to a series of greater precision, then the lower of the two precisions must be used.

Of course it may be that the precision of the series that O(x^n) is added to is already lower than n, in which case adding O(x^n) has no effect. This is the case if the default precision is too low, since x on its own has the default precision.

Puiseux series implementation

Puiseux series have their maximum relative precision capped at some value prec_max. This refers to the internal Laurent series used to store the Puiseux series, i.e. the series without denominators in the exponents.

The Puiseux series type stores such a Laurent series and a scale or denominator for the exponents. For example, $f(x) = 1 + x^{1/3} + 2x^{2/3} + O(x^{7/3})$ would be stored as a Laurent series $1 + x + 2x^2 + O(x^7)$ and a scale of $3$..

The maximum precision is also used as a default (Laurent) precision in the case of coercing coefficients into the ring and for any computation where the result could mathematically be given to infinite precision.

In all models we say that two Puiseux series are equal if they agree up to the minimum absolute precision of the two power series.

Thus, for example, $x^5 + O(x^{10}) == 0 + O(x^5)$, since the minimum absolute precision is $5$.

Sometimes it is necessary to compare Puiseux series not just for arithmetic equality, as above, but to see if they have precisely the same precision and terms. For this purpose we introduce the isequal function.

For example, if $f = x^2 + O(x^7)$ and $g = x^2 + O(x^8)$ and $h = 0 + O(x^2)$ then $f == g$, $f == h$ and $g == h$, but isequal(f, g), isequal(f, h) and isequal(g, h) would all return false. However, if $k = x^2 + O(x^7)$ then isequal(f, k) would return true.

There are a number of technicalities that must be observed when working with Puiseux series. As these are the same as for the other series rings in AbstractAlgebra.jl, we refer the reader to the documentation of series rings for information about these issues.

Basic ring functionality

All Puiseux series provide the functionality described in the Ring and Series Ring interfaces with the exception of the pol_length and polcoeff functions. Naturally the set_precision!, set_valuation! and coeff functions can take a rational exponent.

Examples

julia> S, x = PuiseuxSeriesRing(ZZ, 10, "x")
-(Puiseux series ring in x over integers, x + O(x^11))
-
-julia> f = 1 + 3x + x^3 + O(x^10)
-1 + 3*x + x^3 + O(x^10)
-
-julia> g = 1 + 2x^(1//3) + x^(2//3) + O(x^(7//3))
-1 + 2*x^(1//3) + x^(2//3) + O(x^(7//3))
-
-julia> h = zero(S)
-O(x^10)
-
-julia> k = one(S)
-1 + O(x^10)
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> coeff(g, 1//3)
-2
-
-julia> U = base_ring(S)
-Integers
-
-julia> v = var(S)
-:x
-
-julia> T = parent(x + 1)
-Puiseux series ring in x over integers
-
-julia> g == deepcopy(g)
-true
-
-julia> t = divexact(2g, 2)
-1 + 2*x^(1//3) + x^(2//3) + O(x^(7//3))
-
-julia> p = precision(f)
-10//1
-

Puiseux series functionality provided by AbstractAlgebra.jl

The functionality below is automatically provided by AbstractAlgebra.jl for any Puiseux series.

Of course, modules are encouraged to provide specific implementations of the functions described here, that override the generic implementation.

Basic functionality

coeff(a::Generic.PuiseuxSeriesElem, n::Int)
coeff(a::Generic.PuiseuxSeriesElem, n::Rational{Int})

Return the coefficient of the term of exponent $n$ of the given power series. If $n$ exceeds the current precision of the power series or does not correspond to a nonzero term of the Puiseux series, the function returns a zero coefficient.

modulusMethod
modulus(a::Generic.PuiseuxSeriesElem{T}) where {T <: ResElem}

Return the modulus of the coefficients of the given Puiseux series.

is_genMethod
is_gen(a::Generic.PuiseuxSeriesElem)

Return true if the given Puiseux series is arithmetically equal to the generator of its Puiseux series ring to its current precision, otherwise return false.

Examples

julia> R, t = PuiseuxSeriesRing(QQ, 10, "t")
-(Puiseux series field in t over rationals, t + O(t^11))
-
-julia> S, x = PuiseuxSeriesRing(R, 30, "x")
-(Puiseux series field in x over puiseux series field, x + O(x^31))
-
-julia> a = O(x^4)
-O(x^4)
-
-julia> b = (t + 3)*x + (t^2 + 1)*x^2 + O(x^4)
-(3 + t + O(t^10))*x + (1 + t^2 + O(t^10))*x^2 + O(x^4)
-
-julia> k = is_gen(gen(R))
-true
-
-julia> m = is_unit(-1 + x^(1//3) + 2x^2)
-true
-
-julia> n = valuation(a)
-4//1
-
-julia> p = valuation(b)
-1//1
-
-julia> c = coeff(b, 2)
-1 + t^2 + O(t^10)
-

Division

invMethod
Base.inv(a::PuiseuxSeriesElem{T}) where T <: RingElement

Return the inverse of the power series $a$, i.e. $1/a$, if it exists. Otherwise an exception is raised.

 inv(a::LocElem{T}, checked::Bool = true)  where {T <: RingElem}

Returns the inverse element of $a$ if $a$ is a unit. If 'checked = false' the invertibility of $a$ is not checked and the corresponding inverse element of the Fraction Field is returned.

inv(f::EllCrvIso) -> EllCrvIso

Return the inverse of the isomorphism $f$.

inv(M::MatrixElem{T}) where {T <: RingElement}

Given a non-singular $n\times n$ matrix over a ring, return an $n\times n$ matrix $X$ such that $MX = I_n$, where $I_n$ is the $n\times n$ identity matrix. If $M$ is not invertible over the base ring an exception is raised.

Examples

julia> R, x = PuiseuxSeriesRing(QQ, 30, "x")
-(Puiseux series field in x over rationals, x + O(x^31))
-
-julia> a = 1 + x + 2x^2 + O(x^5)
-1 + x + 2*x^2 + O(x^5)
-
-julia> b = R(-1)
--1 + O(x^30)
-
-julia> c = inv(a)
-1 - x - x^2 + 3*x^3 - x^4 + O(x^5)
-
-julia> d = inv(b)
--1 + O(x^30)
-

Derivative and integral

derivativeMethod
derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the derivative of the given Puiseux series $a$.

derivative(f::AbsPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

derivative(f::RelPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

julia> R, x = power_series_ring(QQ, 10, "x")
-(Univariate power series ring in x over Rationals, x + O(x^11))
-
-julia> f = 2 + x + 3x^3
-2 + x + 3*x^3 + O(x^10)
-
-julia> derivative(f)
-1 + 9*x^2 + O(x^9)
derivative(f::AbstractAlgebra.MPolyRingElem{T}, j::Int) where {T <: RingElement}

Return the partial derivative of f with respect to $j$-th variable of the polynomial ring.

derivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.

derivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable of index $n$.

derivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable $v$.

integralMethod
integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the integral of the given Puiseux series $a$.

integral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem

Return the integral of the power series $f$.

integral(f::AbsPowerSeriesRingElem{T})

Return the integral of the power series $f$.

integral(f::RelPowerSeriesRingElem{T})

Return the integral of the power series $f$.

julia> R, x = power_series_ring(QQ, 10, "x")
-(Univariate power series ring in x over Rationals, x + O(x^11))
-
-julia> f = 2 + x + 3x^3
-2 + x + 3*x^3 + O(x^10)
-
-julia> integral(f)
-2*x + 1//2*x^2 + 3//4*x^4 + O(x^11)

Examples

julia> R, x = PuiseuxSeriesRing(QQ, 10, "x")
-(Puiseux series field in x over rationals, x + O(x^11))
-
-julia> f = x^(5//3) + x^(7//3) + x^(11//3)
-x^(5//3) + x^(7//3) + x^(11//3) + O(x^5)
-
-julia> derivative(f)
-5//3*x^(2//3) + 7//3*x^(4//3) + 11//3*x^(8//3) + O(x^4)
-
-julia> derivative(integral(f)) == f
-true

Special functions

logMethod
log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the logarithm of the given Puiseux series $a$.

expMethod
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

sqrtMethod
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement

Return the square root of the given Puiseux series $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Base.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement

Return the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.

Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S, x = PuiseuxSeriesRing(R, 30, "x")
-(Puiseux series ring in x over univariate polynomial ring, x + O(x^31))
-
-julia> T, z = PuiseuxSeriesRing(QQ, 30, "z")
-(Puiseux series field in z over rationals, z + O(z^31))
-
-julia> a = 1 + z + 3z^2 + O(z^5)
-1 + z + 3*z^2 + O(z^5)
-
-julia> b = z + 2z^2 + 5z^3 + O(z^5)
-z + 2*z^2 + 5*z^3 + O(z^5)
-
-julia> c = exp(x + O(x^40))
-1 + x + 1//2*x^2 + 1//6*x^3 + 1//24*x^4 + 1//120*x^5 + 1//720*x^6 + 1//5040*x^7 + 1//40320*x^8 + 1//362880*x^9 + 1//3628800*x^10 + 1//39916800*x^11 + 1//479001600*x^12 + 1//6227020800*x^13 + 1//87178291200*x^14 + 1//1307674368000*x^15 + 1//20922789888000*x^16 + 1//355687428096000*x^17 + 1//6402373705728000*x^18 + 1//121645100408832000*x^19 + 1//2432902008176640000*x^20 + 1//51090942171709440000*x^21 + 1//1124000727777607680000*x^22 + 1//25852016738884976640000*x^23 + 1//620448401733239439360000*x^24 + 1//15511210043330985984000000*x^25 + 1//403291461126605635584000000*x^26 + 1//10888869450418352160768000000*x^27 + 1//304888344611713860501504000000*x^28 + 1//8841761993739701954543616000000*x^29 + 1//265252859812191058636308480000000*x^30 + O(x^31)
-
-julia> d = divexact(x, exp(x + O(x^40)) - 1)
-1 - 1//2*x + 1//12*x^2 - 1//720*x^4 + 1//30240*x^6 - 1//1209600*x^8 + 1//47900160*x^10 - 691//1307674368000*x^12 + 1//74724249600*x^14 - 3617//10670622842880000*x^16 + 43867//5109094217170944000*x^18 - 174611//802857662698291200000*x^20 + 77683//14101100039391805440000*x^22 - 236364091//1693824136731743669452800000*x^24 + 657931//186134520519971831808000000*x^26 - 3392780147//37893265687455865519472640000000*x^28 + O(x^29)
-
-julia> f = exp(b)
-1 + z + 5//2*z^2 + 43//6*z^3 + 193//24*z^4 + O(z^5)
-
-julia> h = sqrt(a)
-1 + 1//2*z + 11//8*z^2 - 11//16*z^3 - 77//128*z^4 + O(z^5)
-
diff --git a/previews/PR2578/AbstractAlgebra/quotient_module/index.html b/previews/PR2578/AbstractAlgebra/quotient_module/index.html deleted file mode 100644 index 07808cc18ac9..000000000000 --- a/previews/PR2578/AbstractAlgebra/quotient_module/index.html +++ /dev/null @@ -1,69 +0,0 @@ - -Quotient modules · Oscar.jl

Quotient modules

AbstractAlgebra allows the construction of quotient modules/spaces of AbstractAlgebra modules over euclidean domains. These are given as the quotient of a module by a submodule of that module.

We define two quotient modules to be equal if they are quotients of the same module $M$ by two equal submodules.

Generic quotient module type

AbstractAlgebra implements the generic quotient module type Generic.QuotientModule{T} where T is the element type of the base ring, in src/generic/QuotientModule.jl.

Elements of generic quotient modules have type Generic.QuotientModuleElem{T}.

Abstract types

Quotient module types belong to the FPModule{T} abstract type and their elements to FPModuleElem{T}.

Constructors

quoMethod
quo(m::FPModule{T}, subm::FPModule{T}) where T <: RingElement

Return the quotient M of the module m by the module subm (which must have been (transitively) constructed as a submodule of m or be m itself) along with the canonical quotient map from m to M.

Note that a preimage of the canonical projection can be obtained using the preimage function described in the section on module homomorphisms. Note that a preimage element of the canonical projection is not unique and has no special properties.

Examples

julia> M = FreeModule(ZZ, 2)
-Free module of rank 2 over integers
-
-julia> m = M([ZZ(1), ZZ(2)])
-(1, 2)
-
-julia> N, f = sub(M, [m])
-(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)
-
-julia> Q, g = quo(M, N)
-(Quotient module over Integers with 1 generator and no relations, Hom: Free module of rank 2 over integers -> Quotient module over Integers with 1 generator and no relations)
-
-julia> p = M([ZZ(3), ZZ(1)])
-(3, 1)
-
-julia> v2 = g(p)
-(-5)
-
-julia> V = VectorSpace(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> m = V([QQ(1), QQ(2)])
-(1//1, 2//1)
-
-julia> N, f = sub(V, [m])
-(Subspace over Rationals with 1 generator and no relations, Hom: Subspace over Rationals with 1 generator and no relations -> Vector space of dimension 2 over rationals)
-
-julia> Q, g = quo(V, N)
-(Quotient space over:
-Rationals with 1 generator and no relations, Hom: Vector space of dimension 2 over rationals -> Quotient space over:
-Rationals with 1 generator and no relations)
-

Functionality for submodules

In addition to the Module interface, AbstractAlgebra submodules implement the following functionality.

Basic manipulation

supermoduleMethod
supermodule(M::QuotientModule{T}) where T <: RingElement

Return the module that this module is a quotient of.

dimMethod
dim(N::QuotientModule{T}) where T <: FieldElement

Return the dimension of the given vector quotient space.

Examples

julia> M = FreeModule(ZZ, 2)
-Free module of rank 2 over integers
-
-julia> m = M([ZZ(2), ZZ(3)])
-(2, 3)
-
-julia> N, g = sub(M, [m])
-(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)
-
-julia> Q, h = quo(M, N)
-(Quotient module over Integers with 2 generators and relations:
-[2 3], Hom: Free module of rank 2 over integers -> Quotient module over Integers with 2 generators and relations:
-[2 3])
-
-julia> supermodule(Q) == M
-true
-
-julia> V = VectorSpace(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> m = V([QQ(1), QQ(2)])
-(1//1, 2//1)
-
-julia> N, f = sub(V, [m])
-(Subspace over Rationals with 1 generator and no relations, Hom: Subspace over Rationals with 1 generator and no relations -> Vector space of dimension 2 over rationals)
-
-julia> Q, g = quo(V, N)
-(Quotient space over:
-Rationals with 1 generator and no relations, Hom: Vector space of dimension 2 over rationals -> Quotient space over:
-Rationals with 1 generator and no relations)
-
-julia> dim(V)
-2
-
-julia> dim(Q)
-1
-
diff --git a/previews/PR2578/AbstractAlgebra/rand/index.html b/previews/PR2578/AbstractAlgebra/rand/index.html deleted file mode 100644 index 109b91ba8adf..000000000000 --- a/previews/PR2578/AbstractAlgebra/rand/index.html +++ /dev/null @@ -1,53 +0,0 @@ - -Random interface · Oscar.jl

Random interface

AbstractAlgebra makes use of the Julia Random interface for random generation.

In addition we make use of an experimental package RandomExtensions.jl for extending the random interface in Julia.

The latter is required because some of our types require more than one argument to specify how to randomise them.

The usual way of generating random values that Julia and these extensions provide would look as follows:

julia> using AbstractAlgebra
-
-julia> using Random
-
-julia> using RandomExtensions
-
-julia> S, x = polynomial_ring(ZZ, "x")
-(Univariate Polynomial Ring in x over Integers, x)
-
-julia> rand(Random.GLOBAL_RNG, make(S, 1:3, -10:10))
--5*x + 4

This example generates a polynomial over the integers with degree in the range 1 to 3 and with coefficients in the range -10 to 10.

In addition we implement shortened versions for ease of use which don't require creating a make instance or passing in the standard RNG.

julia> using AbstractAlgebra
-
-julia> S, x = polynomial_ring(ZZ, "x")
-(Univariate Polynomial Ring in x over Integers, x)
-
-julia> rand(S, 1:3, -10:10)
--5*x + 4

Because rings can be constructed over other rings in a tower, all of this is supported by defining RandomExtensions.make instances that break the various levels of the ring down into separate make instances.

For example, here is the implementation of make for polynomial rings such as the above:

function RandomExtensions.make(S::PolyRing, deg_range::UnitRange{Int}, vs...)
-   R = base_ring(S)
-   if length(vs) == 1 && elem_type(R) == Random.gentype(vs[1])
-      Make(S, deg_range, vs[1]) # forward to default Make constructor
-   else
-      make(S, deg_range, make(R, vs...))
-   end
-end

As you can see, it has two cases. The first is where this invocation of make is already at the bottom of the tower of rings, in which case it just forwards to the default Make constructor.

The second case expects that we are higher up in the tower of rings and that make needs to be broken up (recursively) into the part that deals with the ring level we are at and the level that deals with the base ring.

To help make we tell it the type of object we are hoping to randomly generate.

RandomExtensions.maketype(S::PolyRing, dr::UnitRange{Int}, _) = elem_type(S)

Finally we implement the actual random generation itself.

# define rand for make(S, deg_range, v)
-function rand(rng::AbstractRNG, sp::SamplerTrivial{<:Make3{<:RingElement,<:PolyRing,UnitRange{Int}}})
-   S, deg_range, v = sp[][1:end]
-   R = base_ring(S)
-   f = S()
-   x = gen(S)
-   # degree -1 is zero polynomial
-   deg = rand(rng, deg_range)
-   if deg == -1
-      return f
-   end
-   for i = 0:deg - 1
-      f += rand(rng, v)*x^i
-   end
-   # ensure leading coefficient is nonzero
-   c = R()
-   while iszero(c)
-      c = rand(rng, v)
-   end
-   f += c*x^deg
-   return f
-end

Note that when generating random elements of the base ring for example, one should use the random number generator rng that is passed in.

As mentioned above, we define a simplified random generator that saves the user having to create make instances.

rand(rng::AbstractRNG, S::PolyRing, deg_range::UnitRange{Int}, v...) =
-   rand(rng, make(S, deg_range, v...))
-
-rand(S::PolyRing, degs, v...) = rand(Random.GLOBAL_RNG, S, degs, v...)

To test whether a random generator is working properly, the test_rand function exists in the AbstractAlgebra test submodule in the file test/runtests.jl. For example, in AbstractAlgebra test code:

using Test
-
-R, x = polynomial_ring(ZZ, "x")
-
-test_rand(R, -1:10, -10:10)

In general, we try to use UnitRange's to specify how 'big' we want the random instance to be, e.g. the range of degrees a polynomial could take, the range random integers could lie in, etc. The objective is to make it easy for the user to control the 'size' of random values in test code.

diff --git a/previews/PR2578/AbstractAlgebra/rational/index.html b/previews/PR2578/AbstractAlgebra/rational/index.html deleted file mode 100644 index 71ef6d8dd335..000000000000 --- a/previews/PR2578/AbstractAlgebra/rational/index.html +++ /dev/null @@ -1,58 +0,0 @@ - -Rational field · Oscar.jl

Rational field

AbstractAlgebra.jl provides a module, implemented in src/julia/Rational.jl for making Julia Rational{BigInt}s conform to the AbstractAlgebra.jl Field interface.

In addition to providing a parent object QQ for Julia Rational{BigInt}s, we implement any additional functionality required by AbstractAlgebra.jl.

Because Rational{BigInt} cannot be directly included in the AbstractAlgebra.jl abstract type hierarchy, we achieve integration of Julia Rational{BigInt}s by introducing a type union, called FieldElement, which is a union of FieldElem and a number of Julia types, including Rational{BigInt}. Everywhere that FieldElem is notionally used in AbstractAlgebra.jl, we are in fact using FieldElement, with additional care being taken to avoid ambiguities.

The details of how this is done are technical, and we refer the reader to the implementation for details. For most intents and purposes, one can think of the Julia Rational{BigInt} type as belonging to FieldElem.

One other technicality is that Julia defines certain functions for Rational{BigInt}, such as sqrt and exp differently to what AbstractAlgebra.jl requires. To get around this, we redefine these functions internally to AbstractAlgebra.jl, without redefining them for users of AbstractAlgebra.jl. This allows the internals of AbstractAlgebra.jl to function correctly, without broadcasting pirate definitions of already defined Julia functions to the world.

To access the internal definitions, one can use AbstractAlgebra.sqrt and AbstractAlgebra.exp, etc.

Types and parent objects

Rationals have type Rational{BigInt}, as in Julia itself. We simply supplement the functionality for this type as required for computer algebra.

The parent objects of such integers has type Rationals{BigInt}.

For convenience, we also make Rational{Int} a part of the AbstractAlgebra.jl type hierarchy and its parent object (accessible as qq) has type Rationals{Int}. But we caution that this type is not particularly useful as a model of the rationals and may not function as expected within AbstractAlgebra.jl.

Rational constructors

In order to construct rationals in AbstractAlgebra.jl, one can first construct the rational field itself. This is accomplished using either of the following constructors.

fraction_field(R::Integers{BigInt})
Rationals{BigInt}()

This gives the unique object of type Rationals{BigInt} representing the field of rationals in AbstractAlgebra.jl.

In practice, one simply uses QQ which is assigned to be the return value of the above constructor. There is no need to call the constructor in practice.

Here are some examples of creating the rational field and making use of the resulting parent object to coerce various elements into the field.

Examples

julia> f = QQ()
-0//1
-
-julia> g = QQ(123)
-123//1
-
-julia> h = QQ(BigInt(1234))
-1234//1
-
-julia> k = QQ(BigInt(12), BigInt(7))
-12//7
-
-julia> QQ == fraction_field(ZZ)
-true
-

Basic field functionality

The rational field in AbstractAlgebra.jl implements the full Field and Fraction Field interfaces.

We give some examples of such functionality.

Examples

julia> f = QQ(12, 7)
-12//7
-
-julia> h = zero(QQ)
-0//1
-
-julia> k = one(QQ)
-1//1
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> U = base_ring(QQ)
-Integers
-
-julia> V = base_ring(f)
-Integers
-
-julia> T = parent(f)
-Rationals
-
-julia> f == deepcopy(f)
-true
-
-julia> g = f + 12
-96//7
-
-julia> r = ZZ(12)//ZZ(7)
-12//7
-
-julia> n = numerator(r)
-12
-

Rational functionality provided by AbstractAlgebra.jl

The functionality below supplements that provided by Julia itself for its Rational{BigInt} type.

Square and n-th root

The functions sqrt, is_square, is_square_with_sqrt are all provided, as are root, is_power and is_power_with_root.

Examples

julia> d = AbstractAlgebra.sqrt(ZZ(36)//ZZ(25))
-6//5
-
-julia> is_square(ZZ(9)//ZZ(16))
-true
-
-julia> root(ZZ(27)//64, 3)
-3//4
diff --git a/previews/PR2578/AbstractAlgebra/real/index.html b/previews/PR2578/AbstractAlgebra/real/index.html deleted file mode 100644 index 5834b0d5cc22..000000000000 --- a/previews/PR2578/AbstractAlgebra/real/index.html +++ /dev/null @@ -1,51 +0,0 @@ - -Real field · Oscar.jl

Real field

AbstractAlgebra.jl provides a module, implemented in src/julia/Float.jl for making Julia BigFloats conform to the AbstractAlgebra.jl Field interface.

In addition to providing a parent object RealField for Julia BigFloats, we implement any additional functionality required by AbstractAlgebra.jl.

Because BigFloat cannot be directly included in the AbstractAlgebra.jl abstract type hierarchy, we achieve integration of Julia BigFloats by introducing a type union, called FieldElement, which is a union of FieldElem and a number of Julia types, including BigFloat. Everywhere that FieldElem is notionally used in AbstractAlgebra.jl, we are in fact using FieldElement, with additional care being taken to avoid ambiguities.

The details of how this is done are technical, and we refer the reader to the implementation for details. For most intents and purposes, one can think of the Julia BigFloat type as belonging to FieldElem.

Types and parent objects

Reals have type BigFloat, as in Julia itself. We simply supplement the functionality for this type as required for computer algebra.

The parent objects of such integers has type Floats{BigFloat}.

For convenience, we also make Float64 a part of the AbstractAlgebra.jl type hierarchy and its parent object (accessible as RDF) has type Floats{Float64}.

Rational constructors

In order to construct reals in AbstractAlgebra.jl, one can first construct the real field itself. This is accomplished using the following constructor.

Floats{BigFloat}()

This gives the unique object of type Floats{BigFloat} representing the field of reals in AbstractAlgebra.jl.

In practice, one simply uses RealField which is assigned to be the return value of the above constructor. There is no need to call the constructor in practice.

Here are some examples of creating the real field and making use of the resulting parent object to coerce various elements into the field.

Examples

julia> RR = RealField
-Floats
-
-julia> f = RR()
-0.0
-
-julia> g = RR(123)
-123.0
-
-julia> h = RR(BigInt(1234))
-1234.0
-
-julia> k = RR(12//7)
-1.714285714285714285714285714285714285714285714285714285714285714285714285714291
-
-julia> m = RR(2.3)
-2.29999999999999982236431605997495353221893310546875
-

Basic field functionality

The real field in AbstractAlgebra.jl implements the full Field interface.

We give some examples of such functionality.

Examples

julia> RR = RealField
-Floats
-
-julia> f = RR(12//7)
-1.714285714285714285714285714285714285714285714285714285714285714285714285714291
-
-julia> h = zero(RR)
-0.0
-
-julia> k = one(RR)
-1.0
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> U = base_ring(RR)
-Union{}
-
-julia> T = parent(f)
-Floats
-
-julia> f == deepcopy(f)
-true
-
-julia> g = f + 12
-13.71428571428571428571428571428571428571428571428571428571428571428571428571433
-
-julia> m = inv(g)
-0.07291666666666666666666666666666666666666666666666666666666666666666666666666631
-
diff --git a/previews/PR2578/AbstractAlgebra/residue/index.html b/previews/PR2578/AbstractAlgebra/residue/index.html deleted file mode 100644 index 4dca07515e49..000000000000 --- a/previews/PR2578/AbstractAlgebra/residue/index.html +++ /dev/null @@ -1,132 +0,0 @@ - -Generic residue rings · Oscar.jl

Generic residue rings

AbstractAlgebra.jl provides modules, implemented in src/Residue.jl and src/residue_field for residue rings and fields, respectively, over any Euclidean domain (in practice most of the functionality is provided for GCD domains that provide a meaningful GCD function) belonging to the AbstractAlgebra.jl abstract type hierarchy.

Generic residue types

AbstractAlgebra.jl implements generic residue rings with type Generic.ResidueRingElem{T} or in the case of residue rings that are known to be fields, Generic.ResidueFieldElem{T}, where T is the type of elements of the base ring. See the file src/generic/GenericTypes.jl for details.

Parent objects of generic residue ring elements have type Generic.ResidueRing{T} and those of residue fields have type GenericResField{T}.

The defining modulus of the residue ring is stored in the parent object.

Abstract types

All residue element types belong to the abstract type ResElem{T} or ResFieldElem{T} in the case of residue fields, and the residue ring types belong to the abstract type ResidueRing{T} or ResidueField{T} respectively. This enables one to write generic functions that can accept any AbstractAlgebra residue type.

Note

Note that both the generic residue ring type Generic.ResidueRing{T} and the abstract type it belongs to, ResidueRing{T} are both called ResidueRing, and similarly for the residue field types. In each case, the former is a (parameterised) concrete type for a residue ring over a given base ring whose elements have type T. The latter is an abstract type representing all residue ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).

Residue ring constructors

In order to construct residues in AbstractAlgebra.jl, one must first construct the residue ring itself. This is accomplished with one of the following constructors.

residue_ring(R::Ring, m::RingElem; cached::Bool = true)
residue_field(R::Ring, m::RingElem; cached::Bool = true)

Given a base ring R and residue $m$ contained in this ring, return the parent object of the residue ring $R/(m)$. By default the parent object S will depend only on R and m and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

The residue_field constructor does the same thing as the residue_ring constructor, but the resulting object has type belonging to Field rather than Ring, so it can be used anywhere a field is expected in AbstractAlgebra.jl. No check is made for maximality of the ideal generated by $m$.

There are also the following for constructing residue rings and fields.

quoMethod
quo(R::Ring, a::RingElement; cached::Bool = true)

Returns S, f where S = residue_ring(R, a) and f is the projection map from R to S. This map is supplied as a map with section where the section is the lift of an element of the residue field back to the ring R.

quoMethod
quo(::Type{Field}, R::Ring, a::RingElement; cached::Bool = true)

Returns S, f where S = residue_field(R, a) and f is the projection map from R to S. This map is supplied as a map with section where the section is the lift of an element of the residue field back to the ring R.

Here are some examples of creating residue rings and making use of the resulting parent objects to coerce various elements into the residue ring.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = residue_ring(R, x^3 + 3x + 1)
-Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> f = S()
-0
-
-julia> g = S(123)
-123
-
-julia> h = S(BigInt(1234))
-1234
-
-julia> k = S(x + 1)
-x + 1
-
-julia> U, f = quo(R, x^3 + 3x + 1)
-(Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1, Map with section with the following data
-
-Domain:
-=======
-Univariate polynomial ring in x over rationals
-
-Codomain:
-========
-Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1)
-
-julia> U === S
-true

All of the examples here are generic residue rings, but specialised implementations of residue rings provided by external modules will also usually provide a residue_ring constructor to allow creation of their residue rings.

Residue constructors

One can use the parent objects of a residue ring to construct residues, as per any ring.

(R::ResidueRing)() # constructs zero
-(R::ResidueRing)(c::Integer)
-(R::ResidueRing)(c::elem_type(R))
-(R::ResidueRing{T})(a::T) where T <: RingElement

Functions for types and parents of residue rings

base_ring(R::ResidueRing)
-base_ring(a::ResElem)

Return the base ring over which the ring was constructed.

parent(a::ResElem)

Return the parent of the given residue.

characteristic(R::ResidueRing)

Return the characteristic of the given residue ring. If the characteristic is not known, an exception is raised.

Residue ring functions

Basic functionality

Residue rings implement the Ring interface.

zero(R::NCRing)
-one(R::NCRing)
-iszero(a::NCRingElement)
-isone(a::NCRingElement)
divexact(a::T, b::T) where T <: RingElement
-inv(a::T)

The Residue Ring interface is also implemented.

modulus(S::ResidueRing)
data(f::ResElem)
-lift(f::ResElem)

Return a lift of the residue to the base ring.

The following functions are also provided for residues.

modulusMethod
modulus(R::ResElem)

Return the modulus $a$ of the residue ring $S = R/(a)$ that the supplied residue $r$ belongs to.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = residue_ring(R, x^3 + 3x + 1)
-Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> f = S(x + 1)
-x + 1
-
-julia> h = zero(S)
-0
-
-julia> k = one(S)
-1
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> is_unit(f)
-true
-
-julia> m = modulus(S)
-x^3 + 3*x + 1
-
-julia> d = data(f)
-x + 1
-
-julia> U = base_ring(S)
-Univariate polynomial ring in x over rationals
-
-julia> V = base_ring(f)
-Univariate polynomial ring in x over rationals
-
-julia> T = parent(f)
-Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> f == deepcopy(f)
-true
-
-julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)

Inversion

invMethod
Base.inv(a::ResElem)

Return the inverse of the element $a$ in the residue ring. If an impossible inverse is encountered, an exception is raised.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = residue_ring(R, x^3 + 3x + 1)
-Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> f = S(x + 1)
-x + 1
-
-julia> g = inv(f)
-1//3*x^2 - 1//3*x + 4//3
-

Greatest common divisor

gcdMethod
gcd(a::ResElem{T}, b::ResElem{T}) where {T <: RingElement}

Return a greatest common divisor of $a$ and $b$ if one exists. This is done by taking the greatest common divisor of the data associated with the supplied residues and taking its greatest common divisor with the modulus.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = residue_ring(R, x^3 + 3x + 1)
-Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> f = S(x + 1)
-x + 1
-
-julia> g = S(x^2 + 2x + 1)
-x^2 + 2*x + 1
-
-julia> h = gcd(f, g)
-1
-

Square Root

is_squareMethod
is_square(a::ResFieldElem{T}) where T <: Integer

Return true if $a$ is a square.

sqrtMethod
sqrt(a::ResFieldElem{T}; check::Bool=true) where T <: Integer

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Examples

julia> R = residue_field(ZZ, 733)
-Residue field of Integers modulo 733
-
-julia> a = R(86)
-86
-
-julia> is_square(a)
-true
-
-julia> sqrt(a)
-532

Random generation

Random residues can be generated using rand. The parameters after the residue ring are used to generate elements of the base ring.

rand(R::ResidueRing, v...)

Examples

julia> R = residue_ring(ZZ, 7)
-Residue ring of integers modulo 7
-
-julia> f = rand(R, 0:6)
-4
-
-julia> S, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> U = residue_field(S, x^3 + 3x + 1)
-Residue field of univariate polynomial ring modulo x^3 + 3*x + 1
-
-julia> g = rand(S, 2:2, -10:10)
--1//4*x^2 - 2//7*x + 1
diff --git a/previews/PR2578/AbstractAlgebra/residue_interface/index.html b/previews/PR2578/AbstractAlgebra/residue_interface/index.html deleted file mode 100644 index 6344e1543572..000000000000 --- a/previews/PR2578/AbstractAlgebra/residue_interface/index.html +++ /dev/null @@ -1,3 +0,0 @@ - -Residue Ring Interface · Oscar.jl

Residue Ring Interface

Residue rings (currently a quotient ring modulo a principal ideal) are supported in AbstractAlgebra.jl, at least for Euclidean base rings. There is also partial support for residue rings of polynomial rings where the modulus has invertible leading coefficient.

In addition to the standard Ring interface, some additional functions are required to be present for residue rings.

Types and parents

AbstractAlgebra provides four abstract types for residue rings and their elements:

  • ResidueRing{T} is the abstract type for residue ring parent types
  • ResidueField{T} is the abstract type for residue rings known to be fields
  • ResElem{T} is the abstract type for types of elements of residue rings (residues)
  • ResFieldElem{T} is the abstract type for types of elements of residue fields

We have that ResidueRing{T} <: AbstractAlgebra.Ring and ResElem{T} <: AbstractAlgebra.RingElem.

Note that these abstract types are parameterised. The type T should usually be the type of elements of the base ring of the residue ring/field.

If the parent object for a residue ring has type MyResRing and residues in that ring have type MyRes then one would have:

  • MyResRing <: ResidueRing{BigInt}
  • MyRes <: ResElem{BigInt}

Residue rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Residue rings should at least be distinguished based on their base ring and modulus (the principal ideal one is taking a quotient of the base ring by).

See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).

Required functionality for residue rings

In addition to the required functionality for the Ring interface the Residue Ring interface has the following required functions.

We suppose that R is a fictitious base ring, $m$ is an element of that ring, and that S is the residue ring (quotient ring) $R/(m)$ with parent object S of type MyResRing{T}. We also assume the residues $r \pmod{m}$ in the residue ring have type MyRes{T}, where T is the type of elements of the base ring.

Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.

Note that the type T must (transitively) belong to the abstract type RingElem.

Data type and parent object methods

modulus(S::MyResRing{T}) where T <: AbstractAlgebra.RingElem

Return the modulus of the given residue ring, i.e. if the residue ring $S$ was specified to be $R/(m)$, return $m$.

Basic manipulation of rings and elements

data(f::MyRes{T}) where T <: RingElem
-lift(f::MyRes{T}) where T <: RingElem

Given a residue $r \pmod{m}$, represented as such, return $r$. In the special case where machine integers are used to represent the residue, data will return the machine integer, whereas lift will return a multiprecision integer. Otherwise lift falls back to data by default.

diff --git a/previews/PR2578/AbstractAlgebra/ring/index.html b/previews/PR2578/AbstractAlgebra/ring/index.html deleted file mode 100644 index b4336e970cca..000000000000 --- a/previews/PR2578/AbstractAlgebra/ring/index.html +++ /dev/null @@ -1,27 +0,0 @@ - -Ring functionality · Oscar.jl

Ring functionality

AbstractAlgebra has both commutative and noncommutative rings. Together we refer to them below as rings.

Abstract types for rings

All commutative ring types in AbstractAlgebra belong to the Ring abstract type and commutative ring elements belong to the RingElem abstract type.

Noncommutative ring types belong to the NCRing abstract type and their elements to NCRingElem.

As Julia types cannot belong to our RingElem type hierarchy, we also provide the union type RingElement which includes RingElem in union with the Julia types Integer, Rational and AbstractFloat.

Similarly NCRingElement includes the Julia types just mentioned in union with NCRingElem.

Note that

Ring <: NCRing
-RingElem <: NCRingElem
-RingElement <: NCRingElement

Functions for types and parents of rings

parent_type(::Type{T}) where T <: NCRingElement
-elem_type(::Type{T}) where T <: NCRing

Return the type of the parent (resp. element) type corresponding to the given ring element (resp. parent) type.

base_ring(R::NCRing)
-base_ring(a::NCRingElement)

For generic ring constructions over a base ring (e.g. polynomials over a coefficient ring), return the parent object of that base ring.

parent(a::NCRingElement)

Return the parent of the given ring element.

is_domain_type(::Type{T}) where T <: NCRingElement
-is_exact_type(::Type{T}) where T <: NCRingElement

Return true if the given ring element type can only belong to elements of an integral domain or exact ring respectively. (An exact ring is one whose elements are represented exactly in the system without approximation.)

The following function is implemented where mathematically and algorithmically possible.

characteristic(R::NCRing)

Constructors

If R is a parent object of a ring in AbstractAlgebra, it can always be used to construct certain objects in that ring.

(R::NCRing)() # constructs zero
-(R::NCRing)(c::Integer)
-(R::NCRing)(c::elem_type(R))
-(R::NCRing{T})(a::T) where T <: RingElement

Basic functions

All rings in AbstractAlgebra are expected to implement basic ring operations, unary minus, binary addition, subtraction and multiplication, equality testing, powering.

In addition, the following are implemented for parents/elements just as they would be in Julia for types/objects.

zero(R::NCRing)
-one(R::NCRing)
-iszero(a::NCRingElement)
-isone(a::NCRingElement)

In addition, the following are implemented where it is mathematically/algorithmically viable to do so.

is_unit(a::NCRingElement)
-is_zero_divisor(a::NCRingElement)
-is_zero_divisor_with_annihilator(a::NCRingElement)

The following standard Julia functions are also implemented for all ring elements.

hash(f::RingElement, h::UInt)
-deepcopy_internal(a::RingElement, dict::IdDict)
-show(io::IO, R::NCRing)
-show(io::IO, a::NCRingElement)

Basic functionality for inexact rings only

By default, inexact ring elements in AbstractAlgebra compare equal if they are the same to the minimum precision of the two elements. However, we also provide the following more strict notion of equality, which also requires the precisions to be the same.

isequal(a::T, b::T) where T <: NCRingElement

For floating point and ball arithmetic it is sometimes useful to be able to check if two elements are approximately equal, e.g. to suppress numerical noise in comparisons. For this, the following are provided.

isapprox(a::T, b::T; atol::Real=sqrt(eps())) where T <: RingElement

Similarly, for a parameterised ring with type MyElem{T} over such an inexact ring we have the following.

isapprox(a::MyElem{T}, b::T; atol::Real=sqrt(eps())) where T <: RingElement
-isapprox(a::T, b::MyElem{T}; atol::Real=sqrt(eps())) where T <: RingElement

These notionally perform a coercion into the parameterised ring before doing the approximate equality test.

Basic functionality for commutative rings only

divexact(a::T, b::T) where T <: RingElement
-inv(a::T)

Return a/b or 1/a respectively, where the slash here refers to the mathematical notion of division in the ring, not Julia's floating point division operator.

Basic functionality for noncommutative rings only

divexact_left(a::T, b::T) where T <: NCRingElement
-divexact_right(a::T, b::T) where T <: NCRingElement

As per divexact above, except that division by b happens on the left or right, respectively, of a.

Unsafe ring operators

To speed up polynomial arithmetic, various unsafe operators are provided, which mutate the output rather than create a new object.

zero!(a::NCRingElement)
-mul!(a::T, b::T, c::T) where T <: NCRingElement
-add!(a::T, b::T, c::T) where T <: NCRingElement
-addeq!(a::T, b::T) where T <: NCRingElement
-addmul!(a::T, b::T, c::T, t::T) where T <: NCRingElement

In each case the mutated object is the leftmost parameter.

The addeq!(a, b) operation does the same thing as add!(a, a, b). The optional addmul!(a, b, c, t) operation does the same thing as mul!(t, b, c); addeq!(a, t) where t is a temporary which can be mutated so that an addition allocation is not needed.

Random generation

The Julia random interface is implemented for all ring parents (instead of for types). The exact interface differs depending on the ring, but the parameters supplied are usually ranges, e.g. -1:10 for the range of allowed degrees for a univariate polynomial.

rand(R::NCRing, v...)

Factorization

For commutative rings supporting factorization and irreducibility testing, the following optional functions may be implemented.

is_irreducible(a::T) where T <: RingElement
-is_squarefree(a::T) where T <: RingElement

Decide whether a is irreducible or squarefree, respectively.

factor(a::T) where T <: RingElement
-factor_squarefree(a::T) where T <: RingElement

Return a factorization into irreducible or squarefree elements, respectively. The return is an object of type Fac{T}.

FacType
Fac{T <: RingElement}

Type for factored ring elements. The structure holds a unit of type T and is an iterable collection of T => Int pairs for the factors and exponents.

unitMethod
unit(a::Fac{T}) -> T

Return the unit of the factorization.

evaluateMethod
evaluate(a::Fac{T}) -> T

Multiply out the factorization into a single element.

getindexMethod
getindex(a::Fac, b) -> Int

If $b$ is a factor of $a$, the corresponding exponent is returned. Otherwise an error is thrown.

setindex!Method
setindex!(a::Fac{T}, c::Int, b::T)

If $b$ is a factor of $a$, the corresponding entry is set to $c$.

diff --git a/previews/PR2578/AbstractAlgebra/ring_interface/index.html b/previews/PR2578/AbstractAlgebra/ring_interface/index.html deleted file mode 100644 index 81f854ed2914..000000000000 --- a/previews/PR2578/AbstractAlgebra/ring_interface/index.html +++ /dev/null @@ -1,275 +0,0 @@ - -Ring Interface · Oscar.jl

Ring Interface

AbstractAlgebra.jl generic code makes use of a standardised set of functions which it expects to be implemented for all rings. Here we document this interface. All libraries which want to make use of the generic capabilities of AbstractAlgebra.jl must supply all of the required functionality for their rings.

In addition to the required functions, there are also optional functions which can be provided for certain types of rings, e.g. GCD domains or fields, etc. If implemented, these allow the generic code to provide additional functionality for those rings, or in some cases, to select more efficient algorithms.

Types

Most rings must supply two types:

  • a type for the parent object (representing the ring itself)
  • a type for elements of that ring

For example, the generic univariate polynomial type in AbstractAlgebra.jl provides two types in generic/GenericTypes.jl:

  • Generic.PolyRing{T} for the parent objects
  • Generic.Poly{T} for the actual polynomials

The parent type must belong to Ring and the element type must belong to RingElem. Of course, the types may belong to these abstract types transitively, e.g. Poly{T} actually belongs to PolyRingElem{T} which in turn belongs to RingElem.

For parameterised rings, we advise that the types of both the parent objects and element objects to be parameterised by the types of the elements of the base ring (see the function base_ring below for a definition).

There can be variations on this theme: e.g. in some areas of mathematics there is a notion of a coefficient domain, in which case it may make sense to parameterise all types by the type of elements of this coefficient domain. But note that this may have implications for the ad hoc operators one might like to explicitly implement.

RingElement type union

Because of its lack of multiple inheritance, Julia does not allow Julia Base types to belong to RingElem. To allow us to work equally with AbstractAlgebra and Julia types that represent elements of rings we define a union type RingElement in src/julia/JuliaTypes.

So far, in addition to RingElem the union type RingElement includes the Julia types Integer, Rational and AbstractFloat.

Most of the generic code in AbstractAlgebra makes use of the union type RingElement instead of RingElem so that the generic functions also accept the Julia Base ring types.

Note

One must be careful when defining ad hoc binary operations for ring element types. It is often necessary to define separate versions of the functions for RingElem then for each of the Julia types separately in order to avoid ambiguity warnings.

Note that even though RingElement is a union type we still have the following inclusion

RingElement <: NCRingElement

Parent object caches

In many cases, it is desirable to have only one object in the system to represent each ring. This means that if the same ring is constructed twice, elements of the two rings will be compatible as far as arithmetic is concerned.

In order to facilitate this, global caches of rings are stored in AbstractAlgebra.jl, usually implemented using dictionaries. For example, the Generic.PolyRing parent objects are looked up in a dictionary PolyID to see if they have been previously defined.

Whether these global caches are provided or not, depends on both mathematical and algorithmic considerations. E.g. in the case of number fields, it isn't desirable to identify all number fields with the same defining polynomial, as they may be considered with distinct embeddings into one another. In other cases, identifying whether two rings are the same may be prohibitively expensive. Generally, it may only make sense algorithmically to identify two rings if they were constructed from identical data.

If a global cache is provided, it must be optionally possible to construct the parent objects without caching. This is done by passing a boolean value cached to the inner constructor of the parent object. See generic/GenericTypes.jl for examples of how to construct and handle such caches.

Required functions for all rings

In the following, we list all the functions that are required to be provided for rings in AbstractAlgebra.jl or by external libraries wanting to use AbstractAlgebra.jl.

We give this interface for fictitious types MyParent for the type of the ring parent object R and MyElem for the type of the elements of the ring.

Note

Generic functions in AbstractAlgebra.jl may not rely on the existence of functions that are not documented here. If they do, those functions will only be available for rings that implement that additional functionality, and should be documented as such.

Data type and parent object methods

parent_type(::Type{MyElem})

Return the type of the corresponding parent object for the given element type. For example, parent_type(Generic.Poly{T}) will return Generic.PolyRing{T}.

elem_type(::Type{MyParent})

Return the type of the elements of the ring whose parent object has the given type. This is the inverse of the parent_type function, i.e. elem_type(Generic.PolyRing{T}) will return Generic.Poly{T}.

base_ring(R::MyParent)

Given a parent object R, representing a ring, this function returns the parent object of any base ring that parameterises this ring. For example, the base ring of the ring of polynomials over the integers would be the integer ring.

If the ring is not parameterised by another ring, this function must return Union{}.

Note

There is a distinction between a base ring and other kinds of parameters. For example, in the ring $\mathbb{Z}/n\mathbb{Z}$, the modulus $n$ is a parameter, but the only base ring is $\mathbb{Z}$. We consider the ring $\mathbb{Z}/n\mathbb{Z}$ to have been constructed from the base ring $\mathbb{Z}$ by taking its quotient by a (principal) ideal.

parent(f::MyElem)

Return the parent object of the given element, i.e. return the ring to which the given element belongs.

This is usually stored in a field parent in each ring element. (If the parent objects have mutable struct types, the internal overhead here is just an additional machine pointer stored in each element of the ring.)

For some element types it isn't necessary to append the parent object as a field of every element. This is the case when the parent object can be reconstructed just given the type of the elements. For example, this is the case for the ring of integers and in fact for any ring element type that isn't parameterised or generic in any way.

is_domain_type(::Type{MyElem})

Return true if every element of the given element type (which may be parameterised or an abstract type) necessarily has a parent that is an integral domain, otherwise if this cannot be guaranteed, the function returns false.

For example, if MyElem was the type of elements of generic residue rings of a polynomial ring, the answer to the question would depend on the modulus of the residue ring. Therefore is_domain_type would have to return false, since we cannot guarantee that we are dealing with elements of an integral domain in general. But if the given element type was for rational integers, the answer would be true, since every rational integer has as parent the ring of rational integers, which is an integral domain.

Note that this function depends only on the type of an element and cannot access information about the object itself, or its parent.

is_exact_type(::Type{MyElem})

Return true if every element of the given type is represented exactly. For example, $p$-adic numbers, real and complex floating point numbers and power series are not exact, as we can only represent them in general with finite truncations. Similarly polynomials and matrices over inexact element types are themselves inexact.

Integers, rationals, finite fields and polynomials and matrices over them are always exact.

Note that MyElem may be parameterised or an abstract type, in which case every element of every type represented by MyElem must be exact, otherwise the function must return false.

Base.hash(f::MyElem, h::UInt)

Return a hash for the object $f$ of type UInt. This is used as a hopefully cheap way to distinguish objects that differ arithmetically.

If the object has components, e.g. the coefficients of a polynomial or elements of a matrix, these should be hashed recursively, passing the same parameter h to all levels. Each component should then be xor'd with h before combining the individual component hashes to give the final hash.

The hash functions in AbstractAlgebra.jl usually start from some fixed 64 bit hexadecimal value that has been picked at random by the library author for that type. That is then truncated to fit a UInt (in case the latter is not 64 bits). This ensures that objects that are the same arithmetically (or that have the same components), but have different types (or structures), are unlikely to hash to the same value.

deepcopy_internal(f::MyElem, dict::IdDict)

Return a copy of the given element, recursively copying all components of the object.

Obviously the parent, if it is stored in the element, should not be copied. The new element should have precisely the same parent as the old object.

For types that cannot self-reference themselves anywhere internally, the dict argument may be ignored.

In the case that internal self-references are possible, please consult the Julia documentation on how to implement deepcopy_internal.

Constructors

Outer constructors for most AbstractAlgebra types are provided by overloading the call syntax for parent objects.

If R is a parent object for a given ring we provide the following constructors.

(R::MyParent)()

Return the zero object of the given ring.

(R::MyParent)(a::Integer)

Coerce the given integer into the given ring.

(R::MyParent)(a::MyElem)

If $a$ belongs to the given ring, the function returns it (without making a copy). Otherwise an error is thrown.

For parameterised rings we also require a function to coerce from the base ring into the parent ring.

(R::MyParent{T})(a::T) where T <: RingElem

Coerce $a$ into the ring $R$ if $a$ belongs to the base ring of $R$.

Basic manipulation of rings and elements

zero(R::MyParent)

Return the zero element of the given ring.

one(R::MyParent)

Return the multiplicative identity of the given ring.

iszero(f::MyElem)

Return true if the given element is the zero element of the ring it belongs to.

isone(f::MyElem)

Return true if the given element is the multiplicative identity of the ring it belongs to.

Canonicalisation

canonical_unit(f::MyElem)

When fractions are created with two elements of the given type, it is nice to be able to represent them in some kind of canonical form. This is of course not always possible. But for example, fractions of integers can be canonicalised by first removing any common factors of the numerator and denominator, then making the denominator positive.

In AbstractAlgebra.jl, the denominator would be made positive by dividing both the numerator and denominator by the canonical unit of the denominator. For a negative denominator, this would be $-1$.

For elements of a field, canonical_unit simply returns the element itself. In general, canonical_unit of an invertible element should be that element. Finally, if $a = ub$ we should have the identity canonical_unit(a) = canonical_unit(u)*canonical_unit(b).

For some rings, it is completely impractical to implement this function, in which case it may return $1$ in the given ring. The function must however always exist, and always return an element of the ring.

String I/O

show(io::IO, R::MyParent)

This should print an English description of the parent ring (to the given IO object). If the ring is parameterised, it can call the corresponding show function for any rings it depends on.

show(io::IO, f::MyElem)

This should print a human readable, textual representation of the object (to the given IO object). It can recursively call the corresponding show functions for any of its components.

Expressions

To obtain best results when printing composed types derived from other types, e.g., polynomials, the following method should be implemented.

expressify(f::MyElem; context = nothing)

which must return either Expr, Symbol, Integer or String.

For a type which implements expressify, one can automatically derive show methods supporting output as plain text, LaTeX and html by using the following:

@enable_all_show_via_expressify MyElem

This defines the following show methods for the specified type MyElem:

function Base.show(io::IO, a::MyElem)
-  show_via_expressify(io, a)
-end
-
-function Base.show(io::IO, mi::MIME"text/plain", a::MyElem)
-  show_via_expressify(io, mi, a)
-end
-
-function Base.show(io::IO, mi::MIME"text/latex", a::MyElem)
-  show_via_expressify(io, mi, a)
-end
-
-function Base.show(io::IO, mi::MIME"text/html", a::MyElem)
-  show_via_expressify(io, mi, a)
-end

As an example, assume that an object f of type MyElem has two components f.a and f.b of integer type, which should be printed as a^b, this can be implemented as

expressify(f::MyElem; context = nothing) = Expr(:call, :^, f.a, f.b)

If f.a and f.b themselves are objects that can be expressified, this can be implemented as

function expressify(f::MyElem; context = nothing)
-  return Expr(:call, :^, expressify(f.a, context = context),
-                         expressify(f.b, context = context))
-end

As noted above, expressify should return an Expr, Symbol, Integer or String. The rendering of such expressions with a particular MIME type to an output context is controlled by the following rules which are subject to change slightly in future versions of AbstracAlgebra.

Integer: The printing of integers is straightforward and automatically includes transformations such as 1 + (-2)*x => 1 - 2*x as this is cumbersome to implement per-type.

Symbol: Since variable names are stored as mere symbols in AbstractAlgebra, some transformations related to subscripts are applied to symbols automatically in latex output. The \operatorname{ in the following table is actually replaced with the more portable \mathop{\mathrm{.

expressifylatex output
Symbol("a")a
Symbol("α"){\alpha}
Symbol("x1")\operatorname{x1}
Symbol("xy_1")\operatorname{xy}_{1}
Symbol("sin")\operatorname{sin}
Symbol("sin_cos")\operatorname{sin\_cos}
Symbol("sin_1")\operatorname{sin}_{1}
Symbol("sin_cos_1")\operatorname{sin\_cos}_{1}
Symbol("αaβb_1_2")\operatorname{{\alpha}a{\beta}b}_{1,2}

Expr: These are the most versatile as the Expr objects themselves contain a symbolic head and any number of arguments. What looks like f(a,b) in textual output is Expr(:call, :f, :a, :b) under the hood. AbstractAlgebra currently contains the following printing rules for such expressions.

expressifyoutputlatex notes
Expr(:call, :+, a, b)a + b
Expr(:call, :*, a, b)a*bone space for implied multiplication
Expr(:call, :cdot, a, b)a * ba real \cdot is used
Expr(:call, :^, a, b)a^bmay include some courtesy parentheses
Expr(:call, ://, a, b)a//bwill create a fraction box
Expr(:call, :/, a, b)a/bwill not create a fraction box
Expr(:call, a, b, c)a(b, c)
Expr(:ref, a, b, c)a[b, c]
Expr(:vcat, a, b)[a; b]actually vertical
Expr(:vect, a, b)[a, b]
Expr(:tuple, a, b)(a, b)
Expr(:list, a, b){a, b}
Expr(:series, a, b)a, b
Expr(:sequence, a, b)ab
Expr(:row, a, b)a bcombine with :vcat to make matrices
Expr(:hcat, a, b)a b

String: Strings are printed verbatim and should only be used as a last resort as they provide absolutely no precedence information on their contents.

Unary operations

-(f::MyElem)

Return $-f$.

Binary operations

+(f::MyElem, g::MyElem)
--(f::MyElem, g::MyElem)
-*(f::MyElem, g::MyElem)

Return $f + g$, $f - g$ or $fg$, respectively.

Comparison

==(f::MyElem, g::MyElem)

Return true if $f$ and $g$ are arithmetically equal. In the case where the two elements are inexact, the function returns true if they agree to the minimum precision of the two.

isequal(f::MyElem, g::MyElem)

For exact rings, this should return the same thing as == above. For inexact rings, this returns true only if the two elements are arithmetically equal and have the same precision.

Powering

^(f::MyElem, e::Int)

Return $f^e$. The function should throw a DomainError() if negative exponents don't make sense but are passed to the function.

Exact division

divexact(f::MyElem, g::MyElem; check::Bool=true)

Return $f/g$, though note that Julia uses / for floating point division. Here we mean exact division in the ring, i.e. return $q$ such that $f = gq$. A DivideError() should be thrown if $g$ is zero.

If check=true the function should check that the division is exact and throw an exception if not.

If check=false the check may be omitted for performance reasons. The behaviour is then undefined if a division is performed that is not exact. This may include throwing an exception, returning meaningless results, hanging or crashing. The function should only be called with check=false if it is already known that the division will be exact.

Inverse

inv(f::MyElem)

Return the inverse of $f$, i.e. $1/f$, though note that Julia uses / for floating point division. Here we mean exact division in the ring.

A fallback for this function is provided in terms of divexact so an implementation can be omitted if preferred.

Unsafe operators

To speed up polynomial and matrix arithmetic, it sometimes makes sense to mutate values in place rather than replace them with a newly created object every time they are modified.

For this purpose, certain mutating operators are required. In order to support immutable types (struct in Julia) and systems that don't have in-place operators, all unsafe operators must return the (ostensibly) mutated value. Only the returned value is used in computations, so this lifts the requirement that the unsafe operators actually mutate the value.

Note the exclamation point is a convention, which indicates that the object may be mutated in-place.

To make use of these functions, one must be certain that no other references are held to the object being mutated, otherwise those values will also be changed!

The results of deepcopy and all arithmetic operations, including powering and division can be assumed to be new objects without other references being held, as can objects returned from constructors.

Note

It is important to recognise that R(a) where R is the ring a belongs to, does not create a new value. For this case, use deepcopy(a).

zero!(f::MyElem)

Set the value $f$ to zero in place. Return the mutated value.

mul!(c::MyElem, a::MyElem, b::MyElem)

Set $c$ to the value $ab$ in place. Return the mutated value. Aliasing is permitted.

add!(c::MyElem, a::MyElem, b::MyElem)

Set $c$ to the value $a + b$ in place. Return the mutated value. Aliasing is permitted.

addeq!(a::MyElem, b::MyElem)

Set $a$ to $a + b$ in place. Return the mutated value. Aliasing is permitted.

Random generation

The random functions are only used for test code to generate test data. They therefore don't need to provide any guarantees on uniformity, and in fact, test values that are known to be a good source of corner cases can be supplied.

rand(R::MyParent, v...)

Return a random element in the given ring of the specified size.

There can be as many arguments as is necessary to specify the size of the test example which is being produced.

Promotion rules

AbstractAlgebra currently has a very simple coercion model. With few exceptions only simple coercions are supported. For example if $x \in \mathbb{Z}$ and $y \in \mathbb{Z}[x]$ then $x + y$ can be computed by coercing $x$ into the same ring as $y$ and then adding in that ring.

Complex coercions such as adding elements of $\mathbb{Q}$ and $\mathbb{Z}[x]$ are not supported, as this would require finding and creating a common overring in which the elements could be added.

AbstractAlgebra supports simple coercions by overloading parent object call syntax R(x) to coerce the object x into the ring R. However, to coerce elements up a tower of rings, one needs to also have a promotion system similar to Julia's type promotion system.

As for Julia, AbstractAlgebra's promotion system only specifies what happens to types. It is the coercions themselves that must deal with the mathematical situation at the level of rings, including checking that the object can even be coerced into the given ring.

We now describe the required AbstractAlgebra type promotion rules.

For every ring, one wants to be able to coerce integers into the ring. And for any ring constructed over a base ring, one would like to be able to coerce from the base ring into the ring.

The required promotion rules to support this look a bit different depending on whether the element type is parameterised or not and whether it is built on a base ring.

For ring element types MyElem that are neither parameterised nor built over a base ring, the promotion rules can be defined as follows:

promote_rule(::Type{MyElem}, ::Type{T}) where {T <: Integer} = MyElem

For ring element types MyElem that aren't parameterised, but which have a base ring with concrete element type T the promotion rules can be defined as follows:

promote_rule(::Type{MyElem}, ::Type{U}) where U <: Integer = MyElem
promote_rule(::Type{MyElem}, ::Type{T}) = MyElem

For ring element types MyElem{T} that are parameterised by the type of elements of the base ring, the promotion rules can be defined as follows:

promote_rule(::Type{MyElem{T}}, ::Type{MyElem{T}}) where T <: RingElement = MyElem{T}
function promote_rule(::Type{MyElem{T}}, ::Type{U}) where {T <: RingElement, U <: RingElement}
-   promote_rule(T, U) == T ? MyElem{T} : Union{}
-end

Required functionality for inexact rings

Approximation (floating point and ball arithmetic only)

isapprox(f::MyElem, g::MyElem; atol::Real=sqrt(eps()))

This is used by test code that uses rings involving floating point or ball arithmetic. The function should return true if all components of $f$ and $g$ are equal to within the square root of the Julia epsilon, since numerical noise may make an exact comparison impossible.

For parameterised rings over an inexact ring, we also require the following ad hoc approximation functionality.

isapprox(f::MyElem{T}, g::T; atol::Real=sqrt(eps())) where T <: RingElem
isapprox(f::T, g::MyElem{T}; atol::Real=sqrt(eps())) where T <: RingElem

These notionally coerce the element of the base ring into the parameterised ring and do a full comparison.

Optional functionality

Some functionality is difficult or impossible to implement for all rings in the system. If it is provided, additional functionality or performance may become available. Here is a list of all functions that are considered optional and can't be relied on by generic functions in the AbstractAlgebra Ring interface.

It may be that no algorithm, or no efficient algorithm is known to implement these functions. As these functions are optional, they do not need to exist. Julia will already inform the user that the function has not been implemented if it is called but doesn't exist.

Optional basic manipulation functionality

is_unit(f::MyElem)

Return true if the given element is a unit in the ring it belongs to.

is_zero_divisor(f::MyElem)

Return true if the given element is a zero divisor in the ring it belongs to. When this function does not exist for a given ring then the total ring of fractions may not be usable over that ring. All fields in the system have a fallback defined for this function.

characteristic(R::MyParent)

Return the characteristic of the ring. The function should not be defined if it is not possible to unconditionally give the characteristic. AbstractAlgebra will raise an exception is such cases.

Optional binary ad hoc operators

By default, ad hoc operations are handled by AbstractAlgebra.jl if they are not defined explicitly, by coercing both operands into the same ring and then performing the required operation.

In some cases, e.g. for matrices, this leads to very inefficient behaviour. In such cases, it is advised to implement some of these operators explicitly.

It can occasionally be worth adding a separate set of ad hoc binary operators for the type Int, if this can be done more efficiently than for arbitrary Julia Integer types.

+(f::MyElem, c::Integer)
--(f::MyElem, c::Integer)
-*(f::MyElem, c::Integer)
+(c::Integer, f::MyElem)
--(c::Integer, f::MyElem)
-*(c::Integer, f::MyElem)

For parameterised types, it is also sometimes more performant to provide explicit ad hoc operators with elements of the base ring.

+(f::MyElem{T}, c::T) where T <: RingElem
--(f::MyElem{T}, c::T) where T <: RingElem
-*(f::MyElem{T}, c::T) where T <: RingElem
+(c::T, f::MyElem{T}) where T <: RingElem
--(c::T, f::MyElem{T}) where T <: RingElem
-*(c::T, f::MyElem{T}) where T <: RingElem

Optional ad hoc comparisons

==(f::MyElem, c::Integer)
==(c::Integer, f::MyElem)
==(f::MyElem{T}, c:T) where T <: RingElem
==(c::T, f::MyElem{T}) where T <: RingElem

Optional ad hoc exact division functions

divexact(a::MyElem{T}, b::T) where T <: RingElem
divexact(a::MyElem, b::Integer)

Optional powering functions

^(f::MyElem, e::BigInt)

In case $f$ cannot explode in size when powered by a very large integer, and it is practical to do so, one may provide this function to support powering with BigInt exponents (or for external modules, any other big integer type).

Optional unsafe operators

addmul!(c::MyElem, a::MyElem, b::MyElem, t::MyElem)

Set $c = c + ab$ in-place. Return the mutated value. The value $t$ should be a temporary of the same type as $a$, $b$ and $c$, which can be used arbitrarily by the implementation to speed up the computation. Aliasing between $a$, $b$ and $c$ is permitted.

Minimal example of ring implementation

Here is a minimal example of implementing the Ring Interface for a constant polynomial type (i.e. polynomials of degree less than one).

# ConstPoly.jl : Implements constant polynomials
-
-using AbstractAlgebra
-
-using Random: Random, SamplerTrivial, GLOBAL_RNG
-using RandomExtensions: RandomExtensions, Make2, AbstractRNG
-
-import AbstractAlgebra: parent_type, elem_type, base_ring, parent, is_domain_type,
-       is_exact_type, canonical_unit, isequal, divexact, zero!, mul!, add!, addeq!,
-       get_cached!, is_unit, characteristic, Ring, RingElem, expressify
-
-import Base: show, +, -, *, ^, ==, inv, isone, iszero, one, zero, rand,
-             deepcopy_internal, hash
-
-mutable struct ConstPolyRing{T <: RingElement} <: Ring
-   base_ring::Ring
-
-   function ConstPolyRing{T}(R::Ring, cached::Bool) where T <: RingElement
-      return get_cached!(ConstPolyID, R, cached) do
-         new{T}(R)
-      end::ConstPolyRing{T}
-   end
-end
-
-const ConstPolyID = AbstractAlgebra.CacheDictType{Ring, ConstPolyRing}()
-   
-mutable struct ConstPoly{T <: RingElement} <: RingElem
-   c::T
-   parent::ConstPolyRing{T}
-
-   function ConstPoly{T}(c::T) where T <: RingElement
-      return new(c)
-   end
-end
-
-# Data type and parent object methods
-
-parent_type(::Type{ConstPoly{T}}) where T <: RingElement = ConstPolyRing{T}
-
-elem_type(::Type{ConstPolyRing{T}}) where T <: RingElement = ConstPoly{T}
-
-base_ring(R::ConstPolyRing) = R.base_ring
-
-parent(f::ConstPoly) = f.parent
-
-is_domain_type(::Type{ConstPoly{T}}) where T <: RingElement = is_domain_type(T)
-
-is_exact_type(::Type{ConstPoly{T}}) where T <: RingElement = is_exact_type(T)
-
-function hash(f::ConstPoly, h::UInt)
-   r = 0x65125ab8e0cd44ca
-   return xor(r, hash(f.c, h))
-end
-
-function deepcopy_internal(f::ConstPoly{T}, dict::IdDict) where T <: RingElement
-   r = ConstPoly{T}(deepcopy_internal(f.c, dict))
-   r.parent = f.parent # parent should not be deepcopied
-   return r
-end
-
-# Basic manipulation
-
-zero(R::ConstPolyRing) = R()
-
-one(R::ConstPolyRing) = R(1)
-
-iszero(f::ConstPoly) = iszero(f.c)
-
-isone(f::ConstPoly) = isone(f.c)
-
-is_unit(f::ConstPoly) = is_unit(f.c)
-
-characteristic(R::ConstPolyRing) = characteristic(base_ring(R))
-
-# Canonical unit
-
-canonical_unit(f::ConstPoly) = canonical_unit(f.c)
-
-# String I/O
-
-function show(io::IO, R::ConstPolyRing)
-   print(io, "Constant polynomials over ")
-   show(io, base_ring(R))
-end
-
-function show(io::IO, f::ConstPoly)
-   print(io, f.c)
-end
-
-# Expressification (optional)
-
-function expressify(R::ConstPolyRing; context = nothing)
-   return Expr(:sequence, Expr(:text, "Constant polynomials over "),
-                          expressify(base_ring(R), context = context))
-end
-
-function expressify(f::ConstPoly; context = nothing)
-   return expressify(f.c, context = context)
-end
-
-# Unary operations
-
-function -(f::ConstPoly)
-   R = parent(f)
-   return R(-f.c)
-end
-
-# Binary operations
-
-function +(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   parent(f) != parent(g) && error("Incompatible rings")
-   R = parent(f)
-   return R(f.c + g.c)
-end
-
-function -(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   parent(f) != parent(g) && error("Incompatible rings")
-   R = parent(f)
-   return R(f.c - g.c)
-end
-
-function *(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   parent(f) != parent(g) && error("Incompatible rings")
-   R = parent(f)
-   return R(f.c*g.c)
-end
-
-# Comparison
-
-function ==(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   parent(f) != parent(g) && error("Incompatible rings")
-   return f.c == g.c
-end
-
-function isequal(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   parent(f) != parent(g) && error("Incompatible rings")
-   return isequal(f.c, g.c)
-end
-
-# Powering need not be implemented if * is
-
-# Exact division
-
-function divexact(f::ConstPoly{T}, g::ConstPoly{T}; check::Bool = true) where T <: RingElement
-   parent(f) != parent(g) && error("Incompatible rings")
-   R = parent(f)
-   return R(divexact(f.c, g.c, check = check))
-end
-
-# Inverse
-
-function inv(f::ConstPoly)
-   R = parent(f)
-   return R(AbstractAlgebra.inv(f.c))
-end
-
-# Unsafe operators
-
-function zero!(f::ConstPoly)
-   f.c = zero(base_ring(parent(f)))
-   return f
-end
-
-function mul!(f::ConstPoly{T}, g::ConstPoly{T}, h::ConstPoly{T}) where T <: RingElement
-   f.c = g.c*h.c
-   return f
-end
-
-function add!(f::ConstPoly{T}, g::ConstPoly{T}, h::ConstPoly{T}) where T <: RingElement
-   f.c = g.c + h.c
-   return f
-end
-
-function addeq!(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   f.c += g.c
-   return f
-end
-
-# Random generation
-
-RandomExtensions.maketype(R::ConstPolyRing, _) = elem_type(R)
-
-rand(rng::AbstractRNG, sp::SamplerTrivial{<:Make2{ConstPoly,ConstPolyRing}}) =
-        sp[][1](rand(rng, sp[][2]))
-
-rand(rng::AbstractRNG, R::ConstPolyRing, n::UnitRange{Int}) = R(rand(rng, n))
-
-rand(R::ConstPolyRing, n::UnitRange{Int}) = rand(Random.GLOBAL_RNG, R, n)
-
-# Promotion rules
-
-promote_rule(::Type{ConstPoly{T}}, ::Type{ConstPoly{T}}) where T <: RingElement = ConstPoly{T}
-
-function promote_rule(::Type{ConstPoly{T}}, ::Type{U}) where {T <: RingElement, U <: RingElement}
-   promote_rule(T, U) == T ? ConstPoly{T} : Union{}
-end
-
-# Constructors
-
-function (R::ConstPolyRing{T})() where T <: RingElement
-   r = ConstPoly{T}(base_ring(R)(0))
-   r.parent = R
-   return r
-end
-
-function (R::ConstPolyRing{T})(c::Integer) where T <: RingElement
-   r = ConstPoly{T}(base_ring(R)(c))
-   r.parent = R
-   return r
-end
-
-# Needed to prevent ambiguity
-function (R::ConstPolyRing{T})(c::T) where T <: Integer
-   r = ConstPoly{T}(base_ring(R)(c))
-   r.parent = R
-   return r
-end
-
-function (R::ConstPolyRing{T})(c::T) where T <: RingElement
-   base_ring(R) != parent(c) && error("Unable to coerce element")
-   r = ConstPoly{T}(c)
-   r.parent = R
-   return r
-end
-
-function (R::ConstPolyRing{T})(f::ConstPoly{T}) where T <: RingElement
-   R != parent(f) && error("Unable to coerce element")
-   return f
-end
-
-# Parent constructor
-
-function ConstantPolynomialRing(R::Ring, cached::Bool=true)
-   T = elem_type(R)
-   return ConstPolyRing{T}(R, cached)
-end

The above implementation of ConstantPolynomialRing may be tested as follows.

using Test
-include(joinpath(pathof(AbstractAlgebra), "..", "..", "test", "Rings-conformance-tests.jl"))
-
-S, _ = polynomial_ring(QQ, "x")
-
-function test_elem(R::ConstPolyRing{elem_type(S)})
-   return R(rand(base_ring(R), 1:6, -999:999))
-end
-
-test_Ring_interface(ConstantPolynomialRing(S))
diff --git a/previews/PR2578/AbstractAlgebra/ring_introduction/index.html b/previews/PR2578/AbstractAlgebra/ring_introduction/index.html deleted file mode 100644 index e9acee75be41..000000000000 --- a/previews/PR2578/AbstractAlgebra/ring_introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

A rich ring hierarchy is provided, supporting both commutative and noncommutative rings.

A number of basic rings are provided, such as the integers, integers mod n and numerous fields.

A recursive rings implementation is then built on top of the basic rings via a number of generic ring constructions. These include univariate and multivariate polynomials and power series, univariate Laurent and Puiseux series, residue rings, matrix algebras, etc.

Where possible, these constructions can be built on top of one another in generic towers.

The ring hierarchy can be extended by implementing new rings to follow one or more ring interfaces. Generic functionality provided by the system is then automatically available for the new rings. These implementations can either be generic or can be specialised implementations provided by, for example, a C library.

In most cases, the interfaces consist of a set of constructors and functions that must be implemented to satisfy the interface. These are the functions that the generic code relies on being available.

diff --git a/previews/PR2578/AbstractAlgebra/series/index.html b/previews/PR2578/AbstractAlgebra/series/index.html deleted file mode 100644 index d12442a1b3c7..000000000000 --- a/previews/PR2578/AbstractAlgebra/series/index.html +++ /dev/null @@ -1,302 +0,0 @@ - -Power series · Oscar.jl

Power series

AbstractAlgebra.jl allows the creation of capped relative and absolute power series over any computable commutative ring $R$.

Capped relative power series are power series of the form $a_jx^j + a_{j+1}x^{j+1} + \cdots + a_{k-1}x^{k-1} + O(x^k)$ where $a_j \in R$ and the relative precision $k - j$ is at most equal to some specified precision $n$.

Capped absolute power series are power series of the form $a_jx^j + a_{j+1}x^{j+1} + \cdots + a_{n-1}x^{n-1} + O(x^n)$ where $j \geq 0$, $a_j \in R$ and the precision $n$ is fixed.

There are two implementations of relative series: relative power series, implemented in src/RelSeries.jl for which $j > 0$ in the above description, and Laurent series where $j$ can be negative, implemented in src/Laurent.jl. Note that there are two implementations for Laurent series, one over rings and one over fields, though in practice most of the implementation uses the same code in both cases.

There is a single implementation of absolute series: absolute power series, implemented in src/AbsSeries.jl.

Generic power series types

AbstractAlgebra.jl provides generic series types implemented in src/generic/AbsSeries.jl, src/generic/RelSeries.jl and src/generic/LaurentSeries.jl which implement the Series interface.

These generic series have types Generic.RelSeries{T}, Generic.AbsSeries{T}, Generic.LaurentSeriesRingElem{T} and Generic.LaurentSeriesFieldElem{T}. See the file src/generic/GenericTypes.jl for details.

The parent objects have types Generic.AbsPowerSeriesRing{T} and Generic.RelPowerSeriesRing{T} and Generic.LaurentSeriesRing{T} respectively.

The default precision, string representation of the variable and base ring $R$ of a generic power series are stored in its parent object.

Abstract types

Relative power series elements belong to the abstract type RelPowerSeriesRingElem.

Laurent series elements belong directly to either RingElem or FieldElem since it is more useful to be able to distinguish whether they belong to a ring or field than it is to distinguish that they are relative series.

Absolute power series elements belong to AbsPowerSeriesRingElem.

The parent types for relative and absolute power series, Generic.RelPowerSeriesRing{T} and Generic.AbsPowerSeriesRing{T} respectively, belong to SeriesRing{T}.

The parent types of Laurent series belong directly to Ring and Field respectively.

Series ring constructors

In order to construct series in AbstractAlgebra.jl, one must first construct the ring itself. This is accomplished with any of the following constructors.

power_series_ring(R::Ring, prec_max::Int, s::VarName; cached::Bool = true, model=:capped_relative)
laurent_series_ring(R::Ring, prec_max::Int, s::VarName; cached::Bool = true)
laurent_series_ring(R::Field, prec_max::Int, s::VarName; cached::Bool = true)

Given a base ring R, a maximum precision (relative or absolute, depending on the model) and a string s specifying how the generator (variable) should be printed, return a tuple S, x representing the series ring and its generator.

By default, S will depend only on S, x and the maximum precision and will be cached. Setting the optional argument cached to false will prevent this.

In the case of power series, the optional argument model can be set to either :capped_absolute or capped_relative, depending on which power series model is required.

It is also possible to construct absolute and relative power series with a default variable. These are lightweight constructors and should be used in generic algorithms wherever possible when creating series rings where the symbol does not matter.

AbsPowerSeriesRing(R::Ring, prec::Int)
-RelPowerSeriesRing(R::Ring, prec::Int)

Return the absolute or relative power series ring over the given base ring $R$ and with precision cap given by prec. Note that a tuple is not returned, only the power series ring itself, not a generator.

Here are some examples of constructing various kinds of series rings and coercing various elements into those rings.

Examples

julia> R, x = power_series_ring(ZZ, 10, "x")
-(Univariate power series ring over integers, x + O(x^11))
-
-julia> S, y = power_series_ring(ZZ, 10, "y"; model=:capped_absolute)
-(Univariate power series ring over integers, y + O(y^10))
-
-julia> T, z = laurent_series_ring(ZZ, 10, "z")
-(Laurent series ring in z over integers, z + O(z^11))
-
-julia> U, w = laurent_series_field(QQ, 10, "w")
-(Laurent series field in w over rationals, w + O(w^11))
-
-julia> f = R()
-O(x^10)
-
-julia> g = S(123)
-123 + O(y^10)
-
-julia> h = U(BigInt(1234))
-1234 + O(w^10)
-
-julia> k = T(z + 1)
-1 + z + O(z^10)
-
-julia> V = AbsPowerSeriesRing(ZZ, 10)
-Univariate power series ring in x with precision 10
-  over integers

Power series constructors

Series can be constructed using arithmetic operators using the generator of the series. Also see the big-oh notation below for specifying the precision.

All of the standard ring constructors can also be used to construct power series.

(R::SeriesRing)() # constructs zero
-(R::SeriesRing)(c::Integer)
-(R::SeriesRing)(c::elem_type(R))
-(R::SeriesRing{T})(a::T) where T <: RingElement

In addition, the following constructors that are specific to power series are provided. They take an array of coefficients, a length, precision and valuation. Coefficients will be coerced into the coefficient ring if they are not already in that ring.

For relative series we have:

(S::SeriesRing{T})(A::Vector{T}, len::Int, prec::Int, val::Int) where T <: RingElem
-(S::SeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: RingElem}
-(S::SeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: Integer}

And for absolute series:

(S::SeriesRing{T})(A::Vector{T}, len::Int, prec::Int) where T <: RingElem

It is also possible to create series directly without having to create the corresponding series ring.

abs_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T
-rel_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, val::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T
-laurent_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, val::Int, scale::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T

Examples

julia> S, x = power_series_ring(QQ, 10, "x"; model=:capped_absolute)
-(Univariate power series ring over rationals, x + O(x^10))
-
-julia> f = S(Rational{BigInt}[0, 2, 3, 1], 4, 6)
-2*x + 3*x^2 + x^3 + O(x^6)
-
-julia> f = abs_series(ZZ, [1, 2, 3], 3, 5, "y")
-1 + 2*y + 3*y^2 + O(y^5)
-
-julia> g = rel_series(ZZ, [1, 2, 3], 3, 7, 4)
-x^4 + 2*x^5 + 3*x^6 + O(x^7)
-
-julia> k = abs_series(ZZ, [1, 2, 3], 1, 6, cached=false)
-1 + O(x^6)
-
-julia> p = rel_series(ZZ, BigInt[], 0, 3, 1)
-O(x^3)
-
-julia> q = abs_series(ZZ, [], 0, 6)
-O(x^6)
-
-julia> s = abs_series(ZZ, [1, 2, 3], 3, 5; max_precision=10)
-1 + 2*x + 3*x^2 + O(x^5)
-
-julia> s = laurent_series(ZZ, [1, 2, 3], 3, 5, 0, 2; max_precision=10)
-1 + 2*x^2 + 3*x^4 + O(x^5)

Big-oh notation

Series elements can be given a precision using the big-oh notation. This is provided by a function of the following form, (or something equivalent for Laurent series):

O(x::SeriesElem)

Examples

julia> R, x = power_series_ring(ZZ, 10, "x")
-(Univariate power series ring over integers, x + O(x^11))
-
-julia> S, y = laurent_series_ring(ZZ, 10, "y")
-(Laurent series ring in y over integers, y + O(y^11))
-
-julia> f = 1 + 2x + O(x^5)
-1 + 2*x + O(x^5)
-
-julia> g = 2y + 7y^2 + O(y^7)
-2*y + 7*y^2 + O(y^7)

What is happening here in practice is that O(x^n) is creating the series 0 + O(x^n) and the rules for addition of series dictate that if this is added to a series of greater precision, then the lower of the two precisions must be used.

Of course it may be that the precision of the series that O(x^n) is added to is already lower than n, in which case adding O(x^n) has no effect. This is the case if the default precision is too low, since x on its own has the default precision.

Power series models

Capped relative power series have their maximum relative precision capped at some value prec_max. This means that if the leading term of a nonzero power series element is $c_ax^a$ and the precision is $b$ then the power series is of the form $c_ax^a + c_{a+1}x^{a+1} + \ldots + O(x^{a + b})$.

The zero power series is simply taken to be $0 + O(x^b)$.

The capped relative model has the advantage that power series are stable multiplicatively. In other words, for nonzero power series $f$ and $g$ we have that divexact(f*g), g) == f.

However, capped relative power series are not additively stable, i.e. we do not always have $(f + g) - g = f$.

Similar comments apply to Laurent series.

On the other hand, capped absolute power series have their absolute precision capped. This means that if the leading term of a nonzero power series element is $c_ax^a$ and the precision is $b$ then the power series is of the form $c_ax^a + c_{a+1}x^{a+1} + \ldots + O(x^b)$.

Capped absolute series are additively stable, but not necessarily multiplicatively stable.

For all models, the maximum precision is also used as a default precision in the case of coercing coefficients into the ring and for any computation where the result could mathematically be given to infinite precision.

In all models we say that two power series are equal if they agree up to the minimum absolute precision of the two power series.

Thus, for example, $x^5 + O(x^{10}) == 0 + O(x^5)$, since the minimum absolute precision is $5$.

During computations, it is possible for power series to lose relative precision due to cancellation. For example if $f = x^3 + x^5 + O(x^8)$ and $g = x^3 + x^6 + O(x^8)$ then $f - g = x^5 - x^6 + O(x^8)$ which now has relative precision $3$ instead of relative precision $5$.

Amongst other things, this means that equality is not transitive. For example $x^6 + O(x^{11}) == 0 + O(x^5)$ and $x^7 + O(x^{12}) == 0 + O(x^5)$ but $x^6 + O(x^{11}) \neq x^7 + O(x^{12})$.

Sometimes it is necessary to compare power series not just for arithmetic equality, as above, but to see if they have precisely the same precision and terms. For this purpose we introduce the isequal function.

For example, if $f = x^2 + O(x^7)$ and $g = x^2 + O(x^8)$ and $h = 0 + O(x^2)$ then $f == g$, $f == h$ and $g == h$, but isequal(f, g), isequal(f, h) and isequal(g, h) would all return false. However, if $k = x^2 + O(x^7)$ then isequal(f, k) would return true.

There are further difficulties if we construct polynomial over power series. For example, consider the polynomial in $y$ over the power series ring in $x$ over the rationals. Normalisation of such polynomials is problematic. For instance, what is the leading coefficient of $(0 + O(x^{10}))y + (1 + O(x^{10}))$?

If one takes it to be $(0 + O(x^{10}))$ then some functions may not terminate due to the fact that algorithms may require the degree of polynomials to decrease with each iteration. Instead, the degree may remain constant and simply accumulate leading terms which are arithmetically zero but not identically zero.

On the other hand, when constructing power series over other power series, if we simply throw away terms which are arithmetically equal to zero, our computations may have different output depending on the order in which the power series are added!

One should be aware of these difficulties when working with power series. Power series, as represented on a computer, simply don't satisfy the axioms of a ring. They must be used with care in order to approximate operations in a mathematical power series ring.

Simply increasing the precision will not necessarily give a "more correct" answer and some computations may not even terminate due to the presence of arithmetic zeroes!

An absolute power series ring over a ring $R$ with precision $p$ behaves very much like the quotient $R[x]/(x^p)$ of the polynomial ring over $R$. Therefore one can often treat absolute power series rings as though they were rings. However, this depends on all series being given a precision equal to the specified maximum precision and not a lower precision.

Functions for types and parents of series rings

base_ring(R::SeriesRing)
-base_ring(a::SeriesElem)

Return the coefficient ring of the given series ring or series.

parent(a::SeriesElem)

Return the parent of the given series.

characteristic(R::SeriesRing)

Return the characteristic of the given series ring. If the characteristic is not known, an exception is raised.

Series functions

Unless otherwise noted, the functions below are available for all series models, including Laurent series. We denote this by using the abstract type RelPowerSeriesRingElem, even though absolute series and Laurent series types do not belong to this abstract type.

Basic functionality

Series implement the Ring Interface

zero(R::SeriesRing)
-one(R::SeriesRing)
-iszero(a::SeriesElem)
-isone(a::SeriesElem)
divexact(a::T, b::T) where T <: SeriesElem
-inv(a::SeriesElem) 

Series also implement the Series Interface, the most important basic functions being the following.

var(S::SeriesRing)

Return a symbol for the variable of the given series ring.

max_precision(S::SeriesRing)

Return the precision cap of the given series ring.

precision(f::SeriesElem)
-valuation(f::SeriesElem)
gen(R::SeriesRing)

The following functions are also provided for all series.

coeff(a::SeriesElem, n::Int)

Return the degree $n$ coefficient of the given power series. Note coefficients are numbered from $n = 0$ for the constant coefficient. If $n$ exceeds the current precision of the power series, the function returns a zero coefficient.

For power series types, $n$ must be non-negative. Laurent series do not have this restriction.

modulusMethod
modulus(a::SeriesElem{T}) where {T <: ResElem}

Return the modulus of the coefficients of the given power series.

is_genMethod
is_gen(a::RelPowerSeriesRingElem)

Return true if the given power series is arithmetically equal to the generator of its power series ring to its current precision, otherwise return false.

Examples

julia> S, x = power_series_ring(ZZ, 10, "x")
-(Univariate power series ring over integers, x + O(x^11))
-
-julia> f = 1 + 3x + x^3 + O(x^10)
-1 + 3*x + x^3 + O(x^10)
-
-julia> g = 1 + 2x + x^2 + O(x^10)
-1 + 2*x + x^2 + O(x^10)
-
-julia> h = zero(S)
-O(x^10)
-
-julia> k = one(S)
-1 + O(x^10)
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> n = pol_length(f)
-4
-
-julia> c = polcoeff(f, 3)
-1
-
-julia> U = base_ring(S)
-Integers
-
-julia> v = var(S)
-:x
-
-julia> max_precision(S) == 10
-true
-
-julia> T = parent(x + 1)
-Univariate power series ring in x with precision 10
-  over integers
-
-julia> g == deepcopy(g)
-true
-
-julia> t = divexact(2g, 2)
-1 + 2*x + x^2 + O(x^10)
-
-julia> p = precision(f)
-10
-
-julia> R, t = power_series_ring(QQ, 10, "t")
-(Univariate power series ring over rationals, t + O(t^11))
-
-julia> S, x = power_series_ring(R, 30, "x")
-(Univariate power series ring over univariate power series ring, x + O(x^31))
-
-julia> a = O(x^4)
-O(x^4)
-
-julia> b = (t + 3)*x + (t^2 + 1)*x^2 + O(x^4)
-(3 + t + O(t^10))*x + (1 + t^2 + O(t^10))*x^2 + O(x^4)
-
-julia> k = is_gen(gen(R))
-true
-
-julia> m = is_unit(-1 + x + 2x^2)
-true
-
-julia> n = valuation(a)
-4
-
-julia> p = valuation(b)
-1
-
-julia> c = coeff(b, 2)
-1 + t^2 + O(t^10)
-
-julia> S, x = power_series_ring(ZZ, 10, "x")
-(Univariate power series ring over integers, x + O(x^11))
-
-julia> f = 1 + 3x + x^3 + O(x^5)
-1 + 3*x + x^3 + O(x^5)
-
-julia> g = S(BigInt[1, 2, 0, 1, 0, 0, 0], 4, 10, 3);
-
-julia> set_length!(g, 3)
-x^3 + 2*x^4 + O(x^10)
-
-julia> g = setcoeff!(g, 2, BigInt(11))
-x^3 + 2*x^4 + 11*x^5 + O(x^10)
-
-julia> fit!(g, 8)
-
-julia> g = setcoeff!(g, 7, BigInt(4))
-x^3 + 2*x^4 + 11*x^5 + O(x^10)

Change base ring

map_coefficientsMethod
map_coefficients(f, p::SeriesElem{<: RingElement}; cached::Bool=true, parent::PolyRing)

Transform the series p by applying f on each non-zero coefficient.

If the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

change_base_ringMethod
change_base_ring(R::Ring, p::SeriesElem{<: RingElement}; parent::PolyRing)

Return the series obtained by coercing the non-zero coefficients of p into R.

If the optional parent keyword is provided, the series will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.

Examples

julia> R, x = power_series_ring(ZZ, 10, "x")
-(Univariate power series ring over integers, x + O(x^11))
-
-julia> f = 4*x^6 + x^7 + 9*x^8 + 16*x^9 + 25*x^10 + O(x^11)
-4*x^6 + x^7 + 9*x^8 + 16*x^9 + 25*x^10 + O(x^11)
-
-julia> map_coefficients(AbstractAlgebra.sqrt, f)
-2*x^6 + x^7 + 3*x^8 + 4*x^9 + 5*x^10 + O(x^11)
-
-julia> change_base_ring(QQ, f)
-4*x^6 + x^7 + 9*x^8 + 16*x^9 + 25*x^10 + O(x^11)

Shifting

shift_leftMethod
shift_left(x::RelPowerSeriesRingElem{T}, n::Int) where T <: RingElement

Return the power series $x$ shifted left by $n$ terms, i.e. multiplied by $x^n$.

shift_rightMethod
shift_right(x::RelPowerSeriesRingElem{T}, n::Int) where T <: RingElement

Return the power series $x$ shifted right by $n$ terms, i.e. divided by $x^n$.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S, x = power_series_ring(R, 30, "x")
-(Univariate power series ring over univariate polynomial ring, x + O(x^31))
-
-julia> a = 2x + x^3
-2*x + x^3 + O(x^31)
-
-julia> b = O(x^4)
-O(x^4)
-
-julia> c = 1 + x + 2x^2 + O(x^5)
-1 + x + 2*x^2 + O(x^5)
-
-julia> d = 2x + x^3 + O(x^4)
-2*x + x^3 + O(x^4)
-
-julia> f = shift_left(a, 2)
-2*x^3 + x^5 + O(x^33)
-
-julia> g = shift_left(b, 2)
-O(x^6)
-
-julia> h = shift_right(c, 1)
-1 + 2*x + O(x^4)
-
-julia> k = shift_right(d, 3)
-1 + O(x^1)
-

Truncation

truncateMethod
truncate(a::RelPowerSeriesRingElem{T}, n::Int) where T <: RingElement

Return $a$ truncated to (absolute) precision $n$.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S, x = power_series_ring(R, 30, "x")
-(Univariate power series ring over univariate polynomial ring, x + O(x^31))
-
-julia> a = 2x + x^3
-2*x + x^3 + O(x^31)
-
-julia> b = O(x^4)
-O(x^4)
-
-julia> c = 1 + x + 2x^2 + O(x^5)
-1 + x + 2*x^2 + O(x^5)
-
-julia> d = 2x + x^3 + O(x^4)
-2*x + x^3 + O(x^4)
-
-julia> f = truncate(a, 3)
-2*x + O(x^3)
-
-julia> g = truncate(b, 2)
-O(x^2)
-
-julia> h = truncate(c, 7)
-1 + x + 2*x^2 + O(x^5)
-
-julia> k = truncate(d, 5)
-2*x + x^3 + O(x^4)
-

Division

invMethod
Base.inv(a::RelPowerSeriesRingElem)

Return the inverse of the power series $a$, i.e. $1/a$.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S, x = power_series_ring(R, 30, "x")
-(Univariate power series ring over univariate polynomial ring, x + O(x^31))
-
-julia> a = 1 + x + 2x^2 + O(x^5)
-1 + x + 2*x^2 + O(x^5)
-
-julia> b = S(-1)
--1 + O(x^30)
-
-julia> c = inv(a)
-1 - x - x^2 + 3*x^3 - x^4 + O(x^5)
-
-julia> d = inv(b)
--1 + O(x^30)
-

Composition

composeMethod
compose(a::RelPowerSeriesRingElem, b::RelPowerSeriesRingElem)

Compose the series $a$ with the series $b$ and return the result, i.e. return $a\circ b$. The two series do not need to be in the same ring, however the series $b$ must have positive valuation or an exception is raised.

Note that subst can be used instead of compose, however the provided functionality is the same. General series substitution is not well-defined.

Derivative and integral

derivativeMethod
derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the derivative of the given Puiseux series $a$.

derivative(f::AbsPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

derivative(f::RelPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

julia> R, x = power_series_ring(QQ, 10, "x")
-(Univariate power series ring in x over Rationals, x + O(x^11))
-
-julia> f = 2 + x + 3x^3
-2 + x + 3*x^3 + O(x^10)
-
-julia> derivative(f)
-1 + 9*x^2 + O(x^9)
derivative(f::AbstractAlgebra.MPolyRingElem{T}, j::Int) where {T <: RingElement}

Return the partial derivative of f with respect to $j$-th variable of the polynomial ring.

derivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement

Return the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.

derivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable of index $n$.

derivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable $v$.

integralMethod
integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the integral of the given Puiseux series $a$.

integral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem

Return the integral of the power series $f$.

integral(f::AbsPowerSeriesRingElem{T})

Return the integral of the power series $f$.

integral(f::RelPowerSeriesRingElem{T})

Return the integral of the power series $f$.

julia> R, x = power_series_ring(QQ, 10, "x")
-(Univariate power series ring in x over Rationals, x + O(x^11))
-
-julia> f = 2 + x + 3x^3
-2 + x + 3*x^3 + O(x^10)
-
-julia> integral(f)
-2*x + 1//2*x^2 + 3//4*x^4 + O(x^11)

Special functions

logMethod
log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the logarithm of the given Puiseux series $a$.

log(a::SeriesElem{T}) where T <: FieldElement

Return the logarithm of the power series $a$.

expMethod
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

sqrtMethod
sqrt(a::RelPowerSeriesRingElem)

Return the square root of the power series $a$. By default the function raises an exception if the input is not a square. If check=false this check is omitted.

Examples

julia> R, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S, x = power_series_ring(R, 30, "x")
-(Univariate power series ring over univariate polynomial ring, x + O(x^31))
-
-julia> T, z = power_series_ring(QQ, 30, "z")
-(Univariate power series ring over rationals, z + O(z^31))
-
-julia> a = 1 + z + 3z^2 + O(z^5)
-1 + z + 3*z^2 + O(z^5)
-
-julia> b = z + 2z^2 + 5z^3 + O(z^5)
-z + 2*z^2 + 5*z^3 + O(z^5)
-
-julia> c = exp(x + O(x^40))
-1 + x + 1//2*x^2 + 1//6*x^3 + 1//24*x^4 + 1//120*x^5 + 1//720*x^6 + 1//5040*x^7 + 1//40320*x^8 + 1//362880*x^9 + 1//3628800*x^10 + 1//39916800*x^11 + 1//479001600*x^12 + 1//6227020800*x^13 + 1//87178291200*x^14 + 1//1307674368000*x^15 + 1//20922789888000*x^16 + 1//355687428096000*x^17 + 1//6402373705728000*x^18 + 1//121645100408832000*x^19 + 1//2432902008176640000*x^20 + 1//51090942171709440000*x^21 + 1//1124000727777607680000*x^22 + 1//25852016738884976640000*x^23 + 1//620448401733239439360000*x^24 + 1//15511210043330985984000000*x^25 + 1//403291461126605635584000000*x^26 + 1//10888869450418352160768000000*x^27 + 1//304888344611713860501504000000*x^28 + 1//8841761993739701954543616000000*x^29 + 1//265252859812191058636308480000000*x^30 + O(x^31)
-
-julia> d = divexact(x, exp(x + O(x^40)) - 1)
-1 - 1//2*x + 1//12*x^2 - 1//720*x^4 + 1//30240*x^6 - 1//1209600*x^8 + 1//47900160*x^10 - 691//1307674368000*x^12 + 1//74724249600*x^14 - 3617//10670622842880000*x^16 + 43867//5109094217170944000*x^18 - 174611//802857662698291200000*x^20 + 77683//14101100039391805440000*x^22 - 236364091//1693824136731743669452800000*x^24 + 657931//186134520519971831808000000*x^26 - 3392780147//37893265687455865519472640000000*x^28 + O(x^29)
-
-julia> f = exp(b)
-1 + z + 5//2*z^2 + 43//6*z^3 + 193//24*z^4 + O(z^5)
-
-julia> log(exp(b)) == b
-true
-
-julia> h = sqrt(a)
-1 + 1//2*z + 11//8*z^2 - 11//16*z^3 - 77//128*z^4 + O(z^5)
-

Random generation

Random series can be constructed using the rand function. A range of possible valuations is provided. The maximum precision of the ring is used as a bound on the precision. Other parameters are used to construct random coefficients.

rand(R::SeriesRing, val_range::UnitRange{Int}, v...)

Examples

julia> R, x = power_series_ring(ZZ, 10, "x")
-(Univariate power series ring over integers, x + O(x^11))
-
-julia> f = rand(R, 3:5, -10:10)
-3*x^4 - x^5 + 4*x^7 + 4*x^8 - 7*x^9 + 2*x^10 + 4*x^11 - x^12 - 4*x^13 + O(x^14)
diff --git a/previews/PR2578/AbstractAlgebra/series_interface/index.html b/previews/PR2578/AbstractAlgebra/series_interface/index.html deleted file mode 100644 index 978613a33dda..000000000000 --- a/previews/PR2578/AbstractAlgebra/series_interface/index.html +++ /dev/null @@ -1,18 +0,0 @@ - -Series Ring Interface · Oscar.jl

Series Ring Interface

Univariate power series rings are supported in AbstractAlgebra in a variety of different forms, including absolute and relative precision models and Laurent series.

In addition to the standard Ring interface, numerous additional functions are required to be present for power series rings.

Types and parents

AbstractAlgebra provides two abstract types for power series rings and their elements:

  • SeriesRing{T} is the abstract type for all power series ring parent types
  • SeriesElem{T} is the abstract type for all power series types

We have that SeriesRing{T} <: Ring and SeriesElem{T} <: RingElem.

Note that both abstract types are parameterised. The type T should usually be the type of elements of the coefficient ring of the power series ring. For example, in the case of $\mathbb{Z}[[x]]$ the type T would be the type of an integer, e.g. BigInt.

Within the SeriesElem{T} abstract type is the abstract type RelPowerSeriesRingElem{T} for relative power series, and AbsPowerSeriesRingElem{T} for absolute power series.

Relative series are typically stored with a valuation and a series that is either zero or that has nonzero constant term. Absolute series are stored starting from the constant term, even if it is zero.

If the parent object for a relative series ring over the bignum integers has type MySeriesRing and series in that ring have type MySeries then one would have:

  • MySeriesRing <: SeriesRing{BigInt}
  • MySeries <: RelPowerSeriesRingElem{BigInt}

Series rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Series rings should at least be distinguished based on their base (coefficient) ring. But if they have the same base ring and symbol (for their variable/generator) and same default precision, they should certainly have the same parent object.

See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).

Required functionality for series

In addition to the required functionality for the Ring interface the Series Ring interface has the following required functions.

We suppose that R is a fictitious base ring (coefficient ring) and that S is a series ring over R (e.g. $S = R[[x]]$) with parent object S of type MySeriesRing{T}. We also assume the series in the ring have type MySeries{T}, where T is the type of elements of the base (coefficient) ring.

Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.

Note that the type T must (transitively) belong to the abstract type RingElem.

Constructors

In addition to the standard constructors, the following constructors, taking an array of coefficients, must be available.

For relative power series and Laurent series we have:

(S::MySeriesRing{T})(A::Vector{T}, len::Int, prec::Int, val::Int) where T <: RingElem

Create the series in the given ring whose valuation is val, whose absolute precision is given by prec and the coefficients of which are given by A, starting from the first nonzero term. Only len terms of the array are used, the remaining terms being ignored. The value len cannot exceed the length of the supplied array.

It is permitted to have trailing zeros in the array, but it is not needed, even if the precision minus the valuation is bigger than the length of the array.

(S::MySeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: RingElem}

As above, but where the array is an array of coefficient that can be coerced into the base ring of the series ring.

(S::MySeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: Integer}

As above, but where the array is an array of integers that can be coerced into the base ring of the series ring.

It may be desirable to implement an addition version which accepts an array of Julia Int values if this can be done more efficiently.

For absolute power series we have:

(S::MySeriesRing{T})(A::Vector{T}, len::Int, prec::Int) where T <: RingElem

Create the series in the given ring whose absolute precision is given by prec and the coefficients of which are given by A, starting from the constant term. Only len terms of the array are used, the remaining terms being ignored.

Note that len is usually maintained separately of any polynomial that is underlying the power series. This allows for easy trucation of a power series without actually modifying the polynomial underlying it.

It is permitted to have trailing zeros in the array, but it is not needed, even if the precision is bigger than the length of the array.

It is also possible to create series directly without having to create the corresponding series ring.

abs_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T
-rel_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, val::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T

Create the power series over the given base ring R with coefficients specified by arr with the given absolute precision prec and in the case of relative series with the given valuation val.

Note that more coefficients may be specified than are actually used. Only the first len coefficients are made part of the series, the remainder being stored internally but ignored.

In the case of absolute series one must have prec >= len and in the case of relative series one must have prec >= len + val.

By default the series are created in a ring with variable x and max_precision equal to prec, however one may specify these directly to override the defaults. Note that series are only compatible if they have the same coefficient ring R, max_precision and variable name var.

Also by default any parent ring created is cached. If this behaviour is not desired, set cached=false. However, this means that subsequent series created in the same way will not be compatible. Instead, one should use the parent object of the first series to create subsequent series instead of calling this function repeatedly with cached=false.

Data type and parent object methods

var(S::MySeriesRing{T}) where T <: RingElem

Return a Symbol representing the variable (generator) of the series ring. Note that this is a Symbol not a String, though its string value will usually be used when printing series.

Custom series types over a given ring should define one of the following functions which return the type of an absolute or relative series object over that ring.

abs_series_type(::Type{T}) where T <: RingElement
-rel_series_type(::Type{T}) where T <: RingElement

Return the type of a series whose coefficients have the given type.

This function is defined for generic series and only needs to be defined for custom series rings, e.g. ones defined by a C implementation.

max_precision(S::MySeriesRing{T}) where T <: RingElem

Return the (default) maximum precision of the power series ring. This is the precision that the output of an operation will be if it cannot be represented to full precision (e.g. because it mathematically has infinite precision).

This value is usually supplied upon creation of the series ring and stored in the ring. It is independent of the precision which each series in the ring actually has. Those are stored on a per element basis in the actual series elements.

Basic manipulation of rings and elements

pol_length(f::MySeries{T}) where T <: RingElem

Return the length of the polynomial underlying the given power series. This is not generally useful to the user, but is used internally.

set_length!(f::MySeries{T}, n::Int) where T <: RingElem

This function sets the effective length of the polynomial underlying the given series. The function doesn't modify the actual polynomial, but simply changes the number of terms of the polynomial which are considered to belong to the power series. The remaining terms are ignored.

This function cannot set the length to a value greater than the length of any underlying polynomial.

The function mutates the series in-place but does not return the mutated series.

precision(f::MySeries{T})

Return the absolute precision of $f$.

set_precision!(f::MySeries{T}, prec::Int)

Set the absolute precision of the given series to the given value.

This return the updated series.

valuation(f::MySeries{T})

Return the valuation of the given series.

set_valuation!(f::MySeries{T}, val::Int)

For relative series and Laurent series only, this function alters the valuation of the given series to the given value.

This function returns the updated series.

polcoeff(f::MySeries{T}, n::Int)

Return the coefficient of degree n of the polynomial underlying the series. If n is larger than the degree of this polynomial, zero is returned. This function is not generally of use to the user but is used internally.

setcoeff!(f::MySeries{T}, n::Int, a::T) where T <: RingElem

Set the degree $n$ coefficient of the polynomial underlying $f$ to $a$. This mutates the polynomial in-place if possible and returns the mutated series (so that immutable types can also be supported). The function must not assume that the polynomial already has space for $n + 1$ coefficients. The polynomial must be resized if this is not the case.

Note

This function is not required to normalise the polynomial and is not necessarily useful to the user, but is used extensively by the generic functionality in AbstractAlgebra.jl. It is for setting raw coefficients in the representation.

normalise(f::MySeries{T}, n::Int)

Given a series $f$ represented by a polynomial of at least the given length, return the normalised length of the underlying polynomial assuming it has length at most $n$. This function does not actually normalise the polynomial and is not particularly useful to the user. It is used internally.

renormalize!(f::MySeries{T}) where T <: RingElem

Given a relative series or Laurent series whose underlying polynomial has zero constant term, say as the result of some internal computation, renormalise the series so that the polynomial has nonzero constant term. The precision and valuation of the series are adjusted to compensate. This function is not intended to be useful to the user, but is used internally.

fit!(f::MySeries{T}, n::Int) where T <: RingElem

Ensure that the polynomial underlying $f$ internally has space for $n$ coefficients. This function must mutate the series in-place if it is mutable. It does not return the mutated series. Immutable types can still be supported by defining this function to do nothing.

Some interfaces for C polynomial types automatically manage the internal allocation of polynomials in every function that can be called on them. Explicit adjustment by the generic code in AbstractAlgebra.jl is not required. In such cases, this function can also be defined to do nothing.

gen(R::MySeriesRing{T}) where T <: RingElem

Return the generator x of the series ring.

Optional functionality for series

Similar and zero

The following functions are available for all absolute and relative series types. The functions similar and zero do the same thing, but are provided for uniformity with other parts of the interface.

similar(x::MySeries, R::Ring, max_prec::Int, var::VarName=var(parent(x)); cached::Bool=true)
-zero(a::MySeries, R::Ring, max_prec::Int, var::VarName=var(parent(a)); cached::Bool=true)

Construct the zero series with the given variable (if specified), coefficients in the specified coefficient ring and with relative/absolute precision cap on its parent ring as given by max_prec.

similar(x::MySeries, R::Ring, var::VarName=var(parent(x)); cached::Bool=true)
-similar(x::MySeries, max_prec::Int, var::VarName=var(parent(x)); cached::Bool=true)
-similar(x::MySeries, var::VarName=var(parent(x)); cached::Bool=true)
-similar(x::MySeries, R::Ring, max_prec::Int, var::VarName; cached::Bool=true)
-similar(x::MySeries, R::Ring, var::VarName; cached::Bool=true)
-similar(x::MySeries, max_prec::Int, var::VarName; cached::Bool=true)
-similar(x::MySeries, var::VarName; cached::Bool=true)
-zero(x::MySeries, R::Ring, var::VarName=var(parent(x)); cached::Bool=true)
-zero(x::MySeries, max_prec::Int, var::VarName=var(parent(x)); cached::Bool=true)
-zero(x::MySeries, var::VarName=var(parent(x)); cached::Bool=true)
-zero(x::MySeries, R::Ring, max_prec::Int, var::VarName; cached::Bool=true)
-zero(x::MySeries, R::Ring, var::VarName; cached::Bool=true)
-zero(x::MySeries, max_prec::Int, var::VarName; cached::Bool=true)
-zero(x::MySeries, var::VarName; cached::Bool=true)

As above, but use the precision cap of the parent ring of x and the base_ring of x if these are not specified.

Custom series rings may choose which series type is best-suited to return for the given coefficient ring, precision cap and variable, however they should return a series with the same model as x, i.e. relative or series.

If custom implementations don't specialise these function the default return type is a Generic.AbsSeries or Generic.RelSeries.

The default implementation of zero calls out to similar, so it's generally sufficient to specialise only similar. For both similar and zero only the most general method has to be implemented as all other methods call out to this more general method.

diff --git a/previews/PR2578/AbstractAlgebra/submodule/index.html b/previews/PR2578/AbstractAlgebra/submodule/index.html deleted file mode 100644 index ac084bc2f9c4..000000000000 --- a/previews/PR2578/AbstractAlgebra/submodule/index.html +++ /dev/null @@ -1,86 +0,0 @@ - -Submodules · Oscar.jl

Submodules

AbstractAlgebra allows the construction of submodules/subvector spaces of AbstractAlgebra modules over euclidean domains. These are given as the submodule generated by a finite list of elements in the original module.

We define two submodules to be equal if they are (transitively) submodules of the same module $M$ and their generators generate the same set of elements.

Generic submodule type

AbstractAlgebra implements a generic submodule type Generic.Submodule{T} where T is the element type of the base ring in src/generic/Submodule.jl. See src/generic/GenericTypes.jl for more details of the type definition.

Elements of a generic submodule have type Generic.SubmoduleElem{T}.

Abstract types

Submodule types belong to the abstract type FPModule{T} and their elements to FPModuleElem{T}.

Constructors

subMethod
sub(m::AbstractAlgebra.FPModule{T}, gens::Vector{<:AbstractAlgebra.FPModuleElem{T}}) where T <: RingElement

Return the submodule of the module m generated by the given generators, given as elements of m.

subMethod
sub(m::Module{T}, subs::Vector{<:Generic.Submodule{T}}) where T <: RingElement

Return the submodule S of the module m generated by the union of the given submodules of $m$, and a map which is the canonical injection from S to m.

Note that the preimage of the canonical injection can be obtained using the preimage function described in the section on module homomorphisms. As the canonical injection is injective, this is unique.

Examples

julia> M = FreeModule(ZZ, 2)
-Free module of rank 2 over integers
-
-julia> m = M([ZZ(1), ZZ(2)])
-(1, 2)
-
-julia> n = M([ZZ(2), ZZ(-1)])
-(2, -1)
-
-julia> N, f = sub(M, [m, n])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 2 over integers)
-
-julia> v = N([ZZ(3), ZZ(4)])
-(3, 4)
-
-julia> v2 = f(v)
-(3, 26)
-
-julia> V = VectorSpace(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> m = V([QQ(1), QQ(2)])
-(1//1, 2//1)
-
-julia> n = V([QQ(2), QQ(-1)])
-(2//1, -1//1)
-
-julia> N, f = sub(V, [m, n])
-(Subspace over Rationals with 2 generators and no relations, Hom: Subspace over Rationals with 2 generators and no relations -> Vector space of dimension 2 over rationals)
-

Functionality for submodules

In addition to the Module interface, AbstractAlgebra submodules implement the following functionality.

Basic manipulation

supermoduleMethod
supermodule(M::Submodule{T}) where T <: RingElement

Return the module that this module is a submodule of.

is_submoduleMethod
is_submodule(M::AbstractAlgebra.FPModule{T}, N::AbstractAlgebra.FPModule{T}) where T <: RingElement

Return true if $N$ was constructed as a submodule of $M$. The relation is taken transitively (i.e. subsubmodules are submodules for the purposes of this relation, etc). The module $M$ is also considered a submodule of itself for this relation.

is_compatibleMethod
is_compatible(M::AbstractAlgebra.FPModule{T}, N::AbstractAlgebra.FPModule{T}) where T <: RingElement

Return true, P if the given modules are compatible, i.e. that they are (transitively) submodules of the same module, P. Otherwise return false, M.

dimMethod
dim(N::Submodule{T}) where T <: FieldElement

Return the dimension of the given vector subspace.

Examples

julia> M = FreeModule(ZZ, 2)
-Free module of rank 2 over integers
-
-julia> m = M([ZZ(2), ZZ(3)])
-(2, 3)
-
-julia> n = M([ZZ(1), ZZ(4)])
-(1, 4)
-
-julia> N1, = sub(M, [m, n])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 2 over integers)
-
-julia> N2, = sub(M, [m])
-(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)
-
-julia> supermodule(N1) == M
-true
-
-julia> is_compatible(N1, N2)
-(true, Free module of rank 2 over integers)
-
-julia> is_submodule(N1, M)
-false
-
-
-julia> V = VectorSpace(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> m = V([QQ(2), QQ(3)])
-(2//1, 3//1)
-
-julia> N, = sub(V, [m])
-(Subspace over Rationals with 1 generator and no relations, Hom: Subspace over Rationals with 1 generator and no relations -> Vector space of dimension 2 over rationals)
-
-julia> dim(V)
-2
-
-julia> dim(N)
-1
-

Intersection

intersectMethod
Base.intersect(M::FPModule{T}, N::FPModule{T}) where T <: RingElement

Return the intersection of the modules $M$ as a submodule of $M$. Note that $M$ and $N$ must be (constructed as) submodules (transitively) of some common module $P$.

Examples

julia> M = FreeModule(ZZ, 2)
-Free module of rank 2 over integers
-
-julia> m = M([ZZ(2), ZZ(3)])
-(2, 3)
-
-julia> n = M([ZZ(1), ZZ(4)])
-(1, 4)
-
-julia> N1 = sub(M, [m, n])
-(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 2 over integers)
-
-julia> N2 = sub(M, [m])
-(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)
-
-julia> I = intersect(N1, N2)
-Any[]
diff --git a/previews/PR2578/AbstractAlgebra/total_fraction/index.html b/previews/PR2578/AbstractAlgebra/total_fraction/index.html deleted file mode 100644 index d19b0f25a3e1..000000000000 --- a/previews/PR2578/AbstractAlgebra/total_fraction/index.html +++ /dev/null @@ -1,108 +0,0 @@ - -Total ring of fractions · Oscar.jl

Total ring of fractions

AbstractAlgebra.jl provides a module, implemented in src/generic/TotalFraction.jl, for the total ring of fractions of a ring.

The total ring of fractions of a ring R is the localisation of R at the non-zero divisors of R, the latter being a multiplicative subset of R.

There are no restrictions on the ring except the function is_zero_divisor must be defined and effective for R.

In particular, we do not assume that all elements of R which are not zero divisors are units in R. This has the effect of making exact division impossible generically in the total ring of fractions of R.

This in turn limits the usefulness of the total ring of fractions as a ring in AbstractAlgebra as a great deal of generic code relies on divexact. Should this be a limitation, the user can define their own divexact function for the total ring of fractions in question.

Note that in most cases a*inv(b) is not a sufficient definition of divexact(a, b) due to the possibility that b is not a unit in the total ring of fractions.

It is also possible to construct a total ring of fractions of R without the is_zero_divisor function existing for R, but some functions such as is_unit, inv, rand and ad hoc arithmetic operations involving rational numbers are not available for the total ring of fractions. One must also construct fractions using the option check=false and it is one's own responsibility to check that the denominator is not a zero divisor.

Note that although the total ring of fractions of an integral domain R is mathematically the same thing as the fraction field of R, these will be different objects in AbstractAlgebra and have different types.

Generic total ring of fraction types

AbstractAlgebra.jl implements a generic type for elements of a total ring of fractions, namelyGeneric.TotFrac{T} where T is the type of elements of the base ring. See the file src/generic/GenericTypes.jl for details.

Parent objects of such elements have type Generic.TotFracRing{T}.

Abstract types

The types for elements of a total ring of fractions belong directly to the abstract type RingElem and the type for the total ring of fractions parent object belongs directly to the abstract type Ring.

Total ring of fractions constructors

In order to construct fractions in a total ring of fractions in AbstractAlgebra.jl, one must first construct the parent object for the total ring of fractions itself. This is accomplished with the following constructor.

total_ring_of_fractions(R::Ring; cached::Bool = true)

Given a base ring R return the parent object of the total ring of fractions of $R$. By default the parent object S will depend only on R and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.

Here are some examples of creating a total ring of fractions and making use of the resulting parent objects to coerce various elements into the ring.

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = total_ring_of_fractions(R)
-Total ring of fractions of Univariate polynomial ring in x over integers
-
-julia> f = S()
-0
-
-julia> g = S(123)
-123
-
-julia> h = S(BigInt(1234))
-1234
-
-julia> k = S(x + 1)
-x + 1

Fraction constructors

One can construct fractions using the total ring of fractions parent object, as for any ring or field.

(R::TotFracRing)() # constructs zero
-(R::TotFracRing)(c::Integer)
-(R::TotFracRing)(c::elem_type(R))
-(R::TotFracRing{T})(a::T) where T <: RingElement

Although one cannot use the double slash operator // to construct elements of a total ring of fractions, as no parent has been specified, one can use the double slash operator to construct elements of a total ring of fractions so long as one of the arguments to the double slash operator is already in the total ring of fractions in question.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = total_ring_of_fractions(R)
-Total ring of fractions of Univariate polynomial ring in x over rationals
-
-julia> f = S(x + 1)
-x + 1
-
-julia> f//3
-(x + 1)//3
-
-julia> 3//f
-3//(x + 1)
-
-julia> f//x
-(x + 1)//x

Functions for types and parents of total rings of fractions

Total rings of fractions in AbstractAlgebra.jl implement the Ring interface except for the divexact function which is not generically possible to implement.

base_ring(R::TotFracRing)
-base_ring(a::TotFrac)

Return the base ring of which the total ring of fractions was constructed.

parent(a::TotFrac)

Return the total ring of fractions that the given fraction belongs to.

characteristic(R::TotFracRing)

Return the characteristic of the base ring of the total ring of fractions. If the characteristic is not known an exception is raised.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = total_ring_of_fractions(R)
-Total ring of fractions of Univariate polynomial ring in x over rationals
-
-julia> f = S(x + 1)
-x + 1
-
-julia> U = base_ring(S)
-Univariate polynomial ring in x over rationals
-
-julia> V = base_ring(f)
-Univariate polynomial ring in x over rationals
-
-julia> T = parent(f)
-Total ring of fractions of Univariate polynomial ring in x over rationals
-
-julia> m = characteristic(S)
-0

Total ring of fractions functions

Basic functions

Total rings of fractions implement the Ring interface.

zero(R::TotFracRing)
-one(R::TotFracRing)
-iszero(a::TotFrac)
-isone(a::TotFrac)
inv(a::T) where T <: TotFrac

They also implement some of the following functions which would usually be associated with the field and fraction field interfaces.

is_unit(f::TotFrac)
numerator(a::TotFrac)
-denominator(a::TotFrac)

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over rationals, x)
-
-julia> S = total_ring_of_fractions(R)
-Total ring of fractions of Univariate polynomial ring in x over rationals
-
-julia> f = S(x + 1)
-x + 1
-
-julia> g = f//(x^3 + 3x + 1)
-(x + 1)//(x^3 + 3*x + 1)
-
-julia> h = zero(S)
-0
-
-julia> k = one(S)
-1
-
-julia> isone(k)
-true
-
-julia> iszero(f)
-false
-
-julia> r = deepcopy(f)
-x + 1
-
-julia> n = numerator(g)
-x + 1
-
-julia> d = denominator(g)
-x^3 + 3*x + 1

Random generation

Random fractions can be generated using rand. The parameters passed after the total ring of fractions tell rand how to generate random elements of the base ring.

rand(R::TotFracRing, v...)

Examples

julia> R = residue_ring(ZZ, 12)
-Residue ring of integers modulo 12
-
-julia> K = total_ring_of_fractions(R)
-Total ring of fractions of Residue ring of integers modulo 12
-
-julia> f = rand(K, 0:11)
-7//5
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over integers, x)
-
-julia> S = total_ring_of_fractions(R)
-Total ring of fractions of Univariate polynomial ring in x over integers
-
-julia> g = rand(S, -1:3, -10:10)
-(4*x + 4)//(-4*x^2 - x + 4)
diff --git a/previews/PR2578/AbstractAlgebra/types/index.html b/previews/PR2578/AbstractAlgebra/types/index.html deleted file mode 100644 index 35e90270a828..000000000000 --- a/previews/PR2578/AbstractAlgebra/types/index.html +++ /dev/null @@ -1,18 +0,0 @@ - -Type interface of AbstractAlgebra.jl · Oscar.jl

Type interface of AbstractAlgebra.jl

Apart from how we usually think of types in programming, we shall in this section discuss why we do not use the typical type interface.

Why types aren't enough

Naively, one might have expected that structures like rings in AbstractAlgebra.jl could be modeled as types and their elements as objects with the given type. But there are various reasons why this is not a good model.

Consider the ring $R = \mathbb{Z}/n\mathbb{Z}$ for a multiprecision integer $n$. If we were to model the ring $R$ as a type, then the type would somehow need to contain the modulus $n$. This is not possible in Julia, and in fact it is not desirable, since the compiler would then recompile all the associated functions every time a different modulus $n$ was used.

We could attach the modulus $n$ to the objects representing elements of the ring, rather than their type.

But now we cannot create new elements of the ring $\mathbb{Z}/n\mathbb{Z}$ given only their type, since the type no longer contains the modulus $n$.

Instead, the way we get around this in AbstractAlgebra.jl is to have special (singleton) objects that act like types, but are really just ordinary Julia objects. These objects, called parent objects, can contain extra information, such as the modulus $n$. In return, we associate this parent object with so called element objects.

In order to create new elements of $\mathbb{Z}/n\mathbb{Z}$ as above, we overload the call operator for the parent object.

In the following AbstractAlgebra.jl example, we create the parent object R corresponding to the ring $\mathbb{Z}/7\mathbb{Z}$. We then create a new element a of this ring by calling the parent object R.

R = residue_ring(ZZ, 7)
-a = R(3)

Here, R is the parent object, containing the modulus $7$. So this example creates the element $a = 3 \pmod{7}$.

Objects known as parents which contain additional information about groups, rings, fields and modules, etc., that can't be stored in types alone.

These details are technical and can be skipped or skimmed by new users of Julia/AbstractAlgebra.jl. Types are almost never dealt with directly when scripting AbstractAlgebra.jl to do mathematical computations.

In contrast, AbstractAlgebra.jl developers will want to know how we model mathematical objects and their rings, fields, groups, etc.

The abstract type hierarchy in AbstractAlgebra.jl

In AbstractAlgebra.jl, we use the abstract type hierarchy in order to give structure when programming the mathematical structures. For example, abstract types in Julia can belong to one another in a hierarchy.

For example, the Field abstract type belongs to the Ring abstract type. The full hierarchy can be seen in diagrams under the section on visualisation of the abstract types.

In practice this is practical since it means that any generic function designed to work with ring objects will also work with field objects.

In AbstractAlgebra.jl we also distinguish between the elements of a field, say, and the field itself.

For example, we have an object of type Generic.PolyRing to model a generic polynomial ring, and elements of that polynomial ring would have type Generic.PolyRingElem.

For this purpose, we also have a hierarchy of abstract types, such as FieldElem, that the types of element objects can belong to.

More complex example of parent objects

Here is some code which constructs a polynomial ring over the integers, a polynomial in that ring and then does some introspection to illustrate the various relations between the objects and types.

julia> using AbstractAlgebra
-
-julia> R, x = ZZ["x"]
-(Univariate polynomial ring in x over integers, x)
-
-julia> f = x^2 + 3x + 1
-x^2 + 3*x + 1
-
-julia> R isa PolyRing
-true
-
-julia> f isa PolyRingElem
-true
-
-julia> parent(f) == R
-true
diff --git a/previews/PR2578/AbstractAlgebra/univpolynomial/index.html b/previews/PR2578/AbstractAlgebra/univpolynomial/index.html deleted file mode 100644 index 0a944632745f..000000000000 --- a/previews/PR2578/AbstractAlgebra/univpolynomial/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Universal polynomial · Oscar.jl

Universal polynomial

AbstractAlgebra.jl provides a module, implemented in src/generic/UnivPoly.jl for a universal polynomial ring. This is very similar to the multivariate polynomial rings, except that variables can be added to the ring at any time.

To compensate for the fact that the number of variables may change, many of the functions relax their restrictions on exponent vectors. For example, if one creates a polynomial when the ring only has two variables, each exponent vector would consist of two integers. Later, when the ring has more variable, these exponent vectors will still be accepted. The exponent vectors are simply padded out to the full number of variables behind the scenes.

Generic sparse distributed universal multivariable polynomial types

AbstractAlgebra provides a generic universal polynomial type Generic.UnivPoly{T, U} where T is the type of elements of the coefficient ring and U is the type of the elements of the underlying multivariate polynomial ring. Essentially, U can be any type belonging to MPolyRingElem{T}.

Parent objects of such polynomials have type Generic.UniversalPolyRing{T, U}.

Abstract types

AbstractAlgebra also provides abstract types for universal polynomials and their rings. These are UniversalPolyRingElem{T, U} and UniversalPolyRing{T, U} respectively. These in turn belong to Ring.

Polynomial ring constructors

In order to construct universal polynomials in AbstractAlgebra.jl, one must first construct the universal polynomial ring itself. This is unique given a base ring.

The universal polynomial ring over a given base ring R is constructed with one of the following constructor functions.

UniversalPolynomialRing(R::Ring; cached::Bool = true, ordering::Symbol=:lex)

Given a base ring R and an array S of strings, return an object representing the universal polynomial ring $S = R[\ldots]$ with no variables in it initially.

Examples

julia> S = UniversalPolynomialRing(ZZ)
-Universal Polynomial Ring over Integers

Adding variables

There are two ways to add variables to a universal polynomial ring S.

gen(S::UniversalPolyRing, var::VarName)
-gens(S::UniversalPolyRing, vars::Vector{VarName})

Examples

julia> S = UniversalPolynomialRing(ZZ)
-Universal Polynomial Ring over Integers
-
-julia> x = gen(S, "x")
-x
-
-julia> y, z = gens(S, ["y", "z"])
-(y, z)

Universal polynomial functionality

The universal polynomial ring behaves exactly like a multivariate polynomial ring with the few differences noted above.

The only functionality not implemented is the ability to do divrem by an ideal of polynomials.

The universal polynomial ring is very useful for doing symbolic manipulation. However, it is important to understand that AbstractAlgebra is not a symbolic system and the performance of the universal polynomial ring will closely match that of a multivariate polynomial ring with the same number of variables.

The disadvantage of this approach to symbolic manipulation is that some manipulations that would be offered by a symbolic system are not available, as variables are not identified by their names alone in AbstractAlgebra, as would be the case symbolically, but by objects.

The most powerful symbolic tools we offer are the generalised evaluation functions, the multivariate coefficient functionality, the ability to change coefficient ring and to map coefficients according to a supplied function and the ability to convert a multivariate which happens to have just one variable into a dense univariate polynomial.

Further facilities may be added in future to ease symbolic manipulations.

diff --git a/previews/PR2578/AbstractAlgebra/visualizing_types/index.html b/previews/PR2578/AbstractAlgebra/visualizing_types/index.html deleted file mode 100644 index e1c9045160ed..000000000000 --- a/previews/PR2578/AbstractAlgebra/visualizing_types/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Visualization of the types of AbstractAlgebra.jl · Oscar.jl

Visualization of the types of AbstractAlgebra.jl

AbstractAlgebra.jl implements a couple of abstract types which can be extended.

Abstract parents

The following diagram shows a complete list of all abstract types in AbstractAlgebra.jl.

Diagram of parent types

Abstract elements

Similarly the following diagram shows a complete list of all abstract types in AbstractAlgebra.jl.

Diagram of element types

Concrete types in AbstractAlgebra.jl

Until now we have discussed the abstract types of AbstractAlgebra.jl. Under this subsection we will instead give some examples of concrete types in AbstractAlgebra.jl.

In parentheses we put the types of the corresponding parent objects.

  • Perm{<:Integer} (SymmetricGroup{<:Integer})
  • GFElem{<:Integer} (GFField{<:Integer})

We also think of various Julia types as though they were AbstractAlgebra.jl types:

  • BigInt (Integers{BigInt})
  • Rational{BigInt} (Rationals{BigInt})

Then there are various types for generic constructions over a base ring. They are all parameterised by a type T which is the type of the elements of the base ring they are defined over.

  • Generic.Poly{T} (Generic.PolyRing{T})
  • Generic.MPoly{T} (Generic.MPolyRing{T})
  • Generic.RelSeries{T} (Generic.RelPowerSeriesRing{T})
  • Generic.AbsSeries{T} (Generic.AbsPowerSeriesRing{T})
  • Generic.LaurentSeriesRingElem{T} (Generic.LaurentSeriesRing{T})
  • Generic.LaurentSeriesFieldElem{T} (Generic.LaurentSeriesField{T})
  • Generic.ResidueRingElem{T} (Generic.ResidueRing{T})
  • Generic.Frac{T} (Generic.FracField{T})
  • Generic.Mat{T} (Generic.MatSpace{T})
diff --git a/previews/PR2578/AbstractAlgebra/ytabs/index.html b/previews/PR2578/AbstractAlgebra/ytabs/index.html deleted file mode 100644 index 19ad632810f9..000000000000 --- a/previews/PR2578/AbstractAlgebra/ytabs/index.html +++ /dev/null @@ -1,260 +0,0 @@ - -Partitions and Young tableaux · Oscar.jl

Partitions and Young tableaux

AbstractAlgebra.jl provides basic support for computations with Young tableaux, skew diagrams and the characters of permutation groups (implemented src/generic/YoungTabs.jl). All functionality of permutations is accessible in the Generic submodule.

Partitions

The basic underlying object for those concepts is Partition of a number $n$, i.e. a sequence of positive integers $n_1, \ldots, n_k$ which sum to $n$. Partitions in AbstractAlgebra.jl are represented internally by non-increasing Vectors of Ints. Partitions are printed using the standard notation, i.e. $9 = 4 + 2 + 1 + 1 + 1$ is shown as $4_1 2_1 1_3$ with the subscript indicating the count of a summand in the partition.

PartitionType
Partition(part::Vector{<:Integer}[, check::Bool=true]) <: AbstractVector{Int}

Represent integer partition in the non-increasing order.

part will be sorted, if necessary. Checks for validity of input can be skipped by calling the (inner) constructor with false as the second argument.

Functionally Partition is a thin wrapper over Vector{Int}.

Fieldnames:

  • n::Int - the partitioned number
  • part::Vector{Int} - a non-increasing sequence of summands of n.

Examples

julia> p = Partition([4,2,1,1,1])
-4₁2₁1₃
-
-julia> p.n == sum(p.part)
-true

Array interface

Partition is a concrete (immutable) subtype of AbstractVector{Integer} and implements the standard Array interface.

sizeMethod
size(p::Partition)

Return the size of the vector which represents the partition.

Examples

julia> p = Partition([4,3,1]); size(p)
-(3,)
getindexMethod
getindex(p::Partition, i::Integer)

Return the i-th part (in non-increasing order) of the partition.

These functions work on the level of p.part vector.

One can easily iterate over all partitions of $n$ using the Generic.partitions function.

partitionsFunction
partitions(n::Integer)

Return the vector of all permutations of n. For an unsafe generator version see partitions!.

Examples

julia> Generic.partitions(5)
-7-element Vector{AbstractAlgebra.Generic.Partition{Int64}}:
- 1₅
- 2₁1₃
- 3₁1₂
- 2₂1₁
- 4₁1₁
- 3₁2₁
- 5₁

You may also have a look at JuLie.jl package for more utilities related to partitions.

The number of all partitions can be computed by the hidden function _numpart. Much faster implementation is available in Nemo.jl.

_numpartFunction
_numpart(n::Integer)

Return the number of all distinct integer partitions of n. The function uses Euler pentagonal number theorem for recursive formula. For more details see OEIS sequence A000041. Note that _numpart(0) = 1 by convention.

Since Partition is a subtype of AbstractVector generic functions which operate on vectors should work in general. However the meaning of conj has been changed to agree with the traditional understanding of conjugation of Partitions:

conjMethod
conj(part::Partition)

Return the conjugated partition of part, i.e. the partition corresponding to the Young diagram of part reflected through the main diagonal.

Examples

julia> p = Partition([4,2,1,1,1])
-4₁2₁1₃
-
-julia> conj(p)
-5₁2₁1₂
conjMethod
conj(part::Partition, v::Vector)

Return the conjugated partition of part together with permuted vector v.

Young Diagrams and Young Tableaux

Mathematically speaking Young diagram is a diagram which consists of rows of square boxes such that the number of boxes in each row is no less than the number of boxes in the previous row. For example partition $4_1 3_2 1$ represents the following diagram.

┌───┬───┬───┬───┐
-│   │   │   │   │
-├───┼───┼───┼───┘
-│   │   │   │
-├───┼───┼───┤
-│   │   │   │
-├───┼───┴───┘
-│   │
-└───┘

Young Tableau is formally a bijection between the set of boxes of a Young Diagram and the set $\{1, \ldots, n\}$. If a bijection is increasing along rows and columns of the diagram it is referred to as standard. For example

┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┼───┤
-│ 8 │ 9 │10 │
-├───┼───┴───┘
-│11 │
-└───┘

is a standard Young tableau of $4_1 3_2 1$ where the bijection assigns consecutive natural numbers to consecutive (row-major) cells.

Constructors

In AbstractAlgebra.jl Young tableau are implemented as essentially row-major sparse matrices, i.e. YoungTableau <: AbstractMatrix{Int} but only the defining Partition and the (row-major) fill-vector is stored.

YoungTableauType
YoungTableau(part::Partition[, fill::Vector{Int}=collect(1:sum(part))])  <: AbstractMatrix{Int}

Return the Young tableaux of partition part, filled linearly by fill vector. Note that fill vector is in row-major format.

Fields:

  • part - the partition defining Young diagram
  • fill - the row-major fill vector: the entries of the diagram.

Examples

julia> p = Partition([4,3,1]); y = YoungTableau(p)
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> y.part
-4₁3₁1₁
-
-julia> y.fill
-8-element Vector{Int64}:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8

For convenience there exists an alternative constructor of YoungTableau, which accepts a vector of integers and constructs Partition internally.

YoungTableau(p::Vector{Integer}[, fill=collect(1:sum(p))])

Array interface

To make YoungTableaux array-like we implement the following functions:

sizeMethod
size(Y::YoungTableau)

Return size of the smallest array containing Y, i.e. the tuple of the number of rows and the number of columns of Y.

Examples

julia> y = YoungTableau([4,3,1]); size(y)
-(3, 4)
getindexMethod
getindex(Y::YoungTableau, n::Integer)

Return the column-major linear index into the size(Y)-array. If a box is outside of the array return 0.

Examples

julia> y = YoungTableau([4,3,1])
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> y[1]
-1
-
-julia> y[2]
-5
-
-julia> y[4]
-2
-
-julia> y[6]
-0

Also the double-indexing corresponds to (row, column) access to an abstract array.

julia> y = YoungTableau([4,3,1])
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> y[1,2]
-2
-
-julia> y[2,3]
-7
-
-julia> y[3,2]
-0

Functions defined for AbstractArray type based on those (e.g. length) should work. Again, as in the case of Partition the meaning of conj is altered to reflect the usual meaning for Young tableaux:

conjMethod
conj(Y::YoungTableau)

Return the conjugated tableau, i.e. the tableau reflected through the main diagonal.

Examples

julia> y = YoungTableau([4,3,1])
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> conj(y)
-┌───┬───┬───┐
-│ 1 │ 5 │ 8 │
-├───┼───┼───┘
-│ 2 │ 6 │
-├───┼───┤
-│ 3 │ 7 │
-├───┼───┘
-│ 4 │
-└───┘

Pretty-printing

Similarly to permutations we have two methods of displaying Young Diagrams:

setyoungtabstyleFunction
setyoungtabstyle(format::Symbol)

Select the style in which Young tableaux are displayed (in REPL or in general as string). This can be either

  • :array - as matrices of integers, or
  • :diagram - as filled Young diagrams (the default).

The difference is purely esthetical.

Examples

julia> Generic.setyoungtabstyle(:array)
-:array
-
-julia> p = Partition([4,3,1]); YoungTableau(p)
- 1  2  3  4
- 5  6  7
- 8
-
-julia> Generic.setyoungtabstyle(:diagram)
-:diagram
-
-julia> YoungTableau(p)
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘

Ulitility functions

matrix_reprMethod
matrix_repr(a::Perm)

Return the permutation matrix as a sparse matrix representing a via natural embedding of the permutation group into the general linear group over $\mathbb{Z}$.

Examples

julia> p = Perm([2,3,1])
-(1,2,3)
-
-julia> matrix_repr(p)
-3×3 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
- ⋅  1  ⋅
- ⋅  ⋅  1
- 1  ⋅  ⋅
-
-julia> Array(ans)
-3×3 Matrix{Int64}:
- 0  1  0
- 0  0  1
- 1  0  0
matrix_repr(Y::YoungTableau)

Construct sparse integer matrix representing the tableau.

Examples

julia> y = YoungTableau([4,3,1]);
-
-
-julia> matrix_repr(y)
-3×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 8 stored entries:
- 1  2  3  4
- 5  6  7  ⋅
- 8  ⋅  ⋅  ⋅
fill!Method
fill!(Y::YoungTableaux, V::Vector{<:Integer})

Replace the fill vector Y.fill by V. No check if the resulting tableau is standard (i.e. increasing along rows and columns) is performed.

Examples

julia> y = YoungTableau([4,3,1])
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> fill!(y, [2:9...])
-┌───┬───┬───┬───┐
-│ 2 │ 3 │ 4 │ 5 │
-├───┼───┼───┼───┘
-│ 6 │ 7 │ 8 │
-├───┼───┴───┘
-│ 9 │
-└───┘

Characters of permutation groups

Irreducible characters (at least over field of characteristic $0$) of the full group of permutations $S_n$ correspond via Specht modules to partitions of $n$.

characterMethod
character(lambda::Partition)

Return the $\lambda$-th irreducible character of permutation group on sum(lambda) symbols. The returned character function is of the following signature:

chi(p::Perm[, check::Bool=true]) -> BigInt

The function checks (if p belongs to the appropriate group) can be switched off by calling chi(p, false). The values computed by $\chi$ are cached in look-up table.

The computation follows the Murnaghan-Nakayama formula: $\chi_\lambda(\sigma) = \sum_{\text{rimhook }\xi\subset \lambda}(-1)^{ll(\lambda\backslash\xi)} \chi_{\lambda \backslash\xi}(\tilde\sigma)$ where $\lambda\backslash\xi$ denotes the skew diagram of $\lambda$ with $\xi$ removed, $ll$ denotes the leg-length (i.e. number of rows - 1) and $\tilde\sigma$ is permutation obtained from $\sigma$ by the removal of the longest cycle.

For more details see e.g. Chapter 2.8 of Group Theory and Physics by S.Sternberg.

Examples

julia> G = SymmetricGroup(4)
-Full symmetric group over 4 elements
-
-julia> chi = character(Partition([3,1])); # character of the regular representation
-
-
-julia> chi(one(G))
-3
-
-julia> chi(perm"(1,3)(2,4)")
--1
characterMethod
character(lambda::Partition, p::Perm, check::Bool=true) -> BigInt

Return the value of lambda-th irreducible character of the permutation group on permutation p.

characterMethod
character(lambda::Partition, mu::Partition, check::Bool=true) -> BigInt

Return the value of lambda-th irreducible character on the conjugacy class represented by partition mu.

The values computed by characters are cached in an internal dictionary Dict{Tuple{BitVector,Vector{Int}}, BigInt}. Note that all of the above functions return BigInts. If you are sure that the computations do not overflow, variants of the last two functions using Int are available:

character(::Type{Int}, lambda::Partition, p::Perm[, check::Bool=true])
-character(::Type{Int}, lambda::Partition, mu::Partition[, check::Bool=true])

The dimension $\dim \lambda$ of the irreducible module corresponding to partition $\lambda$ can be computed using Hook length formula

rowlengthFunction
rowlength(Y::YoungTableau, i, j)

Return the row length of Y at box (i,j), i.e. the number of boxes in the i-th row of the diagram of Y located to the right of the (i,j)-th box.

Examples

julia> y = YoungTableau([4,3,1])
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> Generic.rowlength(y, 1,2)
-2
-
-julia> Generic.rowlength(y, 2,3)
-0
-
-julia> Generic.rowlength(y, 3,3)
-0
collengthFunction
collength(Y::YoungTableau, i, j)

Return the column length of Y at box (i,j), i.e. the number of boxes in the j-th column of the diagram of Y located below of the (i,j)-th box.

Examples

julia> y = YoungTableau([4,3,1])
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> Generic.collength(y, 1,1)
-2
-
-julia> Generic.collength(y, 1,3)
-1
-
-julia> Generic.collength(y, 2,4)
-0
hooklengthFunction
hooklength(Y::YoungTableau, i, j)

Return the hook-length of an element in Y at position (i,j), i.e the number of cells in the i-th row to the right of (i,j)-th box, plus the number of cells in the j-th column below the (i,j)-th box, plus 1.

Return 0 for (i,j) not in the tableau Y.

Examples

julia> y = YoungTableau([4,3,1])
-┌───┬───┬───┬───┐
-│ 1 │ 2 │ 3 │ 4 │
-├───┼───┼───┼───┘
-│ 5 │ 6 │ 7 │
-├───┼───┴───┘
-│ 8 │
-└───┘
-
-julia> hooklength(y, 1,1)
-6
-
-julia> hooklength(y, 1,3)
-3
-
-julia> hooklength(y, 2,4)
-0
dimMethod
dim(Y::YoungTableau) -> BigInt

Return the dimension (using hook-length formula) of the irreducible representation of permutation group $S_n$ associated the partition Y.part.

Since the computation overflows easily BigInt is returned. You may perform the computation of the dimension in different type by calling dim(Int, Y).

Examples

julia> dim(YoungTableau([4,3,1]))
-70
-
-julia> dim(YoungTableau([3,1])) # the regular representation of S_4
-3

The character associated with Y.part can also be used to compute the dimension, but as it is expected the Murnaghan-Nakayama is much slower even though (due to caching) consecutive calls are fast:

julia> λ = Partition(collect(12:-1:1))
-12₁11₁10₁9₁8₁7₁6₁5₁4₁3₁2₁1₁
-
-julia> @time dim(YoungTableau(λ))
-  0.224430 seconds (155.77 k allocations: 7.990 MiB)
-9079590132732747656880081324531330222983622187548672000
-
-julia> @time dim(YoungTableau(λ))
-  0.000038 seconds (335 allocations: 10.734 KiB)
-9079590132732747656880081324531330222983622187548672000
-
-julia> G = SymmetricGroup(sum(λ))
-Full symmetric group over 78 elements
-
-julia> @time character(λ, one(G))
-  0.000046 seconds (115 allocations: 16.391 KiB)
-9079590132732747656880081324531330222983622187548672000
-
-julia> @time character(λ, one(G))
-  0.001439 seconds (195 allocations: 24.453 KiB)
-9079590132732747656880081324531330222983622187548672000

Low-level functions and characters

As mentioned above character functions use the Murnaghan-Nakayama rule for evaluation. The implementation follows

Dan Bernstein, The computational complexity of rules for the character table of $S_n$ Journal of Symbolic Computation, 37 (6), 2004, p. 727-748,

implementing the following functions. For precise definitions and meaning please consult the paper cited.

partitionseqFunction
partitionseq(lambda::Partition)

Return a sequence (as BitVector) of falses and trues constructed from lambda: tracing the lower contour of the Young Diagram associated to lambda from left to right a true is inserted for every horizontal and false for every vertical step. The sequence always starts with true and ends with false.

partitionseq(seq::BitVector)

Return the essential part of the sequence seq, i.e. a subsequence starting at first true and ending at last false.

is_rimhookMethod
is_rimhook(R::BitVector, idx::Integer, len::Integer)

R[idx:idx+len] forms a rim hook in the Young Diagram of partition corresponding to R iff R[idx] == true and R[idx+len] == false.

MN1innerFunction
MN1inner(R::BitVector, mu::Partition, t::Integer, charvals)

Return the value of $\lambda$-th irreducible character on conjugacy class of permutations represented by partition mu, where R is the (binary) partition sequence representing $\lambda$. Values already computed are stored in charvals::Dict{Tuple{BitVector,Vector{Int}}, Int}. This is an implementation (with slight modifications) of the Murnaghan-Nakayama formula as described in

Dan Bernstein,
-"The computational complexity of rules for the character table of Sn"
-_Journal of Symbolic Computation_, 37(6), 2004, p. 727-748.

Skew Diagrams

Skew diagrams are formally differences of two Young diagrams. Given $\lambda$ and $\mu$, two partitions of $n+m$ and $m$ (respectively). Suppose that each of cells of $\mu$ is a cell of $\lambda$ (i.e. parts of $\mu$ are no greater than the corresponding parts of $\lambda$). Then the skew diagram denoted by $\lambda/\mu$ is the set theoretic difference the of sets of boxes, i.e. is a diagram with exactly $n$ boxes:

SkewDiagramType
SkewDiagram(lambda::Partition, mu::Partition) <: AbstractMatrix{Int}

Implements a skew diagram, i.e. a difference of two Young diagrams represented by partitions lambda and mu. (below dots symbolise the removed entries)

Examples

julia> l = Partition([4,3,2])
-4₁3₁2₁
-
-julia> m = Partition([3,1,1])
-3₁1₂
-
-julia> xi = SkewDiagram(l,m)
-3×4 AbstractAlgebra.Generic.SkewDiagram{Int64}:
- ⋅  ⋅  ⋅  1
- ⋅  1  1
- ⋅  1
-

SkewDiagram implements array interface with the following functions:

sizeMethod
size(xi::SkewDiagram)

Return the size of array where xi is minimally contained. See size(Y::YoungTableau) for more details.

inMethod
in(t::Tuple{Integer,Integer}, xi::SkewDiagram)

Check if box at position (i,j) belongs to the skew diagram xi.

getindexMethod
getindex(xi::SkewDiagram, n::Integer)

Return 1 if linear index n corresponds to (column-major) entry in xi.lam which is not contained in xi.mu. Otherwise return 0.

The support for skew diagrams is very rudimentary. The following functions are available:

is_rimhookMethod
is_rimhook(xi::SkewDiagram)

Check if xi represents a rim-hook diagram, i.e. its diagram is edge-connected and contains no $2\times 2$ squares.

leglengthFunction
leglength(xi::SkewDiagram[, check::Bool=true])

Compute the leglength of a rim-hook xi, i.e. the number of rows with non-zero entries minus one. If check is false function will not check whether xi is actually a rim-hook.

matrix_reprMethod
matrix_repr(xi::SkewDiagram)

Return a sparse representation of the diagram xi, i.e. a sparse array A where A[i,j] == 1 if and only if (i,j) is in xi.lam but not in xi.mu.

diff --git a/previews/PR2578/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html b/previews/PR2578/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html deleted file mode 100644 index 15dacef68b7c..000000000000 --- a/previews/PR2578/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html +++ /dev/null @@ -1,72 +0,0 @@ - -Affine Algebraic Sets · Oscar.jl

Affine Algebraic Sets

Introduction

Let $\mathbb{A}^n(k)=k^n$ be the affine space of dimension $n$ over a field $k$. For finitely many multivariate polynomials $f_1, \dots f_r \in k[x_1,\dots x_n]$ and $I = (f_1, \dots f_r) \subseteq k[x_1,\dots x_n]$ the ideal they generate, we denote by $X = V(I)$ the (affine) algebraic set defined by the ideal $I$ and call $k$ its base field.

If $k \subseteq K$ is any field extension, we denote the set of $K$-points of $X$ by

\[\begin{aligned}X(K) &= \{ P \in \mathbb{A}^n(K) \mid f_1(P)=\dots = f_n(P)=0\}\\&=\{P \in \mathbb{A}^n(K) \mid \forall f\in I : f(P)=0\}.\end{aligned}\]

Most properties of the algebraic set $X$ refer to $X(K)$ where $K$ is an algebraically closed field. For instance is_empty returns whether $X(K) = \emptyset$.

Exceptions to the rule, that we refer to $X(K)$, are documented in the respective methods. For example the property of being irreducible depends on $k$: The algebraic set $X = V(x^2+y^2) \subseteq \mathbb{A}^2$ is irreducible over $k = \mathbb{R}$. But it is the union of two lines over $K = \mathbb{C}$, i.e. $X$ is irreducible but geometrically reducible. See is_irreducible(X::AbsSpec{<:Field, <:MPolyAnyRing}) for details.

Rational points

To study the $k$-points, also called $k$-rational points, of the algebraic set $X$ one first considers the solutions $X(K)$ over an algebraically closed field extension $K$ of $k$. Then in a second step one studies $X(k)$ as a subset of $X(K)$.

The first step involves calculations with ideals. For instance Hilbert's Nullstellensatz implies that $X(K)$ is empty if and only if the ideal $I=(1)$. This is decided by an ideal membership test relying on a Gröbner basis computation of $I$ and can be carried out in $k[x_1,\dots x_n]$ without taking any field extensions.

The second step involves methods from number theory (if $k$ is a number field) or from real algebraic geometry (if $k = \mathbb{R}$).

Algebraic sets in Oscar are designed for the first step. Most of their properfties should be interpreted as properties of the set $X(K)$ of their $K$-points over an algebraic closure $K$.

Relation to Schemes

One may view an (affine) algebraic set as a geometrically reduced (affine) scheme over a field $k$.

Many constructions involving varieties lead naturally to schemes. For instance the intersection of $X = V(x^2 - y)$ and $Y = V(y)$ as sets is the point ${(0,0)}=V(x,y)$. As a scheme the intersection is defined by the ideal $(x^2, y)$ which can be interpreted as a point of multiplicity $2$ and contains the information that the intersection of $X$ and $Y$ is tangential in $(0,0)$.

Therefore we have two methods

Note

If a construction returns a scheme $Z$, but you want to ignore the scheme structure, call the function algebraic_set(Z) to convert the scheme $Z$ to an affine algebraic set.

For example algebraic_set(intersection(X, Y)) is equivalent to set_theoretic_intersection(X, Y).

Internally an AffineAlgebraicSet is constructed from a possibly non-reduced affine scheme, which we call the fat_scheme of X as opposed to the reduced_scheme of X which we refer to as the underlying_scheme.

fat_idealMethod
fat_ideal(X::AbsAffineAlgebraicSet) -> Ideal

Return an ideal whose radical is the vanishing ideal of X.

If X is constructed from an ideal I this returns I.

julia> A2 = affine_space(QQ, [:x,:y])
-Affine space of dimension 2
-  over rational field
-with coordinates [x, y]
-
-julia> (x, y) = coordinates(A2);
-
-julia> I = ideal([x^2, y]);
-
-julia> X = algebraic_set(I)
-Affine algebraic set
-  in affine 2-space over QQ with coordinates [x, y]
-defined by ideal(x^2, y)
-
-julia> fat_ideal(X) === I
-true
source
fat_schemeMethod
fat_scheme(X::AffineAlgebraicSet) -> AbsSpec

Return a scheme whose reduced subscheme is $X$.

This does not trigger any computation and is therefore cheap. Use this instead of underlying_scheme when possible.

source
underlying_schemeMethod
underlying_scheme(X::AffineAlgebraicSet) -> AbsSpec

Return the underlying reduced scheme defining $X$.

This is used to forward the AbsSpec functionality to $X$, but may trigger the computation of a radical ideal. Hence this can be expensive.

source

More general affine algebraic sets

By abuse of terminology we say that a scheme is an affine algebraic set if it is isomorphic to one. For example a hypersurface complement is an affine algebraic set. In particular, we allow affine algebraic sets which are not necessarily Zariski closed in their ambient affine space.

AbsAffineAlgebraicSetType
AbsAffineAlgebraicSet <: AbsSpec

An affine, geometrically reduced subscheme of an affine space over a field.

source

Constructors

One can create an algebraic set from an ideal or a multivariate polynomial.

algebraic_setMethod
algebraic_set(I::MPolyIdeal; is_radical::Bool=false, check::Bool=true)

Return the affine algebraic set defined $I$.

If is_radical is set, assume that $I$ is a radical ideal.

julia> R, (x,y) = GF(2)[:x,:y];
-
-julia> X = algebraic_set(ideal([y^2+y+x^3+1,x]))
-Affine algebraic set
-  in affine 2-space over GF(2) with coordinates [x, y]
-defined by ideal(x^3 + y^2 + y + 1, x)
-
source
algebraic_setMethod
algebraic_set(p::MPolyRingElem)

Return the affine algebraic set defined by the multivariate polynomial p.

julia> R, (x,y) = QQ[:x,:y];
-
-julia> X = algebraic_set((y^2+y+x^3+1)*x^2)
-Affine algebraic set
-  in affine 2-space over QQ with coordinates [x, y]
-defined by ideal(x^5 + x^2*y^2 + x^2*y + x^2)
-
-julia> R, (x,y) = GF(2)[:x,:y];
-
-julia> X = algebraic_set((y^2+y+x^3+1)*x^2)
-Affine algebraic set
-  in affine 2-space over GF(2) with coordinates [x, y]
-defined by ideal(x^5 + x^2*y^2 + x^2*y + x^2)
-
source

Convert an affine scheme to an affine algebraic set in order to ignore its (non-reduced) scheme structure.

algebraic_setMethod
algebraic_set(X::Spec; is_reduced=false, check=true) -> AffineAlgebraicSet

Convert X to an AffineAlgebraicSet by considering its reduced structure.

If is_reduced is set, assume that X is already reduced. If is_reduced and check are set, check that X is actually geometrically reduced as claimed.

source
set_theoretic_intersectionMethod
set_theoretic_intersection(X::AbsAffineAlgebraicSet, Y::AbsAffineAlgebraicSet)

Return the set theoretic intersection of X and Y as an algebraic set.

julia> A = affine_space(QQ, [:x,:y])
-Affine space of dimension 2
-  over rational field
-with coordinates [x, y]
-
-julia> (x, y) = coordinates(A)
-2-element Vector{QQMPolyRingElem}:
- x
- y
-
-julia> X = algebraic_set(ideal([y - x^2]))
-Affine algebraic set
-  in affine 2-space over QQ with coordinates [x, y]
-defined by ideal(-x^2 + y)
-
-julia> Y = algebraic_set(ideal([y]))
-Affine algebraic set
-  in affine 2-space over QQ with coordinates [x, y]
-defined by ideal(y)
-
-julia> Zred = set_theoretic_intersection(X, Y)
-Affine algebraic set
-  in affine 2-space over QQ with coordinates [x, y]
-defined by ideal(-x^2 + y, y)
-
-

Note that the set theoretic intersection forgets the intersection multiplicities which the scheme theoretic intersection remembers. Therefore they are different.

julia> Z = intersect(X, Y) # a non reduced scheme
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables over QQ
-    by ideal(x^2 - y, y)
-
-julia> Zred == Z
-false
-
-julia> Zred == reduced_scheme(Z)[1]
-true
-
source
closureMethod
closure(X::AbsAffineAlgebraicSet)

Return the closure of $X$ in its ambient affine space.

source

Attributes

In addition to the attributes inherited from Affine schemes the following are available.

geometric_irreducible_componentsMethod
geometric_irreducible_components(X::AbsAffineAlgebraicSet)

Return the geometrically irreducible components of $X$.

They are the irreducible components $V_{ij}$ of $X$ seen over an algebraically closed field and given as a vector of tuples $(A_i, V_{ij}, d_{ij})$, say, where $A_i$ is an algebraic set which is irreducible over the base field of $X$ and $V_{ij}$ represents a corresponding class of galois conjugated geometrically irreducible components of $A_i$ defined over a number field of degree $d_{ij}$ whose generator prints as _a.

This is expensive and involves taking field extensions.

source
vanishing_idealMethod
vanishing_ideal(X::AbsAffineAlgebraicSet) -> Ideal

Return the ideal of all polynomials vanishing in $X$.

By Hilbert's Nullstellensatz this is a radical ideal.

Note

This triggers the computation of a radical, which is expensive.

source

Methods

Inherited from Affine schemes

Properties

Inherited from Affine schemes

diff --git a/previews/PR2578/AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/index.html b/previews/PR2578/AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/index.html deleted file mode 100644 index 305cbb80def1..000000000000 --- a/previews/PR2578/AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/index.html +++ /dev/null @@ -1,41 +0,0 @@ - -Projective Algebraic Sets · Oscar.jl

Projective Algebraic Sets

For finitely many homogeneous polynomials $f_1,\dots f_r \in k[x_0,\dots x_n]$, and $I=(f_1,\dots , f_n) \leq k[x_0,\dots x_n]$ the homogeneous ideal they generate, we denote by $X = V(I) \subseteq \mathbb{P}^n$ the projective algebraic set defined by $I$ and call $k$ its base field.

Let $\mathbb{P}^n(k)=(k^{n+1}\setminus\{0\})/k^*$ be the set of $k$-points of projective space of dimension $n$. If $k \subseteq K$ is any field extension, we denote the set of $K$-points of $X$ by

\[\begin{aligned}X(K) &= \{ P \in \mathbb{P}^n(K) \mid f_1(P)=\dots = f_n(P)=0\}\\ -&=\{P \in \mathbb{P}^n(K) \mid \forall f\in I : f(P)=0\}.\end{aligned}\]

Most properties of the projective variety $X$ refer to $X(K)$ where $K$ is an algebraically closed field. Just like for affine schemes there are a few exceptions to this rule, for instance, whether $X$ is irreducible or not depends on its base field. See is_irreducible(X::AbsProjectiveScheme) for details. Further exceptions are documented in the individual methods.

Relation to schemes

One can view a projective algebraic set as a scheme. See Projective schemes.

More formally we define a projective algebraic set as follows:

AbsProjectiveAlgebraicSetType
AbsProjectiveAlgebraicSet <: AbsProjectiveScheme

A projective, geometrically reduced scheme of finite type over a field.

source

Constructors

Projective algebraic sets can be created from homogeneous polynomials and homogeneous ideals in standard graded rings.

algebraic_setMethod
algebraic_set(I::MPolyIdeal{MPolyDecRingElem})

Return the projrective algebraic set defined by the homogeneous ideal $I$.

julia> P,(x0,x1) = graded_polynomial_ring(QQ,[:x0,:x1]);
-
-julia> algebraic_set(ideal([x0,x1]))
-Algebraic set
-  in projective 1-space over QQ with coordinates [x0, x1]
-defined by ideal(x1, x0)
-
source
algebraic_setMethod
algebraic_set(p::MPolyDecRingElem; check::Bool=true)

Return the projective algebraic set defined by the homogeneous polynomial p.

source

Algebraic sets can also be constructed from projective schemes.

algebraic_setMethod
algebraic_set(X::AbsProjectiveScheme; is_reduced::Bool=false, check::Bool=true) -> ProjectiveAlgebraicSet

Convert X to a ProjectiveAlgebraicSet by considering its underlying reduced scheme.

If is_reduced is true assume that X is already reduced.

julia> P, (x0, x1, x2) = graded_polynomial_ring(QQ,[:x0,:x1,:x2]);
-
-julia> X = projective_scheme(ideal([x0*x1^2, x2]))
-Projective scheme
-  over rational field
-defined by ideal(x0*x1^2, x2)
-
-julia> Y = algebraic_set(X)
-Algebraic set
-  in projective 2-space over QQ with coordinates [x0, x1, x2]
-defined by ideal(x2, x0*x1)
-
source
set_theoretic_intersectionMethod
set_theoretic_intersection(X::AbsProjectiveAlgebraicSet, Y::AbsProjectiveAlgebraicSet) -> AbsProjectiveAlgebraicSet

Return the set theoretic intersection of X and Y as as algebraic sets in projective space.

This is the reduced subscheme of the scheme theoretic intersection.

source
irreducible_componentsMethod
irreducible_components(X::AbsProjectiveAlgebraicSet) -> Vector{ProjectiveVariety}

Return the irreducible components of $X$ defined over the base field of $X$.

Note that even if $X$ is irreducible, there may be several geometrically irreducible components.

julia> P1 = projective_space(QQ,1)
-Projective space of dimension 1
-  over rational field
-with homogeneous coordinates [s0, s1]
-
-julia> (s0,s1) = homogeneous_coordinates(P1);
-
-julia> X = algebraic_set((s0^2+s1^2)*s1)
-Algebraic set
-  in projective 1-space over QQ with coordinates [s0, s1]
-defined by ideal(s0^2*s1 + s1^3)
-
-julia> (X1,X2) = irreducible_components(X)
-2-element Vector{ProjectiveAlgebraicSet{QQField, MPolyQuoRing{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}}:
- V(s0^2 + s1^2)
- V(s1)
-
-julia> X1  # irreducible but not geometrically irreducible
-Algebraic set
-  in projective 1-space over QQ with coordinates [s0, s1]
-defined by ideal(s0^2 + s1^2)
-
source
geometric_irreducible_componentsMethod
geometric_irreducible_components(X::AbsProjectiveAlgebraicSet) -> Vector{ProjectiveVariety}

Return the geometrically irreducible components of X.

They are the irreducible components of X seen over an algebraically closed field.

This is expensive and involves taking field extensions.

source

Attributes

In addition to the attributes inherited from Projective schemes the following are available.

vanishing_idealMethod
vanishing_ideal(X::AbsProjectiveAlgebraicSet) -> Ideal

Return the ideal of all homogeneous polynomials vanishing in $X$.

source
fat_idealMethod
fat_ideal(X::AbsProjectiveAlgebraicSet) -> Ideal

Return a homogenous ideal whose radical is the vanishing ideal of X.

source

Methods

Inherited from Projective schemes

Properties

Inherited from Projective schemes

diff --git a/previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/AffineVariety/index.html b/previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/AffineVariety/index.html deleted file mode 100644 index 9eb1fa1f5daf..000000000000 --- a/previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/AffineVariety/index.html +++ /dev/null @@ -1,23 +0,0 @@ - -Affine Varieties · Oscar.jl

Affine Varieties

An affine variety is an algebraic set such that $X(K)$ is irreducible for $k \subseteq K$ an algebraic closure. See Affine Algebraic Sets.

In Oscar varieties are implemented as special instances of Affine schemes and more formally defined as follows.

AbsAffineVarietyType
AbsAffineVariety <: AbsAffineAlgebraicSet

An affine, geometrically integral subscheme of an affine space over a field.

source

Functionality which is not (yet) provided by a variety-specific implementation, falls back to the appropriate functionality of schemes.

Constructors

varietyMethod
variety(I::MPolyIdeal; check=true) -> AffineVariety

Return the affine variety defined by the ideal $I$.

By our convention, varieties are absolutely irreducible. Hence we check that the radical of $I$ is prime and stays prime when viewed over the algebraic closure. This is an expensive check that can be disabled.

julia> R, (x,y) = QQ[:x,:y]
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> variety(ideal([x,y]))
-Affine variety
-  in affine 2-space over QQ with coordinates [x, y]
-defined by defined by ideal(x, y)
-

Over fields different from QQ, currently, we cannot check for irreducibility over the algebraic closure. But if you know that the ideal in question defines a variety, you can construct it by disabling the check.

julia> R, (x,y) = GF(2)[:x,:y];
-
-julia> variety(x^3+y+1, check=false)
-Affine variety
-  in affine 2-space over GF(2) with coordinates [x, y]
-defined by defined by ideal(x^3 + y + 1)
-
source
varietyMethod
variety(X::AbsSpec; is_reduced::false, check::Bool=true) -> AffineVariety

Convert $X$ to an affine variety.

If is_reduced is set, assume that X is already reduced.

source
varietyMethod
variety(R::Ring; check=true)

Return the affine variety with coordinate ring R.

We require that $R$ is a finitely generated algebra over a field $k$ and moreover that the base change of $R$ to the algebraic closure $\bar k$ is an integral domain.

julia> R, (x,y) = QQ[:x,:y];
-
-julia> Q,_ = quo(R,ideal([x,y]));
-
-julia> variety(Q)
-Affine variety
-  in affine 2-space over QQ with coordinates [x, y]
-defined by defined by ideal(x, y)
-
source

Attributes

So far all are inherited from Affine Algebraic Sets and Affine schemes.

Properties

So far all are inherited from Affine Algebraic Sets and Affine schemes.

Methods

So far all are inherited from Affine Algebraic Sets and Affine schemes.

diff --git a/previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html b/previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html deleted file mode 100644 index 1c1a98987fbb..000000000000 --- a/previews/PR2578/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html +++ /dev/null @@ -1,23 +0,0 @@ - -Projective Varieties · Oscar.jl

Projective Varieties

A projective variety over an algebraically closed field is an irreducible projective algebraic set. See Projective Algebraic Sets.

In practice we work over non-closed fields. To be called a variety an algebraic set $V$ must stay irreducible when viewed over the algebraic closure.

In Oscar projective varieties are Projective schemes and more formally defined as follows.

AbsProjectiveVarietyType
AbsProjectiveVariety <: AbsProjectiveAlgebraicSet

A geometrically integral subscheme of a projective space over a field.

source

Constructors

varietyMethod
variety(I::MPolyIdeal; is_prime::Bool, check::Bool=true) -> ProjectiveVariety

Return the projective variety defined by the homogeneous prime ideal $I$.

Since in our terminology varieties are irreducible over the algebraic closure, we check that $I$ stays prime when viewed over the algebraic closure. This is an expensive check that can be disabled. Note that the ideal $I$ must live in a standard graded ring.

julia> P3 = projective_space(QQ,3)
-Projective space of dimension 3
-  over rational field
-with homogeneous coordinates [s0, s1, s2, s3]
-
-julia> (s0,s1,s2,s3) = homogeneous_coordinates(P3);
-
-julia> X = variety(s0^3 + s1^3 + s2^3 + s3^3)
-Projective variety
-  in projective 3-space over QQ with coordinates [s0, s1, s2, s3]
-defined by ideal(s0^3 + s1^3 + s2^3 + s3^3)
-
-julia> dim(X)
-2
-
-julia> Y = variety(ideal([s0^3 + s1^3 + s2^3 + s3^3, s0]))
-Projective variety
-  in projective 3-space over QQ with coordinates [s0, s1, s2, s3]
-defined by ideal(s0, s1^3 + s2^3 + s3^3)
-
-julia> dim(Y)
-1
source
varietyMethod
variety(X::AbsProjectiveScheme; is_reduced::Bool=false, check::Bool=true) -> ProjectiveVariety

Convert $X$ to a projective variety by considering its reduced structure

source
varietyMethod
variety(R::GradedRing; check::Bool=true)

Return the projective variety defined by the $\mathbb{Z}$ standard graded ring $R$.

We require that $R$ is a finitely generated algebra over a field $k$ and moreover that the base change of $R$ to the algebraic closure $\bar k$ is an integral domain.

source
varietyMethod
variety(f::MPolyDecRingElem; check=true)

Return the projective variety defined by the homogeneous polynomial f.

This checks that f is absolutely irreducible.

source

Attributes

So far all are inherited from Projective Algebraic Sets and Projective schemes.

Properties

So far all are inherited from Projective Algebraic Sets and Projective schemes.

Methods

So far all are inherited from Projective Algebraic Sets and Projective schemes.

diff --git a/previews/PR2578/AlgebraicGeometry/Curves/para_rational_curves/index.html b/previews/PR2578/AlgebraicGeometry/Curves/para_rational_curves/index.html deleted file mode 100644 index 3fd70a945087..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Curves/para_rational_curves/index.html +++ /dev/null @@ -1,49 +0,0 @@ - -Rational Parametrizations of Rational Plane Curves · Oscar.jl

Rational Parametrizations of Rational Plane Curves

Note

In this section, $C$ will denote a complex projective plane curve, defined by an absolutely irreducible, homogeneous polynomial in three variables, with coefficients in $\mathbb Q$. Moreover, we will write $n = \deg C$.

Recall that the curve $C$ is rational if it is birationally equivalent to the projective line $\mathbb P^1(\mathbb C)$. In other words, there exists a rational parametrization of $C$, that is, a birational map $\mathbb P^1(\mathbb C)\dashrightarrow C$. Note that such a parametrization is given by three homogeneous polynomials of the same degree in the homogeneous coordinates on $\mathbb P^1(\mathbb C)$.

Note

The curve $C$ is rational iff its geometric genus is zero.

Based on work of Max Noether on adjoint curves, Hilbert und Hurwitz showed that if $C$ is rational, then there is a birational map $C \dashrightarrow D$ defined over $\mathbb Q$ such that $D = \mathbb P^1(\mathbb C)$ if $n$ is odd, and $D\subset\mathbb P^2(\mathbb C)$ is a conic if $n$ is even.

Note

If a conic $D$ contains a rational point, then there exists a parametrization of $D$ defined over $\mathbb Q$; otherwise, there exists a parametrization of $D$ defined over a quadratic field extension of $\mathbb Q$.

The approach of Hilbert und Hurwitz is constructive and allows one, in principle, to find rational parametrizations. The resulting algorithm is not very practical, however, as the approach asks to compute adjoint curves repeatedly, at each of a number of reduction steps.

The algorithm implemented in OSCAR relies on reduction steps of a different type and requires the computation of adjoint curves only once. Its individual steps are interesting in their own right:

  • Assure that the curve $C$ is rational by checking that its geometric genus is zero;
  • compute a basis of the adjoint curves of $C$ of degree ${n-2}$; each such basis defines a birational map $C \dashrightarrow C_{n-2},$ where $C_{n-2}$ is a rational normal curve in $\mathbb P^{n-2}(\mathbb C)$;
  • the anticanonical linear system on $C_{n-2}$ defines a birational map $C_{n-2}\dashrightarrow C_{n-4}$, where $C_{n-4}$ is a rational normal curve in in $\mathbb P^{n-4}(\mathbb C)$;
  • iterate the previous step to obtain a birational map $C_{n-2} \dashrightarrow \dots \dashrightarrow D$, where $D = \mathbb P^1(\mathbb C)$ if $n$ is odd, and $D\subset\mathbb P^2(\mathbb C)$ is a conic if $n$ is even;
  • invert the birational map $C \dashrightarrow C_{n-2} \dashrightarrow \dots \dashrightarrow D$;
  • if $n$ is even, compute a parametrization of the conic $D$ and compose it with the inverted map above.
Note

The defining property of an adjoint curve is that it passes with “sufficiently high” multiplicity through the singularities of $C$. There are several concepts of making this precise. For each such concept, there is a corresponding adjoint ideal of $C$, namely the homogeneous ideal formed by the defining polynomials of the adjoint curves. In OSCAR, we follow the concept of Gorenstein which leads to the largest possible adjoint ideal.

See Janko Böhm (1999) and Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister (2017) for details and further references.

Creating Projective Plane Curves

The data structures for algebraic curves in OSCAR are still under development and subject to change. Here is the current constructor for projective plane curves:

ProjPlaneCurveMethod
ProjPlaneCurve(f::MPolyRingElem{T}) where {T <: FieldElem}

Given a homogeneous polynomial f in three variables with coefficients in a field, create the projective plane curve defined by f.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, ["x", "y", "z"])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(z*x^2-y^3)
-Projective plane curve defined by x^2*z - y^3
source

The Genus of a Plane Curve

geometric_genusMethod
geometric_genus(C::ProjectivePlaneCurve{T}) where T <: FieldElem

Return the geometric genus of C.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> C = ProjPlaneCurve(z*x^2-y^3)
-Projective plane curve defined by x^2*z - y^3
-
-julia> geometric_genus(C)
-0
source

Adjoint Ideals of Plane Curves

adjoint_idealMethod
adjoint_ideal(C::ProjPlaneCurve{QQFieldElem})

Return the Gorenstein adjoint ideal of C.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> C = ProjPlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)
-Projective plane curve defined by -2*x^3*z + 3*x^2*z^2 + y^4 - 2*y^2*z^2
-
-julia> I = adjoint_ideal(C)
-ideal(-x*z + y^2, x*y - y*z, x^2 - x*z)
source

Rational Points on Conics

rational_point_conicMethod
rational_point_conic(D::ProjPlaneCurve{QQFieldElem})

If the conic D contains a rational point, return the homogeneous coordinates of such a point. If no such point exists, return a point on D defined over a quadratic field extension of $\mathbb Q$.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> D = ProjPlaneCurve(x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z);
-
-julia> P = rational_point_conic(D)
-3-element Vector{AbstractAlgebra.Generic.MPoly{nf_elem}}:
- -1//4*a
- -1//4*a + 1//4
- 0
-
-julia> S = parent(P[1])
-Multivariate polynomial ring in 3 variables x, y, z
-  over number field of degree 2 over QQ
-
-julia> NF = base_ring(S)
-Number field with defining polynomial t^2 - 2
-  over rational field
-
-julia> a = gen(NF)
-a
-
-julia> minpoly(a)
-t^2 - 2
source

Parametrizing Rational Plane Curves

parametrization_plane_curveMethod
parametrization_plane_curve(C::ProjPlaneCurve{QQFieldElem})

Return a rational parametrization of C.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> C = ProjPlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)
-Projective plane curve defined by -2*x^3*z + 3*x^2*z^2 + y^4 - 2*y^2*z^2
-
-julia> parametrization_plane_curve(C)
-3-element Vector{QQMPolyRingElem}:
- 12*s^4 - 8*s^2*t^2 + t^4
- -12*s^3*t + 2*s*t^3
- 8*s^4
source

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html b/previews/PR2578/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html deleted file mode 100644 index 586c7b91e377..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html +++ /dev/null @@ -1,9 +0,0 @@ - -Some Special Ideals · Oscar.jl

Some Special Ideals

This page is still in its development stage. Currently, it only contains the function below:

Grassmann Plücker Ideal

grassmann_pluecker_idealFunction
grassmann_pluecker_ideal([ring::MPolyRing,] subspace_dimension::Int, ambient_dimension::Int)

Given a ring, an ambient dimension and a subspace dimension return the ideal in the given ring generated by the Plücker relations. If the ring is not specified return the ideal in a multivariate polynomial ring over the rationals.

The Grassmann-Plücker ideal is the homogeneous ideal generated by the relations defined by the Plücker Embedding of the Grassmannian. That is given Gr$(k, n)$ the Moduli space of all $k$-dimensional subspaces of an $n$-dimensional vector space, the relations are given by all $d \times d$ minors of a $d \times n$ matrix. For the algorithm see Bernd Sturmfels (1993).

Examples

julia> grassmann_pluecker_ideal(2, 4)
-ideal(x[1]*x[6] - x[2]*x[5] + x[3]*x[4])
-
-julia> R, x = polynomial_ring(residue_ring(ZZ, 7), "x" => (1:2, 1:3), ordering=:degrevlex)
-(Multivariate polynomial ring in 6 variables over ZZ/(7), zzModMPolyRingElem[x[1, 1] x[1, 2] x[1, 3]; x[2, 1] x[2, 2] x[2, 3]])
-
-julia> grassmann_pluecker_ideal(R, 2, 4)
-ideal(x[1, 2]*x[2, 2] + 6*x[2, 1]*x[1, 3] + x[1, 1]*x[2, 3])
source

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/AlgebraicGeometry/RationalPoints/Affine/index.html b/previews/PR2578/AlgebraicGeometry/RationalPoints/Affine/index.html deleted file mode 100644 index 3c17b00a8613..000000000000 --- a/previews/PR2578/AlgebraicGeometry/RationalPoints/Affine/index.html +++ /dev/null @@ -1,20 +0,0 @@ - -Affine · Oscar.jl

Affine

AbsAffineRationalPointType
AbsAffineRationalPoint{CoefficientType, ParentType}

A rational point $P$ of an affine scheme $X$. We refer to $X$ as the parent of $P$.

Let $X \subseteq \mathbb{A}^n_k$ be an algebraic set or more generally a subscheme defined by the ideal $I = (f_1, \dots f_r) \subseteq k[x_1,\dots x_n]$. A rational point $p$ of $X$ is a tuple $p = (p_1, \dots , p_n) \in k^n$ such that $f_1(p) = \dots = f_n(p) = 0$.

source
AffineRationalPointType
AffineRationalPoint{CoeffType<:RingElem, ParentType<:RationalPointSet}

A rational point represented in terms of a vector of coordinates.

Examples

julia> A2 = affine_space(GF(2), [:x, :y]);
-
-julia> (x, y) = coordinates(A2);
-
-julia> X = algebraic_set(x*y);
-
-julia> X([1, 0])
-Rational point
-  of V(x*y)
-with coordinates (1, 0)
-
source
coordinatesMethod
coordinates(p::AffineRationalPoint{S,T}) -> Vector{S}

Return the coordinates of the rational point p.

The coordinates are with respect to the ambient space of its ambient scheme.

source
idealMethod
ideal(P::AbsAffineRationalPoint)

Return the maximal ideal associated to P in the coordinate ring of its ambient space.

source
schemeMethod
scheme(P::AbsAffineRationalPoint) -> AbsSpec

Return the rational point $P$ viewed as a reduced, affine subscheme of its ambient affine space.

source
closed_embeddingMethod
closed_embedding(P::AbsAffineRationalPoint) -> ClosedEmbedding

Return the closed embedding of P into its ambient scheme X.

source
is_smoothMethod
is_smooth(P::AbsAffineRationalPoint)

Return whether $P$ is a smooth point of its ambient scheme $X$.

source

Some experimental methods are available too. Note that their interface is likely to change in the future.

is_du_val_singularityMethod
is_du_val_singularity(P::AbsAffineRationalPoint{<:Field})

Return whether the ambient scheme of P has at most a Du Val singularity at P.

Note that this includes the case that $P$ is a smooth point.

source
decide_du_val_singularityMethod
decide_du_val_singularity(P::AbsAffineRationalPoint{<:Field})

Return whether the ambient scheme of P has a Du Val singularity at P.

Examples

julia> A3 = affine_space(QQ, [:x, :y, :z]);
-
-julia> (x, y, z) = ambient_coordinates(A3);
-
-julia> X = subscheme(A3, ideal([x^2+y^2-z^2]));
-
-julia> Oscar.decide_du_val_singularity(X([0,0,0]))
-(true, (:A, 1))
-
source
diff --git a/previews/PR2578/AlgebraicGeometry/RationalPoints/Projective/index.html b/previews/PR2578/AlgebraicGeometry/RationalPoints/Projective/index.html deleted file mode 100644 index 3b53fd942d24..000000000000 --- a/previews/PR2578/AlgebraicGeometry/RationalPoints/Projective/index.html +++ /dev/null @@ -1,17 +0,0 @@ - -Projective · Oscar.jl

Projective

AbsProjectiveRationalPointType
AbsProjectiveRationalPoint

A rational point $P$ of a projective scheme $X$. We refer to $X$ as the parent of $P$.

Let $k$ be a field. A rational point is an element of $\mathbb{P}^n(k) = k^{n+1} \setminus \{0\} / k^*$ where two vectors $v,w$ in $k^{n+1} \setminus \{0\}$ are identified if $v = \alpha w$ for a non-zero scalar $\alpha \in k^*$.

Let $X \subseteq \mathbb{P}^n_k$ be an algebraic set or more generally a closed subscheme defined by the homogeneous ideal $I = (f_1, \dots f_r)$. Then a rational point of $X$ is $p \in \mathbb{P}^n(k)$ such that $f_1(p) = \dots = f_n(p) = 0$.

This type includes points in weighted projective space.

source
ProjectiveRationalPointType
ProjectiveRationalPoint{CoeffType<:RingElem, ParentType<:AbsProjectiveScheme}

Type for rational points in projective varieties.

Examples

julia> P2 = projective_space(QQ, 2);
-
-julia> P2([4, 0 , 2//3])
-Projective rational point
-  of Projective 2-space over QQ with coordinates [s0, s1, s2]
-with coordinates (4 : 0 : 2//3)
-
source
coordinatesMethod
coordinates(p::AbsProjectiveRationalPoint{S,T}) -> Vector{S}

Return the homogeneous coordinates of the rational point p.

source
idealMethod
ideal(P::AbsProjectiveRationalPoint)

Return the homogeneous ideal associated to P in the homogeneous coordinate ring of its ambient space.

source
ideal(O::NfRelOrd, M::PMat; check::Bool = true, M_in_hnf::Bool = false) -> NfRelOrdIdl

Creates the ideal of $\mathcal O$ with basis pseudo-matrix $M$. If check is set, then it is checked whether $M$ defines an ideal. If M_in_hnf is set, then it is assumed that $M$ is already in lower left pseudo HNF.

ideal(O::NfRelOrd, M::Generic.Mat; check::Bool = true) -> NfRelOrdIdl

Creates the ideal of $\mathcal O$ with basis matrix $M$. If check is set, then it is checked whether $M$ defines an ideal.

ideal(O::NfRelOrd{T, S}, x::NfRelElem{T}, y::NfRelElem{T}, a::S, b::S; check::Bool = true) -> NfRelOrdIdl{T, S}

Creates the ideal $x\cdot a + y\cdot b$ of $\mathcal O$. If check is set, then it is checked whether these elements define an ideal.

ideal(O::NfRelOrd{T, S}, x::NfRelOrdElem{T}) -> NfRelOrdIdl{T, S}
-*(O::NfRelOrd{T, S}, x::NfRelOrdElem{T}) -> NfRelOrdIdl{T, S}
-*(x::NfRelOrdElem{T}, O::NfRelOrd{T, S}) -> NfRelOrdIdl{T, S}

Creates the ideal $x\cdot \mathcal O$ of $\mathcal O$.

ideal(O::NfRelOrd{T, S}, a::S; check::Bool = true) -> NfRelOrdIdl{T, S}

Creates the ideal $a \cdot \mathcal O$ of $\mathcal O$. If check is set, then it is checked whether $a$ defines an (integral) ideal.

ideal(O::AlgAssAbsOrd, x::AbsAlgAssElem) -> AlgAssAbsOrdIdl
-ideal(O::AlgAssAbsOrd, x::AlgAssAbsOrdElem) -> AlgAssAbsOrdIdl

Returns the twosided principal ideal of $O$ generated by $x$.

ideal(O::AlgAssAbsOrd, x::AbsAlgAssElem, side::Symbol) -> AlgAssAbsOrdIdl
-ideal(O::AlgAssAbsOrd, x::AlgAssAbsOrdElem, side::Symbol) -> AlgAssAbsOrdIdl

Returns the ideal $O \cdot x$ if side == :left, and $x \cdot O$ if side == :right.

ideal(A::AbsAlgAss, M::PMat; M_in_hnf::Bool = false) -> AlgAssRelOrdIdl

Returns the ideal in $A$ with basis pseudo-matrix $M$. If M_in_hnf == true, it is assumed that $M$ is already in lower left pseudo HNF.

ideal(A::AbsAlgAss, O::AlgAssRelOrd, M::PMat; side::Symbol = :nothing,
-      M_in_hnf::Bool = false)
-  -> AlgAssRelOrdIdl

Returns the ideal of $O$ in $A$ with basis pseudo-matrix $M$ (in the basis of $A$). If the ideal is known to be a right/left/twosided ideal of $O$, side may be set to :right/:left/:twosided respectively. If M_in_hnf == true, it is assumed that $M$ is already in lower left pseudo HNF.

ideal(O::AlgAssRelOrd, x::AbsAlgAssElem) -> AlgAssRelOrdIdl
-ideal(O::AlgAssRelOrd, x::AlgAssRelOrdElem) -> AlgAssRelOrdIdl

Returns the twosided principal ideal of $O$ generated by $x$.

ideal(O::AlgAssRelOrd, x::AbsAlgAssElem, side::Symbol) -> AlgAssRelOrdIdl
-ideal(O::AlgAssRelOrd, x::AlgAssRelOrdElem, side::Symbol) -> AlgAssRelOrdIdl

Returns the ideal $O \cdot x$ if side == :left, and $x \cdot O$ if side == :right.

ideal(O::AlgAssRelOrd, a::NfOrdFracIdl) -> AlgAssRelOrdIdl
-ideal(O::AlgAssRelOrd, a::NfRelOrdFracIdl) -> AlgAssRelOrdIdl

Returns the ideal $a \cdot O$ where $a$ is a fractional ideal of base_ring(O).

schemeMethod
scheme(P::AbsProjectiveRationalPoint) -> AbsProjectiveScheme

Return the rational point $P$ viewed as a reduced, projective subscheme of its ambient projective space.

source
normalize!Method
normalize!(a::AbsProjectiveRationalPoint{<:FieldElem})

Normalize a such that its first non-zero coordinate is one.

source
normalize!Method
normalize!(a::AbsProjectiveRationalPoint{ZZRingElem})

Normalize a such that its first non-zero coordinate is positive.

source
diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/AffineSchemes/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/AffineSchemes/index.html deleted file mode 100644 index 3fff3b97cab6..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/AffineSchemes/index.html +++ /dev/null @@ -1,471 +0,0 @@ - -Affine schemes · Oscar.jl

Affine schemes

Let $\mathbb k$ be a commutative noetherian base ring (in practice: an algebraic extension of $\mathbb Q$ or $\mathbb F_p$). We support functionality for affine schemes $X = \mathrm{Spec}(R)$ over $\mathbb k$. Currently, we support rings $R$ of type MPolyRing, MPolyQuoRing, MPolyLocRing, and MPolyQuoLocRing defined over the integers, a finite field or algebraic field extensions of $\mathbb Q$

Constructors

General constructors

Besides Spec(R) for R of either one of the types MPolyRing, MPolyQuoRing, MPolyLocRing, or MPolyQuoLocRing, we have the following constructors:

SpecMethod
Spec(R::MPolyRing, I::MPolyIdeal)

Constructs the affine scheme of the ideal $I$ in the ring $R$. This is the spectrum of the quotient ring $R/I$.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> I = ideal(R, [x]);
-
-julia> Spec(R, I)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables over QQ
-    by ideal(x)
source
SpecMethod
Spec(R::MPolyRing, U::AbsMPolyMultSet)

Given a polynomial ring $R$, we can localize that polynomial ring at a multiplicatively closed subset $U$ of $R$. The spectrum of the localized ring $U^{-1} R$ is computed by this method.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> I = ideal(R, [x]);
-
-julia> U = complement_of_prime_ideal(I);
-
-julia> Spec(R, U)
-Spectrum
-  of localization
-    of multivariate polynomial ring in 2 variables over QQ
-    at complement of prime ideal(x)
source
SpecMethod
Spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet)

We allow to combine quotients and localizations at the same time. That is, consider a polynomial ring $R$, an ideal $I$ of $R$ and a multiplicatively closed subset $U$ of $R$. The spectrum of the localized ring $U^{-1} (R/I)$ is computed by this method.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> I = ideal(R, [x]);
-
-julia> U = complement_of_prime_ideal(ideal(R, [y]));
-
-julia> Spec(R, I, U)
-Spectrum
-  of localization
-    of quotient of multivariate polynomial ring by ideal with 1 generator
-    at complement of prime ideal(y)
source

See inclusion_morphism(::AbsSpec, ::AbsSpec) for a way to obtain the ideal $I$ from $X = \mathrm{Spec}(R, I)$.

Affine n-space

affine_spaceMethod
affine_space(kk::BRT, n::Int; variable_name="x") where {BRT<:Ring}

The $n$-dimensional affine space over a ring $kk$ is created by this method. By default, the variable names are chosen as $x_1$, $x_2$ and so on. This choice can be overwritten with a third optional argument.

Examples

julia> affine_space(QQ, 5)
-Affine space of dimension 5
-  over rational field
-with coordinates [x1, x2, x3, x4, x5]
-
-julia> affine_space(QQ,5,variable_name="y")
-Affine space of dimension 5
-  over rational field
-with coordinates [y1, y2, y3, y4, y5]
source
affine_spaceMethod
affine_space(kk::BRT, var_symbols::Vector{Symbol}) where {BRT<:Ring}

Creates the $n$-dimensional affine space over a ring $kk$, but allows more flexibility in the choice of variable names. The following example demonstrates this.

Examples

julia> affine_space(QQ,[:y1,:z2,:a])
-Affine space of dimension 3
-  over rational field
-with coordinates [y1, z2, a]
source

Closed subschemes

subschemeMethod
subscheme(X::AbsSpec, f::Vector{<:RingElem})

For an affine spectrum $X$ and elements $f_1$, $f_2$, etc. of the coordinate ring of $X$, this method computes the subscheme $V(f_1, f_2, \dots)$ of $X$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> subscheme(X,x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> subscheme(X,[x1,x2])
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1, x2)
source
subschemeMethod
subscheme(X::AbsSpec, I::Ideal)

For a scheme $X = Spec(R)$ and an ideal $I ⊂ 𝒪(X)$, return the closed subscheme defined by $I$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> subscheme(X,ideal(R,[x1*x2]))
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1*x2)
source

Intersections

intersectMethod
Base.intersect(X::AbsSpec, Y::AbsSpec)

This method computes the intersection to two affine schemes that reside in the same ambient affine space.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y1 = subscheme(X,[x1])
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> Y2 = subscheme(X,[x2])
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x2)
-
-julia> intersect(Y1, Y2)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1, x2)
source

Open subschemes

hypersurface_complementMethod
hypersurface_complement(X::AbsSpec, f::RingElem)

For a scheme $X = Spec(R)$ and an element $f ∈ R$, return the open subscheme $U = Spec(R[f⁻¹]) = X ∖ V(f)$ defined by the complement of the vanishing locus of $f$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1, x2, x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> hypersurface_complement(X, x1)
-Spectrum
-  of localization
-    of multivariate polynomial ring in 3 variables over QQ
-    at products of 1 element
source
hypersurface_complementMethod
hypersurface_complement(X::AbsSpec, f::Vector{<:RingElem})

For a scheme $X = Spec(R)$ and elements $f₁, f₂, ... ∈ R$, return the open subscheme $U = Spec(R[f₁⁻¹,f₂⁻¹, ...]) = X ∖ V(f₁⋅f₂⋅…)$ defined by the complement of the vanishing locus of the product $f₁⋅f₂⋅…$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> hypersurface_complement(X,[x1,x2])
-Spectrum
-  of localization
-    of multivariate polynomial ring in 3 variables over QQ
-    at products of 2 elements
source

Closure

closureMethod
closure(X::AbsSpec, Y::AbsSpec)

Return the closure of $X$ in $Y$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> H = subscheme(X,ideal(R,[x1]))
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> closure(H, X)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
source

Attributes

Ambient affine space

Most affine schemes in Oscar $X = \mathrm{Spec}(R)$ over a ring $B$, come with an embedding into an affine space $\mathbb{A}_B$. More precisely, ambient_space(X) is defined for X = Spec(R) if R is constructed from a polynomial ring. In particular $\mathrm{Spec}(\mathbb{Z})$ or $\mathrm{Spec}(\mathbb{k})$ for $\mathbb k$ a field do not have an ambient affine space.

ambient_spaceMethod
ambient_space(X::AbsSpec)

Return the ambient affine space of $X$.

Use ambient_embedding(::AbsSpec) to obtain the embedding of $X$ in its ambient affine space.

Examples

julia> X = affine_space(QQ, [:x,:y])
-Affine space of dimension 2
-  over rational field
-with coordinates [x, y]
-
-julia> ambient_space(X) == X
-true
-
-julia> (x, y) = coordinates(X);
-
-julia> Y = subscheme(X, [x])
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables over QQ
-    by ideal(x)
-
-julia> X == ambient_space(Y)
-true
-
-julia> Z = subscheme(Y, y)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables over QQ
-    by ideal(x, y)
-
-julia> ambient_space(Z) == X
-true
-
-julia> V = hypersurface_complement(Y, y)
-Spectrum
-  of localization
-    of quotient of multivariate polynomial ring by ideal with 1 generator
-    at products of 1 element
-
-julia> ambient_space(V) == X
-true

We can create $X$, $Y$ and $Z$ also by first constructing the corresponding coordinate rings. The subset relations are inferred from the coordinate rings. More precisely, for a polynomial ring $P$ an ideal $I ⊆ P$ and a multiplicatively closed subset $U$ of $P$ let $R$ be one of $P$, $U^{-1}P$, $P/I$ or $U^{-1}(P/I)$. In each case the ambient affine space is given by Spec(P).

Examples

julia> P, (x, y) = polynomial_ring(QQ, [:x, :y])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> X = Spec(P)
-Spectrum
-  of multivariate polynomial ring in 2 variables x, y
-    over rational field
-
-julia> I = ideal(P, x)
-ideal(x)
-
-julia> RmodI, quotient_map = quo(P, I);
-
-julia> Y = Spec(RmodI)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables over QQ
-    by ideal(x)
-
-julia> ambient_space(Y) == X
-true
-
-julia> J = ideal(RmodI, y);
-
-julia> RmodJ, quotient_map2 = quo(RmodI, J);
-
-julia> Z = Spec(RmodJ)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables over QQ
-    by ideal(x, y)
-
-julia> ambient_space(Z) == X
-true
-
-julia> U = powers_of_element(y)
-Multiplicative subset
-  of multivariate polynomial ring in 2 variables over QQ
-  given by the products of [y]
-
-julia> URmodI, _ = localization(RmodI, U);
-
-julia> V = Spec(URmodI)
-Spectrum
-  of localization
-    of quotient of multivariate polynomial ring by ideal with 1 generator
-    at products of 1 element
-
-julia> ambient_space(V) == X
-true

Note: compare with ==, as the same affine space could be represented internally by different objects for technical reasons.

Examples

julia> AX = ambient_space(X);
-
-julia> AY = ambient_space(Y);
-
-julia> AX == AY
-true
-
-julia> AX === AY
-false
source

Other attributes

base_ringMethod
base_ring(I::MPolyIdeal)

Return the ambient ring of I.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> base_ring(I)
-Multivariate polynomial ring in 2 variables x, y
-  over rational field
source
base_ring(X::AbsSpec)

On an affine scheme $X/𝕜$ over $𝕜$ this returns the ring $𝕜$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> base_ring(X)
-Rational field
source
base_ring(M::PMat)

The PMat $M$ defines an $R$-module for some maximal order $R$. This function returns the $R$ that was used to defined $M$.

codimMethod
codim(X::AbsSpec)

Return the codimension of $X$ in its ambient affine space.

Throws and error if $X$ does not have an ambient affine space.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> codim(X)
-0
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> codim(Y)
-1
source
ambient_embeddingMethod
ambient_embedding(X::AbsSpec)

Return the embedding of $X$ in its ambient affine space.

Examples

julia> X = affine_space(QQ, [:x,:y])
-Affine space of dimension 2
-  over rational field
-with coordinates [x, y]
-
-julia> (x, y) = coordinates(X);
-
-julia> Y = subscheme(X, [x])
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables over QQ
-    by ideal(x)
-
-julia> inc = ambient_embedding(Y)
-Morphism
-  from [x, y]  spec of quotient of multivariate polynomial ring
-  to   [x, y]  affine 2-space over QQ
-given by the pullback function
-  x -> 0
-  y -> y
-
-julia> inc == inclusion_morphism(Y, X)
-true
source
dimMethod
dim(X::AbsSpec)

Return the dimension the affine scheme $X = Spec(R)$.

By definition, this is the Krull dimension of $R$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> dim(X)
-3
-
-julia> Y = affine_space(ZZ, 2)
-Spectrum
-  of multivariate polynomial ring in 2 variables x1, x2
-    over integer Ring
-
-julia> dim(Y) # one dimension comes from ZZ and two from x1 and x2
-3
source
nameMethod
name(X::AbsSpec)

Return the current name of an affine scheme.

This name can be specified via set_name!.

Examples

julia> X = affine_space(QQ, 3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> name(X)
-"unnamed affine variety"
-
-julia> set_name!(X, "affine 3-dimensional space")
-
-julia> name(X)
-"affine 3-dimensional space"
source
OOMethod
OO(X::AbsSpec)

On an affine scheme $X = Spec(R)$, return the ring $R$.

source

Type getters

We support functions which return the types of schemes, associated rings, and their elements. See the source code for details.

Properties

is_open_embeddingMethod
is_open_embedding(X::AbsSpec, Y::AbsSpec)

Checks whether $X$ is openly embedded in $Y$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X,ideal(R,[x1*x2]))
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1*x2)
-
-julia> is_open_embedding(Y, X)
-false
-
-julia> Z = hypersurface_complement(X, x1)
-Spectrum
-  of localization
-    of multivariate polynomial ring in 3 variables over QQ
-    at products of 1 element
-
-julia> is_open_embedding(Z, X)
-true
source
is_closed_embeddingMethod
is_closed_embedding(X::AbsSpec, Y::AbsSpec)

Checks whether $X$ is closed embedded in $Y$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X,ideal(R,[x1*x2]))
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1*x2)
-
-julia> is_closed_embedding(Y, X)
-true
-
-julia> Z = hypersurface_complement(X, x1)
-Spectrum
-  of localization
-    of multivariate polynomial ring in 3 variables over QQ
-    at products of 1 element
-
-julia> is_closed_embedding(Z, X)
-false
source
isemptyMethod
is_empty(X::AbsSpec)

Check whether the affine scheme $X$ is empty.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> isempty(X)
-false
-
-julia> is_empty(subscheme(X, one(OO(X))))
-true
-
-julia> isempty(EmptyScheme(QQ))
-true
source
issubsetMethod
is_subset(X::AbsSpec, Y::AbsSpec)

Check whether $X$ is a subset of $Y$ based on the comparison of their coordinate rings. See inclusion_morphism(::AbsSpec, ::AbsSpec) for the corresponding morphism.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X,ideal(R,[x1*x2]))
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1*x2)
-
-julia> is_subset(X, Y)
-false
-
-julia> is_subset(Y, X)
-true
source

Methods

Comparison

Two schemes $X$ and $Y$ can be compared if their ambient affine spaces are equal. In particular $X$ and $Y$ are considered equal (==) if and only if the identity morphism of their ambient affine space induces an isomorphism of $X$ and $Y$. For $X$ and $Y$ with different ambient affine space X==Y is always false.

Auxiliary methods

is_non_zero_divisorMethod
is_non_zero_divisor(f::RingElem, X::AbsSpec)

Checks if a ring element is a non-zero divisor in the coordinate ring of an affine scheme.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> (x1, x2, x3) = gens(OO(X))
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> is_non_zero_divisor(x1, X)
-true
-
-julia> is_non_zero_divisor(zero(OO(X)), X)
-false
source
diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/index.html deleted file mode 100644 index 3cd8aff35079..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/index.html +++ /dev/null @@ -1,24 +0,0 @@ - -Architecture of affine schemes · Oscar.jl

Architecture of affine schemes

Requirements on rings and ideals

Any type of ring $R$ to be used within the schemes framework must come with its own ideal type IdealType<:Ideal for which we require the following interface to be implemented:

    # constructor of ideals in R
-    ideal(R::RingType, g::Vector{<:RingElem})::Ideal
-
-    # constructor for quotient rings
-    quo(R::RingType, I::IdealType)::Tuple{<:Ring, <:Map}
-
-    # ideal membership test
-    in(f::RingElem, I::IdealType)::Bool
-
-    # a (fixed) set of generators
-    gens(I::IdealType)::Vector{<:RingElem}
-
-    # writing an element as linear combination of the generators
-    coordinates(f::RingElem, I::IdealType)::Vector{<:RingElem}

The latter function must return a vector $v = (a_1,\dots, a_r)$ of elements in $R$ such that $f = a_1 \cdot g_1 + \dots + a_r \cdot g_r$ where $g_1,\dots,g_r$ is the set of gens(I). When $f$ does not belong to $I$, it must error. Note that the ring returned by quo must again be admissible for the AbsSpec interface.

With a view towards the use of the ambient_coordinate_ring(X) for computations, it is customary to also implement

    saturated_ideal(I::IdealType)::MPolyIdeal

returning an ideal $J$ in the ambient_coordinate_ring(X) with the property that $a \in I$ for some element $a \in R$ if and only if lifted_numerator(a) is in $J$.

Interplay between ambient coordinate ring and coordinate ring

Let $X$ be an affine variety. In practice, all computations in the coordinate ring R = OO(X) will be deferred to computations in P = ambient_coordinate_ring(X) in one way or the other; this is another reason to include the ambient affine space in our abstract interface for affine schemes. In order to make the ambient_coordinate_ring(X) accessible for this purpose, we need the following methods to be implemented for elements $a\in R$ of type RingElemType:

   lifted_numerator(a::RingElemType)
-   lifted_denominator(a::RingElemType)

These must return representatives of the numerator and the denominator of $a$. Note that the denominator is equal to one(P) in case $R \cong P$ or $R \cong P/I$.

Recall that the coordinates $x_i$ of $X$ are induced by the coordinates of the ambient affine space. Moreover, we will assume that for homomorphisms from $R$ there is a method

    hom(R::RingType, S::Ring, a::Vector{<:RingElem})

where RingType is the type of $R$ and a the images of the coordinates $x_i$ in $S$. This will be important when we come to morphisms of affine schemes below.

Algebraically speaking, embedding the affine scheme $X = Spec(R)$ over $𝕜$ into an affine space with coordinate ring $P = 𝕜[x₁,…,xₙ]$ corresponds to a morphism of rings $P → R$ with the property that for every other (commutative) ring $S$ and any homomorphism $φ : R → S$ there is a morphism $ψ : P → S$ factoring through $φ$ and such that $φ$ is uniquely determined by $ψ$. Note that the morphism $P → R$ is induced by natural coercions.

Existing types of affine schemes and how to derive new types

The abstract type for affine schemes is

AbsSpecType
AbsSpec{BaseRingType, RingType<:Ring}

An affine scheme $X = Spec(R)$ with $R$ of type RingType over a ring $𝕜$ of type BaseRingType.

source

For any concrete instance of this type, we require the following functions to be implemented:

  • base_ring(X::AbsSpec),
  • OO(X::AbsSpec).

A concrete instance of this type is

SpecType
Spec{BaseRingType, RingType}

An affine scheme $X = Spec(R)$ with $R$ a Noetherian ring of type RingType over a base ring $𝕜$ of type BaseRingType.

source

It provides an implementation of affine schemes for rings $R$ of type MPolyRing, MPolyQuoRing, MPolyLocRing, and MPolyQuoLocRing defined over the integers or algebraic field extensions of $\mathbb Q$. This minimal implementation can be used internally, when deriving new concrete types MySpec<:AbsSpec such as, for instance, group schemes, toric schemes, schemes of a particular dimension like curves and surfaces, etc. To this end, one has to store an instance Y of Spec in MySpec and implement the methods

    underlying_scheme(X::MySpec)::Spec # return Y as above

Then all methods implemented for Spec are automatically forwarded to any instance of MySpec.

Note: The above method necessarily returns an instance of Spec! Of course, it can be overwritten for any higher type MySpec<:AbsSpec as needed.

Existing types of affine scheme morphisms and how to derive new types

Any abstract morphism of affine schemes is of the following type:

AbsSpecMorType
AbsSpecMor{DomainType<:AbsSpec, 
-           CodomainType<:AbsSpec, 
-           PullbackType<:Hecke.Map,
-           MorphismType, 
-           BaseMorType
-           }

Abstract type for morphisms $f : X → Y$ of affine schemes where

  • $X = Spec(S)$ is of type DomainType,
  • $Y = Spec(R)$ is of type CodomainType,
  • $f^* : R → S$ is a ring homomorphism of type PullbackType,
  • $f$ itself is of type MorphismType (required for the Map interface),
  • if $f$ is defined over a morphism of base schemes $BX → BY$ (e.g. a field extension), then this base scheme morphism is of type BaseMorType; otherwise, this can be set to Nothing.
source

Any such morphism has the attributes domain, codomain and pullback. A concrete and minimalistic implementation exist for the type SpecMor:

SpecMorType
SpecMor{DomainType<:AbsSpec, 
-        CodomainType<:AbsSpec, 
-        PullbackType<:Hecke.Map
-       }

A morphism $f : X → Y$ of affine schemes $X = Spec(S)$ of type DomainType and $Y = Spec(R)$ of type CodomainType, both defined over the same base_ring, with underlying ring homomorphism $f^* : R → S$ of type PullbackType.

source

This basic functionality consists of

  • compose(f::AbsSpecMor, g::AbsSpecMor),
  • identity_map(X::AbsSpec),
  • restrict(f::AbsSpecMor, X::AbsSpec, Y::AbsSpec; check::Bool=true),
  • ==(f::AbsSpecMor, g::AbsSpecMor),
  • preimage(f::AbsSpecMor, Z::AbsSpec).

In particular, for every concrete instance of a type MySpec<:AbsSpec that implements underlying_scheme, this basic functionality of SpecMor should run naturally.

We may derive higher types of morphisms of affine schemes MySpecMor<:AbsSpecMor by storing an instance g of SpecMor inside an instance f of MySpecMor and implementing

    underlying_morphism(f::MySpecMor)::SpecMor # return g

For example, this allows us to define closed embeddings.

diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/CoveredSchemes/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/CoveredSchemes/index.html deleted file mode 100644 index e7011007298e..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/CoveredSchemes/index.html +++ /dev/null @@ -1,142 +0,0 @@ - -Covered schemes · Oscar.jl

Covered schemes

Oscar supports modeling abstract schemes by means of a covering by affine charts.

Types

The abstract type for these is:

AbsCoveredSchemeType
AbsCoveredScheme{BaseRingType}

An abstract scheme $X$ over some base_ring $𝕜$ of type BaseRingType, given by means of affine charts and their glueings.

source

The basic concrete instance of an AbsCoveredScheme is:

CoveredSchemeType
CoveredScheme{BaseRingType}

A covered scheme $X$ given by means of at least one Covering.

A scheme may possess several coverings which are partially ordered by refinement. Use default_covering(X) to obtain one covering of $X$.

source

Constructors

You can manually construct a CoveredScheme from a Covering using

CoveredSchemeMethod
CoveredScheme(C::Covering)

Return a CoveredScheme $X$ with C as its default_covering.

Examples

julia> P1, (x,y) = QQ["x", "y"];
-
-julia> P2, (u,v) = QQ["u", "v"];
-
-julia> U1 = Spec(P1);
-
-julia> U2 = Spec(P2);
-
-julia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> V1 = PrincipalOpenSubset(U1, x); # Preparations for glueing
-
-julia> V2 = PrincipalOpenSubset(U2, u);
-
-julia> f = SpecMor(V1, V2, [1//x, y//x]); # The glueing isomorphism
-
-julia> g = SpecMor(V2, V1, [1//u, v//u]); # and its inverse
-
-julia> G = Glueing(U1, U2, f, g); # Construct the glueing
-
-julia> add_glueing!(C, G) # Make the glueing part of the Covering
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> X = CoveredScheme(C) # Create a CoveredScheme from the Glueing
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
source

In most cases, however, you may wish for the computer to provide you with a ready-made Covering and use a more high-level constructor, such as, for instance,

covered_schemeMethod
covered_scheme(P::AbsProjectiveScheme)

Return a CoveredScheme $X$ isomorphic to P with standard affine charts given by dehomogenization.

Use dehomogenization_map with U one of the affine_charts of $X$ to obtain the dehomogenization map from the homogeneous_coordinate_ring of P to the coordinate_ring of U.

Examples

julia> P = projective_space(QQ, 2);
-
-julia> Pcov = covered_scheme(P)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-    3: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(s1//s0), (s2//s0)]
-    2: [(s0//s1), (s2//s1)]
-    3: [(s0//s2), (s1//s2)]
source

Attributes

To access the affine charts of a CoveredScheme $X$ use

affine_chartsMethod
affine_charts(X::AbsCoveredScheme)

Return the affine charts in the default_covering of $X$.

Examples

julia> P = projective_space(QQ, 2);
-
-julia> S = homogeneous_coordinate_ring(P);
-
-julia> I = ideal(S, [S[1]*S[2]-S[3]^2]);
-
-julia> X = subscheme(P, I)
-Projective scheme
-  over rational field
-defined by ideal(s0*s1 - s2^2)
-
-julia> Xcov = covered_scheme(X)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of quotient of multivariate polynomial ring
-    2: spec of quotient of multivariate polynomial ring
-    3: spec of quotient of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(s1//s0), (s2//s0)]
-    2: [(s0//s1), (s2//s1)]
-    3: [(s0//s2), (s1//s2)]
-
-julia> affine_charts(Xcov)
-3-element Vector{AbsSpec}:
- Spec of quotient of multivariate polynomial ring
- Spec of quotient of multivariate polynomial ring
- Spec of quotient of multivariate polynomial ring
-
source

Other attributes are the base_ring over which the scheme is defined and

default_coveringMethod
default_covering(X::AbsCoveredScheme)

Return the default covering for $X$.

Examples

julia> P = projective_space(QQ, 2);
-
-julia> S = homogeneous_coordinate_ring(P);
-
-julia> I = ideal(S, [S[1]*S[2]-S[3]^2]);
-
-julia> X = subscheme(P, I)
-Projective scheme
-  over rational field
-defined by ideal(s0*s1 - s2^2)
-
-julia> Xcov = covered_scheme(X)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of quotient of multivariate polynomial ring
-    2: spec of quotient of multivariate polynomial ring
-    3: spec of quotient of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(s1//s0), (s2//s0)]
-    2: [(s0//s1), (s2//s1)]
-    3: [(s0//s2), (s1//s2)]
-
-julia> default_covering(Xcov)
-Covering
-  described by patches
-    1: spec of quotient of multivariate polynomial ring
-    2: spec of quotient of multivariate polynomial ring
-    3: spec of quotient of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(s1//s0), (s2//s0)]
-    2: [(s0//s1), (s2//s1)]
-    3: [(s0//s2), (s1//s2)]
-
source

Properties

An AbsCoveredScheme may have different properties such as

    is_empty(X::AbsCoveredScheme)
-    is_smooth(X::AbsCoveredScheme)

The modeling of covered schemes and their expected behaviour

Any AbsCoveredScheme may possess several Coverings. This is necessary for several reasons; for instance, a morphism $f : X \to Y$ between AbsCoveredSchemes will in general only be given on affine patches on a refinement of the default_covering of X. The list of available Coverings can be obtained using

coveringsMethod
coverings(X::AbsCoveredScheme)

Return the list of internally stored Coverings of $X$.

Examples

julia> P = projective_space(QQ, 2);
-
-julia> Pcov = covered_scheme(P)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-    3: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(s1//s0), (s2//s0)]
-    2: [(s0//s1), (s2//s1)]
-    3: [(s0//s2), (s1//s2)]
-
-julia> coverings(Pcov)
-1-element Vector{Covering{QQField}}:
- Covering with 3 patches
source

Every AbsCoveredScheme $X$ has to be modeled using one original default_covering $C$, simply to gather the data necessary to fully describe $X$. The affine_charts of $X$ return the patches of this covering. For any refinement $D < C$, we require the following to hold: Every element $U$ of the affine_charts of $D$ is either

  • directly an element of the affine_charts of $C$;
  • a PrincipalOpenSubset with some ancestor in the affine_charts of $C$;
  • a SimplifiedSpec with some original in the affine_charts of $C$.

In all these cases, the affine subsets in the refinements form a tree and thus remember their origins and ambient spaces. In particular, affine patches and also their glueings can be recycled and reused in different coverings and the latter should be merely seen as lists pointing to the objects involved.

diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/CoveringsAndGlueings/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/CoveringsAndGlueings/index.html deleted file mode 100644 index 0a671546e512..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/CoveringsAndGlueings/index.html +++ /dev/null @@ -1,133 +0,0 @@ - -Coverings · Oscar.jl

Coverings

Coverings are the backbone data structure for CoveredSchemes in Oscar.

CoveringType
Covering

A covering of a scheme $X$ by affine charts $Uᵢ$ which are glued along isomorphisms $gᵢⱼ : Uᵢ⊃ Vᵢⱼ → Vⱼᵢ ⊂ Uⱼ$.

Note: The distinction between the different affine charts of the scheme is made from their hashes. Thus, an affine scheme must not appear more than once in any covering!

source

Constructors

CoveringMethod
Covering(patches::Vector{<:AbsSpec})

Return a Covering with pairwise disjoint affine charts $Uᵢ$ given by the entries of patches. This Covering will have no glueings except those glueings along the identity of every affine chart to itself.

Examples

julia> P1, (x,y) = QQ["x", "y"];
-
-julia> P2, (u,v) = QQ["u", "v"];
-
-julia> U1 = Spec(P1);
-
-julia> U2 = Spec(P2);
-
-julia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
source
disjoint_unionMethod
disjoint_union(C1::Covering, C2::Covering)

Return the Covering corresponding to the disjoint union of C1 and C2.

The charts and glueings of the disjoint union are given by the disjoint union of the charts and glueings of the covers C1 and C2.

Examples

julia> P1, (x,y) = QQ["x", "y"];
-
-julia> P2, (u,v) = QQ["u", "v"];
-
-julia> U1 = Spec(P1);
-
-julia> U2 = Spec(P2);
-
-julia> C1 = Covering(U1) # Set up the trivial covering with only one patch
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-
-julia> C2 = Covering(U2)
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [u, v]
-
-julia> C = disjoint_union(C1, C2)
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
source

Attributes

affine_chartsMethod
affine_charts(C::Covering)

Return the list of affine charts that make up the Covering C.

source
glueingsMethod
glueings(C::Covering)

Return a dictionary of glueings of the affine_charts of C.

The keys are pairs (U, V) of affine_charts. One can also use C[U, V] to obtain the respective glueing.

Note: Glueings are lazy in the sense that they are in general only computed when asked for. This method only returns the internal cache, but does not try to compute new glueings.

source

Methods

add_glueing!Method
add_glueing!(C::Covering, G::AbsGlueing)

Add a glueing G to the covering C.

The patches of G must be among the affine_charts of C.

Examples

julia> P1, (x,y) = QQ["x", "y"];
-
-julia> P2, (u,v) = QQ["u", "v"];
-
-julia> U1 = Spec(P1);
-
-julia> U2 = Spec(P2);
-
-julia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> V1 = PrincipalOpenSubset(U1, x); # Preparations for glueing
-
-julia> V2 = PrincipalOpenSubset(U2, u);
-
-julia> f = SpecMor(V1, V2, [1//x, y//x]); # The glueing isomorphism
-
-julia> g = SpecMor(V2, V1, [1//u, v//u]); # and its inverse
-
-julia> G = Glueing(U1, U2, f, g); # Construct the glueing
-
-julia> add_glueing!(C, G) # Make the glueing part of the Covering
-Covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> C[U1, U2] == G # Check whether the glueing of U1 and U2 in C is G.
-true
source

Glueings

Glueings are used to identify open subsets $U \subset X$ and $V \subset Y$ of affine schemes along an isomorphism $f \colon U \leftrightarrow V \colon g$.

Types

The abstract type of any such glueing is

AbsGlueingType
AbsGlueing

A glueing of two affine schemes $X$ and $Y$ (the patches) along open subsets $U$ in $X$ and $V$ in $Y$ (the glueing_domains) along mutual isomorphisms $f : U ↔ V : g$ (the glueing_morphisms).

source

The available concrete types are

GlueingType
Glueing

Concrete instance of an AbsGlueing for glueings of affine schemes $X ↩ U ≅ V ↪ Y$ along open subsets $U$ and $V$ of type SpecOpen.

source
SimpleGlueingType
SimpleGlueing

Concrete instance of an AbsGlueing for glueings of affine schemes $X ↩ U ≅ V ↪ Y$ along open subsets $U$ and $V$ of type PrincipalOpenSubset.

source

Constructors

GlueingMethod
Glueing(X::AbsSpec, Y::AbsSpec, f::SchemeMor, g::SchemeMor)

Glue two affine schemes $X$ and $Y$ along mutual isomorphisms $f$ and $g$ of open subsets $U$ of $X$ and $V$ of $Y$.

Examples

julia> P1, (x,y) = QQ["x", "y"]; P2, (u,v) = QQ["u", "v"];
-
-julia> U1 = Spec(P1); U2 = Spec(P2);
-
-julia> V1 = PrincipalOpenSubset(U1, x); # Preparations for glueing
-
-julia> V2 = PrincipalOpenSubset(U2, u);
-
-julia> f = SpecMor(V1, V2, [1//x, y//x]); # The glueing isomorphism
-
-julia> g = SpecMor(V2, V1, [1//u, v//u]); # and its inverse
-
-julia> G = Glueing(U1, U2, f, g) # Construct the glueing
-Glueing
-  of  spec of multivariate polynomial ring
-  and spec of multivariate polynomial ring
-along the open subsets
-  [x, y]   spec of localized ring
-  [u, v]   spec of localized ring
-given by the pullback function
-  u -> 1/x
-  v -> y/x
-
-julia> typeof(G)<:SimpleGlueing # Since the glueing domains were `PrincipalOpenSubsets`, this defaults to a `SimpleGlueing`
-true
-
-julia> # Alternative using SpecOpens as glueing domains:
-
-julia> W1 = SpecOpen(U1, [x]); W2 = SpecOpen(U2, [u]);
-
-julia> h1 = SpecOpenMor(W1, W2, [1//x, y//x]);
-
-julia> h2 = SpecOpenMor(W2, W1, [1//u, v//u]);
-
-julia> H = Glueing(U1, U2, h1, h2)
-Glueing
-  of  spec of multivariate polynomial ring
-  and spec of multivariate polynomial ring
-along the open subsets
-  [x, y]   complement to V(x) in affine scheme with coordinates [x, y]
-  [u, v]   complement to V(u) in affine scheme with coordinates [u, v]
-defined by the map
-  morphism
-    from [x, y]  spec of localized ring
-    to   [u, v]  spec of multivariate polynomial ring
-  given by the pullback function
-    u -> 1/x
-    v -> y/x
-
-julia> typeof(H)<:Glueing
-true
source

Attributes

patchesMethod
patches(G::AbsGlueing)

Return a pair of affine schemes (X, Y) which are glued by G.

source
glueing_domainsMethod
glueing_domains(G::AbsGlueing)

Return a pair of open subsets $U$ and $V$ of the respective patches of G which are glued by G along the glueing_morphisms of G.

source
glueing_morphismsMethod
glueing_morphisms(G::AbsGlueing)

Return a pair of mutually inverse isomorphisms (f, g) of open subsets $U$ and $V$ of the respective patches of G which are used for the glueing identification.

source
inverseMethod
inverse(G::AbsGlueing)

Return the glueing H with patches, glueing_domains, and glueing_morphisms in opposite order compared to G.

source

Methods

composeMethod
compose(G::AbsGlueing, H::AbsGlueing)

Given glueings X ↩ U ≅ V ↪ Y and Y ↩ V' ≅ W ↪ Z, return the glueing X ↩ V ∩ V' ↪ Z.

WARNING: In general such a glueing will not provide a separated scheme. Use maximal_extension to extend the glueing.

source
maximal_extensionMethod
maximal_extension(G::Glueing)

Given a glueing X ↩ U ≅ V ↪ Y, try to find the maximal extension to an open subset U' ⊃ U in X and V' ⊃ V in Y so that the resulting scheme is separated.

source
restrictMethod
restrict(G::AbsGlueing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true)

Given a glueing $X ↩ U ≅ V ↪ Y$ and isomorphisms $f : X → X'$ and $g: Y → Y'$, return the induced glueing of $X'$ and $Y'$.

source
diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/GeneralSchemes/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/GeneralSchemes/index.html deleted file mode 100644 index e3ada60829b8..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/GeneralSchemes/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -General schemes · Oscar.jl

General schemes

Arbitrary schemes over a commutative base ring $\mathbb k$ with unit are instances of the abstract type

SchemeType
Scheme{BaseRingType<:Ring}

A scheme over a ring $𝕜$ of type BaseRingType.

source

Morphisms of schemes shall be derived from the abstract type

SchemeMorType
SchemeMor{DomainType, CodomainType, MorphismType, BaseMorType}

A morphism of schemes $f : X → Y$ of type MorphismType with $X$ of type DomainType and $Y$ of type CodomainType.

When $X$ and $Y$ are defined over schemes $BX$ and $BY$ other than $Spec(𝕜)$, BaseMorType is the type of the underlying morphism $BX → BY$; otherwise, it can be set to Nothing.

source

Change of base

base_changeMethod
base_change(phi::Any, X::Scheme)

For a Scheme $X$ over a base_ring $𝕜$ and a map $φ : 𝕜 → R$ we compute $X' = X ×ₖ Spec(R)$ and return a pair (X', f) where $f : X' → X$ is the canonical morphism.

Note

We do not restrict phi to be a Hecke.Map so that one can also use coercion, anonymous functions, etc.

source
base_changeMethod
base_change(phi::Any, f::SchemeMor;
-    domain_map::SchemeMor, codomain_map::SchemeMor
-  )

For a morphism $f : X → Y$ with both $X$ and $Y$ defined over a base_ring $𝕜$ and a map $φ : 𝕜 → R$ return a triple (a, F, b) where $a : X' → X$ is the morphism from base_change(phi, X), $b : Y' → Y$ the one for $Y$, and $F : X' → Y'$ the induced morphism on those fiber products.

Note

We do not restrict phi to be a Hecke.Map so that one can also use coercion, anonymous functions, etc.

Note

The morphisms $a$ and $b$ can be passed as the optional arguments domain_map and codomain_map, respectively.

source
diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html deleted file mode 100644 index b126cd57b4b4..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html +++ /dev/null @@ -1,284 +0,0 @@ - -Morphisms of affine schemes · Oscar.jl

Morphisms of affine schemes

Constructors

General constructors

SpecMorMethod
SpecMor(X::AbsSpec, Y::AbsSpec, f::Vector{<:RingElem}; check::Bool=true)

This method constructs a morphism from the scheme $X$ to the scheme $Y$. For this one has to specify the images of the coordinates (the generators of ambient_coordinate_ring(Y)) under the pullback map $𝒪(Y) → 𝒪(X)$ as third argument.

Note that expensive checks can be turned off by setting check=false.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> Y = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> SpecMor(X, Y, gens(OO(X)))
-Morphism
-  from [x1, x2, x3]  affine 3-space over QQ
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
source

Special constructors

identity_mapMethod
identity_map(X::AbsSpec{<:Any, <:MPolyRing})

This method constructs the identity morphism from an affine scheme to itself.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> identity_map(X)
-Morphism
-  from [x1, x2, x3]  affine 3-space over QQ
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
source
inclusion_morphismMethod
inclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true)

Return the inclusion map from $X$ to $Y$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> f = inclusion_morphism(Y, X)
-Morphism
-  from [x1, x2, x3]  spec of quotient of multivariate polynomial ring
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> 0
-  x2 -> x2
-  x3 -> x3
-
-julia> I = kernel(pullback(f))  # this is a way to obtain the ideal ``I ⊆  O(X)`` cutting out ``Y`` from ``X``.
-ideal(x1)
-
-julia> base_ring(I) == OO(X)
-true
source
composeMethod
compose(f::AbsSpecMor, g::AbsSpecMor)

This method computes the composition of two morphisms.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> m1 = inclusion_morphism(Y, X)
-Morphism
-  from [x1, x2, x3]  spec of quotient of multivariate polynomial ring
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> 0
-  x2 -> x2
-  x3 -> x3
-
-julia> m2 = identity_map(X)
-Morphism
-  from [x1, x2, x3]  affine 3-space over QQ
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
-
-julia> m3 = identity_map(Y)
-Morphism
-  from [x1, x2, x3]  spec of quotient of multivariate polynomial ring
-  to   [x1, x2, x3]  spec of quotient of multivariate polynomial ring
-given by the pullback function
-  x1 -> 0
-  x2 -> x2
-  x3 -> x3
-
-julia> compose(m3, compose(m1, m2)) == m1
-true
source
restrictMethod
restrict(f::SpecMor, U::AbsSpec, V::AbsSpec)

This method restricts the domain of the morphism $f$ to $U$ and its codomain to $V$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> restrict(identity_map(X), Y, Y) == identity_map(Y)
-true
source

Attributes

General attributes

domainMethod
domain(f::AbsSpecMor)

On a morphism $f : X → Y$ of affine schemes, this returns $X$.

Examples

julia> Y = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(Y)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> X = subscheme(Y, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> f = inclusion_morphism(X, Y)
-Morphism
-  from [x1, x2, x3]  spec of quotient of multivariate polynomial ring
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> 0
-  x2 -> x2
-  x3 -> x3
-
-julia> domain(f)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
source
codomainMethod
codomain(f::AbsSpecMor)

On a morphism $f : X → Y$ of affine schemes, this returns $Y$.

Examples

julia> Y = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(Y)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> X = subscheme(Y, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> f = inclusion_morphism(X, Y)
-Morphism
-  from [x1, x2, x3]  spec of quotient of multivariate polynomial ring
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> 0
-  x2 -> x2
-  x3 -> x3
-
-julia> codomain(f)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
source
pullbackMethod
pullback(f::AbsSpecMor)

On a morphism $f : X → Y$ of affine schemes $X = Spec(S)$ and $Y = Spec(R)$, this returns the ring homomorphism $f^* : R → S$.

Examples

julia> Y = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(Y)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> X = subscheme(Y, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> pullback(inclusion_morphism(X, Y))
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Quotient of multivariate polynomial ring by ideal with 1 generator
source
graphMethod
graph(f::AbsSpecMor)

Return the graph of $f : X → Y$ as a subscheme of $X×Y$ as well as the two projections to $X$ and $Y$.

Examples

julia> Y = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(Y)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> X = subscheme(Y, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> f = inclusion_morphism(X, Y)
-Morphism
-  from [x1, x2, x3]  spec of quotient of multivariate polynomial ring
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> 0
-  x2 -> x2
-  x3 -> x3
-
-julia> graph(f)
-(Spec of quotient of multivariate polynomial ring, Morphism: spec of quotient of multivariate polynomial ring -> spec of quotient of multivariate polynomial ring, Morphism: spec of quotient of multivariate polynomial ring -> affine 3-space over QQ with coordinates [x1, x2, x3])
source

Special attributes

In addition to the standard getters and methods for instances of SpecMor, we also have

image_idealMethod
image_ideal(f::ClosedEmbedding)

For a closed embedding $f : X → Y$ of affine schemes $X = Spec(S)$ into $Y = Spec(R)$ such that $S ≅ R/I$ via $f$ for some ideal $I ⊂ R$ this returns $I$.

source

Undocumented

The following functions do exist but are currently undocumented:

  • underlying_morphism,
  • complement_ideal,
  • complement_scheme,
  • preimage,
  • inverse,
  • various type getters.

Properties

is_isomorphismMethod
is_isomorphism(f::AbsSpecMor)

This method checks if a morphism is an isomorphism.

source
is_inverse_ofMethod
is_inverse_of(f::AbsSpecMor, g::AbsSpecMor)

This method checks if a morphism $f$ is the inverse of a morphism $g$.

source
is_identity_mapMethod
is_identity_map(f::AbsSpecMor)

This method checks if a morphism is the identity map.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> R = OO(X)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
-
-julia> (x1,x2,x3) = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
-
-julia> Y = subscheme(X, x1)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables over QQ
-    by ideal(x1)
-
-julia> is_identity_map(inclusion_morphism(Y, X))
-false
source

Methods

fiber_productMethod
fiber_product(f::SpecMor{SpecType, SpecType, <:Any}, g::SpecMor{SpecType, SpecType, <:Any}) where {SpecType<:StdSpec}

For morphisms $f : Y → X$ and $g : Z → X$ return the fiber product $Y×Z$ over $X$ together with its two canonical projections.

source
productMethod
product(X::AbsSpec, Y::AbsSpec)

Return a triple $(X×Y, p₁, p₂)$ consisting of the product $X×Y$ over the common base ring $𝕜$ and the two projections $p₁ : X×Y → X$ and $p₂ : X×Y → Y$.

source
simplifyMethod
simplify(X::AbsSpec{<:Field})

Given an affine scheme $X$ with coordinate ring $R = 𝕜[x₁,…,xₙ]/I$ (or a localization thereof), use Singular's elimpart to try to eliminate variables $xᵢ$ to arrive at a simpler presentation $R ≅ R' = 𝕜[y₁,…,yₘ]/J$ for some ideal $J$; return a SimplifiedSpec $Y$ with $X$ as its original.

***Note:*** The ambient_coordinate_ring of the output Y will be different from the one of X and hence the two schemes will not compare using ==.

source
diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/index.html deleted file mode 100644 index b873e43f52b5..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/index.html +++ /dev/null @@ -1,33 +0,0 @@ - -Morphisms of projective schemes · Oscar.jl

Morphisms of projective schemes

Let $Q = B[y_0, \dots, y_n]/J$ and $P = A[x_0,\dots,x_m]/I$ be graded affine algebras over base_rings A and B, respectively. A morphism $\varphi : \mathrm{Proj}(Q) \to \mathrm{Proj}(P)$ is modeled via a morphism of graded algebras $\varphi^* : P \to Q$. In the case of A != B, this involves a non-trivial morphism of rings $A \to B$.

Abstract types and basic interface

At the moment we have no abstract type for such morphisms and no interface spelled out.

Types

ProjectiveSchemeMorType
ProjectiveSchemeMor

A morphism of projective schemes

     ℙˢ(B)     ℙʳ(A)
-       ∪         ∪
-       P    →    Q
-       ↓         ↓
-    Spec(B) → Spec(A)

given by means of a commutative diagram of homomorphisms of graded rings

    A[v₀,…,vᵣ] → B[u₀,…,uₛ]
-        ↑            ↑
-        A      →     B

If no morphism A → B of the base rings is specified, then both $P$ and $Q$ are assumed to be defined in relative projective space over the same ring with the identity on the base.

source

Constructors

morphism_of_projective_schemesMethod
morphism_of_projective_schemes(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map; check::Bool=true )

Given a morphism $f : T → S$ of the homogeneous_coordinate_rings of Q and P, respectively, construct the associated morphism of projective schemes.

source
morphism_of_projective_schemesMethod
morphism_of_projective_schemes(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map, h::SchemeMor; check::Bool=true )

Suppose $P ⊂ ℙʳ_A$ and $Q ⊂ ℙˢ_B$ are projective schemes, $h : Spec(A) → Spec(B)$ is a morphism of their base_schemes, and $f : T → S$ a morphism of the homogeneous_coordinate_rings of Q and P over $h^* : B → A$. This constructs the associated morphism of projective schemes.

source
morphism_of_projective_schemesMethod
morphism_of_projective_schemes(X::AbsProjectiveScheme, Y::AbsProjectiveScheme, a::Vector{<:RingElem})

Suppose $X ⊂ ℙʳ$ and $Y ⊂ ℙˢ$ are projective schemes over the same base_scheme. Construct the morphism of projective schemes associated to the morphism of graded rings which takes the generators of the homogeneous_coordinate_ring of $Y$ to the elements in a of the homogeneous_coordinate_ring of $X$.

source

Attributes

As every instance of Map, a morphism of projective schemes can be asked for its (co-)domain:

    domain(phi::ProjectiveSchemeMor) 
-    codomain(phi::ProjectiveSchemeMor)

Moreover, we provide getters for the associated morphisms of rings:

pullbackMethod
 pullback(phi::ProjectiveSchemeMor)

For a morphism phi of projective schemes, this returns the associated morphism of graded affine algebras.

source
base_ring_morphismMethod
base_ring_morphism(phi::ProjectiveSchemeMor)

For a morphism phi : P → Q of relative projective spaces over psi : Spec(A) → Spec(B) this returns the associated map B → A.

source
base_mapMethod
base_map(phi::ProjectiveSchemeMor)

For a morphism phi : P → Q of relative projective spaces over psi : Spec(A) → Spec(B) this returns psi.

source
map_on_affine_conesMethod
map_on_affine_cones(phi::ProjectiveSchemeMor)

For a morphism phi : X → Y this returns the associated morphism of the affine_cones $C(X) → C(Y)$.

source

Methods

covered_scheme_morphismMethod
covered_scheme_morphism(f::ProjectiveSchemeMor)

Given a morphism of ProjectiveSchemes $f : X → Y$, construct and return the same morphism as a CoveredSchemeMorphism of the covered_schemes of $X$ and $Y$, respectively.

Examples

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal([x^3-y^2*z]);
-
-julia> Y = projective_scheme(P, I);
-
-julia> f = identity_map(Y)
-Morphism
-  from projective scheme in IP^2 over QQ
-  to   projective scheme in IP^2 over QQ
-
-julia> fcov = covered_scheme_morphism(f);
-
-julia> codomain(fcov)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of quotient of multivariate polynomial ring
-    2: spec of quotient of multivariate polynomial ring
-    3: spec of quotient of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(y//x), (z//x)]
-    2: [(x//y), (z//y)]
-    3: [(x//z), (y//z)]
source
diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html deleted file mode 100644 index a9a66adf5abb..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html +++ /dev/null @@ -1,201 +0,0 @@ - -Projective schemes · Oscar.jl

Projective schemes

Let $A$ be a commutative noetherian base ring and $S = A[x_0,\dots, x_n]$ the standard graded polynomial ring over $A$. Then $X = \mathrm{Proj}(S) = \mathbb P^n_A$ is a (relative) projective scheme over $\mathrm{Spec}(A)$. Similarly, for a homogeneous ideal $I \subset S$ we have $X = \mathrm{Proj}(S/I) \subset \mathbb P^n_A$ a (relative) projective scheme over $\mathrm{Spec}(A)$ which is a closed subscheme of $\mathbb P^n_A$ in a natural way. The majority of applications will be in the setting where $A = \mathbb k$ is a field, but be aware that we also support different base rings such as the usual four MPolyRing, MPolyQuoRing, MPolyLocRing, and MPolyQuoLocRing.

Abstract types and basic interface

The abstract type for such projective schemes is

    AbsProjectiveScheme{CoeffRingType, RingType} where {CoeffRingType<:Ring}

where, in the above notation, CoeffRingType denotes the type of A and RingType the type of either S or S/I, respectively. The abstract type comes with the following interface:

base_ringMethod
base_ring(X::AbsProjectiveScheme)

On $X ⊂ ℙʳ_A$ this returns $A$.

source
base_schemeMethod
base_scheme(X::AbsProjectiveScheme)

Return the base scheme $Y$ for $X ⊂ ℙʳ×ₖ Y → Y$ with $Y$ defined over a field $𝕜$.

source
homogeneous_coordinate_ringMethod
homogeneous_coordinate_ring(P::AbsProjectiveScheme)

On a projective scheme $P = Proj(S)$ for a standard graded finitely generated algebra $S$ this returns $S$.

Example

julia> S, _ = grade(QQ["x", "y", "z"][1]);
-
-julia> I = ideal(S, S[1] + S[2]);
-
-julia> X = ProjectiveScheme(S, I)
-Projective scheme
-  over rational field
-defined by ideal(x + y)
-
-julia> homogeneous_coordinate_ring(X)
-Quotient
-  of graded multivariate polynomial ring in 3 variables over QQ
-  by ideal(x + y)
source
relative_ambient_dimensionMethod
relative_ambient_dimension(X::AbsProjectiveScheme)

On $X ⊂ ℙʳ_A$ this returns $r$.

Example

julia> S, _ = grade(QQ["x", "y", "z"][1]);
-
-julia> I = ideal(S, S[1] + S[2])
-ideal(x + y)
-
-julia> X = ProjectiveScheme(S, I)
-Projective scheme
-  over rational field
-defined by ideal(x + y)
-
-julia> relative_ambient_dimension(X)
-2
-
-julia> dim(X)
-1
source
ambient_coordinate_ringMethod
ambient_coordinate_ring(P::AbsProjectiveScheme)

On a projective scheme $P = Proj(S)$ with $S = P/I$ for a standard graded polynomial ring $P$ and a homogeneous ideal $I$ this returns $P$.

Example

julia> S, _ = grade(QQ["x", "y", "z"][1])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> I = ideal(S, S[1] + S[2])
-ideal(x + y)
-
-julia> X = ProjectiveScheme(S, I)
-Projective scheme
-  over rational field
-defined by ideal(x + y)
-
-julia> homogeneous_coordinate_ring(X)
-Quotient
-  of graded multivariate polynomial ring in 3 variables over QQ
-  by ideal(x + y)
-
-julia> ambient_coordinate_ring(X) === S
-true
-
-julia> ambient_coordinate_ring(X) === homogeneous_coordinate_ring(X)
-false
source
ambient_spaceMethod
ambient_space(X::AbsProjectiveScheme)

On $X ⊂ ℙʳ_A$ this returns $ℙʳ_A$.

Example

julia> S, _ = grade(QQ["x", "y", "z"][1]);
-
-julia> I = ideal(S, S[1] + S[2]);
-
-julia> X = ProjectiveScheme(S, I)
-Projective scheme
-  over rational field
-defined by ideal(x + y)
-
-julia> P = ambient_space(X)
-Projective space of dimension 2
-  over rational field
-with homogeneous coordinates [x, y, z]
source
defining_idealMethod
defining_ideal(X::AbsProjectiveScheme)

On $X ⊂ ℙʳ_A$ this returns the homogeneous ideal $I ⊂ A[s₀,…,sᵣ]$ defining $X$.

Example

julia> R, (u, v) = QQ["u", "v"];
-
-julia> Q, _ = quo(R, ideal(R, u^2 + v^2));
-
-julia> S, _ = grade(Q["x", "y", "z"][1]);
-
-julia> P = projective_scheme(S)
-Projective space of dimension 2
-  over quotient of multivariate polynomial ring by ideal with 1 generator
-with homogeneous coordinates [x, y, z]
-
-julia> defining_ideal(P)
-ideal()
source
affine_coneMethod
affine_cone(X::AbsProjectiveScheme)

On $X = Proj(S) ⊂ ℙʳ_𝕜$ this returns a pair (C, f) where $C = C(X) ⊂ 𝕜ʳ⁺¹$ is the affine cone of $X$ and $f : S → 𝒪(C)$ is the morphism of rings from the homogeneous_coordinate_ring to the coordinate_ring of the affine cone.

Note that if the base scheme is not affine, then the affine cone is not affine.

Example

julia> R, (u, v) = QQ["u", "v"];
-
-julia> Q, _ = quo(R, ideal(R, u^2 + v^2));
-
-julia> S, _ = grade(Q["x", "y", "z"][1]);
-
-julia> P = projective_scheme(S)
-Projective space of dimension 2
-  over quotient of multivariate polynomial ring by ideal with 1 generator
-with homogeneous coordinates [x, y, z]
-
-julia> affine_cone(P)
-(Spec of quotient of multivariate polynomial ring, Map with following data
-Domain:
-=======
-S
-Codomain:
-=========
-Quotient of multivariate polynomial ring by ideal with 1 generator)
source
homogeneous_coordinates_on_affine_coneMethod
homogeneous_coordinates_on_affine_cone(X::AbsProjectiveScheme)

On $X ⊂ ℙʳ_A$ this returns a vector with the homogeneous coordinates $[s₀,…,sᵣ]$ as entries where each one of the $sᵢ$ is a function on the affine cone of $X$.

Example

julia> R, (u, v) = QQ["u", "v"];
-
-julia> Q, _ = quo(R, ideal(R, u^2 + v^2));
-
-julia> S, _ = grade(Q["x", "y", "z"][1]);
-
-julia> P = projective_scheme(S)
-Projective space of dimension 2
-  over quotient of multivariate polynomial ring by ideal with 1 generator
-with homogeneous coordinates [x, y, z]
-
-julia> homogeneous_coordinates_on_affine_cone(P)
-3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x
- y
- z
-
-julia> gens(OO(affine_cone(P)[1])) # all coordinates on the affine cone
-5-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x
- y
- z
- u
- v
-
source
covered_schemeMethod
covered_scheme(P::AbsProjectiveScheme)

Return a CoveredScheme $X$ isomorphic to P with standard affine charts given by dehomogenization.

Use dehomogenization_map with U one of the affine_charts of $X$ to obtain the dehomogenization map from the homogeneous_coordinate_ring of P to the coordinate_ring of U.

Examples

julia> P = projective_space(QQ, 2);
-
-julia> Pcov = covered_scheme(P)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-    3: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(s1//s0), (s2//s0)]
-    2: [(s0//s1), (s2//s1)]
-    3: [(s0//s2), (s1//s2)]
source

The minimal concrete type realizing this interface is

    ProjectiveScheme{CoeffRingType, RingType} <: AbsProjectiveScheme{CoeffRingType, RingType}

Constructors

Besides ProjectiveScheme(S) for some graded polynomial ring or a graded affine algebra S, we provide the following constructors:

    projective_scheme(S::MPolyDecRing)
-    projective_scheme(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem}
-    projective_scheme(I::MPolyIdeal{<:MPolyDecRingElem})
-    projective_scheme(Q::MPolyQuoRing{MPolyDecRingElem{T, PT}}) where {T, PT<:MPolyRingElem{T}} = ProjectiveScheme(Q)

Subschemes defined by homogeneous ideals, ring elements, or lists of elements can be created via the respective methods of the subscheme(P::AbsProjectiveScheme, ...) function. Special constructors are provided for projective space itself via the function projective_space and its various methods.

projective_spaceMethod
projective_space(A::Ring, var_symb::Vector{VarName})

Create the (relative) projective space Proj(A[x₀,…,xₙ]) over A where x₀,…,xₙ is a list of variable names.

Examples

julia> projective_space(QQ, [:x, :PPP, :?])
-Projective space of dimension 2
-  over rational field
-with homogeneous coordinates [x, PPP, ?]
-
-julia> homogeneous_coordinate_ring(ans)
-Multivariate polynomial ring in 3 variables over QQ graded by
-  x -> [1]
-  PPP -> [1]
-  ? -> [1]
source
projective_spaceMethod
projective_space(A::Ring, r::Int; var_name::VarName=:s)

Create the (relative) projective space Proj(A[s₀,…,sᵣ]) over A where s is a string for the variable names.

source

Attributes

Besides those attributes already covered by the above general interface we have the following (self-explanatory) ones for projective schemes over a field.

    dim(P::AbsProjectiveScheme{<:Field})
-    hilbert_polynomial(P::AbsProjectiveScheme{<:Field})
-    degree(P::AbsProjectiveScheme{<:Field})
-    arithmetic_genus(P::AbsProjectiveScheme{<:Field})

Methods

To facilitate the interplay between an AbsProjectiveScheme and the affine charts of its covered_scheme we provide the following methods:

dehomogenization_mapMethod
dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec)

Return the restriction morphism from the graded coordinate ring of $X$ to 𝒪(U).

Examples

julia> P = projective_space(QQ, ["x0", "x1", "x2"])
-Projective space of dimension 2
-  over rational field
-with homogeneous coordinates [x0, x1, x2]
-
-julia> X = covered_scheme(P);
-
-julia> U = first(affine_charts(X))
-Spectrum
-  of multivariate polynomial ring in 2 variables (x1//x0), (x2//x0)
-    over rational field
-
-julia> phi = dehomogenization_map(P, U);
-
-julia> S = homogeneous_coordinate_ring(P);
-
-julia> phi(S[2])
-(x1//x0)
-
source
dehomogenization_mapMethod
dehomogenization_map(X::AbsProjectiveScheme, i::Int)

Return the restriction morphism from the graded coordinate ring of $X$ to 𝒪(Uᵢ). Where Uᵢ is the i-th affine chart of X.

source
homogenization_mapMethod
homogenization_map(P::AbsProjectiveScheme, U::AbsSpec)

Given an affine chart $U ⊂ P$ of an AbsProjectiveScheme $P$, return a method $h$ for the homogenization of elements $a ∈ 𝒪(U)$.

This means that $h(a)$ returns a pair $(p, q)$ representing a fraction $p/q ∈ S$ of the ambient_coordinate_ring of $P$ such that $a$ is the dehomogenization of $p/q$.

Note: For the time being, this only works for affine charts which are of the standard form $sᵢ ≠ 0$ for $sᵢ∈ S$ one of the homogeneous coordinates of $P$.

Note: Since this map returns representatives only, it is not a mathematical morphism and, hence, in particular not an instance of Hecke.Map.

Examples

julia> A, _ = QQ["u", "v"];
-
-julia> P = projective_space(A, ["x0", "x1", "x2"])
-Projective space of dimension 2
-  over multivariate polynomial ring in 2 variables over QQ
-with homogeneous coordinates [x0, x1, x2]
-
-julia> X = covered_scheme(P)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of multivariate polynomial ring
-    2: spec of multivariate polynomial ring
-    3: spec of multivariate polynomial ring
-  in the coordinate(s)
-    1: [(x1//x0), (x2//x0), u, v]
-    2: [(x0//x1), (x2//x1), u, v]
-    3: [(x0//x2), (x1//x2), u, v]
-
-julia> U = first(affine_charts(X))
-Spectrum
-  of multivariate polynomial ring in 4 variables (x1//x0), (x2//x0), u, v
-    over rational field
-
-julia> phi = homogenization_map(P, U);
-
-julia> R = OO(U);
-
-julia> phi.(gens(R))
-4-element Vector{Tuple{MPolyDecRingElem{QQMPolyRingElem, AbstractAlgebra.Generic.MPoly{QQMPolyRingElem}}, MPolyDecRingElem{QQMPolyRingElem, AbstractAlgebra.Generic.MPoly{QQMPolyRingElem}}}}:
- (x1, x0)
- (x2, x0)
- (u, 1)
- (v, 1)
source

Properties

Further properties of projective schemes (all self-explanatory):

    is_empty(P::AbsProjectiveScheme{<:Field})
-    is_smooth(P::AbsProjectiveScheme)
-    is_irreducible(P::AbsProjectiveScheme)
-    is_reduced(P::AbsProjectiveScheme)
-    is_geometrically_reduced(P::AbsProjectiveScheme{<:Field})
-    is_geometrically_irreducible(P::AbsProjectiveScheme{<:Field})
-    is_integral(X::AbsProjectiveScheme{<:Field})
-    is_geometrically_integral(X::AbsProjectiveScheme{<:Field})
diff --git a/previews/PR2578/AlgebraicGeometry/Schemes/intro/index.html b/previews/PR2578/AlgebraicGeometry/Schemes/intro/index.html deleted file mode 100644 index e77d30224dee..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Schemes/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl
diff --git a/previews/PR2578/AlgebraicGeometry/Surfaces/K3Surfaces/index.html b/previews/PR2578/AlgebraicGeometry/Surfaces/K3Surfaces/index.html deleted file mode 100644 index 257d45df572d..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Surfaces/K3Surfaces/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Automorphism Groups of K3 surfaces · Oscar.jl

Automorphism Groups of K3 surfaces

A complex K3 surface is a compact complex surface $X$ with vanishing irregularity $h^1(X, \mathcal{O}_X)=0$ and trivial canonical bundle $\mathcal{O}_X\cong \omega_X$.

Much of the theory of (complex) K3 surfaces is governed by its Hodge structure and the $\mathbb{Z}$-lattices $NS(X) \subseteq H^2(X, \mathbb{Z})$.

See Daniel Huybrechts (2016) for the theory of K3 surfaces.

Automorphisms

K3_surface_automorphism_groupMethod
K3_surface_automorphism_group(S::ZZLat [, ample_class]) -> generators, rational curves, chambers

Compute the automorphism group of a very-general $S$-polarized K3 surface.

Further return representatives of the $\mathrm{Aut}(X)$-orbits of (-2)-curves on X and a fundamental domain for the action of $\mathrm{Aut}(X)$ on the set of nef L|S chambers. This is almost a fundamental domain for $\mathrm{Aut}(X)$ on the nef cone.

Here very general means that $Num(X)$ is isomorphic to S and the image of $\mathrm{Aut}(X) \to H^0(X,\Omega^2_X)$ is $ \pm 1$.

The function returns generators for the image of

\[f\colon \mathrm{Aut}(X) \to O(Num(X))\]

The output is represented with respect to the basis of S.

Note that under our genericity assumptions the kernel of $f$ is of order at most $2$ and it is equal to $2$ if and only if $S$ is $2$-elementary. If an ample class is given, then the generators returned preserve it.

This kind of computation can be very expensive. To print progress information use set_verbose_level(:K3Auto, 2) or higher.

Input

  • S: a hyperbolic lattice
  • ample: a row matrix or a vector given with respect to the ambient space of S.
source
borcherds_methodFunction
borcherds_method(S::ZZLat, n::Integer; compute_OR=true, entropy_abort=false, max_nchambers=-1)
-borcherds_method(L::ZZLat, S::ZZLat, w::QQMatrix; compute_OR=true, entropy_abort=false, max_nchambers=-1)

Compute the symmetry group of a Weyl chamber up to finite index.

Arguments

  • w: initial Weyl row vector represented with respect to the basis of L;
  • L: even, unimodular, hyperbolic lattice of rank n=10,18 or 26;
  • S: a primitive sublattice of L;
  • compute_OR=true: if false take as G all isometries of S extending to L;
  • max_nchambers: break the computation after max_nchambers are found;
  • entropy_abort abort if an automorphism of positive entropy is found.
source
K3ChamberType
K3Chamber

The $L|S$ chamber induced from a Weyl vector in L.

Let $L$ be an even, unimodular and hyperbolic lattice of rank $10$, $18$ or $26$ and $S$ be a primitive sublattice. Any Weyl vector $w$ of $L$ defines a Weyl chamber $C(w)$ in the positive cone of $L$. The Weyl chamber is a rational locally polyhedral cone with infinitely many facets, i.e. walls. It is the intersection of the positive half-spaces defined by $\Delta_L(w) = \{r \in L | r^2=-2, r.w = 1\}$. We have

\[C(w)=\{x \in \mathcal{P}_L | \forall r \in \Delta_L(w): x.r \geq 0\}\]

The Weyl chamber is a fundamental domain for the action of the Weyl group on the positive cone. We say that $S \otimes \mathbb{R} \cap C(w)$ is the $L|S$-chamber induced by $w$.

Note that two Weyl vectors induce the same chamber if and only if their orthogonal projections to $S$ coincide.

source
chamberFunction
chamber(data::BorcherdsCtx, weyl_vector::ZZMatrix, [parent_wall::ZZMatrix, walls::Vector{ZZMatrix}])

Return the $L|S$-chamber with the given Weyl vector.

The lattices $L$ and $S$ are stored in data. Via the parent walls we can obtain a spanning tree of the chamber graph.

source
weyl_vectorMethod
weyl_vector(D::K3Chamber) -> ZZMatrix

Return the Weyl vector defining this chamber.

source
wallsMethod
walls(D::K3Chamber) -> Vector{ZZMatrix}

Return the walls of the chamber D, i.e. its facets.

The corresponding half space of the wall defined by v in walls(D) is

\[\{x \in S \otimes \mathbb{R} | \langle x,v \rangle \geq 0\}.\]

v is given with respect to the basis of S and is primitive in S.

Note that Ichiro Shimada (2015) follows a different convention and takes v primitive in S^\vee.

source
inner_pointMethod
inner_point(L::ZZLat, S::ZZLat, w::QQMatrix)
-inner_point(C::K3Chamber)

Return a reasonably small integer inner point of the given L|S chamber.

source
raysMethod
rays(D::K3Chamber)

Return the rays of the chamber D.

They are represented as primitive row vectors with respect to the basis of S.

source
autMethod
aut(E::K3Chamber) -> Vector{ZZMatrix}

Return the stabilizer $\mathrm{Aut}_G(E)$ of $E$ in $G$.

The elements are represented with respect to the basis of $S$.

source
homMethod
hom(D::K3Chamber, E::K3Chamber) -> Vector{ZZMatrix}

Return the set $\mathrm{Hom}_G(D, E)$ of elements of $G$ mapping D to E.

The elements are represented with respect to the basis of $S$.

source
adjacent_chamberMethod
adjacent_chamber(D::K3Chamber, v::ZZMatrix) -> K3Chamber

Return return the $L|S$ chamber adjacent to D via the wall defined by v.

source
separating_hyperplanesMethod
separating_hyperplanes(S::ZZLat, v::QQMatrix, h::QQMatrix, d)

Return $\{x \in S | x^2=d, x.v>0, x.h<0\}$.

Arguments

  • S: a hyperbolic lattice
  • d: a negative integer
  • v,h: vectors of positive square
source
has_zero_entropyFunction
has_zero_entropy(S::ZZLat; rank_unimod=26) ->

Compute if the symmetry group of a Weyl chamber is elliptic, parabolic or hyperbolic.

Output

  • 1 - elliptic – the symmetry group is finite
  • 0 - parabolic – there is a unique cusp with infinite stabilizer
  • -1 - hyperbolic – positive entropy

This calls borcherds_method and breaks the computation as soon as a symmetry of a Weyl chamber with positive entrop is found.

source

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/AlgebraicGeometry/Surfaces/SurfacesP4/index.html b/previews/PR2578/AlgebraicGeometry/Surfaces/SurfacesP4/index.html deleted file mode 100644 index 1ed0f1e0f3cf..000000000000 --- a/previews/PR2578/AlgebraicGeometry/Surfaces/SurfacesP4/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Nongeneral Type Surfaces in mathbb P^4 · Oscar.jl

Nongeneral Type Surfaces in $\mathbb P^4$

Every smooth, projective surface can be embedded in $\mathbb P^5$, but there are constraints on the numerical invariants of a smooth surface in $\mathbb P^4$: The invariants of each such surface $S$ satisfy the double point formula

\[d^2-5d-10(\pi-1)+2(\chi(\mathcal O_S)-K_S^2) = 0.\]

Here, $d$ is the degree of $S$, $\pi$ its sectional genus, $\chi(\mathcal O_S)$ its Euler-Poincare characteristic, and $K_S$ its canonical class. The double point formula is a key ingredient in the proof of a theorem of Ellingsrud and Peskine which states that there are only finitely many families of smooth surfaces in $\mathbb P^4$ which are not of general type. That is, the degree of such surfaces in bounded from above. The best bound known so far is $52$, while examples exist up to degree $15$.

For details, we refer to

and the references given there.

Below, we present functions which return one hard coded example for each family presented in the first two papers above. Based on these papers, the existence of further families has been shown. Explicit examples to be included here are under construction.

Note

To ease subsequent computations, all hard coded examples are defined over a finite prime field.

Rational Surfaces

A Rational Surface with $d=3$, $\pi=0$

cubic_scrollMethod
cubic_scroll()

Return a smooth rational surface in $\mathbb P^4$ with degree 3 and sectional genus 0.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=4$, $\pi=0$

veroneseMethod
veronese()

Return a smooth rational surface in $\mathbb P^4$ with degree 4 and sectional genus 0.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=5$, $\pi=2$

castelnuovoMethod
castelnuovo()

Return a smooth rational surface in $\mathbb P^4$ with degree 5 and sectional genus 2.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=6$, $\pi=3$

bordigaMethod
bordiga()

Return a smooth rational surface in $\mathbb P^4$ with degree 6 and sectional genus 3.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=7$, $\pi=4$

rational_d7_pi4Method
rational_d7_pi4()

Return a smooth rational surface in $\mathbb P^4$ with degree 7 and sectional genus 4.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=8$, $\pi=5$

rational_d8_pi5Method
rational_d8_pi5()

Return a smooth rational surface in $\mathbb P^4$ with degree 8 and sectional genus 5.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=8$, $\pi=6$

rational_d8_pi6Method
rational_d8_pi6()

Return a smooth rational surface in $\mathbb P^4$ with degree 8 and sectional genus 6.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=9$, $\pi=6$

rational_d9_pi6Method
rational_d9_pi6()

Return a smooth rational surface in $\mathbb P^4$ with degree 9 and sectional genus 6.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=9$, $\pi=7$

rational_d9_pi7Method
rational_d9_pi7()

Return a smooth rational surface in $\mathbb P^4$ with degree 9 and sectional genus 7.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=10$, $\pi=8$

rational_d10_pi8Method
rational_d10_pi8()

Return a smooth rational surface in $\mathbb P^4$ with degree 10 and sectional genus 8.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=10$, $\pi=9$ which is Contained in one Quartic

rational_d10_pi9_quart_1Method
rational_d10_pi9_quart_1()

Return a smooth rational surface in $\mathbb P^4$ with degree 10 and sectional genus 9 which is contained in precisely one quartic.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=10$, $\pi=9$ which is Contained in a Pencil of Quartics

rational_d10_pi9_quart_2Method
rational_d10_pi9_quart_2()

Return a smooth rational surface in $\mathbb P^4$ with degree 10 and sectional genus 9 which is contained in a pencil of quartics.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=11$, $\pi=11$, and no 6-Secant

rational_d11_pi11_ss_0Method
rational_d11_pi11_ss_0()

Return a smooth rational surface in $\mathbb P^4$ with degree 11, sectional genus 11, and no 6-secant.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=11$, $\pi=11$, and one 6-Secant

rational_d11_pi11_ss_1Method
rational_d11_pi11_ss_1()

Return a smooth rational surface in $\mathbb P^4$ with degree 11, sectional genus 11, and one 6-secant.

The returned surface is defined over a prime field of characteristic 31991.

source

A Rational Surface with $d=11$, $\pi=11$, and Infinitely Many 6-Secants

rational_d11_pi11_ss_infMethod
rational_d11_pi11_ss_inf()

Return a smooth rational surface in $\mathbb P^4$ with degree 11, sectional genus 11, and infinitely many 6-secants.

The returned surface is defined over a prime field of characteristic 31991.

source

Ruled Surfaces

A Ruled Surface with $d=5$, $\pi=1$

quintic_elliptic_scrollMethod
quintic_elliptic_scroll()

Return a smooth ruled surface in $\mathbb P^4$ with degree 5 and sectional genus 1.

The returned surface is defined over a prime field of characteristic 31991.

source

Enriques Surfaces

An Enriques Surface with $d=9$, $\pi=6$

enriques_d9_pi6Method
enriques_d9_pi6()

Return a smooth Enriques surface in $\mathbb P^4$ with degree 9 and sectional genus 6.

The returned surface is defined over a prime field of characteristic 31991.

source

An Enriques Surface with $d=10$, $\pi=8$

enriques_d10_pi8Method
enriques_d10_pi8()

Return a smooth Enriques surface in $\mathbb P^4$ with degree 10 and sectional genus 8.

The returned surface is defined over a prime field of characteristic 31991.

source

An Enriques Surface with $d=11$, $\pi=10$

enriques_d11_pi10Method
enriques_d11_pi10()

Return a smooth Enriques surface in $\mathbb P^4$ with degree 11 and sectional genus 10.

The returned surface is defined over a prime field of characteristic 43.

source

An Enriques Surface with $d=13$, $\pi=16$

enriques_d13_pi16Method
enriques_d13_pi16()

Return a smooth Enriques surface in $\mathbb P^4$ with degree 13 and sectional genus 16.

The returned surface is defined over a prime field of characteristic 31991.

source

An Enriques Surface with $d=13$, $\pi=16$

enriques_d13_pi16_twoMethod
enriques_d13_pi16_two()

Return a smooth Enriques surface in $\mathbb P^4$ with degree 13 and sectional genus 16.

The returned surface is defined over a prime field of characteristic 31991.

source

K3 Surfaces

A K3 Surface with $d=7$, $\pi=5$

k3_d7_pi5Function
k3_d7_pi5()

Return a smooth K3 surface in $\mathbb P^4$ with degree 7 and sectional genus 5.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=8$, $\pi=6$

k3_d8_pi6Function
k3_d8_pi6()

Return a smooth K3 surface in $\mathbb P^4$ with degree 8 and sectional genus 6.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=9$, $\pi=8$

k3_d9_pi8Function
k3_d9_pi8()

Return a smooth K3 surface in $\mathbb P^4$ with degree 9 and sectional genus 8.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=10$, $\pi=9$ which is Contained in one Quartic

k3_d10_pi9_quart_1Method
k3_d10_pi9_quart_1()

Return a smooth K3 surface in $\mathbb P^4$ with degree 10 and sectional genus 9 which is contained in precisely one quartic.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=10$, $\pi=9$ which is Contained in a Pencil of Quartics

k3_d10_pi9_quart_2Method
k3_d10_pi9_quart_2()

Return a smooth K3 surface in $\mathbb P^4$ with degree 10 and sectional genus 9 which is contained in a pencil of quartics.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=11$, $\pi=11$ and no 6-Secant

k3_d11_pi11_ss_0Method
k3_d11_pi11_ss_0()

Return a smooth K3 surface in $\mathbb P^4$ with degree 11, sectional genus 11, and no 6-secant.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=11$, $\pi=11$ and one 6-Secant

k3_d11_pi11_ss_1Method
k3_d11_pi11_ss_1()

Return a smooth K3 surface in $\mathbb P^4$ with degree 11, sectional genus 11, and one 6-secant.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=11$, $\pi=11$ and two 6-Secants

k3_d11_pi11_ss_2Method
k3_d11_pi11_ss_2()

Return a smooth K3 surface in $\mathbb P^4$ with degree 11, sectional genus 11, and two 6-secants.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=11$, $\pi=11$ and three 6-Secants

k3_d11_pi11_ss_3Method
k3_d11_pi11_ss_3()

Return a smooth K3 surface in $\mathbb P^4$ with degree 11, sectional genus 11, and three 6-secants.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=11$, $\pi=12$

k3_d11_pi12Method
k3_d11_pi12()

Return a smooth K3 surface in $\mathbb P^4$ with degree 11 and sectional genus 12.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=12$, $\pi=14$

k3_d12_pi14Method
k3_d12_pi14()

Return a smooth K3 surface in $\mathbb P^4$ with degree 12 and sectional genus 14.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=13$, $\pi=16$

k3_d13_pi16Method
k3_d13_pi16()

Return a smooth K3 surface in $\mathbb P^4$ with degree 13 and sectional genus 16.

The returned surface is defined over a prime field of characteristic 31991.

source

A K3 Surface with $d=14$, $\pi=19$

k3_d14_pi19Method
k3_d14_pi19()

Return a smooth K3 surface in $\mathbb P^4$ with degree 14 and sectional genus 19.

The returned surface is defined over a prime field of characteristic 31991.

source

Bielliptic Surfaces

A Bielliptic Surface with $d=10$, $\pi=6$

bielliptic_d10_pi6Method
bielliptic_d10_pi6()

Return a smooth bielliptic surface in $\mathbb P^4$ with degree 10 and sectional genus 6.

The returned surface is defined over a prime field of characteristic 911.

source

A Bielliptic Surface with $d=15$, $\pi=21$

bielliptic_d15_pi21Method
bielliptic_d15_pi21()

Return a smooth bielliptic surface in $\mathbb P^4$ with degree 15 and sectional genus 21.

The returned surface is defined over a prime field of characteristic 911.

source

Abelian Surfaces

An Abelian Surface with $d=10$, $\pi=6$

abelian_d10_pi6Method
abelian_d10_pi6()

Return a smooth abelian surface in $\mathbb P^4$ with degree 10 and sectional genus 6.

The returned surface is defined over a prime field of characteristic 31991.

source

An Abelian Surface with $d=15$, $\pi=21$ which is Contained in a Net of Quintics

abelian_d15_pi21_quintic_3Method
abelian_d15_pi21_quintic_3()

Return a smooth abelian surface in $\mathbb P^4$ with degree 15 and sectional genus 21 which is contained in a net of quintics.

The returned surface is defined over a prime field of characteristic 31991.

source

An Abelian Surface with $d=15$, $\pi=21$ which is Contained in one Quintic

abelian_d15_pi21_quintic_1Method
abelian_d15_pi21_quintic_1()

Return a smooth abelian surface in $\mathbb P^4$ with degree 15 and sectional genus 21 which is contained in precisely one quintic.

The returned surface is defined over a prime field of characteristic 31991.

source

Elliptic Surfaces

An Elliptic Surface with $d=7$, $\pi=6$

elliptic_d7_pi6Method
elliptic_d7_pi6()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 7 and sectional genus 6.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=8$, $\pi=7$

elliptic_d8_pi7Method
elliptic_d8_pi7()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 8 and sectional genus 7.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=9$, $\pi=7$

elliptic_d9_pi7Method
elliptic_d9_pi7()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 9 and sectional genus 7.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=10$, $\pi=9$

elliptic_d10_pi9Method
elliptic_d10_pi9()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 10 and sectional genus 9.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=10$, $\pi=10$

elliptic_d10_pi10Method
elliptic_d10_pi10()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 10 and sectional genus 10.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=11$, $\pi=12$

elliptic_d11_pi12Method
elliptic_d11_pi12()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 11 and sectional genus 12.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=12$, $\pi=13$

elliptic_d12_pi13Method
elliptic_d12_pi13()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 12 and sectional genus 13.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=12$, $\pi=14$ and no 6-Secant

elliptic_d12_pi14_ss_0Method
elliptic_d12_pi14_ss_0()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 12, sectional genus 14, and no 6-secant.

The returned surface is defined over a prime field of characteristic 31991.

source

An Elliptic Surface with $d=12$, $\pi=14$, and Infinitely Many 6-Secants

elliptic_d12_pi14_ss_infMethod
elliptic_d12_pi14_ss_inf()

Return a smooth elliptic surface in $\mathbb P^4$ with degree 12, sectional genus 14, and infinitely many 6-secants.

The returned surface is defined over a prime field of characteristic 31991.

source

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html deleted file mode 100644 index 644afb29f55b..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html +++ /dev/null @@ -1,205 +0,0 @@ - -The Chow ring · Oscar.jl

The Chow ring

Algebraic cycles are formal linear sum of irreducible subvarieies over the integers. Perse, algebraic cycles do not admit a well-defined intersection product.

To see this, think of intersecting a non-trivial algebraic cycle C with itself. Of course, in set theory we can intersect C with itself and the result is again C. However, for a well-defined intersection theory, we would ask that the self-intersection of C is an algebraic cycle of strictly smaller dimension.

In theory, this is resolved by saying that the self-intersection of C is given by intersecting C with a distinct algebraic cycle D which is obtained by moving C a little bit. The general phrase for this is to "move C in general position".

This leads to a famous notion of equivalence among algebraic cycles, the so-called rational equivalence. The set of equivalence classes of algebraic cycles together with the intersection product then furnishes the Chow ring of the variety in question.

For complete and simplicial toric varieties, many things are known about the Chow ring and algebraic cycles (cf. section 12.5 in David A. Cox, John B. Little, Henry K. Schenck (2011):

among the Chow ring and the cohomology ring. Note that the cohomology ring is naturally graded (cf. last paragraph on page 593 in David A. Cox, John B. Little, Henry K. Schenck (2011)). However, the Chow ring is usually considered as a non-graded ring. To match this general convention, and in particular the implementation of the Chow ring for matroids in OSCAR, the toric Chow ring is constructed as a non-graded ring.

to the quotient of the non-graded Cox ring and a certain ideal. Specifically, the ideal in question is the sum of the ideal of linear relations and the Stanley-Reisner ideal.

  • It is worth noting that the ideal of linear relations is not

homogeneous with respect to the class group grading of the Cox ring. In order to construct the cohomology ring, one can introduce a $\mathbb{Z}$-grading on the Cox ring such that the ideal of linear relations and the Stanley-Reißner ideal are homogeneous.

rational equivalence classes of algebraic cycles are one-to-one to the cones in the fan of the toric variety.

Constructors

General constructors

rational_equivalence_classMethod
rational_equivalence_class(v::AbstractNormalToricVariety, p::MPolyQuoRingElem)

Construct the rational equivalence class of algebraic cycles corresponding to a linear combination of cones.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> chow_ring(P2)
-Quotient
-  of multivariate polynomial ring in 3 variables over QQ
-  by ideal(x1 - x3, x2 - x3, x1*x2*x3)
-
-julia> (x1, x2, x3) = gens(chow_ring(P2))
-3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x1
- x2
- x3
-
-julia> rational_equivalence_class(P2, x1)
-Rational equivalence classon a normal toric variety represented by V(x3)
source
rational_equivalence_classMethod
rational_equivalence_class(v::AbstractNormalToricVariety, coefficients::Vector{T}) where {T <: IntegerUnion}

Construct the rational equivalence class of algebraic cycles corresponding to a linear combination of cones.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> rational_equivalence_class(P2, [6, 5, 4, 3, 2, 1])
-Rational equivalence class on a normal toric variety represented by 15V(x1,x3)+6V(x3)
source

Special constructors

rational_equivalence_classMethod
rational_equivalence_class(d::ToricDivisor)

Construct the rational equivalence class of algebraic cycles corresponding to the toric divisor d.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(P2, [1, 2, 3])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)
source
rational_equivalence_classMethod
rational_equivalence_class(c::ToricDivisorClass)

Construct the algebraic cycle corresponding to the toric divisor class c.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, [2])
-Divisor class on a normal toric variety
-
-julia> rational_equivalence_class(tdc)
-Rational equivalence class on a normal toric variety represented by 2V(x3)
source
rational_equivalence_classMethod
RationalEquivalenceClass(l::ToricLineBundle)

Construct the toric algebraic cycle corresponding to the toric line bundle l.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(P2, [2])
-Toric line bundle on a normal toric variety
-
-julia> polynomial(rational_equivalence_class(l))
-2*x3
source
rational_equivalence_classMethod
rational_equivalence_class(cc::CohomologyClass)

Construct the toric algebraic cycle corresponding to the cohomology class cc.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> (x1, x2, x3) = gens(cohomology_ring(P2))
-3-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- x1
- x2
- x3
-
-julia> cc = CohomologyClass(P2, x1+x2)
-Cohomology class on a normal toric variety given by x1 + x2
-
-julia> rational_equivalence_class(cc)
-Rational equivalence class on a normal toric variety represented by 2V(x3)
source
rational_equivalence_classMethod
rational_equivalence_class(sv::ClosedSubvarietyOfToricVariety)

Construct the rational equivalence class of algebraic cycles of a closed subvariety of a normal toric variety.

Examples

julia> ntv = normal_toric_variety(Oscar.normal_fan(Oscar.cube(2)))
-Normal toric variety
-
-julia> set_coordinate_names(ntv, ["x1", "x2", "y1", "y2"]);
-
-julia> (x1, x2, y1, y2) = gens(cox_ring(ntv))
-4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- y1
- y2
-
-julia> sv = closed_subvariety_of_toric_variety(ntv, [x1^2+x1*x2+x2^2, y2])
-Closed subvariety of a normal toric variety
-
-julia> rational_equivalence_class(sv)
-Rational equivalence class on a normal toric variety represented by 2V(x2,y2)
source

Addition, subtraction and scalar multiplication

Algebraic cycles can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem.

Note that one can easily define the Chow ring also a formal linear sums of irreducible subvarieties with coefficients being rational numbers. We support this more general ring and therefore also allow for left multiplication with scalars of type QQFieldElem.

Intersection product

The intersection product of algebraic cycles is implemented via *. This makes sense, since algebraic cycles on toric varieties are elements of the Chow ring, which in turn is (a certain) quotient of the Cox ring. Hence, internally, an algebraic cycle can be thought of as a polynomial in this ring and the intersection product corresponds to the product of two (equivalence classes of) polynomials.

An algebraic cycle can be intersected n- with itself via ^n, where n can be an integer of of type ZZRingElem.

A closed subvarieties defines in a natural way a rational equivalence class (cf. section on special constructors above). This allows to compute intersection products among closed subvarieties and rational equivalence classes in the Chow ring.

Attributes

Defining attributes

toric_varietyMethod
toric_variety(ac::RationalEquivalenceClass)

Return the normal toric variety of a rational equivalence class of algebraic cycles.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> ac = rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)
-
-julia> toric_variety(ac)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
source
polynomialMethod
polynomial(ac::RationalEquivalenceClass)

On a simplicial and complete toric variety, the Chow ring is isomorphic to a certain quotient of the Cox ring. This function returns the ring element corresponding to a given rational equivalence class of algebraic cycles.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> ac = rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)
-
-julia> polynomial(ac)
-6*x3 + e1 + 7*e2
source
polynomialMethod
polynomial(ring::MPolyQuoRing, ac::RationalEquivalenceClass)

On a simplicial and complete toric variety, the Chow ring is isomorphic to a certain quotient of the Cox ring. This function returns the ring element corresponding to a given rational equivalence class of algebraic cycles. The first argument of this function allows to obtain this ring element in a different ring. This allows to change the coefficient ring if desired.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> ac = rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)
-
-julia> R, _ = polynomial_ring(QQ, 5)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x1, x2, x3, x4, x5])
-
-julia> (x1, x2, x3, x4, x5) = gens(R)
-5-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
- x4
- x5
-
-julia> sr_and_linear_relation_ideal = ideal([x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5])
-ideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)
-
-julia> R_quo = quo(R, sr_and_linear_relation_ideal)[1]
-Quotient
-  of multivariate polynomial ring in 5 variables over QQ
-  by ideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)
-
-julia> polynomial(R_quo, ac)
-6*x3 + x4 + 7*x5
source

Representatives

In order to see a geometric interpretation of rational equivalence classes of algebraic cycles most efficiently, it is best to replace self-intersections by transverse complete intersections. Indeed, within the regime of simplicial, complete toric varieties this is always possible. However, this involves a choice. Consequently, the following methods will pick a special choice and return values for that particular choice of representative of the rational equivalence class in question.

representativeMethod
representative(ac::RationalEquivalenceClass)

Return a polynomial in the Cox ring mapping to polynomial(ac).

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> ac = rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)
-
-julia> ac*ac
-Rational equivalence class on a normal toric variety represented by 34V(x2,x3)
-
-julia> representative(ac*ac)
-34*x2*x3
source

It can be rather convenient to investigate such a representative in order to understand the geometric meaning of a rational equivalence class. For this purpose, we support the following methods.

coefficientsMethod
coefficients(ac::RationalEquivalenceClass)

Return the coefficients of polynomial(ac).

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> ac = rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)
-
-julia> coefficients(ac*ac)
-1-element Vector{QQFieldElem}:
- -34
source
componentsMethod
components(ac::RationalEquivalenceClass)

Turn each monomial of representative(ac) into a closed subvariety and return the list formed from these subvarieties. Note that each of these subvarieties is irreducible and their formal linear sum, with the coefficients computed by the method coefficients(ac::RationalEquivalenceClass), defines an algebraic cycle, whose rational equivalence class is identical to the one given to this method.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> ac = rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)
-
-julia> length(components(ac*ac))
-1
source

Other attributes

cohomology_classMethod
cohomology_class(ac::RationalEquivalenceClass)

Return the cohomology class of a rational equilvalence class of algebraic cycles.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> ac = rational_equivalence_class(d)
-Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)
-
-julia> cohomology_class(ac)
-Cohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2
source

Properties

One can check if a rational equivalence class of algebraic cycles is trivial via is_trivial. Equality can be tested with ==.

Special attributes of toric varieties

chow_ringMethod
chow_ring(v::AbstractNormalToricVariety)

Return the Chow ring of the simplicial toric variety v.

While David A. Cox, John B. Little, Henry K. Schenck (2011) focus on simplicial and complete varieties to define the Chow ring, it was described in Christoph Pegel (2014) that this notion can also be extended to non-complete varieties. We explicitly support the Chow ring also for non-complete varieties.

This is demonstrated by the following example. Note that the computation for the non-complete variety leads to a Chow ring which is identical to the Chow ring of a certain matroid. This observation can be anticipated by e.g. the results in Eva Maria Feichtner, Sergey Yuzvinsky (2004).

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> is_complete(p2)
-true
-
-julia> ngens(chow_ring(p2))
-3
-
-julia> v = normal_toric_variety([[1, 0], [0, 1], [-1, -1]], [[1], [2], [3]])
-Normal toric variety
-
-julia> is_complete(v)
-false
-
-julia> set_coordinate_names(v, ["x_{1}", "x_{2}", "x_{3}"])
-
-julia> chow_ring(v)
-Quotient
-  of multivariate polynomial ring in 3 variables over QQ
-  by ideal(x_{1} - x_{3}, x_{2} - x_{3}, x_{1}*x_{2}, x_{1}*x_{3}, x_{2}*x_{3})
-
-julia> M = cycle_matroid(complete_graph(3))
-Matroid of rank 2 on 3 elements
-
-julia> chow_ring(M)
-Quotient
-  of multivariate polynomial ring in 3 variables over QQ
-  by ideal(x_{1} - x_{2}, x_{1} - x_{3}, x_{1}*x_{2}, x_{1}*x_{3}, x_{2}*x_{3})
source
gens_of_rational_equivalence_classesMethod
gens_of_rational_equivalence_classes(v::AbstractNormalToricVariety)

Return a list of generators of the Chow ring of a complete, simplicial toric variety.

Recall that the cones of a complete, simplicial toric variety can be seen as generators of the Chow ring (lemma 12.5.1 in David A. Cox, John B. Little, Henry K. Schenck (2011)). This function first maps each cone to an element of the Chow ring and then removes elements by taking rational equivalence into account.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> gens_of_rational_equivalence_classes(p2)
-6-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x3^2
- x3^2
- x3^2
- x3
- x3
- x3
source
map_gens_of_chow_ring_to_cox_ringMethod
map_gens_of_chow_ring_to_cox_ring(v::AbstractNormalToricVariety)

Return a dictionary which maps the generators of the chow ring to monomials in the Cox ring. This dictionary involves a choice, i.e. is not unique.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> map_gens_of_chow_ring_to_cox_ring(p2)
-Dict{QQMPolyRingElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:
-  x3^2 => x1*x3
-  x3   => x3
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html deleted file mode 100644 index 07438662c1bb..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html +++ /dev/null @@ -1,179 +0,0 @@ - -Cohomology Classes · Oscar.jl

Cohomology Classes

Constructors

General constructors

cohomology_classMethod
cohomology_class(v::AbstractNormalToricVariety, p::MPolyQuoRingElem)

Construct the toric cohomology class on the toric variety v corresponding to the polynomial p. Note that p must reside in the cohomology ring of v.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> c = cohomology_class(P2, gens(cohomology_ring(P2))[1])
-Cohomology class on a normal toric variety given by x1
source
cohomology_classMethod
cohomology_class(d::ToricDivisor)

Construct the toric cohomology class corresponding to the toric divisor d.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(P2, [1, 2, 3])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> cohomology_class(d)
-Cohomology class on a normal toric variety given by 6*x3
source
cohomology_classMethod
cohomology_class(c::ToricDivisorClass)

Construct the toric cohomology class corresponding to the toric divisor class c.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, [2])
-Divisor class on a normal toric variety
-
-julia> cohomology_class(tdc)
-Cohomology class on a normal toric variety given by 2*x3
source
cohomology_classMethod
cohomology_class(l::ToricLineBundle)

Construct the toric cohomology class corresponding to the toric line bundle l.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(P2, [2])
-Toric line bundle on a normal toric variety
-
-julia> polynomial(cohomology_class(l))
-2*x3
source

Addition, subtraction and scalar multiplication

Cohomology classes can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem or QQFieldElem.

Wedge product

The wedge product of cohomology classes is implemented via *, using internally the multiplication of the corresponding polynomial (equivalence classes) in the Cox ring.

A cohomology class can be wedged n-times with itself via ^n, where n can be an integer or of type ZZRingElem.

Properties

One can check if a cohomology class is trivial via is_trivial.

Equality of cohomology classes can be tested via ==.

Attributes

toric_varietyMethod
toric_variety(c::CohomologyClass)

Return the normal toric variety of the cohomology class c.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> cc = cohomology_class(d)
-Cohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2
-
-julia> toric_variety(cc)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
source
coefficientsMethod
coefficients(c::CohomologyClass)

Return the coefficients of the cohomology class c.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> cc = cohomology_class(d)
-Cohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2
-
-julia> coefficients(cc)
-3-element Vector{QQFieldElem}:
- 6
- 1
- 7
source
exponentsMethod
exponents(c::CohomologyClass)

Return the exponents of the cohomology class c.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> cc = cohomology_class(d)
-Cohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2
-
-julia> exponents(cc)
-[0   0   1   0   0]
-[0   0   0   1   0]
-[0   0   0   0   1]
source
polynomialMethod
polynomial(c::CohomologyClass)

Return the polynomial in the cohomology ring of the normal toric variety toric_variety(c) which corresponds to c.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> cc = cohomology_class(d)
-Cohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2
-
-julia> polynomial(cc)
-6*x3 + e1 + 7*e2
source
polynomialMethod
polynomial(c::CohomologyClass, ring::MPolyQuoRing)

Return the polynomial in ring corresponding to the cohomology class c.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> cc = cohomology_class(d)
-Cohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2
-
-julia> R, _ = polynomial_ring(QQ, 5)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x1, x2, x3, x4, x5])
-
-julia> (x1, x2, x3, x4, x5) = gens(R)
-5-element Vector{QQMPolyRingElem}:
- x1
- x2
- x3
- x4
- x5
-
-julia> sr_and_linear_relation_ideal = ideal([x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5])
-ideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)
-
-julia> R_quo = quo(R, sr_and_linear_relation_ideal)[1]
-Quotient
-  of multivariate polynomial ring in 5 variables over QQ
-  by ideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)
-
-julia> polynomial(R_quo, cc)
-6*x3 + x4 + 7*x5
source

Methods

integrateMethod
integrate(c::CohomologyClass)

Integrate the cohomolgy class c over the normal toric variety toric_variety(c).

Examples

julia> dP3 = del_pezzo_surface(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> (x1, x2, x3, e1, e2, e3) = gens(cohomology_ring(dP3))
-6-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- x1
- x2
- x3
- e1
- e2
- e3
-
-julia> c = cohomology_class(dP3, e3*e3 + e3)
-Cohomology class on a normal toric variety given by e3^2 + e3
-
-julia> integrate(c)
--1
-
-julia> F3 = hirzebruch_surface(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> (x1, x2, x3, x4) = gens(cohomology_ring(F3))
-4-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- t1
- x1
- t2
- x2
-
-julia> c = cohomology_class(F3, x1*x2 + x3*x4)
-Cohomology class on a normal toric variety given by 2//3*x2^2
-
-julia> integrate(c)
-2

The following example constructs the Fano variety 2-36 (cf. https://www.fanography.info/2-36) and verifies that the triple self-intersection number of its anticanonical bundle is 62.

Examples

julia> e1 = [1,0,0];
-
-julia> e2 = [0,1,0];
-
-julia> e3 = [0,0,1];
-
-julia> m = 2;
-
-julia> ray_generators = [e1, -e1, e2, e3, - e2 - e3 - m * e1];
-
-julia> max_cones = [[1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5]];
-
-julia> X = normal_toric_variety(ray_generators, max_cones; non_redundant = true)
-Normal toric variety
-
-julia> cox_ring(X)
-Multivariate polynomial ring in 5 variables over QQ graded by
-  x1 -> [1 0]
-  x2 -> [1 2]
-  x3 -> [0 -1]
-  x4 -> [0 -1]
-  x5 -> [0 -1]
-
-julia> cohomology_ring(X)
-Quotient
-  of graded multivariate polynomial ring in 5 variables over QQ
-  by ideal(x1 - x2 - 2*x5, x3 - x5, x4 - x5, x1*x2, x3*x4*x5)
-
-julia> integrate(cohomology_class(anticanonical_divisor(X))^3)
-62
-
-julia> integrate(cohomology_class(anticanonical_divisor_class(X))^3)
-62
source

Special attributes of toric varieties

cohomology_ringMethod
cohomology_ring(v::AbstractNormalToricVariety)

Return the cohomology ring of the simplicial and complete toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> ngens(cohomology_ring(p2))
-3
source
volume_formMethod
volume_form(v::NormalToricVariety)

Construct the volume form of the normal toric toric variety v.

Examples

julia> polynomial(volume_form(projective_space(NormalToricVariety, 2)))
-x3^2
-
-julia> polynomial(volume_form(del_pezzo_surface(NormalToricVariety, 3)))
--e3^2
-
-julia> polynomial(volume_form(hirzebruch_surface(NormalToricVariety, 5)))
-1//5*x2^2
source
intersection_formMethod
intersection_form(v::NormalToricVariety)

Computes the intersection numbers among the cohomology classes associated to the torusinvariant prime divisors of the normal toric toric variety v.

Examples

julia> F3 = hirzebruch_surface(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> length(intersection_form(F3))
-10
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/index.html deleted file mode 100644 index aa84272b1ec6..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/index.html +++ /dev/null @@ -1,59 +0,0 @@ - -Cyclic Quotient Singularities · Oscar.jl

Cyclic Quotient Singularities

Introduction

Cyclic quotient singularities are quotients of $\mathbb{C}^2$ by the action of $\mathbb{Z}/n\mathbb{Z}$ acting via $\left(\begin{array}{cc}\xi & 0\\0 & \xi^q\end{array}\right)$, where $\xi$ is a $n$-th root of unity, and $q$ and $n$ are integers, such that $q$ is coprime with $n$, and $0<q<n$.

For the notation we rely on Jan Arthur Christophersen (1991) and Jan Stevens (1991).

Warning

Note that Jan Arthur Christophersen (1991) and Jan Stevens (1991) use Hirzebruch-Jung continued fraction, which differ from the commonly known continued fraction from literature and used in the rest of OSCAR.

Constructors

cyclic_quotient_singularityMethod
cyclic_quotient_singularity(n::ZZRingElem, q::ZZRingElem)

Return the cyclic quotient singularity for the parameters $n$ and $q$, with $0<q<n$ and $q, n$ coprime.

Examples

julia> cqs = cyclic_quotient_singularity(7, 5)
-Cyclic quotient singularity Y(7, 5)
-
-julia> is_affine(cqs)
-true
-
-julia> is_smooth(cqs)
-false
source

Attributes

continued_fraction_hirzebruch_jungMethod
continued_fraction_hirzebruch_jung(cqs::CyclicQuotientSingularity)

Return the Hirzebruch-Jung continued fraction associated with the cyclic quotient singularity, i.e. the Hirzebruch-Jung continued fraction corresponding to $n/q$.

The rational number corresponding to a Hirzebruch-Jung continued fraction $[c_1, c_2,\ldots, c_n]$ is $r([c_1, c_2,\ldots, c_n])\ =\ -c_1-\frac{1}{r([c_2,\ldots, c_n])}$ where $r([c_n]) = c_n$. Note that this is differs in sign from what is commonly known as continued fraction.

Examples

julia> cqs = cyclic_quotient_singularity(7, 5)
-Cyclic quotient singularity Y(7, 5)
-
-julia> cf = continued_fraction_hirzebruch_jung(cqs)
-3-element Vector{ZZRingElem}:
- 2
- 2
- 3
-
-julia> ecf = cf[1]-1//(cf[2]-QQFieldElem(1, cf[3]))
-7//5
source
dual_continued_fraction_hirzebruch_jungMethod
dual_continued_fraction_hirzebruch_jung(cqs::CyclicQuotientSingularity)

Return the dual Hirzebruch-Jung continued fraction associated with the cyclic quotient singularity, i.e. the Hirzebruch-Jung continued fraction corresponding to $q/(n-q)$.

The rational number corresponding to a Hirzebruch-Jung continued fraction $[c_1, c_2,\ldots, c_n]$ is $r([c_1, c_2,\ldots, c_n])\ =\ -c_1-\frac{1}{r([c_2,\ldots, c_n])}$ where $r([c_n]) = c_n$. Note that this is differs in sign from what is commonly known as continued fraction.

Examples

julia> cqs = cyclic_quotient_singularity(7, 5)
-Cyclic quotient singularity Y(7, 5)
-
-julia> dcf = dual_continued_fraction_hirzebruch_jung(cqs)
-2-element Vector{ZZRingElem}:
- 4
- 2
-
-julia> edcf = dcf[1] - QQFieldElem(1, dcf[2])
-7//2
source

Auxiliary Methods

continued_fraction_hirzebruch_jung_to_rationalMethod
continued_fraction_hirzebruch_jung_to_rational(v::Vector{ZZRingElem})

Return the rational number corresponding to a Hirzebruch-Jung continued fraction given as a vector of (positive) integers.

The rational number corresponding to a Hirzebruch-Jung continued fraction $[c_1, c_2,\ldots, c_n]$ is $r([c_1, c_2,\ldots, c_n])\ =\ -c_1-\frac{1}{r([c_2,\ldots, c_n])}$ where $r([c_n]) = c_n$. Note that this is differs in sign from what is commonly known as continued fraction.

Examples

julia> cqs = cyclic_quotient_singularity(7, 5)
-Cyclic quotient singularity Y(7, 5)
-
-julia> v = continued_fraction_hirzebruch_jung(cqs)
-3-element Vector{ZZRingElem}:
- 2
- 2
- 3
-
-julia> continued_fraction_hirzebruch_jung_to_rational(v)
-7//5
source
rational_to_continued_fraction_hirzebruch_jungMethod
rational_to_continued_fraction_hirzebruch_jung(r::QQFieldElem)

Encode a (positive) rational number as a Hirzebruch-Jung continued fraction, i.e. find the Hirzebruch-Jung continued fraction corresponding to the given rational number.

The rational number corresponding to a Hirzebruch-Jung continued fraction $[c_1, c_2,\ldots, c_n]$ is $r([c_1, c_2,\ldots, c_n])\ =\ -c_1-\frac{1}{r([c_2,\ldots, c_n])}$ where $r([c_n]) = c_n$. Note that this is differs in sign from what is commonly known as continued fraction.

Examples

julia> r = QQFieldElem(2464144958, 145732115)
-2464144958//145732115
-
-julia> cf = rational_to_continued_fraction_hirzebruch_jung(r)
-7-element Vector{ZZRingElem}:
- 17
- 11
- 23
- 46
- 18
- 19
- 37
-
-julia> continued_fraction_hirzebruch_jung_to_rational(cf)
-2464144958//145732115
-
-julia> r == continued_fraction_hirzebruch_jung_to_rational(cf)
-true
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html deleted file mode 100644 index 312931d8ae38..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html +++ /dev/null @@ -1,418 +0,0 @@ - -Normal Toric Varieties · Oscar.jl

Normal Toric Varieties

Introduction

We introduce two main types of normal toric varieties, distinguishing between the affine and non-affine case:

Warning

The lattice is always assumed to be the standard lattice $\mathbb{Z}^n$. Transformations for non-standard lattices will have to be done by the user.

Constructors

All of the constructors below accept as their last argument an optional boolean. This boolean set_attributes controls whether the constructors sets attributes for the constructed variety. The benefit of such setters is increased performance. However, as per usual, a shortcut comes at a price. In the case at hand, it might lead to possible inconsistencies, despite our best efforts to prevent this from happening.

The default is set_attributes = true, that is our constructors set attributes upon construction. If not desired, it can be switched off by passing set_attributes = false as last argument. Note however, that the constructors of del_pezzo_surface, hirzebruch_surface, projective_space and weighted_projective_space always make a default/standard choice for the grading of the Cox ring.

Affine Toric Varieties

affine_normal_toric_varietyMethod
affine_normal_toric_variety(C::Cone; set_attributes::Bool = true)

Construct the affine normal toric variety $U_{C}$ corresponding to a polyhedral cone C.

Examples

Set C to be the positive orthant in two dimensions.

julia> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> antv = affine_normal_toric_variety(C)
-Normal, affine toric variety
source
normal_toric_varietyMethod
normal_toric_variety(C::Cone; set_attributes::Bool = true)

Construct the (affine) normal toric variety $X_{\Sigma}$ corresponding to a polyhedral fan $\Sigma = C$ consisting only of the cone C.

Examples

Set C to be the positive orthant in two dimensions.

julia> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> ntv = normal_toric_variety(C)
-Normal, affine toric variety
source
affine_normal_toric_varietyMethod
affine_normal_toric_variety(v::NormalToricVariety; set_attributes::Bool = true)

For internal design, we make a strict distinction between normal toric varieties and affine toric varieties. Given an affine, normal toric variety v, this method turns it into an affine toric variety.

Examples

julia> v = normal_toric_variety(positive_hull([1 0; 0 1]))
-Normal, affine toric variety
-
-julia> affineVariety = affine_normal_toric_variety(v)
-Normal, affine toric variety
source

Normal Toric Varieties

normal_toric_varietyMethod
normal_toric_variety(rays::AbstractMatrix, max_cones::Vector{Vector{Int64}})

Construct a normal toric variety $X$ by providing the rays and maximal cones as vector of vectors. By default, this method assumes that the input is not non-redundant (e.g. that a ray was entered twice by accident). If the user is certain that no redundancy exists in the entered information, one can pass non_redundant = true as third argument. This will bypass these consistency checks. In addition, this will ensure that the order of the rays is not altered by the constructor.

Examples

julia> ray_generators = [[1,0], [0, 1], [-1, 5], [0, -1]]
-4-element Vector{Vector{Int64}}:
- [1, 0]
- [0, 1]
- [-1, 5]
- [0, -1]
-
-julia> max_cones = [[1, 2], [2, 3], [3, 4], [4, 1]]
-4-element Vector{Vector{Int64}}:
- [1, 2]
- [2, 3]
- [3, 4]
- [4, 1]
-
-julia> normal_toric_variety(ray_generators, max_cones)
-Normal toric variety
-
-julia> normal_toric_variety(ray_generators, max_cones; non_redundant = true)
-Normal toric variety
source
normal_toric_varietyMethod
normal_toric_variety(PF::PolyhedralFan)

Construct the normal toric variety $X_{PF}$ corresponding to a polyhedral fan PF.

Examples

Take PF to be the normal fan of the square.

julia> square = cube(2)
-Polyhedron in ambient dimension 2
-
-julia> nf = normal_fan(square)
-Polyhedral fan in ambient dimension 2
-
-julia> ntv = normal_toric_variety(nf)
-Normal toric variety
source
normal_toric_varietyMethod
normal_toric_variety(P::Polyhedron; set_attributes::Bool = true)

Construct the normal toric variety $X_{\Sigma_P}$ corresponding to the normal fan $\Sigma_P$ of the given polyhedron P.

Note that this only coincides with the projective variety associated to P from the affine relations of the lattice points in P, if P is very ample.

Examples

Set P to be a square.

julia> square = cube(2)
-Polyhedron in ambient dimension 2
-
-julia> ntv = normal_toric_variety(square)
-Normal toric variety
source

Famous Toric Vareties

affine_spaceMethod
affine_space(::Type{NormalToricVariety}, d::Int; set_attributes::Bool = true)

Constructs the (toric) affine space of dimension d.

Examples

julia> affine_space(NormalToricVariety, 2)
-Normal, affine, 2-dimensional toric variety
source
del_pezzo_surfaceMethod
del_pezzo_surface(::Type{NormalToricVariety}, b::Int; set_attributes::Bool = true)

Constructs the del Pezzo surface with b blowups for b at most 3.

Examples

julia> del_pezzo_surface(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
source
hirzebruch_surfaceMethod
hirzebruch_surface(::Type{NormalToricVariety}, r::Int; set_attributes::Bool = true)

Constructs the r-th Hirzebruch surface.

Examples

julia> hirzebruch_surface(NormalToricVariety, 5)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
source
projective_spaceMethod
projective_space(::Type{NormalToricVariety}, d::Int; set_attributes::Bool = true)

Construct the projective space of dimension d.

Examples

julia> projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
source
weighted_projective_spaceMethod
weighted_projective_space(::Type{NormalToricVariety}, w::Vector{T}; set_attributes::Bool = true) where {T <: IntegerUnion}

Construct the weighted projective space corresponding to the weights w.

Examples

julia> weighted_projective_space(NormalToricVariety, [2,3,1])
-Normal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor
source

Constructions based on triangulations

It is possible to associate toric varieties to star triangulations of the lattice points of polyhedrons. Specifically, we can associate to any full star triangulation of the lattice points of the polyhedron in question a toric variety. For this task, we provide the following constructors.

normal_toric_variety_from_star_triangulationMethod
normal_toric_variety_from_star_triangulation(P::Polyhedron; set_attributes::Bool = true)

Returns a toric variety that was obtained from a fine regular star triangulation of the lattice points of the polyhedron P. This is particularly useful when the lattice points of the polyhedron in question admit many triangulations.

Examples

julia> P = convex_hull([0 0 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1])
-Polyhedron in ambient dimension 3
-
-julia> v = normal_toric_variety_from_star_triangulation(P)
-Normal toric variety
source
normal_toric_varieties_from_star_triangulationsMethod
normal_toric_varieties_from_star_triangulations(P::Polyhedron; set_attributes::Bool = true)

Returns the list of toric varieties obtained from fine regular star triangulations of the polyhedron P. With this we can compute the two phases of the famous conifold transition.

Examples

julia> P = convex_hull([0 0 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1])
-Polyhedron in ambient dimension 3
-
-julia> (v1, v2) = normal_toric_varieties_from_star_triangulations(P)
-2-element Vector{NormalToricVariety}:
- Normal toric variety
- Normal toric variety
-
-julia> stanley_reisner_ideal(v1)
-ideal(x1*x4)
-
-julia> stanley_reisner_ideal(v2)
-ideal(x2*x3)
source

An application of this functionality exists in the physics. Witten's Generalized-Sigma models (GLSM) Edward Witten (1988) originally sparked interest in the physics community in toric varieties. On a mathematical level, this establishes a construction of toric varieties for which a Z^n grading of the Cox ring is provided. See for example Huijun Fan, Tyler Jarvis, Yongbin Ruan (2017), which describes this as GIT construction David A. Cox, John B. Little, Henry K. Schenck (2011).

Explicitly, given the grading of the Cox ring, the map from the group of torus invariant Weil divisors to the class group is known. Under the assumption that the variety in question has no torus factor, we can then identify the map from the lattice to the group of torus invariant Weil divisors as the kernel of the map from the torus invariant Weil divisor to the class group. The latter is a map between free Abelian groups, i.e. is provided by an integer valued matrix. The rows of this matrix are nothing but the ray generators of the fan of the toric variety. It then remains to triangulate these rays, hence in general for a GLSM the toric variety is only unique up to fine regular star triangulations. We provide the following two constructors:

normal_toric_variety_from_glsmMethod

normaltoricvarietyfromglsm(charges::ZZMatrix; set_attributes::Bool = true)

This function returns one toric variety with the desired GLSM charges. This can be particularly useful provided that there are many such toric varieties.

Examples

julia> charges = [[1, 1, 1]]
-1-element Vector{Vector{Int64}}:
- [1, 1, 1]
-
-julia> normal_toric_variety_from_glsm(charges)
-Normal toric variety

For convenience, we also support:

  • normaltoricvarietyfromglsm(charges::Vector{Vector{Int}})
  • normaltoricvarietyfromglsm(charges::Vector{Vector{ZZRingElem}})
source
normal_toric_varieties_from_glsmMethod
normal_toric_varieties_from_glsm(charges::ZZMatrix; set_attributes::Bool = true)

This function returns all toric variety with the desired GLSM charges. This computation may take a long time if there are many such toric varieties.

Examples

julia> charges = [[1, 1, 1]]
-1-element Vector{Vector{Int64}}:
- [1, 1, 1]
-
-julia> normal_toric_varieties_from_glsm(charges)
-1-element Vector{NormalToricVariety}:
- Normal toric variety
-
-julia> varieties = normal_toric_varieties_from_glsm(matrix(ZZ, [1 2 3 4 6 0; -1 -1 -2 -2 -3 1]))
-1-element Vector{NormalToricVariety}:
- Normal toric variety
-
-julia> cox_ring(varieties[1])
-Multivariate polynomial ring in 6 variables over QQ graded by 
-  x1 -> [1 -1]
-  x2 -> [2 -1]
-  x3 -> [3 -2]
-  x4 -> [4 -2]
-  x5 -> [6 -3]
-  x6 -> [0 1]

For convenience, we also support:

  • normaltoricvarietiesfromglsm(charges::Vector{Vector{Int}})
  • normaltoricvarietiesfromglsm(charges::Vector{Vector{ZZRingElem}})
source

Further Constructions

blow_upMethod
blow_up(v::AbstractNormalToricVariety, I::MPolyIdeal; coordinate_name::String = "e", set_attributes::Bool = true)

Blow up the toric variety by subdividing the cone in the list of all cones of the fan of v which corresponds to the provided ideal I. Note that this cone need not be maximal.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor
-
-julia> (x1,x2,x3,x4) = gens(cox_ring(P3))
-4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
-
-julia> I = ideal([x2,x3])
-ideal(x2, x3)
-
-julia> bP3 = domain(blow_up(P3, I))
-Normal toric variety
-
-julia> cox_ring(bP3)
-Multivariate polynomial ring in 5 variables over QQ graded by
-  x1 -> [1 0]
-  x2 -> [0 1]
-  x3 -> [0 1]
-  x4 -> [1 0]
-  e -> [1 -1]
source
blow_upMethod
blow_up(v::AbstractNormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String = "e", set_attributes::Bool = true)

Blow up the toric variety by subdividing the fan of the variety with the provided new ray. Note that this ray must be a primitive element in the lattice Z^d, with d the dimension of the fan. This function returns the corresponding blowdown morphism.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor
-
-julia> blow_down_morphism = blow_up(P3, [0, 1, 1])
-A toric morphism
-
-julia> bP3 = domain(blow_down_morphism)
-Normal toric variety
-
-julia> cox_ring(bP3)
-Multivariate polynomial ring in 5 variables over QQ graded by
-  x1 -> [1 0]
-  x2 -> [0 1]
-  x3 -> [0 1]
-  x4 -> [1 0]
-  e -> [1 -1]
source
blow_upMethod
blow_up(v::AbstractNormalToricVariety, n::Int; coordinate_name::String = "e", set_attributes::Bool = true)

Blow up the toric variety by subdividing the n-th cone in the list of all cones of the fan of v. This cone need not be maximal. This function returns the corresponding blowdown morphism.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor
-
-julia> blow_down_morphism = blow_up(P3, 5)
-A toric morphism
-
-julia> bP3 = domain(blow_down_morphism)
-Normal toric variety
-
-julia> cox_ring(bP3)
-Multivariate polynomial ring in 5 variables over QQ graded by
-  x1 -> [1 0]
-  x2 -> [0 1]
-  x3 -> [0 1]
-  x4 -> [1 0]
-  e -> [1 -1]
source
*Method
Base.:*(v::AbstractNormalToricVariety, w::AbstractNormalToricVariety; set_attributes::Bool = true)

Return the Cartesian/direct product of two normal toric varieties v and w.

By default, we prepend an "x" to all homogeneous coordinate names of the first factor v and a "y" to all homogeneous coordinate names of the second factor w. This default can be overwritten by invoking set_coordinate_names after creating the variety (cf. set_coordinate_names(v::AbstractNormalToricVariety, coordinate_names::Vector{String})).

Important: Recall that the coordinate names can only be changed as long as the toric variety in question is not finalized (cf. is_finalized(v::AbstractNormalToricVariety)).

Crucially, the order of the homogeneous coordinates is not shuffled. To be more specific, assume that v has $n_1$ and w has $n_2$ homogeneous coordinates. Then v * w has $n_1 + n_2$ homogeneous coordinates. The first $n_1$ of these coordinates are those of v and appear in the very same order as they do for v. The remaining $n_2$ homogeneous coordinates are those of w and appear in the very same order as they do for w.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> v1 = P2 * P2
-Normal toric variety
-
-julia> cox_ring(v1)
-Multivariate polynomial ring in 6 variables over QQ graded by
-  xx1 -> [1 0]
-  xx2 -> [1 0]
-  xx3 -> [1 0]
-  yx1 -> [0 1]
-  yx2 -> [0 1]
-  yx3 -> [0 1]
-
-julia> v2 = P2 * P2
-Normal toric variety
-
-julia> set_coordinate_names(v2, ["x1", "x2", "x3", "y1", "y2", "y3"])
-
-
-julia> cox_ring(v2)
-Multivariate polynomial ring in 6 variables over QQ graded by
-  x1 -> [1 0]
-  x2 -> [1 0]
-  x3 -> [1 0]
-  y1 -> [0 1]
-  y2 -> [0 1]
-  y3 -> [0 1]
source

Properties of Toric Varieties

has_torusfactorMethod
has_torusfactor(v::AbstractNormalToricVariety)

Checks if the normal toric variety v has a torus factor.

Examples

julia> has_torusfactor(projective_space(NormalToricVariety, 2))
-false
source
is_affineMethod
is_affine(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is affine.

Examples

julia> is_affine(projective_space(NormalToricVariety, 2))
-false
source
is_completeMethod
is_complete(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is complete.

Examples

julia> is_complete(projective_space(NormalToricVariety, 2))
-true
source
is_fanoMethod
is_fano(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is fano.

Examples

julia> is_fano(projective_space(NormalToricVariety, 2))
-true
source
is_gorensteinMethod
is_gorenstein(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is Gorenstein.

Examples

julia> is_gorenstein(projective_space(NormalToricVariety, 2))
-true
source
is_simplicialMethod
is_simplicial(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is simplicial. Hence, this function works just as is_orbifold. It is implemented for user convenience.

Examples

julia> is_simplicial(projective_space(NormalToricVariety, 2))
-true
source
is_smoothMethod
is_smooth(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is smooth.

Examples

julia> is_smooth(projective_space(NormalToricVariety, 2))
-true
source
is_normalMethod
is_normal(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is normal. (This function is somewhat tautological at this point.)

Examples

julia> is_normal(projective_space(NormalToricVariety, 2))
-true
source
is_orbifoldMethod
is_orbifold(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is an orbifold.

Examples

julia> is_orbifold(projective_space(NormalToricVariety, 2))
-true
source
is_projectiveMethod
is_projective(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is projective, i.e. if the fan of v is the the normal fan of a polytope.

Examples

julia> is_projective(projective_space(NormalToricVariety, 2))
-true
source
is_projective_spaceMethod
is_projective_space(v::AbstractNormalToricVariety)

Decides if the normal toric varieties v is a projective space.

Examples

julia> F5 = hirzebruch_surface(NormalToricVariety, 5)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> is_projective_space(F5)
-false
-
-julia> is_projective_space(projective_space(NormalToricVariety, 2))
-true
source
is_q_gorensteinMethod
is_q_gorenstein(v::AbstractNormalToricVariety)

Checks if the normal toric variety v is Q-Gorenstein.

Examples

julia> is_q_gorenstein(projective_space(NormalToricVariety, 2))
-true
source

Operations for Toric Varieties

Affine Open Covering

affine_open_coveringMethod
affine_open_covering(v::AbstractNormalToricVariety)

Compute an affine open cover of the normal toric variety v, i.e. returns a list of affine toric varieties.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> affine_open_covering(p2)
-3-element Vector{AffineNormalToricVariety}:
- Normal, affine toric variety
- Normal, affine toric variety
- Normal, affine toric variety
source

Characters, Weil Divisors, Cartier Divisors, Class Group and Picard Group

torusinvariant_cartier_divisor_groupMethod
torusinvariant_cartier_divisor_group(v::AbstractNormalToricVariety)

Return the Cartier divisor group of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> torusinvariant_cartier_divisor_group(p2)
-GrpAb: Z^3
source
character_latticeMethod
character_lattice(v::AbstractNormalToricVariety)

Return the character lattice of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> character_lattice(p2)
-GrpAb: Z^2
source
class_groupMethod
class_group(v::AbstractNormalToricVariety)

Return the class group of the normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> class_group(p2)
-GrpAb: Z
source
map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_groupMethod
map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)

Return the embedding of the group of Cartier divisors into the group of torus-invariant Weil divisors of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(p2)
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^3
-Codomain:
-=========
-Abelian group with structure: Z^3
source
map_from_torusinvariant_cartier_divisor_group_to_picard_groupMethod
map_from_torusinvariant_cartier_divisor_group_to_picard_group(v::AbstractNormalToricVariety)

Return the map from the Cartier divisors to the Picard group of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> map_from_torusinvariant_cartier_divisor_group_to_picard_group(p2)
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^3
-Codomain:
-=========
-Abelian group with structure: Z
source
map_from_character_lattice_to_torusinvariant_weil_divisor_groupMethod
map_from_character_lattice_to_torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)

Return the map from the character lattice to the group of principal divisors of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> map_from_character_lattice_to_torusinvariant_weil_divisor_group(p2)
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^2
-Codomain:
-=========
-Abelian group with structure: Z^3
source
map_from_torusinvariant_weil_divisor_group_to_class_groupMethod
map_from_torusinvariant_weil_divisor_group_to_class_group(v::AbstractNormalToricVariety)

Return the map from the group of Weil divisors to the class of group of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> map_from_torusinvariant_weil_divisor_group_to_class_group(p2)
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^3
-Codomain:
-=========
-Abelian group with structure: Z
source
picard_groupMethod
picard_group(v::AbstractNormalToricVariety)

Return the Picard group of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> picard_group(p2)
-GrpAb: Z
source
torusinvariant_weil_divisor_groupMethod
torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)

Return the torusinvariant divisor group of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> torusinvariant_weil_divisor_group(p2)
-GrpAb: Z^3
source
torusinvariant_prime_divisorsMethod
torusinvariant_prime_divisors(v::AbstractNormalToricVariety)

Return the list of all torus invariant prime divisors in a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> torusinvariant_prime_divisors(p2)
-3-element Vector{ToricDivisor}:
- Torus-invariant, prime divisor on a normal toric variety
- Torus-invariant, prime divisor on a normal toric variety
- Torus-invariant, prime divisor on a normal toric variety
source

Cones and Fans

polyhedral_fanMethod
polyhedral_fan(v::AbstractNormalToricVariety)

Return the fan of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> polyhedral_fan(p2)
-Polyhedral fan in ambient dimension 2
source
coneMethod
cone(v::AffineNormalToricVariety)

Return the cone of the affine normal toric variety v.

Examples

julia> cone(affine_normal_toric_variety(Oscar.positive_hull([1 1; -1 1])))
-Polyhedral cone in ambient dimension 2
source
dual_coneMethod
dual_cone(v::AffineNormalToricVariety)

Return the dual cone of the affine normal toric variety v.

Examples

julia> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> antv = affine_normal_toric_variety(C)
-Normal, affine toric variety
-
-julia> dual_cone(antv)
-Polyhedral cone in ambient dimension 2
-
-julia> polarize(cone(antv)) == dual_cone(antv)
-true
source
hilbert_basisMethod
hilbert_basis(v::AffineNormalToricVariety)

For an affine toric variety $v$, this returns the Hilbert basis of the cone dual to the cone of $v$.

Examples

julia> C = positive_hull([-1 1; 1 1])
-Polyhedral cone in ambient dimension 2
-
-julia> antv = affine_normal_toric_variety(C)
-Normal, affine toric variety
-
-julia> hilbert_basis(antv)
-[-1   1]
-[ 1   1]
-[ 0   1]
source
mori_coneMethod
mori_cone(v::NormalToricVariety)

Return the mori cone of the normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> mori = mori_cone(p2)
-Polyhedral cone in ambient dimension 1
-
-julia> dim(mori)
-1
source
nef_coneMethod
nef_cone(v::NormalToricVariety)

Return the nef cone of the normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> nef = nef_cone(p2)
-Polyhedral cone in ambient dimension 1
-
-julia> dim(nef)
-1
source

Dimensions

dimMethod
dim(v::AbstractNormalToricVariety)

Return the dimension of the normal toric variety v.

Examples

julia> C = Oscar.positive_hull([1 0]);
-
-julia> antv = affine_normal_toric_variety(C);
-
-julia> dim(antv)
-1
source
dim_of_torusfactorMethod
dim_of_torusfactor(v::AbstractNormalToricVariety)

Return the dimension of the torus factor of the normal toric variety v.

Examples

julia> C = Oscar.positive_hull([1 0]);
-
-julia> antv = affine_normal_toric_variety(C);
-
-julia> dim_of_torusfactor(antv)
-1
source
euler_characteristicMethod
euler_characteristic(v::AbstractNormalToricVariety)

Return the Euler characteristic of the normal toric variety v.

Examples

julia> C = Oscar.positive_hull([1 0]);
-
-julia> antv = affine_normal_toric_variety(C);
-
-julia> euler_characteristic(antv)
-1
source
betti_numberMethod
betti_number(v::AbstractNormalToricVariety, i::Int)

Compute the i-th Betti number of the normal toric variety v. Specifically, this method returns the dimension of the i-th simplicial homology group (with rational coefficients) of v. The employed algorithm is derived from theorem 12.3.12 in David A. Cox, John B. Little, Henry K. Schenck (2011). Note that this theorem requires that the normal toric variety v is both complete and simplicial.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor
-
-julia> betti_number(P3,0)
-1
-
-julia> betti_number(P3, 1)
-0
source

Rings and ideals

We support the following rings and ideals for toric varieties:

Of course, for any of these coordinate names and the coefficient ring have to be chosen. The coefficient ring is fixed to Q. Therefore, the method coefficient_ring(v::AbstractNormalToricVariety) always return the field of rational numbers. For the coordinate names, we provide the following setter functions:

set_coordinate_namesMethod
set_coordinate_names(v::AbstractNormalToricVariety, coordinate_names::Vector{String})

Allows to set the names of the homogeneous coordinates as long as the toric variety in question is not yet finalized (cf. is_finalized(v::AbstractNormalToricVariety)).

Examples

julia> C = Oscar.positive_hull([1 0]);
-
-julia> antv = affine_normal_toric_variety(C);
-
-julia> set_coordinate_names(antv, ["u"])
-
-julia> coordinate_names(antv)
-1-element Vector{String}:
- "u"
source
set_coordinate_names_of_torusMethod
set_coordinate_names_of_torus(v::AbstractNormalToricVariety, coordinate_names::Vector{String})

Allows to set the names of the coordinates of the torus.

Examples

julia> F3 = hirzebruch_surface(NormalToricVariety, 3);
-
-julia> set_coordinate_names_of_torus(F3, ["u", "v"])
-
-julia> coordinate_names_of_torus(F3)
-2-element Vector{String}:
- "u"
- "v"
source

The following methods allow to etract the chosen coordinates:

coordinate_namesMethod
coordinate_names(v::AbstractNormalToricVariety)

Return the names of the homogeneous coordinates of the normal toric variety v. The default is x1, ..., xn.

Examples

julia> C = Oscar.positive_hull([1 0]);
-
-julia> antv = affine_normal_toric_variety(C);
-
-julia> coordinate_names(antv)
-1-element Vector{String}:
- "x1"
source
coordinate_names_of_torusMethod
coordinate_names_of_torus(v::AbstractNormalToricVariety)

Return the names of the coordinates of the torus of the normal toric variety v. The default is x1, ..., xn.

source

In order to efficiently construct algebraic cycles (elements of the Chox ring), cohomology classes (elements of the cohomology ring), or in order to compare ideals, it is imperative to fix choices of the coordinate names. The default value for coordinate names is [x1, x2, ... ]. The choice of coordinate names is fixed, once one of the above-mentioned rings is computed via one the following methods:

cox_ringMethod
cox_ring(v::AbstractNormalToricVariety)

Computes the Cox ring of the normal toric variety v. Note that David A. Cox, John B. Little, Henry K. Schenck (2011) refers to this ring as the "total coordinate ring".

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> set_coordinate_names(p2, ["y1", "y2", "y3"])
-
-julia> cox_ring(p2)
-Multivariate polynomial ring in 3 variables over QQ graded by
-  y1 -> [1]
-  y2 -> [1]
-  y3 -> [1]
source
irrelevant_idealMethod
irrelevant_ideal(v::AbstractNormalToricVariety)

Return the irrelevant ideal of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> length(gens(irrelevant_ideal(p2)))
-3
source
ideal_of_linear_relationsMethod
ideal_of_linear_relations(v::AbstractNormalToricVariety)

Return the ideal of linear relations of the simplicial and complete toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> ngens(ideal_of_linear_relations(p2))
-2
source
stanley_reisner_idealMethod
stanley_reisner_ideal(v::AbstractNormalToricVariety)

Return the Stanley-Reisner ideal of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> ngens(stanley_reisner_ideal(p2))
-1
source
toric_idealMethod
toric_ideal(antv::AffineNormalToricVariety)

Return the toric ideal defining the affine normal toric variety.

Examples

Take the cone over the square at height one. The resulting toric variety has one defining equation. In projective space this corresponds to $\mathbb{P}^1\times\mathbb{P}^1$. Note that this cone is self-dual, the toric ideal comes from the dual cone.

julia> C = positive_hull([1 0 0; 1 1 0; 1 0 1; 1 1 1])
-Polyhedral cone in ambient dimension 3
-
-julia> antv = affine_normal_toric_variety(C)
-Normal, affine toric variety
-
-julia> toric_ideal(antv)
-ideal(-x1*x2 + x3*x4)
source
coordinate_ring_of_torusMethod
coordinate_ring_of_torus(v::AbstractNormalToricVariety)

Computes the coordinate ring of the torus of the normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> set_coordinate_names_of_torus(p2, ["y1", "y2"])
-
-julia> coordinate_ring_of_torus(p2)
-Quotient
-  of multivariate polynomial ring in 4 variables over QQ
-  by ideal(y1*y1_ - 1, y2*y2_ - 1)
source

One can check the status as follows:

is_finalizedMethod
is_finalized(v::AbstractNormalToricVariety)

Checks if the Cox ring, the coordinate ring of the torus, the cohomology_ring, the Chow ring, the Stanley-Reisner ideal, the irrelevant ideal, the ideal of linear relations or the toric ideal has been cached. If any of these has been cached, then this function returns true and otherwise false.

Examples

julia> is_finalized(del_pezzo_surface(NormalToricVariety, 3))
-false
source

After the variety finalized, one can enforce to obtain the above ideals in different rings. Also, one can opt to compute the above rings with a different choice of coordinate names and different coefficient ring. To this end, onc provides a custom ring (which reflects the desired choice of coordinate names and coefficient ring) as first argument. However, note that the cached ideals and rings are not altered.

cox_ringMethod
cox_ring(R::MPolyRing, v::AbstractNormalToricVariety)

Computes the Cox ring of the normal toric variety v, in this case by adding the Cox grading to the given ring R. Note that David A. Cox, John B. Little, Henry K. Schenck (2011) refers to this ring as the "total coordinate ring".

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> R, _ = polynomial_ring(QQ, 3);
-
-julia> cox_ring(R, p2)
-Multivariate polynomial ring in 3 variables over QQ graded by
-  x1 -> [1]
-  x2 -> [1]
-  x3 -> [1]
source
irrelevant_idealMethod
irrelevant_ideal(R::MPolyRing, v::AbstractNormalToricVariety)

Return the irrelevant ideal of a normal toric variety v as an ideal in R.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> R, _ = polynomial_ring(QQ, 3);
-
-julia> length(gens(irrelevant_ideal(R, p2)))
-3
source
ideal_of_linear_relationsMethod
ideal_of_linear_relations(R::MPolyRing, v::AbstractNormalToricVariety)

Return the ideal of linear relations of the simplicial and complete toric variety v in the ring R.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> R, _ = polynomial_ring(QQ, 3);
-
-julia> ngens(ideal_of_linear_relations(R, p2))
-2
source
stanley_reisner_idealMethod
stanley_reisner_ideal(R::MPolyRing, v::AbstractNormalToricVariety)

Return the Stanley-Reisner ideal of a normal toric variety v as an ideal of R.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> R, _ = polynomial_ring(QQ, 3);
-
-julia> ngens(stanley_reisner_ideal(R, p2))
-1
source
toric_idealMethod
toric_ideal(R::MPolyRing, antv::AffineNormalToricVariety)

Return the toric ideal defining the affine normal toric variety as an ideal in R.

Examples

Take the cone over the square at height one. The resulting toric variety has one defining equation. In projective space this corresponds to $\mathbb{P}^1\times\mathbb{P}^1$. Note that this cone is self-dual, the toric ideal comes from the dual cone.

julia> C = positive_hull([1 0 0; 1 1 0; 1 0 1; 1 1 1])
-Polyhedral cone in ambient dimension 3
-
-julia> antv = affine_normal_toric_variety(C)
-Normal, affine toric variety
-
-julia> R, _ = polynomial_ring(QQ, 4);
-
-julia> toric_ideal(R, antv)
-ideal(-x1*x2 + x3*x4)
source
coordinate_ring_of_torusMethod
coordinate_ring_of_torus(R::MPolyRing, v::AbstractNormalToricVariety)

Computes the coordinate ring of the torus of the normal toric variety v in the given polynomial ring R.

source

Along the same lines, characters can be turned into rational functions:

character_to_rational_functionMethod
character_to_rational_function(v::AbstractNormalToricVariety, character::Vector{ZZRingElem})

Computes the rational function corresponding to a character of the normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> character_to_rational_function(p2, [-1, 2])
-x2^2*x1_
source
character_to_rational_functionMethod
character_to_rational_function(R::MPolyRing, v::AbstractNormalToricVariety, character::Vector{ZZRingElem})

Computes the rational function corresponding to a character of the normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> R, _ = polynomial_ring(QQ, 4);
-
-julia> character_to_rational_function(R, p2, [-1, 2])
-x2^2*x3
source

Auxiliary Methods

binomial_exponents_to_idealMethod
binomial_exponents_to_ideal(binoms::Union{AbstractMatrix, ZZMatrix})

This function converts the rows of a matrix to binomials. Each row $r$ is written as $r=u-v$ with $u, v\ge 0$ by splitting into positive and negative entries. Then the row $r$ corresponds to $x^u-x^v$. The resulting ideal is returned.

Examples

julia> A = [-1 -1 0 2; 2 3 -2 -1]
-2×4 Matrix{Int64}:
- -1  -1   0   2
-  2   3  -2  -1
-
-julia> binomial_exponents_to_ideal(A)
-ideal(-x1*x2 + x4^2, x1^2*x2^3 - x3^2*x4)
source
toric_idealMethod
toric_ideal(pts::ZZMatrix)

Return the toric ideal generated from the linear relations between the points pts. This is the ideal generated by the set of binomials $\{x^u-x^v\ |\ u, v\in\mathbb{Z}^n_{\ge 0}\ (pts)^T\cdot(u-v) = 0\}$

Examples

julia> C = positive_hull([-2 5; 1 0]);
-
-julia> H = hilbert_basis(C);
-
-julia> toric_ideal(H)
-ideal(x2*x3 - x4^2, -x1*x3 + x2^2*x4, -x1*x4 + x2^3, -x1*x3^2 + x2*x4^3, -x1*x3^3 + x4^5)
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/Subvarieties/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/Subvarieties/index.html deleted file mode 100644 index 9beab651de5a..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/Subvarieties/index.html +++ /dev/null @@ -1,50 +0,0 @@ - -Subvarieties · Oscar.jl

Subvarieties

Introduction

We focus on simplicial toric varieties. Then, any closed subvariety is given as the vanishing set of a homogeneous ideal in the Cox ring of the toric variety in question (cf. proposition 5.2.4 in David A. Cox, John B. Little, Henry K. Schenck (2011)). As of now, we provide elementary support for closed subvarieties of simplicial toric varieties.

Constructors

General constructors

closed_subvariety_of_toric_varietyMethod
closed_subvariety_of_toric_variety(toric_variety::AbstractNormalToricVariety, defining_polynomials::Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}})

Construct the closed subvariety of a simplicial normal toric variety. The defining data for the closed subvariety is a list of homogeneous polynomials, all of which must be elements of the Cox ring of the toric variety in question. The common vanishing locus of these polynomials defines the closed subvariety in question. By proposition 5.2.4 in David A. Cox, John B. Little, Henry K. Schenck (2011) every closed subvariety of a simplicial toric variety arises in this way.

Examples

julia> f2 = hirzebruch_surface(NormalToricVariety, 2);
-
-julia> (t1, x1, t2, x2) = gens(cox_ring(f2));
-
-julia> closed_subvariety_of_toric_variety(f2, [t1])
-Closed subvariety of a normal toric variety
source
closed_subvariety_of_toric_varietyMethod
closed_subvariety_of_toric_variety(toric_variety::AbstractNormalToricVariety, defining_ideal::MPolyIdeal)

Construct the closed subvariety of a simplicial normal toric variety. The defining data for the closed subvariety is an ideal of the Cox ring of the toric variety in question. By proposition 5.2.4 in David A. Cox, John B. Little, Henry K. Schenck (2011) every closed subvariety of a simplicial toric variety arises in this way.

Examples

julia> f2 = hirzebruch_surface(NormalToricVariety, 2);
-
-julia> (t1, x1, t2, x2) = gens(cox_ring(f2));
-
-julia> closed_subvariety_of_toric_variety(f2, ideal([t1]))
-Closed subvariety of a normal toric variety
source

Properties

is_emptyMethod
is_empty(c::ClosedSubvarietyOfToricVariety)

Checks if a closed subvariety of a toric variety is empty. This check uses proposition 5.2.6 in David A. Cox, John B. Little, Henry K. Schenck (2011).

Examples

julia> f2 = hirzebruch_surface(NormalToricVariety, 2);
-
-julia> (t1, x1, t2, x2) = gens(cox_ring(f2));
-
-julia> c = closed_subvariety_of_toric_variety(f2, [t1])
-Closed subvariety of a normal toric variety
-
-julia> is_empty(c)
-false
-
-julia> c2 = closed_subvariety_of_toric_variety(f2, [x1,x2])
-Closed subvariety of a normal toric variety
-
-julia> is_empty(c2)
-true
source

Attributes

toric_varietyMethod
toric_variety(c::ClosedSubvarietyOfToricVariety)

When constructing a closed subvariety, a toric variety must be provided in which the closed subvariety is contained. This method returns this initially provided toric supervariety.

Note however that perse, a closed subvariety can be contained in different non-isomorphic toric varieties.

Examples

julia> f2 = hirzebruch_surface(NormalToricVariety, 2);
-
-julia> (t1, x1, t2, x2) = gens(cox_ring(f2));
-
-julia> c = closed_subvariety_of_toric_variety(f2, [t1])
-Closed subvariety of a normal toric variety
-
-julia> toric_variety(c) == f2
-true
source
defining_idealMethod
defining_ideal(c::ClosedSubvarietyOfToricVariety)

When constructing a closed subvariety, an ideal in the Cox ring of a normal toric variety must be provided. This method returns this initially provided ideal.

Examples

julia> f2 = hirzebruch_surface(NormalToricVariety, 2);
-
-julia> (t1, x1, t2, x2) = gens(cox_ring(f2));
-
-julia> c = closed_subvariety_of_toric_variety(f2, [t1])
-Closed subvariety of a normal toric variety
-
-julia> defining_ideal(c) == ideal([t1])
-true
source
radicalMethod
radical(c::ClosedSubvarietyOfToricVariety)

When constructing a closed subvariety, an ideal in the Cox ring of a normal toric variety must be provided. This method returns the radical of this initially provided ideal.

Examples

julia> f2 = hirzebruch_surface(NormalToricVariety, 2);
-
-julia> (t1, x1, t2, x2) = gens(cox_ring(f2));
-
-julia> c = closed_subvariety_of_toric_variety(f2, [t1])
-Closed subvariety of a normal toric variety
-
-julia> radical(c) == ideal([t1])
-true
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html deleted file mode 100644 index 657883f0a796..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html +++ /dev/null @@ -1,65 +0,0 @@ - -Toric Divisor Classes · Oscar.jl

Toric Divisor Classes

Introduction

Toric divisor classes are equivalence classes of Weil divisors modulo linear equivalence.

Constructors

General constructors

toric_divisor_classMethod
toric_divisor_class(v::AbstractNormalToricVariety, class::GrpAbFinGenElem)

Construct the toric divisor class associated to a group element of the class group of the normal toric variety v.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, class_group(P2)([1]))
-Divisor class on a normal toric variety
source
toric_divisor_classMethod
toric_divisor_class(v::AbstractNormalToricVariety, coeffs::Vector{T}) where {T <: IntegerUnion}

Construct the toric divisor class associated to a list of integers which specify an element of the class group of the normal toric variety v.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, class_group(P2)([ZZRingElem(1)]))
-Divisor class on a normal toric variety
source
toric_divisor_classMethod
toric_divisor_class(td::ToricDivisor)

Construct the toric divisor class associated to the element ... of the class group of the normal toric variety v.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(P2, [1, 2, 3])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> tdc = toric_divisor_class(td)
-Divisor class on a normal toric variety
source

Addition, subtraction and scalar multiplication

Toric divisor classes can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem.

Special divisor classes

trivial_divisor_classMethod
trivial_divisor_class(v::AbstractNormalToricVariety)

Construct the trivial divisor class of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> trivial_divisor_class(v)
-Divisor class on a normal toric variety
source
anticanonical_divisor_classMethod
anticanonical_divisor_class(v::AbstractNormalToricVariety)

Construct the anticanonical divisor class of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> anticanonical_divisor_class(v)
-Divisor class on a normal toric variety
source
canonical_divisor_classMethod
canonical_divisor_class(v::AbstractNormalToricVariety)

Construct the canonical divisor class of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> canonical_divisor_class(v)
-Divisor class on a normal toric variety
source

Properties

Equality of toric divisor classes can be tested via ==.

To check if a toric divisor class is trivial, one can invoke is_trivial.

is_effectiveMethod
is_effective(tdc::ToricDivisorClass)

Determines whether the toric divisor class tdc is effective, that is if a toric divisor in this divisor class is linearly equivalent to an effective toric divisor.

Examples

julia> P2 = projective_space(NormalToricVariety,2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, [1])
-Divisor class on a normal toric variety
-
-julia> is_effective(tdc)
-true
-
-julia> tdc2 = toric_divisor_class(P2, [-1])
-Divisor class on a normal toric variety
-
-julia> is_effective(tdc2)
-false
source

Attributes

divisor_classMethod
divisor_class(tdc::ToricDivisorClass)

Return the element of the class group corresponding to the toric divisor class tdc.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, class_group(P2)([1]))
-Divisor class on a normal toric variety
-
-julia> divisor_class(tdc)
-Element of
-GrpAb: Z
-with components [1]
source
toric_varietyMethod
toric_variety(tdc::ToricDivisorClass)

Return the toric variety on which the toric divisor class tdc is defined.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, class_group(P2)([1]))
-Divisor class on a normal toric variety
-
-julia> toric_variety(tdc)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
source
toric_divisorMethod
toric_divisor(tdc::ToricDivisorClass)

Constructs a toric divisor corresponding to the toric divisor class tdc.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> tdc = toric_divisor_class(P2, class_group(P2)([1]))
-Divisor class on a normal toric variety
-
-julia> toric_divisor(tdc)
-Torus-invariant, prime divisor on a normal toric variety
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html deleted file mode 100644 index c8ddc311c3ba..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html +++ /dev/null @@ -1,130 +0,0 @@ - -Toric Divisors · Oscar.jl

Toric Divisors

Introduction

Toric divisors are those divisors that are invariant under the torus action. They are formal sums of the codimension one orbits, and these in turn correspond to the rays of the underlying fan.

Constructors

General constructors

divisor_of_characterMethod
divisor_of_character(v::AbstractNormalToricVariety, character::Vector{T}) where {T <: IntegerUnion}

Construct the torus invariant divisor associated to a character of the normal toric variety v.

Examples

julia> divisor_of_character(projective_space(NormalToricVariety, 2), [1, 2])
-Torus-invariant, non-prime divisor on a normal toric variety
source
toric_divisorMethod
toric_divisor(v::AbstractNormalToricVariety, coeffs::Vector{T}) where {T <: IntegerUnion}

Construct the torus invariant divisor on the normal toric variety v as linear combination of the torus invariant prime divisors of v. The coefficients of this linear combination are passed as list of integers as first argument.

Examples

julia> toric_divisor(projective_space(NormalToricVariety, 2), [1, 1, 2])
-Torus-invariant, non-prime divisor on a normal toric variety
source

Addition, subtraction and scalar multiplication

Toric divisors can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem.

Special divisors

trivial_divisorMethod
trivial_divisor(v::AbstractNormalToricVariety)

Construct the trivial divisor of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> trivial_divisor(v)
-Torus-invariant, non-prime divisor on a normal toric variety
source
anticanonical_divisorMethod
anticanonical_divisor(v::AbstractNormalToricVariety)

Construct the anticanonical divisor of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> anticanonical_divisor(v)
-Torus-invariant, non-prime divisor on a normal toric variety
source
canonical_divisorMethod
canonical_divisor(v::AbstractNormalToricVariety)

Construct the canonical divisor of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> canonical_divisor(v)
-Torus-invariant, non-prime divisor on a normal toric variety
source

Properties of toric divisors

Equality of toric divisors can be tested via ==.

To check if a toric divisor is trivial, one can invoke is_trivial. This checks if all coefficients of the toric divisor in question are zero. This must not be confused with a toric divisor being principal, for which we support the following:

is_principalMethod
is_principal(td::ToricDivisor)

Determine whether the toric divisor td is principal.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_principal(td)
-false
source

Beyond this, we support the following properties of toric divisors:

is_ampleMethod
is_ample(td::ToricDivisor)

Determine whether the toric divisor td is ample.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_ample(td)
-false
source
is_basepoint_freeMethod
is_basepoint_free(td::ToricDivisor)

Determine whether the toric divisor td is basepoint free.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_basepoint_free(td)
-true
source
is_cartierMethod
is_cartier(td::ToricDivisor)

Checks if the divisor td is Cartier.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_cartier(td)
-true
source
is_effectiveMethod
is_effective(td::ToricDivisor)

Determine whether the toric divisor td is effective, i.e. if all of its coefficients are non-negative.

Examples

julia> P2 = projective_space(NormalToricVariety,2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(P2, [1,-1,0])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> is_effective(td)
-false
-
-julia> td2 = toric_divisor(P2, [1,2,3])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> is_effective(td2)
-true
source
is_integralMethod
is_integral(td::ToricDivisor)

Determine whether the toric divisor td is integral.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_integral(td)
-true
source
is_nefMethod
is_nef(td::ToricDivisor)

Determine whether the toric divisor td is nef.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_nef(td)
-true
source
is_primeMethod
is_prime(td::ToricDivisor)

Determine whether the toric divisor td is a prime divisor.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_prime(td)
-true
source
is_q_cartierMethod
is_q_cartier(td::ToricDivisor)

Determine whether the toric divisor td is Q-Cartier.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_q_cartier(td)
-true
source
is_very_ampleMethod
is_very_ample(td::ToricDivisor)

Determine whether the toric divisor td is very ample.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_very_ample(td)
-false
source

Attributes

coefficientsMethod
coefficients(td::ToricDivisor)

Identify the coefficients of a toric divisor in the group of torus invariant Weil divisors.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> D = toric_divisor(F4, [1, 2, 3, 4])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> coefficients(D)
-4-element Vector{ZZRingElem}:
- 1
- 2
- 3
- 4
source
polyhedronMethod
polyhedron(td::ToricDivisor)

Construct the polyhedron $P_D$ of a torus invariant divisor $D:=td$ as in 4.3.2 of David A. Cox, John B. Little, Henry K. Schenck (2011). The lattice points of this polyhedron correspond to the global sections of the divisor.

Examples

The polyhedron of the divisor with all coefficients equal to zero is a point, if the ambient variety is complete. Changing the coefficients corresponds to moving hyperplanes. One direction moves the hyperplane away from the origin, the other moves it across. In the latter case there are no global sections anymore and the polyhedron becomes empty.

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> td0 = toric_divisor(F4, [0,0,0,0])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> is_feasible(polyhedron(td0))
-true
-
-julia> dim(polyhedron(td0))
-0
-
-julia> td1 = toric_divisor(F4, [1,0,0,0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_feasible(polyhedron(td1))
-true
-
-julia> td2 = toric_divisor(F4, [-1,0,0,0])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> is_feasible(polyhedron(td2))
-false
source
toric_varietyMethod
toric_variety(td::ToricDivisor)

Return the toric variety of a torus-invariant Weil divisor.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4);
-
-julia> D = toric_divisor(F4, [1, 2, 3, 4]);
-
-julia> toric_variety(D)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html deleted file mode 100644 index d622357998ed..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html +++ /dev/null @@ -1,142 +0,0 @@ - -Toric Line Bundles · Oscar.jl

Toric Line Bundles

Constructors

Generic constructors

toric_line_bundleMethod
toric_line_bundle(v::AbstractNormalToricVariety, picard_class::GrpAbFinGenElem)

Construct the line bundle on the abstract normal toric variety with given class in the Picard group of the toric variety in question.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(P2, picard_group(P2)([1]))
-Toric line bundle on a normal toric variety
source
toric_line_bundleMethod
toric_line_bundle(v::AbstractNormalToricVariety, picard_class::Vector{T}) where {T <: IntegerUnion}

Construct the line bundle on the abstract normal toric variety v with class c in the Picard group of v.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
source
toric_line_bundleMethod
toric_line_bundle(v::AbstractNormalToricVariety, d::ToricDivisor)

Construct the toric variety associated to a (Cartier) torus-invariant divisor d on the normal toric variety v.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, toric_divisor(v, [1, 2, 3]))
-Toric line bundle on a normal toric variety
source
toric_line_bundleMethod
toric_line_bundle(d::ToricDivisor)

Construct the toric variety associated to a (Cartier) torus-invariant divisor d.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(v, [1, 2, 3]);
-
-julia> l = toric_line_bundle(d)
-Toric line bundle on a normal toric variety
source
toric_line_bundleMethod
toric_line_bundle(v::AbstractNormalToricVariety, dc::ToricDivisorClass)

Construct the toric variety associated to a divisor class in the class group of a toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(v, [1, 2, 3])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> dc = toric_divisor_class(d)
-Divisor class on a normal toric variety
-
-julia> l = toric_line_bundle(v, dc)
-Toric line bundle on a normal toric variety
source
toric_line_bundleMethod
toric_line_bundle(dc::ToricDivisorClass)

Construct the toric variety associated to a divisor class in the class group of a toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> d = toric_divisor(v, [1, 2, 3])
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> dc = toric_divisor_class(d)
-Divisor class on a normal toric variety
-
-julia> l = toric_line_bundle(dc)
-Toric line bundle on a normal toric variety
source

Tensor products

Toric line bundles can be tensored via *. The n-th tensor power can be computed via ^n. In particular, ^(-1) computes the inverse of a line bundle. Alternatively, one can compute the inverse by invoking inv.

Special line bundles

anticanonical_bundleMethod
anticanonical_bundle(v::AbstractNormalToricVariety)

Construct the anticanonical bundle of a normal toric variety. For convenience, we also support anticanonical_bundle(variety).

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> anticanonical_bundle(v)
-Toric line bundle on a normal toric variety
source
canonical_bundleMethod
canonical_bundle(v::AbstractNormalToricVariety)

Construct the canonical bundle of a normal toric variety. For convenience, we also support canonical_bundle(variety).

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> canonical_bundle(v)
-Toric line bundle on a normal toric variety
source
structure_sheafMethod
structure_sheaf(v::AbstractNormalToricVariety)

Construct the structure sheaf of a normal toric variety. For convenience, we also support structure_sheaf(variety).

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> structure_sheaf(v)
-Toric line bundle on a normal toric variety
source

Properties

Equality of toric line bundles can be tested via ==.

To check if a toric line bundle is trivial, one can invoke is_trivial. Beyond this, we support the following properties of toric line bundles:

is_basepoint_freeMethod
is_basepoint_free(l::ToricLineBundle)

Return true if the toric line bundle l is basepoint free and false otherwise.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> is_basepoint_free(toric_line_bundle(F4, [1, 0]))
-true
source
is_ampleMethod
is_ample(l::ToricLineBundle)

Return true if the toric line bundle l is ample and false otherwise.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> is_ample(toric_line_bundle(F4, [1,0]))
-false
source
is_very_ampleMethod
is_very_ample(l::ToricLineBundle)

Return true if the toric line bundle l is very ample and false otherwise.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> is_very_ample(toric_line_bundle(F4, [1,0]))
-false
source

Attributes

degreeMethod
degree(l::ToricLineBundle)

Return the degree of the toric line bundle l.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> degree(l)
-2
source
picard_classMethod
picard_class(l::ToricLineBundle)

Return the class in the Picard group which defines the toric line bundle l.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> picard_class(l)
-Element of
-GrpAb: Z
-with components [2]
source
toric_divisorMethod
toric_divisor(l::ToricLineBundle)

Return a toric divisor corresponding to the toric line bundle l.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> toric_divisor(l)
-Torus-invariant, cartier, non-prime divisor on a normal toric variety
-
-julia> is_cartier(toric_divisor(l))
-true
source
toric_divisor_classMethod
toric_divisor_class(l::ToricLineBundle)

Return a divisor class in the Class group corresponding to the toric line bundle l.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> toric_divisor(l)
-Torus-invariant, cartier, non-prime divisor on a normal toric variety
-
-julia> is_cartier(toric_divisor(l))
-true
source
toric_varietyMethod
toric_variety(l::ToricLineBundle)

Return the toric variety over which the toric line bundle l is defined.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> toric_variety(l)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
source

Methods

basis_of_global_sections_via_rational_functionsMethod
basis_of_global_sections_via_rational_functions(l::ToricLineBundle)

Return a basis of the global sections of the toric line bundle l in terms of rational functions.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> basis_of_global_sections_via_rational_functions(l)
-6-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x1_^2
- x2*x1_^2
- x2^2*x1_^2
- x1_
- x2*x1_
- 1
source
basis_of_global_sections_via_homogeneous_componentMethod
basis_of_global_sections_via_homogeneous_component(l::ToricLineBundle)

Return a basis of the global sections of the toric line bundle l in terms of a homogeneous component of the Cox ring of toric_variety(l). For convenience, this method can also be called via basis_of_global_sections(l::ToricLineBundle).

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> basis_of_global_sections_via_homogeneous_component(l)
-6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x3^2
- x2*x3
- x2^2
- x1*x3
- x1*x2
- x1^2
-
-julia> basis_of_global_sections(l)
-6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x3^2
- x2*x3
- x2^2
- x1*x3
- x1*x2
- x1^2
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html deleted file mode 100644 index 14d0fb134f0b..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html +++ /dev/null @@ -1,163 +0,0 @@ - -ToricMorphisms · Oscar.jl

ToricMorphisms

A class of morphisms among toric varieties are described by certain lattice morphisms. Let $N_1$ and $N_2$ be lattices and $\Sigma_1$, $\Sigma_2$ fans in $N_1$ and $N_2$ respectively. A $\mathbb{Z}$-linear map

\[\overline{\phi} \colon N_1 \to N_2\]

is said to be compatible with the fans $\Sigma_1$ and $\Sigma_2$ if for every cone $\sigma_1 \in \Sigma_1$, there exists a cone $\sigma_2 \in \Sigma_2$ such that $\overline{\phi}_{\mathbb{R}}(\sigma_1) \subseteq \sigma_2$.

By theorem 3.3.4 David A. Cox, John B. Little, Henry K. Schenck (2011), such a map $\overline{\phi}$ induces a morphism $\phi \colon X_{\Sigma_1} \to X_{\Sigma_2}$ of the toric varieties, and those morphisms are exactly the toric morphisms.

Constructors

Generic constructors without specified codomain

toric_morphismMethod
toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Vector{Vector{T}}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = [[0, 1]]
-1-element Vector{Vector{Int64}}:
- [0, 1]
-
-julia> toric_morphism(domain, mapping_matrix)
-A toric morphism
source
toric_morphismMethod
toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Matrix{T}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = [0 1]
-1×2 Matrix{Int64}:
- 0  1
-
-julia> toric_morphism(domain, mapping_matrix)
-A toric morphism
source
toric_morphismMethod
toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::ZZMatrix, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> codomain = hirzebruch_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = matrix(ZZ, [0 1])
-[0   1]
-
-julia> toric_morphism(domain, mapping_matrix, codomain)
-A toric morphism
source
toric_morphismMethod
function toric_morphism(domain::AbstractNormalToricVariety, grid_morphism::GrpAbFinGenMap, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism from the domain to the codomain with map given by the grid_morphism. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> codomain = hirzebruch_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = matrix(ZZ, [[0, 1]])
-[0   1]
-
-julia> grid_morphism = hom(character_lattice(domain), character_lattice(codomain), mapping_matrix)
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z
-Codomain:
-=========
-Abelian group with structure: Z^2
-
-julia> toric_morphism(domain, grid_morphism, codomain)
-A toric morphism
source

Generic constructors with specified codomain

toric_morphismMethod
toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Vector{Vector{T}}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = [[0, 1]]
-1-element Vector{Vector{Int64}}:
- [0, 1]
-
-julia> toric_morphism(domain, mapping_matrix)
-A toric morphism
source
toric_morphismMethod
toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Matrix{T}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = [0 1]
-1×2 Matrix{Int64}:
- 0  1
-
-julia> toric_morphism(domain, mapping_matrix)
-A toric morphism
source
toric_morphismMethod
toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::ZZMatrix, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> codomain = hirzebruch_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = matrix(ZZ, [0 1])
-[0   1]
-
-julia> toric_morphism(domain, mapping_matrix, codomain)
-A toric morphism
source
toric_morphismMethod
function toric_morphism(domain::AbstractNormalToricVariety, grid_morphism::GrpAbFinGenMap, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}

Construct the toric morphism from the domain to the codomain with map given by the grid_morphism. As optional argument, the codomain of the morphism can be specified.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor
-
-julia> codomain = hirzebruch_surface(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> mapping_matrix = matrix(ZZ, [[0, 1]])
-[0   1]
-
-julia> grid_morphism = hom(character_lattice(domain), character_lattice(codomain), mapping_matrix)
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z
-Codomain:
-=========
-Abelian group with structure: Z^2
-
-julia> toric_morphism(domain, grid_morphism, codomain)
-A toric morphism
source

Special constructors

toric_identity_morphismMethod
toric_identity_morphism(variety::AbstractNormalToricVariety)

Construct the toric identity morphism from variety to variety.

Examples

julia> toric_identity_morphism(hirzebruch_surface(NormalToricVariety, 2))
-A toric morphism
source

Attributes of Toric Morhpisms

General attributes

domainMethod
domain(tm::ToricMorphism)

Return the domain of the toric morphism tm.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> domain(toric_identity_morphism(F4))
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
source
imageMethod
image(tm::ToricMorphism)

Return the image of the toric morphism tm.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> image(toric_identity_morphism(F4))
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
source
codomainMethod
codomain(tm::ToricMorphism)

Return the codomain of the toric morphism tm.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> codomain(toric_identity_morphism(F4))
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
source
grid_morphismMethod
grid_morphism(tm::ToricMorphism)

Return the underlying grid morphism of the toric morphism tm.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> grid_morphism(toric_identity_morphism(F4))
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^2
-Codomain:
-=========
-Abelian group with structure: Z^2
source
morphism_on_torusinvariant_weil_divisor_groupMethod
morphism_on_torusinvariant_weil_divisor_group(tm::ToricMorphism)

For a given toric morphism tm, this method computes the corresponding map of the torusinvariant Weil divisors.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> morphism_on_torusinvariant_weil_divisor_group(toric_identity_morphism(F4))
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^4
-Codomain:
-=========
-Abelian group with structure: Z^4
source
morphism_on_torusinvariant_cartier_divisor_groupMethod
morphism_on_torusinvariant_cartier_divisor_group(tm::ToricMorphism)

For a given toric morphism tm, this method computes the corresponding map of the Cartier divisors.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> morphism_on_torusinvariant_cartier_divisor_group(toric_identity_morphism(F4))
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^4
-Codomain:
-=========
-Abelian group with structure: Z^4
source
morphism_on_class_groupMethod
morphism_on_class_group(tm::ToricMorphism)

For a given toric morphism tm, this method computes the corresponding map of the Class groups.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> morphism_on_class_group(toric_identity_morphism(F4))
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^2
-Codomain:
-=========
-Abelian group with structure: Z^2
source
morphism_on_picard_groupMethod
morphism_on_picard_group(tm::ToricMorphism)

For a given toric morphism tm, this method computes the corresponding map of the Picard groups.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> morphism_on_picard_group(toric_identity_morphism(F4))
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z^2
-Codomain:
-=========
-Abelian group with structure: Z^2
source

Special attributes of toric varieties

To every toric variety $v$ we can associate a special toric variety, the Cox variety. By definition, the Cox variety is such that the mapping matrix of the toric morphism from the Cox variety to the variety $v$ is simply given by the ray generators of the variety $v$. Put differently, if there are exactly $N$ ray generators for the fan of $v$, then the Cox variety of $v$ has a fan for which the ray generators are the standard basis of $\mathbb{R}^N$ and the maximal cones are one to one to the maximal cones of the fan of $v$.

morphism_from_cox_varietyMethod
morphism_from_cox_variety(variety::AbstractNormalToricVariety)

Return the quotient morphism from the Cox variety to the toric variety in question.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> morphism_from_cox_variety(F4)
-A toric morphism
source
cox_varietyMethod
cox_variety(variety::AbstractNormalToricVariety)

Return the Cox variety of the toric variety in question.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor
-
-julia> cox_variety(F4)
-Normal toric variety
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html deleted file mode 100644 index cd1c9ee5919f..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html +++ /dev/null @@ -1,69 +0,0 @@ - -Line bundle cohomology with cohomCalg · Oscar.jl

Line bundle cohomology with cohomCalg

We employ the cohomCalg algorithm Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010) to compute the dimension of line bundle cohomologies as well as vanishing sets.

Dimensions of line bundle cohomology

all_cohomologiesMethod
all_cohomologies(l::ToricLineBundle)

Computes the dimension of all sheaf cohomologies of the toric line bundle l by use of the cohomCalg algorithm Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010), Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010) (see also Helmut Roschy, Thorsten Rahn (2010), Shin-Yao Jow (2011) and Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2012)).

Examples

julia> dP3 = del_pezzo_surface(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> all_cohomologies(toric_line_bundle(dP3, [1, 2, 3, 4]))
-3-element Vector{ZZRingElem}:
- 0
- 16
- 0
source
cohomologyMethod
cohomology(l::ToricLineBundle, i::Int)

Computes the dimension of the i-th sheaf cohomology of the toric line bundle l by use of the cohomCalg algorithm Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010), Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010) (see also Helmut Roschy, Thorsten Rahn (2010), Shin-Yao Jow (2011) and Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2012)).

Examples

julia> dP3 = del_pezzo_surface(NormalToricVariety, 3)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> cohomology(toric_line_bundle(dP3, [4, 1, 1, 1]), 0)
-12
source

Toric vanishing sets

Vanishing sets describe subsets of the Picard group of toric varieties. Their computations is based on Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010), i.e. this functionality is only available if the toric variety in question is either smooth and complete or alternatively, simplicial and projective. This approach to identify vanishing sets on toric varieties was originally introduced in Martin Bies (2018). As described there, on a technical level, a vanishing set is the complement of a finite family of polyhedra.

For a toric variety, all vanishing sets are computed as follows:

vanishing_setsMethod
vanishing_sets(variety::AbstractNormalToricVariety)

Compute the vanishing sets of an abstract toric variety v by use of the cohomCalg algorithm.

source

The return value is a vector of vanishing sets. This vector has length one larger than the dimension of the variety in question. The first vanishing set in this vector describes all line bundles for which the zero-th sheaf cohomology vanishes. More generally, if a line bundle is contained in the n-th vanishing set, then its n-1-th sheaf cohomology vanishes. The following method checks if a line bundle is contained in a vanishing set:

containsMethod
contains(tvs::ToricVanishingSet, l::ToricLineBundle)

Checks if the toric line bundle l is contained in the toric vanishing set tvs.

Examples

julia> dP1 = del_pezzo_surface(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> l = toric_line_bundle(dP1, [3, 2])
-Toric line bundle on a normal toric variety
-
-julia> all_cohomologies(l)
-3-element Vector{ZZRingElem}:
- 7
- 0
- 0
-
-julia> vs = vanishing_sets(dP1)
-3-element Vector{ToricVanishingSet}:
- Toric vanishing set for cohomology index 0
- Toric vanishing set for cohomology index 1
- Toric vanishing set for cohomology index 2
-
-julia> contains(vs[1], l)
-false
-
-julia> contains(vs[2], l)
-true
-
-julia> contains(vs[3], l)
-true
source

A vanishing set can in principle cover the entire Picard group. This can be checked with isfull. This methods returns true if the vanishing set is the entire Picard group and false otherwise. Beyond this, we support the following attributes for vanishing sets:

toric_varietyMethod
toric_variety(tvs::ToricVanishingSet)

Return the toric variety of the vanishing set tvs.

Examples

julia> dP1 = del_pezzo_surface(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> vs = vanishing_sets(dP1)
-3-element Vector{ToricVanishingSet}:
- Toric vanishing set for cohomology index 0
- Toric vanishing set for cohomology index 1
- Toric vanishing set for cohomology index 2
-
-julia> toric_variety(vs[3])
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
source
polyhedraMethod
polyhedra(tvs::ToricVanishingSet)

Return the vector of the polyhedra whose complement defines the vanishing set tvs.

Examples

julia> dP1 = del_pezzo_surface(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> vs = vanishing_sets(dP1)
-3-element Vector{ToricVanishingSet}:
- Toric vanishing set for cohomology index 0
- Toric vanishing set for cohomology index 1
- Toric vanishing set for cohomology index 2
-
-julia> polyhedra(vs[3])
-1-element Vector{Polyhedron{QQFieldElem}}:
- Polyhedron in ambient dimension 2
source
cohomology_indexMethod
cohomology_index(tvs::ToricVanishingSet)

Return the cohomology index of the toric vanishing set tvs.

Examples

julia> dP1 = del_pezzo_surface(NormalToricVariety, 1)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> vs = vanishing_sets(dP1)
-3-element Vector{ToricVanishingSet}:
- Toric vanishing set for cohomology index 0
- Toric vanishing set for cohomology index 1
- Toric vanishing set for cohomology index 2
-
-julia> cohomology_index(vs[3])
-2
source
diff --git a/previews/PR2578/AlgebraicGeometry/ToricVarieties/intro/index.html b/previews/PR2578/AlgebraicGeometry/ToricVarieties/intro/index.html deleted file mode 100644 index bcc50c132d24..000000000000 --- a/previews/PR2578/AlgebraicGeometry/ToricVarieties/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Content

The toric geometry part of OSCAR comprises algorithms addressing normal toric varieties and objects from commutative algebra and polyhedral geometry derived thereof. In particular, we provide support for the following:

Status

This project is work-in-progress.

Tutorial

We provide a tutorial for toric geometry in OSCAR.

Long term goals

We follow David A. Cox, John B. Little, Henry K. Schenck (2011). Our long term goals include the following:

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/AlgebraicGeometry/TropicalGeometry/curve/index.html b/previews/PR2578/AlgebraicGeometry/TropicalGeometry/curve/index.html deleted file mode 100644 index c7419e0a19f0..000000000000 --- a/previews/PR2578/AlgebraicGeometry/TropicalGeometry/curve/index.html +++ /dev/null @@ -1,174 +0,0 @@ - -Curves · Oscar.jl

Curves

Introduction

An abstract tropical curve is a finite, loopless, multigraph. It is defined by an incidence matrix with vertices as columns and edges as rows.

A divisor on an abstract tropical curve is a formal linear combination of the vertices with integer coefficients. The degree of a divisor is the sum of its coefficients. A divisor is effective if all its coefficients are nonnegative.

For more definitions on the theory of divisors and linear sisyems on abstract tropical curve, we refer to Matthew Baker, Serguei Norine (2007).

The tropical Jacobian of an abstract tropical curve is the group of divisors of degree zero modulo the subgroup of principal divisors. Here a principal divisor is the divisor associated to a piecewise-linear function on the vertices by the Laplacian operator. The tropical Jacobian is a finite abelian group, with order equal to the number of maximal spanning trees in the graph. It is isomorphic to $\prod{\mathbb{Z}/n_{i}\mathbb{Z}}$, where the $n_{i}$ are the nonzero elementary divisors of the Laplacian matrix. For more details, see Matthew Baker, Serguei Norine (2007).

Construction

TropicalCurveMethod
TropicalCurve(PC::PolyhedralComplex)

Construct a tropical curve from a polyhedral complex. If the curve is embedded, vertices must are points in $\mathbb R^n$. If the curve is abstract, the polyhedral complex is empty, vertices must be 1, ..., n, and the graph is given as attribute.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]])
-3×4 IncidenceMatrix
-[1, 2]
-[1, 3]
-[1, 4]
-
-
-julia> VR = [0 0; 1 0; -1 0; 0 1]
-4×2 Matrix{Int64}:
-  0  0
-  1  0
- -1  0
-  0  1
-
-julia> PC = polyhedral_complex(QQFieldElem, IM, VR)
-Polyhedral complex in ambient dimension 2
-
-julia> TC = TropicalCurve(PC)
-min tropical curve in 2-dimensional Euclidean space
-
-julia> abs_TC = TropicalCurve(IM)
-Abstract min tropical curve
source
DivisorOnTropicalCurveMethod
DivisorOnTropicalCurve(tc::TropicalCurve, coeffs::Vector{Int})

Construct a divisor with coefficients coeffs on an abstract tropical curve tc.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> coeffs = [0, 1, 1, 1];
-
-julia> dtc = DivisorOnTropicalCurve(tc,coeffs)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])
source

Auxiliary functions

graphMethod
graph(tc::TropicalCurve)

Return the graph of an abstract tropical curve tc.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> graph(tc)
-6×4 IncidenceMatrix
-[1, 2]
-[1, 3]
-[1, 4]
-[2, 3]
-[2, 4]
-[3, 4]
source
n_nodesMethod
n_nodes(tc::TropicalCurve)

Return the number of nodes of an abstract tropical curve tc.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> n_nodes(tc)
-4
source
coefficientsMethod
coefficients(dtc::DivisorOnTropicalCurve)

Construct a divisor dtc with coefficients coeffs on an abstract tropical curve.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> coeffs = [0, 1, 1, 1];
-
-julia> dtc = DivisorOnTropicalCurve(tc,coeffs)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])
-
-julia> coefficients(dtc)
-4-element Vector{Int64}:
- 0
- 1
- 1
- 1
source
degreeMethod

degree(dtc::DivisorOnTropicalCurve)

Compute the degree of a divisor dtc on an abstract tropical curve.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> coeffs = [0, 1, 1, 1];
-
-julia> dtc = DivisorOnTropicalCurve(tc,coeffs)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])
-
-julia> degree(dtc)
-3
source
is_effectiveMethod
is_effective(dtc::DivisorOnTropicalCurve)

Check whether a divisor dtc on an abstract tropical curve is effective.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> coeffs = [0, 1, 1, 1];
-
-julia> dtc = DivisorOnTropicalCurve(tc,coeffs)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])
-
-julia> is_effective(dtc)
-true
source
chip_firing_moveMethod

chipfiringmove(dtc::DivisorOnTropicalCurve, position::Int)

Given a divisor dtc and vertex labelled position, compute the linearly equivalent divisor obtained by a chip firing move from the given vertex position.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> coeffs = [0, 1, 1, 1];
-
-julia> dtc = DivisorOnTropicalCurve(tc,coeffs)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])
-
-julia> chip_firing_move(dtc,1)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [-3, 2, 2, 2])
source
v_reducedMethod

v_reduced(dtc::DivisorOnTropicalCurve, vertex::Int)

Given a divisor dtc and vertex labelled vertex, compute the unique divisor reduced with repspect to vertex as defined in Matthew Baker, Serguei Norine (2007). The divisor dtc must have positive coefficients apart from vertex.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> coeffs = [0, 1, 1, 1];
-
-julia> dtc = DivisorOnTropicalCurve(tc,coeffs)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])
-
-julia> v_reduced(dtc,1)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [3, 0, 0, 0])
source
is_linearly_equivalentMethod

islinearlyequivalent(dtc1::DivisorOnTropicalCurve, dtc2::DivisorOnTropicalCurve)

Given two effective divisors dtc1 and dtc2 on the same tropical curve, check whether they are linearly equivalent.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);
-
-julia> tc = TropicalCurve(IM)
-Abstract min tropical curve
-
-julia> coeffs1 = [0, 1, 1, 1];
-
-julia> dtc1 = DivisorOnTropicalCurve(tc,coeffs1)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])
-
-julia> coeffs2 = [3,0,0,0];
-
-julia> dtc2 = DivisorOnTropicalCurve(tc,coeffs2)
-DivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [3, 0, 0, 0])
-
-julia> is_linearly_equivalent(dtc1, dtc2)
-true
source
structure_tropical_jacobianMethod
structure_tropical_jacobian(TC::TropicalCurve)

Compute the elementary divisors $n_i$ of the Laplacian matrix of the tropical curve TC. The tropical Jacobian is then isomorphic to $\prod (Z/(n_i)Z)$.

Examples

julia> cg = complete_graph(5);
-
-julia> IM1=IncidenceMatrix([[src(e), dst(e)] for e in edges(cg)])
-10×5 IncidenceMatrix
-[1, 2]
-[1, 3]
-[2, 3]
-[1, 4]
-[2, 4]
-[3, 4]
-[1, 5]
-[2, 5]
-[3, 5]
-[4, 5]
-
-julia> TC1 = TropicalCurve(IM1)
-Abstract min tropical curve
-
-julia> structure_tropical_jacobian(TC1)
-(General) abelian group with relation matrix
-[1 0 0 0; 0 5 0 0; 0 0 5 0; 0 0 0 5]
-
-julia> cg2 = complete_graph(3);
-
-julia> IM2=IncidenceMatrix([[src(e), dst(e)] for e in edges(cg2)])
-3×3 IncidenceMatrix
-[1, 2]
-[1, 3]
-[2, 3]
-
-julia> TC2 = TropicalCurve(IM2)
-Abstract min tropical curve
-
-julia> structure_tropical_jacobian(TC2)
-(General) abelian group with relation matrix
-[1 0; 0 3]
-
-julia> IM3 = IncidenceMatrix([[1,2],[2,3],[3,4],[4,5],[1,5]])
-5×5 IncidenceMatrix
-[1, 2]
-[2, 3]
-[3, 4]
-[4, 5]
-[1, 5]
-
-julia> TC3=TropicalCurve(IM3)
-Abstract min tropical curve
-
-julia> G = structure_tropical_jacobian(TC3)
-(General) abelian group with relation matrix
-[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 5]
source
diff --git a/previews/PR2578/AlgebraicGeometry/TropicalGeometry/intro/index.html b/previews/PR2578/AlgebraicGeometry/TropicalGeometry/intro/index.html deleted file mode 100644 index e76cdbd4de06..000000000000 --- a/previews/PR2578/AlgebraicGeometry/TropicalGeometry/intro/index.html +++ /dev/null @@ -1,214 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This page lists the OSCAR features for tropical geometry, which are still at the very beginning of their development. For notation we refer to Diane Maclagan, Bernd Sturmfels (2015) and Michael Joswig (2021).

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

Tropical semirings

TropicalSemiringType
TropicalSemiring(M::Union{typeof(min),typeof(max)}=min)

The tropical semiring with min (default) or max.

Warning

There is no subtraction in the tropical semiring. Any subtraction of two tropical numbers will yield an error.

Examples (basic arithmetic)

julia> T = TropicalSemiring() # = TropicalSemiring(min)
-Tropical semiring (min)
-
-julia> T = TropicalSemiring(max)
-Tropical semiring (max)
-
-julia> 0*T(3) + 1*T(1)^2 + inf(T) # = max(0+3,1+2*1,-∞)
-(3)
-
-julia> T(0) == 0    # checks whether the tropical number is 0
-true
-
-julia> iszero(T(0)) # checks whether the tropical number is neutral element of addition
-false

Examples (polynomials)

julia> T = TropicalSemiring()
-Tropical semiring (min)
-
-julia> Tx,(x1,x2) = polynomial_ring(T,3)
-(Multivariate polynomial ring in 3 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x1, x2, x3])
-
-julia> f = x1 + -1*x2 + 0
-x1 + (-1)*x2 + (0)
-
-julia> evaluate(f,[T(-1//2),T(1//2)]) # warning: omitting T(0) gives an error
-(-1//2)

Examples (matrices)

julia> T = TropicalSemiring()
-Tropical semiring (min)
-
-julia> A = [T(0) inf(T); inf(T) T(0)] # = tropical identity matrix
-2×2 Matrix{Oscar.TropicalSemiringElem{typeof(min)}}:
- (0)  ∞
- ∞    (0)
-
-julia> 2*A
-2×2 Matrix{Oscar.TropicalSemiringElem{typeof(min)}}:
- (2)  ∞
- ∞    (2)
-
-julia> A*A
-2×2 Matrix{Oscar.TropicalSemiringElem{typeof(min)}}:
- (0)  ∞
- ∞    (0)
-
-julia> det(A)
-(0)
source
TropicalSemiringMapType
TropicalSemiringMap(K,p,M::Union{typeof(min),typeof(max)}=min)

Constructs a map val from K to the min tropical semiring T (default) or the max tropical semiring that:

  • is a semigroup homomorphism (K,*) -> (T,+),
  • preserves the ordering on both sides.

In other words, val is either a valuation on K with image in TropicalSemiring(min) or the negative of a valuation on K with image in TropicalSemiring(max).

The role of val is to encode with respect to which valuation on K and under which convention (min or max) tropical computations should take place.

Currently, the only supported valuations are:

  • the $t$-adic valuation on $\mathbb{Q}(t)$
  • the $p$-adic valuations on $\mathbb{Q}$
  • the trivial valuation on any field

Examples

$p$-adic valuation on $\mathbb{Q}$:

julia> val_2 = TropicalSemiringMap(QQ,2); # = TropicalSemiringMap(QQ,2,min)
-
-julia> val_2(4)
-(2)
-julia> val_2(1//4)
-(-2)
-julia> val_2 = TropicalSemiringMap(QQ,2,max);
-
-julia> val_2(4)
-(-2)
-julia> val_2(1//4)
-(2)

$t$-adic valuation on $\mathbb{Q}(t)$:

julia> Kt,t = RationalFunctionField(QQ,"t");
-
-julia> val_t = TropicalSemiringMap(Kt,t);
-
-julia> val_t(t^2)
-(2)
-julia> val_t(1//t^2)
-(-2)

Trivial valuation on $\mathbb{Q}$:

julia> val = TropicalSemiringMap(QQ);
-
-julia> val(4)
-(0)
-julia> val(1//4)
-(0)
-julia> val(0)
-∞
source
tropical_polynomialFunction
tropical_polynomial(f::MPolyRingElem,M::Union{typeof(min),typeof(max)}=min)

Given a polynomial f over a field with an intrinsic valuation (i.e., a field on which a function valuation is defined such as PadicField(7,2)), returns the tropicalization of f as a polynomial over the min tropical semiring (default) or the max tropical semiring.

Examples

julia> K = PadicField(7, 2)
-Field of 7-adic numbers
-
-julia> Kxy, (x,y) = K["x", "y"]
-(Multivariate polynomial ring in 2 variables over QQ_7, AbstractAlgebra.Generic.MPoly{padic}[x, y])
-
-julia> f = 7*x+y+49
-(7^1 + O(7^3))*x + y + 7^2 + O(7^4)
-
-julia> tropical_polynomial(f,min)
-(1)*x + y + (2)
-
-julia> tropical_polynomial(f,max)
-(-1)*x + y + (-2)
source
tropical_polynomial(f::MPolyRingElem,val::TropicalSemiringMap)

Given a polynomial f and a tropical semiring map val, returns the tropicalization of f as a polynomial over the tropical semiring.

Examples

julia> R, (x,y) = polynomial_ring(QQ,["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> val = TropicalSemiringMap(QQ,7)
-The 7-adic valuation on Rational field
-
-julia> f = 7*x+y+49
-7*x + y + 49
-
-julia> tropical_polynomial(f,val)
-(1)*x + y + (2)
source

Tropical curves

(no functions yet, under active development)

TropicalCurveType
TropicalCurve(PC::PolyhedralComplex)

Construct a tropical curve from a polyhedral complex. If the curve is embedded, vertices must are points in $\mathbb R^n$. If the curve is abstract, the polyhedral complex is empty, vertices must be 1, ..., n, and the graph is given as attribute.

Examples

julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]])
-3×4 IncidenceMatrix
-[1, 2]
-[1, 3]
-[1, 4]
-
-
-julia> VR = [0 0; 1 0; -1 0; 0 1]
-4×2 Matrix{Int64}:
-  0  0
-  1  0
- -1  0
-  0  1
-
-julia> PC = polyhedral_complex(QQFieldElem, IM, VR)
-Polyhedral complex in ambient dimension 2
-
-julia> TC = TropicalCurve(PC)
-min tropical curve in 2-dimensional Euclidean space
-
-julia> abs_TC = TropicalCurve(IM)
-Abstract min tropical curve
source

in work: chip firing, jacobians.

Tropical hypersurfaces

TropicalHypersurfaceType
TropicalHypersurface(f::AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{T}})

Return the tropical hypersurface of a tropical polynomial f.

Examples

julia> T = TropicalSemiring(min)
-Tropical semiring (min)
-
-julia> Txy,(x,y) = T["x","y"]
-(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])
-
-julia> f = x+y+1
-x + y + (1)
-
-julia> Tf = TropicalHypersurface(f)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
source
TropicalHypersurface(f::MPolyRingElem,M::Union{typeof(min),typeof(max)}=min)

Given a polynomial f over a field with an intrinsic valuation (i.e., a field on which a function valuation is defined such as PadicField(7,2)), return the tropical hypersurface of f under the convention specified by M.

Examples

julia> K = PadicField(7, 2);
-
-julia> Kxy, (x,y) = K["x", "y"]
-(Multivariate polynomial ring in 2 variables over QQ_7, AbstractAlgebra.Generic.MPoly{padic}[x, y])
-
-julia> f = 7*x+y+49;
-
-julia> TropicalHypersurface(f, min)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> TropicalHypersurface(f, max)
-max tropical hypersurface embedded in 2-dimensional Euclidean space
source
TropicalHypersurface(f::MPolyRingElem,M::Union{typeof(min),typeof(max)}=min)

Construct the tropical hypersurface from a polynomial f and a map to the tropical semiring val.

Examples

julia> Kx, (x1,x2) = polynomial_ring(QQ,2)
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x1, x2])
-
-julia> val = TropicalSemiringMap(QQ,7)
-The 7-adic valuation on Rational field
-
-julia> f = 7*x1+x2+49;
-
-julia> TropicalHypersurface(f, val)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
source
dual_subdivisionMethod
dual_subdivision(TH::TropicalHypersurface{M, EMB})

Return the dual subdivision of TH if it is embedded. Otherwise an error is thrown.

Examples

A tropical hypersurface in $\mathbb{R}^n$ is always of dimension n-1.

julia> T = TropicalSemiring(min);
-
-julia> Txy,(x,y) = T["x","y"];
-
-julia> f = x+y+1;
-
-julia> tropicalLine = TropicalHypersurface(f);
-
-julia> dual_subdivision(tropicalLine)
-Subdivision of points in ambient dimension 3
source

in work: minimal tropical polynomials of a hypersurface.

Tropical linear spaces

TropicalLinearSpaceType
TropicalLinearSpace(I::MPolyIdeal, val::TropicalSemiringMap)

Construct a tropical linear space from a degree 1 polynomial ideal I and a map to the tropical semiring val.

Examples

julia> R,(x1,x2,x3,x4,x5,x6) = polynomial_ring(ZZ,6)
-(Multivariate polynomial ring in 6 variables over ZZ, ZZMPolyRingElem[x1, x2, x3, x4, x5, x6])
-
-julia> I = ideal(R,[-x1+x3+x4,-x2+x3+x5,-x1+x2+x6])
-ideal(-x1 + x3 + x4, -x2 + x3 + x5, -x1 + x2 + x6)
-
-julia> val = TropicalSemiringMap(ZZ)
-The trivial valuation on Integer Ring
-
-julia> TropicalLinearSpace(I,val)
-TropicalLinearSpace{min, true}(Polyhedral complex in ambient dimension 6, #undef)
source
TropicalLinearSpace(A::MatElem,val::TropicalSemiringMap)

Construct a tropical linear space from a matrix A and a map to the tropical semiring val.

Examples

julia> Kt, t = RationalFunctionField(QQ,"t");
-
-julia> val = TropicalSemiringMap(Kt,t);
-
-julia> A = matrix(Kt,[[t,4*t,0,2],[1,4,1,t^2]]);
-
-julia> TropicalLinearSpace(A, val)
-TropicalLinearSpace{min, true}(Polyhedral complex in ambient dimension 4, #undef)
-
-julia> p = 3;
-
-julia> val = TropicalSemiringMap(QQ, p);
-
-julia> A = matrix(QQ, [[3,7,5,1], [9,7,1,2]])
-[3   7   5   1]
-[9   7   1   2]
-
-julia> TropicalLinearSpace(A,val)
-TropicalLinearSpace{min, true}(Polyhedral complex in ambient dimension 4, #undef)
source

Tropical varieties

(no functions yet, under active development)

in work: tropical_variety(I::MPolyIdeal,val::TropicalSemiringMap)

Groebner bases and Groebner polyhedra

groebner_basisMethod
groebner_basis(I::Ideal, val::TropicalSemiringMap, w::Vector; complete_reduction::Bool, return_lead::Bool)

Compute a Groebner basis of I over a field with valuation val with respect to weight vector w, that is a finite generating set of I whose initial forms generate the initial ideal with respect to w.

For the definitions of initial form, initial ideal and Groebner basis see Section 2.4 of Diane Maclagan, Bernd Sturmfels (2015).

Warning

Groebner bases over fields with valuation are still in an experimental stage. I must be generated by homogeneous polynomials and val must be non-trivial.

Examples

julia> R,(x,y) = polynomial_ring(QQ,["x","y"]);
-
-julia> I = ideal([x^3-5*x^2*y,3*y^3-2*x^2*y])
-ideal(x^3 - 5*x^2*y, -2*x^2*y + 3*y^3)
-
-julia> val_2 = TropicalSemiringMap(QQ,2);
-
-julia> w = [0,0];
-
-julia> groebner_basis(I,val_2,w)
-5-element Vector{QQMPolyRingElem}:
- 2*x^2*y - 3*y^3
- x^3 - 5*x^2*y
- x*y^3 - 5*y^4
- y^5
- x^2*y^3 + 69*y^5
source

in work: groebner_polyhedron(I::MPolyIdeal,val::TropicalSemiringMap,w::Vector{<: Union{Int,Rational{Int}})

Intersections and stable intersections

intersectMethod
intersect(T1, T2)

Intersect two tropical varieties.

Examples

julia> RR = TropicalSemiring(min)
-Tropical semiring (min)
-
-julia> S,(x,y) = RR["x","y"]
-(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])
-
-julia> f1 = x+y+1
-x + y + (1)
-
-julia> f2 = x^2+y^2+RR(-6)
-x^2 + y^2 + (-6)
-
-julia> hyp1 = TropicalHypersurface(f1)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> hyp2 = TropicalHypersurface(f2)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> tv12 = intersect(hyp1, hyp2)
-min tropical variety of dimension 1 embedded in 2-dimensional Euclidean space
source
diff --git a/previews/PR2578/AlgebraicGeometry/intro/index.html b/previews/PR2578/AlgebraicGeometry/intro/index.html deleted file mode 100644 index 203d26fc77a8..000000000000 --- a/previews/PR2578/AlgebraicGeometry/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The algebraic geometry part of OSCAR provides functionality for dealing with

  • affine algebraic sets and varieties
  • projective algebraic sets and varieties
  • schemes
  • toric varieties,
  • toric schemes,
  • tropical geometry.

Computations in affine and projective algebraic geometry rely on Commutative Algebra.

Similarly, most algorithms for toric varieties and schemes are are based on Polyhedral Geometry.

General textbooks offering details on the theory of varieties and schemes include:

Conventions

Projectivization

There are two opposite conventions in common use when defining the projectivization. For details, see https://stacks.math.columbia.edu/tag/01OA (search for "Warning").

For an example, look at proposition 3 in https://arxiv.org/abs/1501.04049. This proposition states that any elliptically fibred K3-surface can be described as hypersurface in the space $\mathbb{P}(\mathcal{O}_{\mathbb{P}^1}(0) \oplus \mathcal{O}_{\mathbb{P}^1}(-4) \oplus \mathcal{O}_{\mathbb{P}^1}(-6))$. Authors, that apply the opposite convention, would say that any elliptically fibred K3-surface is a hypersurface in $\mathbb{P}(\mathcal{O}_{\mathbb{P}^1}(0) \oplus \mathcal{O}_{\mathbb{P}^1}(4) \oplus \mathcal{O}_{\mathbb{P}^1}(6))$. Note the opposite signs.

Irrespective of the signs used to denote the ambient space, there is always agreement on the hypersurface equation and the transformation behavior of the local coordinates. In the above example, the hypersurface equation is

\[z y^2 = x^3 + \alpha(s,t) x z^2 + \beta(s,t) z^3 \, ,\]

where $(s,t)$ are coordinates on $\mathbb{P}^1$ and $\alpha(s,t)$, $\beta(s,t)$ are homogeneous polynomials in $s$, $t$ of degrees 8 and 12, respectively. The projective coordinates $[x : y : z]$ of the ambient space transform as sections of the bundles $\mathcal{O}_{\mathbb{P}^1}(4)$, $\mathcal{O}_{\mathbb{P}^1}(6)$ and $\mathcal{O}_{\mathbb{P}^1}(0)$, respectively.

diff --git a/previews/PR2578/Combinatorics/graphs/index.html b/previews/PR2578/Combinatorics/graphs/index.html deleted file mode 100644 index b92d4f8b6393..000000000000 --- a/previews/PR2578/Combinatorics/graphs/index.html +++ /dev/null @@ -1,225 +0,0 @@ - -Graphs · Oscar.jl

Graphs

Introduction

Graphs are a fundamental object within all of mathematics and computer science. A graph consists of two sets of data:

  • a finite set $V := \{1,\ldots,n\}$ of vertices; and
  • a finite set $E \subseteq V\times V$ of edges.

There are two types of graphs, directed and undirected. For a directed graph the elements of $E$ are considered to be ordered pairs, for an undirected graph the elements of $E$ are unordered pairs or rather sets with two elements.

The interface is modeled alongside the Graphs.jl interface to allow for easier integration elsewhere.

Warning

The mechanism for removing a vertex is slightly different in out implementation to the Graphs.jl implementation: In Graphs.jl first the vertex to be removed is swapped with the last vertex, then the last vertex is removed. In our implementation, the vertex is removed and all subsequent vertices have their labels changed. Hence edges can be different in the two implementations after removing a vertex.

Construction

GraphMethod
Graph{T}(nverts::Int64) where {T <: Union{Directed, Undirected}}

Construct a graph on nverts vertices and no edges. T indicates whether the graph should be Directed or Undirected.

Examples

Make a directed graph with 5 vertices and print the number of nodes and edges.

julia> g = Graph{Directed}(5);
-
-julia> nv(g)
-5
-
-julia> ne(g)
-0
source
dualgraphMethod
dualgraph(p::Polyhedron)

Return the dual graph of a Polyhedron, vertices of the graph correspond to facets of the polyhedron and there is an edge between two vertices if the corresponding facets are neighboring, meaning their intersection is a codimension 2 face of the polyhedron.

For bounded polyhedra containing 0 in the interior this is the same as the edge graph the polar dual polyhedron.

Examples

Construct the dual graph of the cube. This is the same as the edge graph of the octahedron, so it has 6 vertices and 12 edges.

julia> c = cube(3);
-
-julia> g = dualgraph(c);
-
-julia> nv(g)
-6
-
-julia> ne(g)
-12
source
edgegraphMethod
edgegraph(p::Polyhedron)

Return the edge graph of a Polyhedron, vertices of the graph correspond to vertices of the polyhedron, there is an edge between two vertices if the polyhedron has an edge between the corresponding vertices. The resulting graph is Undirected.

Examples

Construct the edge graph of the cube. Like the cube it has 8 vertices and 12 edges.

julia> c = cube(3);
-
-julia> g = edgegraph(c);
-
-julia> nv(g)
-8
-
-julia> ne(g)
-12
source
graph_from_adjacency_matrixFunction
graph_from_adjacency_matrix(::Type{T}, G) where {T <:Union{Directed, Undirected}}

Return the graph with adjacency matrix G.

This means that the nodes $i, j$ are connected by an edge if and only if $G_{i,j}$ is one. In the undirected case, it is assumed that $i > j$ i.e. the upper triangular part of $G$ is ignored.

Examples

julia> G = ZZ[0 0; 1 0]
-[0   0]
-[1   0]
-
-julia> graph_from_adjacency_matrix(Directed, G)
-Graph{Directed}(pm::graph::Graph<pm::graph::Directed>
-{}
-{0}
-)
-
-julia> graph_from_adjacency_matrix(Undirected, G)
-Graph{Undirected}(pm::graph::Graph<pm::graph::Undirected>
-{1}
-{0}
-)
-
source

Modifying graphs

add_edge!Method
add_edge!(g::Graph{T}, s::Int64, t::Int64) where {T <: Union{Directed, Undirected}}

Add edge (s,t) to the graph g.

Examples

julia> g = Graph{Directed}(2);
-
-julia> add_edge!(g, 1, 2);
-
-julia> ne(g)
-1
source
add_vertices!Method
add_vertices!(g::Graph{T}, n::Int64) where {T <: Union{Directed, Undirected}}

Add a n new vertices to the graph g.

Examples

julia> g = Graph{Directed}(2);
-
-julia> nv(g)
-2
-
-julia> add_vertices!(g, 5);
-
-julia> nv(g)
-7
source
add_vertex!Method
add_vertex!(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Add a vertex to the graph g. The return value is the new vertex.

Examples

julia> g = Graph{Directed}(2);
-
-julia> nv(g)
-2
-
-julia> add_vertex!(g)
-3
-
-julia> nv(g)
-3
source
rem_edge!Method
rem_edge!(g::Graph{T}, s::Int64, t::Int64) where {T <: Union{Directed, Undirected}}

Remove edge (s,t) from the graph g.

Examples

julia> g = Graph{Directed}(2);
-
-julia> add_edge!(g, 1, 2);
-
-julia> ne(g)
-1
-
-julia> rem_edge!(g, 1, 2);
-
-julia> ne(g)
-0
source
rem_vertex!Method
rem_vertex!(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}

Remove the vertex v from the graph g.

Examples

julia> g = Graph{Directed}(2);
-
-julia> nv(g)
-2
-
-julia> rem_vertex!(g, 1)
-
-julia> nv(g)
-1
source

Auxiliary functions

all_neighborsMethod
all_neighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}

Return all vertices of a graph g that are connected to the vertex v via an edge, independent of the edge direction.

Examples

julia> g = Graph{Directed}(5);
-
-julia> add_edge!(g, 1, 3);
-
-julia> add_edge!(g, 3, 4);
-
-julia> all_neighbors(g, 3)
-2-element Vector{Int64}:
- 1
- 4
-
-julia> all_neighbors(g, 4)
-1-element Vector{Int64}:
- 3
source
automorphism_group_generatorsMethod
automorphism_group_generators(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Return generators of the automorphism group of the graph g.

Examples

julia> g = complete_graph(4);
-
-julia> automorphism_group_generators(g)
-3-element Vector{PermGroupElem}:
- (3,4)
- (2,3)
- (1,2)
source
complete_graphMethod
complete_graph(n::Int64)

Assemble the undirected complete graph on n nodes.

Examples

julia> g = complete_graph(3);
-
-julia> collect(edges(g))
-3-element Vector{Edge}:
- Edge(2, 1)
- Edge(3, 1)
- Edge(3, 2)
source
complete_bipartite_graphMethod
complete_bipartite_graph(n::Int64, m::Int64)

Assemble the undirected complete bipartite graph between n and m nodes.

Examples

julia> g = complete_bipartite_graph(2,2);
-
-julia> collect(edges(g))
-4-element Vector{Edge}:
- Edge(3, 1)
- Edge(3, 2)
- Edge(4, 1)
- Edge(4, 2)
source
edgesMethod
edges(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Return an iterator over the edges of the graph g.

Examples

A triangle has three edges.

julia> triangle = simplex(2);
-
-julia> g = edgegraph(triangle);
-
-julia> collect(edges(g))
-3-element Vector{Edge}:
- Edge(2, 1)
- Edge(3, 1)
- Edge(3, 2)
source
has_edgeMethod
has_edge(g::Graph{T}, source::Int64, target::Int64) where {T <: Union{Directed, Undirected}}

Check for an edge in a graph.

Examples

Check for the edge $1\to 2$ in the edge graph of a triangle.

julia> triangle = simplex(2);
-
-julia> g = edgegraph(triangle);
-
-julia> has_edge(g, 1, 2)
-true
source
has_vertexMethod
has_vertex(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}

Check for a vertex in a graph.

Examples

The edge graph of a triangle only has 3 vertices.

julia> triangle = simplex(2);
-
-julia> g = edgegraph(triangle);
-
-julia> has_vertex(g, 1)
-true
-
-julia> has_vertex(g, 4)
-false
source
inneighborsMethod
inneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}

Return the vertices of a graph g that have an edge going towards v. For an undirected graph, all neighboring vertices are returned.

Examples

julia> g = Graph{Directed}(5);
-
-julia> add_edge!(g, 1, 3);
-
-julia> add_edge!(g, 3, 4);
-
-julia> inneighbors(g, 3)
-1-element Vector{Int64}:
- 1
-
-julia> inneighbors(g, 1)
-Int64[]
source
neMethod
ne(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Return the number of edges of a graph.

Examples

The edge graph of the cube has 12 edges just like the cube itself.

julia> c = cube(3);
-
-julia> g = edgegraph(c);
-
-julia> ne(g)
-12
source
neighborsMethod
neighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}

Return the neighboring vertices of a vertex v in a graph g. If the graph is directed, the neighbors reachable via outgoing edges are returned.

Examples

julia> g = Graph{Directed}(5);
-
-julia> add_edge!(g, 1, 3);
-
-julia> add_edge!(g, 3, 4);
-
-julia> neighbors(g, 3)
-1-element Vector{Int64}:
- 4
source
nvMethod
nv(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Return the number of vertices of a graph.

Examples

The edge graph of the cube has eight vertices, just like the cube itself.

julia> c = cube(3);
-
-julia> g = edgegraph(c);
-
-julia> nv(g)
-8
source
outneighborsMethod
outneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}

Return the vertices of a graph g that are target of an edge coming from v. For an undirected graph, all neighboring vertices are returned.

Examples

julia> g = Graph{Directed}(5);
-
-julia> add_edge!(g, 1, 3);
-
-julia> add_edge!(g, 3, 4);
-
-julia> outneighbors(g, 3)
-1-element Vector{Int64}:
- 4
-
-julia> outneighbors(g, 4)
-Int64[]
source
shortest_path_dijkstraFunction
shortest_path_dijkstra(g::Graph{T}, s::Int64, t::Int64; reverse::Bool=false) where {T <: Union{Directed, Undirected}}

Compute the shortest path between two vertices in a graph using Dijkstra's algorithm. All edges are set to have a length of 1. The optional parameter indicates whether the edges should be considered reversed.

Examples

julia> g = Graph{Directed}(3);
-
-julia> add_edge!(g, 1, 2);
-
-julia> add_edge!(g, 2, 3);
-
-julia> add_edge!(g, 3, 1);
-
-julia> shortest_path_dijkstra(g, 3, 1)
-2-element Vector{Int64}:
- 3
- 1
-
-julia> shortest_path_dijkstra(g, 1, 3)
-3-element Vector{Int64}:
- 1
- 2
- 3
-
-julia> shortest_path_dijkstra(g, 3, 1; reverse=true)
-3-element Vector{Int64}:
- 3
- 2
- 1
source
is_isomorphicMethod
is_isomorphic(g1::Graph{T}, g2::Graph{T}) where {T <: Union{Directed, Undirected}}

Checks if the graph g1 is isomorphic to the graph g2.

Examples

julia> is_isomorphic(edgegraph(simplex(3)), dualgraph(simplex(3)))
-true
-
-julia> is_isomorphic(edgegraph(cube(3)), dualgraph(cube(3)))
-false
source
is_isomorphic_with_permutationMethod
is_isomorphic_with_permutation(G1::Graph, G2::Graph) -> Bool, Vector{Int}

Return whether G1 is isomorphic to G2 as well as a permutation of the nodes of G1 such that both graphs agree.

Examples

julia> is_isomorphic_with_permutation(edgegraph(simplex(3)), dualgraph(simplex(3)))
-(true, [1, 2, 3, 4])
-
source

Edges

dstMethod
dst(e::Edge)

Return the destination of an edge.

Examples

julia> g = complete_graph(2);
-
-julia> E = collect(edges(g));
-
-julia> e = E[1]
-Edge(2, 1)
-
-julia> dst(e)
-1
source
reverseMethod
reverse(e::Edge)

Return the edge in the opposite direction of the edge e.

Examples

julia> g = complete_graph(2);
-
-julia> E = collect(edges(g));
-
-julia> e = E[1]
-Edge(2, 1)
-
-julia> reverse(e)
-Edge(1, 2)
source
srcMethod
src(e::Edge)

Return the source of an edge.

Examples

julia> g = complete_graph(2);
-
-julia> E = collect(edges(g));
-
-julia> e = E[1]
-Edge(2, 1)
-
-julia> src(e)
-2
source

Saving and loading

Objects of type Graph can be saved to a file and loaded with the methods load and save. The file is in JSON format and contains the underlying polymake object. In particular, this file can now be read by both polymake and OSCAR.

diff --git a/previews/PR2578/Combinatorics/intro/index.html b/previews/PR2578/Combinatorics/intro/index.html deleted file mode 100644 index 08e0b4e6c4c3..000000000000 --- a/previews/PR2578/Combinatorics/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl
diff --git a/previews/PR2578/Combinatorics/matroids/index.html b/previews/PR2578/Combinatorics/matroids/index.html deleted file mode 100644 index 293209ef350c..000000000000 --- a/previews/PR2578/Combinatorics/matroids/index.html +++ /dev/null @@ -1,410 +0,0 @@ - -Matroids · Oscar.jl

Matroids

Introduction

Matroids are a fundamental combinatorial object with connections to various fields of mathematics. It is an abstraction of linear independence in vector spaces and forests in graphs. One way to define a matroid is via the following two sets of data:

  • a finite ground set $E := \{1,\ldots,n\}$ and
  • a nonempty finite set $\mathcal{B} \subseteq \mathcal{P}(E)$ of bases satisfying an exchange property.

There are however many equivalent ways to define a matroid. One can also define a matroid via its circuits, hyperplanes, a graph, or a matrix. For a detailed introduction of matroids we refer to the textbook James Oxley (2011).

Construction

matroid_from_basesMethod
matroid_from_bases(B, [n, E])

Arguments

  • B::AbstractVector: The set of bases of the matroid.
  • n::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.
  • E::AbstractVector: An explicit ground set passed as vector.

Construct a matroid with bases B on the ground set E (which can be the empty set). The set B is a non-empty collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n.

See Section 1.2 of James Oxley (2011).

Examples

To construct a rank two matroid with five bases on four elements you can write:

julia> B = [[1,2],[1,3],[1,4],[2,3],[2,4]];
-
-julia> M = matroid_from_bases(B,4)
-Matroid of rank 2 on 4 elements

To construct the same matroid on the four elements 1,2,i,j you may write:

julia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j'])
-Matroid of rank 2 on 4 elements
source
matroid_from_nonbasesMethod
matroid_from_nonbases(N, [n, E])

Arguments

  • N::AbstractVector: The set of nonbases of the matroid.
  • n::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.
  • E::AbstractVector: An explicit ground set passed as vector.

Construct a matroid with nonbases N on the ground set E (which can be the empty set). That means that the matroid has as bases all subsets of the size |N[1]| of the ground set that are not in N. The set N can't be empty in this function. The described complement of N needs to be a non-empty collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n.

See Section 1.2 of James Oxley (2011).

Examples

To construct the Fano matroid you may write:

julia> H = [[1,2,4],[2,3,5],[1,3,6],[3,4,7],[1,5,7],[2,6,7],[4,5,6]];
-
-julia> M = matroid_from_nonbases(H,7)
-Matroid of rank 3 on 7 elements
-
source
matroid_from_circuitsMethod
matroid_from_circuits(C, [n, E])

Arguments

  • C::AbstractVector: The set of circuits of the matroid.
  • n::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.
  • E::AbstractVector: An explicit ground set passed as vector.

A matroid with circuits C on the ground set E (which can be the empty set). The set C is a collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n.

See Section 1.1 of James Oxley (2011).

Examples

To construct a rank two matroid with five bases on four elements by its circuits you may write:

julia> C = [[1,2,3],[1,2,4],[3,4]];
-
-julia> M = matroid_from_circuits(C,4)
-Matroid of rank 2 on 4 elements

To construct the same matroid on the ground set {1,2,i,j} you may write:

julia> C = [[1,2,'j'],[1,2,'i'],['i','j']];
-
-julia> M = matroid_from_circuits(C,[1,2,'i','j'])
-Matroid of rank 2 on 4 elements
source
matroid_from_hyperplanesMethod
matroid_from_hyperplanes(H, [n, E])

Arguments

  • H::AbstractVector: The set of hyperplanes of the matroid.
  • n::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.
  • E::AbstractVector: An explicit ground set passed as vector.

A matroid with hyperplanes H on the ground set E (which can be the empty set). A hyperplane is a flat of rank r-1. The set H is a collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n.

See Section 1.4 of James Oxley (2011).

Examples

To construct the Fano matroid you may write:

julia> H = [[1,2,4],[2,3,5],[1,3,6],[3,4,7],[1,5,7],[2,6,7],[4,5,6]];
-
-julia> M = matroid_from_hyperplanes(H,7)
-Matroid of rank 3 on 7 elements
-
source
matroid_from_matrix_columnsMethod
matroid_from_matrix_columns(A::MatrixElem)

A matroid represented by the column vectors of a matrix A.

See Section 1.1 of James Oxley (2011).

Examples

To construct the vector matroid (a.k.a linear matroid) of the matrix A over the field with two elements write:

julia> A = matrix(GF(2),[[1,0,1,1],[0,1,1,1]]);
-
-julia> M = matroid_from_matrix_columns(A)
-Matroid of rank 2 on 4 elements
source
matroid_from_matrix_rowsMethod
matroid_from_matrix_columns(A::MatrixElem)

A matroid represented by the row vectors of a matrix.

See Section 1.1 of James Oxley (2011).

Examples

To construct the linear matroid of the rows of the matrix A over the field with two elements write:

julia> A = matrix(GF(2),[[1,0],[0,1],[1,1],[1,1]]);
-
-julia> M = matroid_from_matrix_rows(A)
-Matroid of rank 2 on 4 elements
source
cycle_matroidMethod
cycle_matroid(g::Graph)

The cycle matroid of a graph g.

See Section 1.1 of James Oxley (2011).

Examples

To construct the cycle matroid of the complete graph of 4 vertices write:

julia> g = complete_graph(4);
-
-julia> M = cycle_matroid(g)
-Matroid of rank 3 on 6 elements
source
bond_matroidMethod
bond_matroid(g::Graph)

The "bond matroid" or "cocycle matroid" of a graph which is the dual of a cycle matroid, i.e., cographic.

See Section 2.3 of James Oxley (2011).

Examples

To construct the bond or cocycle matroid of the complete graph of 4 vertices write:

julia> g = complete_graph(4);
-
-julia> M = bond_matroid(g)
-Matroid of rank 3 on 6 elements

or equivalently

julia> g = complete_graph(4);
-
-julia> M = cocycle_matroid(g)
-Matroid of rank 3 on 6 elements
source
MatroidType
Matroid(pm_matroid::Polymake.BigObjectAllocated, [E::GroundsetType])

Construct a matroid from a polymake matroid M on the default ground set {1,...,n}.

source
matroid_from_revlex_basis_encodingMethod
matroid_from_revlex_basis_encoding(rvlx::String, r::IntegerUnion, n::IntegerUnion)

Construct a matroid from a revlex-basis-encoding-string rvlx of rank r and size n.

Examples

julia> matroid_from_revlex_basis_encoding("0******0******0***0******0*0**0****", 3, 7)
-Matroid of rank 3 on 7 elements
source

Examples

uniform_matroidMethod
uniform_matroid(r,n)

Construct the uniform matroid of rank r on the n elements {1,...,n}.

source
all_subsets_matroidMethod
all_subsets_matroid(r)

Construct the all-subsets-matroid of rank r, a.k.a. the matroid underlying the resonance arrangement or rank r.

source
projective_planeMethod
projective_plane(q::Int)

The projective plane of order q. Note that this only works for prime numbers q for now.

See Section 6.1 of James Oxley (2011).

Examples

julia> M = projective_plane(3)
-Matroid of rank 3 on 13 elements
-
source
projective_geometryMethod
projective_geometry(r::Int, q::Int)

The projective geometry of order q and rank r+1. Note that this only works for prime numbers q for now.

See Section 6.1 of James Oxley (2011). Warning: Following the book of Oxley, the rank of the resulting matroid is r+1.

Examples

julia> M = projective_geometry(2, 3)
-Matroid of rank 3 on 13 elements
-
source
affine_geometryMethod
affine_geometry(r::Int, q::Int)

The affine geometry of order q and rank r+1. Note that this only works for prime numbers q for now.

See Section 6.1 of James Oxley (2011). Warning: Following the book of Oxley, the rank of the resulting matroid is r+1.

Examples

julia> M = affine_geometry(2, 3)
-Matroid of rank 3 on 9 elements
source

Modifying matroids

dual_matroidMethod
dual_matroid(M::Matroid)

The dual matroid of a given matroid M.

See page 65 and Sectrion 2 in James Oxley (2011).

Examples

To construct the dual of the Fano matroid write:

julia> M = dual_matroid(fano_matroid())
-Matroid of rank 4 on 7 elements
source
direct_sumMethod
direct_sum(M::Matroid, N::Matroid)

The direct sum of the matroids M and N. Optionally one can also pass a vector of matroids.

See Section 4.2 of James Oxley (2011).

To obtain the direct sum of the Fano and a uniform matroid type:

Examples

julia> direct_sum(fano_matroid(), uniform_matroid(2,4))
-Matroid of rank 5 on 11 elements

To take the sum of three uniform matroids use:

Examples

julia> matroids = Vector([uniform_matroid(2,4), uniform_matroid(1,3), uniform_matroid(3,4)]);
-
-julia> M = direct_sum(matroids)
-Matroid of rank 6 on 11 elements
source
deletionMethod
deletion(M, [S, e])

Arguments

  • M::Matroid: A matroid M.
  • S::GroundsetType: A subset S of the ground set of M.
  • e::ElementType: An element e of the ground set of M.

The deletion M\S of an element e or a subset S of the ground set E of the matroid M.

See Section 3 of James Oxley (2011).

Examples

julia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);
-
-julia> N = deletion(M,'i')
-Matroid of rank 2 on 3 elements

Examples

julia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);
-
-julia> N = deletion(M,['i','j'])
-Matroid of rank 2 on 2 elements
-
-julia> matroid_groundset(N)
-2-element Vector{Any}:
- 1
- 2
source
restrictionMethod
restriction(M, S)

Arguments

  • M::Matroid: A matroid M.
  • S::GroundSetType: A subset S of the ground set of M.

The restriction M|S on a subset S of the ground set E of the matroid M.

See Section 3 of James Oxley (2011).

Examples

julia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);
-
-julia> N = restriction(M,[1,2])
-Matroid of rank 2 on 2 elements
-
-julia> matroid_groundset(N)
-2-element Vector{Any}:
- 1
- 2
source
contractionMethod
contraction(M, [S, e])

Arguments

  • M::Matroid: A matroid M.
  • S::GroundSetType: A subset S of the ground set of M.
  • e::ElementType: An element e of the ground set of M.

The contraction M/S of an element or a subset S of the ground set E of the matroid M.

See Section 3 of James Oxley (2011).

Examples

julia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);
-
-julia> N = contraction(M,'i')
-Matroid of rank 1 on 3 elements

Examples

julia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);
-
-julia> N = contraction(M,['i','j'])
-Matroid of rank 1 on 2 elements
-
-julia> matroid_groundset(N)
-2-element Vector{Any}:
- 1
- 2
source
minorMethod
minor(M::Matroid, set_del::GroundsetType, set_cont::GroundsetType)

The minor M\S/T of disjoint subsets S and T of the ground set E of the matroid M.

See also contraction and deletion. You can find more in Section 3 of James Oxley (2011).

Examples

julia> M = fano_matroid();
-
-julia> S = [1,2,3];
-
-julia> T = [4];
-
-julia>  N = minor(M,S,T) 
-Matroid of rank 2 on 3 elements
source
principal_extensionMethod
principal_extension(M::Matroid, F::GroundsetType, e::ElementType)

The principal extension M +_F e of a matroid M where the element e is freely added to the flat F.

See Section 7.2 of James Oxley (2011).

Examples

To add 5 freely to the flat {1,2} of the uniform matroid U_{3,4} do

julia> M = uniform_matroid(3,4);
-
-julia> N = principal_extension(M,[1,2],5)
-Matroid of rank 3 on 5 elements
source
free_extensionMethod
free_extension(M::Matroid, e::ElementType)

The free extension M +_E e of a matroid M where the element e.

See $principal_extension$ and Section 7.2 of James Oxley (2011).

Examples

To add 5 freely to the uniform matroid U_{3,4} do

julia> M = uniform_matroid(3,4);
-
-julia>  N = free_extension(M,5)
-Matroid of rank 3 on 5 elements
source
series_extensionMethod
series_extension(M::Matroid, f::ElementType, e::ElementType)

The series extension of a matroid M where the element e is added in series to f.

This is actually a coextension see also Section 7.2 of James Oxley (2011).

Examples

To add e in series to 1 in the uniform matroid U_{3,4} do

julia> M = uniform_matroid(1,4);
-
-julia> N = series_extension(M,1,'e')
-Matroid of rank 2 on 5 elements
-
-julia> cocircuits(N)[1]
-2-element Vector{Any}:
- 1
-  'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
source
parallel_extensionMethod
parallel_extension(M::Matroid, f::ElementType, e::ElementType)

The parallel extension M +_{cl(f)} e of a matroid M where the element e is added parallel to (the closure of) f.

See Section 7.2 of James Oxley (2011).

Examples

To add e parallel to 1 in the uniform matroid U_{3,4} do

julia> M = uniform_matroid(3,4);
-
-julia> N = parallel_extension(M,1,'e')
-Matroid of rank 3 on 5 elements
-
-julia> circuits(N)[1]
-2-element Vector{Any}:
- 1
-  'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
source

Properties

matroid_groundsetMethod
matroid_groundset(M::Matroid)

The ground set E of a matroid M.

To obtain the ground set of the Fano matroid write:

Examples

julia> matroid_groundset(fano_matroid())
-7-element Vector{Int64}:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
source
lengthMethod
length(M::Matroid)

Return the size of the ground set of the matroid M.

Examples

julia> length(fano_matroid())
-7
source
rankMethod
rank(M::Matroid)

Return the rank of the matroid M.

Examples

julia> rank(fano_matroid())
-3
source
rankMethod
rank(M::Matroid, set::GroundsetType)

Return the rank of set in the matroid M.

Examples

julia> M = fano_matroid();
-
-julia> rank(M, [1,2,3])
-2
source
basesMethod
bases(M::Matroid)

Return the list of bases of the matroid M.

Examples

julia> bases(uniform_matroid(2, 3))
-3-element Vector{Vector{Int64}}:
- [1, 2]
- [1, 3]
- [2, 3]
source
nonbasesMethod
nonbases(M::Matroid)

Return the list of nonbases of the matroid M.

Examples

julia> nonbases(fano_matroid())
-7-element Vector{Vector{Int64}}:
- [1, 2, 3]
- [1, 4, 5]
- [1, 6, 7]
- [2, 4, 6]
- [2, 5, 7]
- [3, 4, 7]
- [3, 5, 6]
source
circuitsMethod
circuits(M::Matroid)

Return the list of circuits of the matroid M.

Examples

julia> circuits(uniform_matroid(2, 4))
-4-element Vector{Vector{Int64}}:
- [1, 2, 3]
- [1, 2, 4]
- [1, 3, 4]
- [2, 3, 4]
source
hyperplanesMethod
hyperplanes(M::Matroid)

Return the list of hyperplanes of the matroid M.

Examples

julia> hyperplanes(fano_matroid())
-7-element Vector{Vector{Int64}}:
- [3, 5, 6]
- [3, 4, 7]
- [2, 5, 7]
- [2, 4, 6]
- [1, 6, 7]
- [1, 4, 5]
- [1, 2, 3]
source
flatsFunction
flats(M::Matroid, [r::Int])

Return the list of flats of the matroid M. By default all flats are returned. One may specify a rank r as the second parameter in which case only the flats of rank r are returned.

Examples

julia> M = fano_matroid()
-Matroid of rank 3 on 7 elements
-
-julia> flats(M)
-16-element Vector{Vector}:
- Any[]
- [1]
- [2]
- [3]
- [4]
- [5]
- [6]
- [7]
- [1, 2, 3]
- [1, 4, 5]
- [1, 6, 7]
- [2, 4, 6]
- [2, 5, 7]
- [3, 5, 6]
- [3, 4, 7]
- [1, 2, 3, 4, 5, 6, 7]
-
-julia> flats(M, 2)
-7-element Vector{Vector}:
- [1, 2, 3]
- [1, 4, 5]
- [1, 6, 7]
- [2, 4, 6]
- [2, 5, 7]
- [3, 5, 6]
- [3, 4, 7]
source
cyclic_flatsFunction
cyclic_flats(M::Matroid, [r::Int])

Return the list of cyclic flats of the matroid M. These are the flats that are the union of cycles. See Section 2.1 in James Oxley (2011).

By default all cyclic flats are returned. One may specify a rank r as the second parameter. In this case only the cyclic flats of this rank are returned.

Examples

julia> M = fano_matroid()
-Matroid of rank 3 on 7 elements
-
-julia> cyclic_flats(M)
-9-element Vector{Vector}:
- Any[]
- [1, 2, 3]
- [1, 4, 5]
- [1, 6, 7]
- [2, 4, 6]
- [2, 5, 7]
- [3, 5, 6]
- [3, 4, 7]
- [1, 2, 3, 4, 5, 6, 7]
-
-julia> cyclic_flats(M, 2)
-7-element Vector{Vector}:
- [1, 2, 3]
- [1, 4, 5]
- [1, 6, 7]
- [2, 4, 6]
- [2, 5, 7]
- [3, 5, 6]
- [3, 4, 7]
source
closureMethod
closure(M::Matroid, set::GroundsetType)

Return the closure of set in the matroid M.

Examples

julia> closure(fano_matroid(), [1,2])
-3-element Vector{Int64}:
- 1
- 2
- 3
source
nullityMethod
nullity(M::Matroid, set::GroundsetType)

Return the nullity of set in the matroid M. This is defined to be |set| - rk(set).

Examples

julia> M = fano_matroid();
-
-julia> nullity(M, [1,2,3])
-1
source
fundamental_circuitMethod
fundamental_circuit(M::Matroid, basis::GroundsetType, elem::ElementType)

Return the unique circuit contained in the union of basis and elem of the matroid M. See Section 1.2 of James Oxley (2011). Note that elem needs to be in the complement of the basis in this case.

Examples

julia> M = fano_matroid();
-
-julia> fundamental_circuit(M, [1,2,4], 7)
-4-element Vector{Int64}:
- 1
- 2
- 4
- 7
-
-julia> fundamental_circuit(M, [1,2,4], 3)
-3-element Vector{Int64}:
- 1
- 2
- 3
source
fundamental_cocircuitMethod
fundamental_cocircuit(M::Matroid, cobasis::GroundsetType, elem::ElementType)

Return the unique circuit of the dual matroid of M in the union of the complement of basis and elem. See Section 2.1 of James Oxley (2011). Note that elem needs to be an element of the basis in this case.

Examples

julia> fundamental_cocircuit(fano_matroid(), [1,2,4], 4)
-4-element Vector{Int64}:
- 4
- 5
- 6
- 7
source
independent_setsMethod
independent_sets(M::Matroid)

Return the list of independent sets of the matroid M. These are all subsets of the bases.

Examples

julia> independent_sets(uniform_matroid(2, 3))
-7-element Vector{Vector{Integer}}:
- []
- [1]
- [2]
- [3]
- [1, 3]
- [2, 3]
- [1, 2]
source
spanning_setsMethod
spanning_sets(M::Matroid)

Return the list of spanning sets of the matroid M. These are all sets containing a basis.

Examples

julia> spanning_sets(uniform_matroid(2, 3))
-4-element Vector{Vector{Integer}}:
- [1, 2]
- [1, 3]
- [2, 3]
- [1, 2, 3]
source
cobasesMethod
cobases(M::Matroid)

Return the bases of the dual matroid of M. See Section 2 in James Oxley (2011).

Examples

julia> cobases(uniform_matroid(2, 3))
-3-element Vector{Vector{Int64}}:
- [3]
- [2]
- [1]
source
cocircuitsMethod
cocircuits(M::Matroid)

Return the circuits of the dual matroid of M. See Section 2 in James Oxley (2011).

Examples

julia> cocircuits(uniform_matroid(2, 5))
-5-element Vector{Vector{Int64}}:
- [1, 2, 3, 4]
- [1, 2, 3, 5]
- [1, 2, 4, 5]
- [1, 3, 4, 5]
- [2, 3, 4, 5]
source
cohyperplanesMethod
cohyperplanes(M::Matroid)

Return the hyperplanes of the dual matroid of M. See Section 2 in James Oxley (2011).

Examples

julia> cohyperplanes(fano_matroid())
-14-element Vector{Vector{Int64}}:
- [4, 5, 6, 7]
- [2, 3, 6, 7]
- [2, 3, 4, 5]
- [1, 3, 5, 7]
- [1, 3, 4, 6]
- [1, 2, 5, 6]
- [1, 2, 4, 7]
- [3, 5, 6]
- [3, 4, 7]
- [2, 5, 7]
- [2, 4, 6]
- [1, 6, 7]
- [1, 4, 5]
- [1, 2, 3]
source
corankMethod
corank(M::Matroid, set::GroundsetType)

Return the rank of set in the dual matroid of M.

Examples

julia> corank(fano_matroid(), [1,2,3])
-3
source
is_clutterMethod
is_clutter(sets::AbstractVector{T}) where T <: GroundsetType

Checks if the collection of subsets sets is a clutter. A collection of subsets is a clutter if none of the sets is a proper subset of another. See Section 2.1 in James Oxley (2011).

Examples

julia> is_clutter([[1,2], [1,2,3]])
-false
-
-julia> is_clutter(circuits(fano_matroid()))
-true
source
is_regularMethod
is_regular(M::Matroid)

Checks if the matroid M is regular, that is representable over every field. See Section 6.6 in James Oxley (2011).

Examples

julia> is_regular(uniform_matroid(2, 3))
-true
-
-julia> is_regular(fano_matroid())
-false
source
is_binaryMethod
is_binary(M::Matroid)

Checks if the matroid M is binary, that is representable over the finite field F_2. See Section 6.5 in James Oxley (2011).

Examples

julia> is_binary(uniform_matroid(2, 4))
-false
-
-julia> is_binary(fano_matroid())
-true
source
is_ternaryMethod
is_ternary(M::Matroid)

Checks if the matroid M is ternary, that is representable over the finite field F_3. See Section 4.1 in James Oxley (2011).

Examples

julia> is_ternary(uniform_matroid(2, 4))
-true
-
-julia> is_ternary(fano_matroid())
-false
source
n_connected_componentsMethod
n_connected_components(M::Matroid)

Return the number of connected components of M. See Section 4.1 in James Oxley (2011).

Examples

julia> n_connected_components(fano_matroid())
-1
-
-julia> n_connected_components(uniform_matroid(3, 3))
-3
source
connected_componentsMethod
connected_components(M::Matroid)

Return the connected components of M. The function returns a partition of the ground set where each part corresponds to one connected component. See Section 4.1 in James Oxley (2011).

Examples

julia> connected_components(fano_matroid())
-1-element Vector{Vector{Int64}}:
- [1, 2, 3, 4, 5, 6, 7]
-
-julia> connected_components(uniform_matroid(3, 3))
-3-element Vector{Vector{Int64}}:
- [1]
- [2]
- [3]
source
is_connectedMethod
is_connected(M::Matroid)

Check if the matroid M is connected, that is has one connected component See Section 4.1 in James Oxley (2011).

Examples

julia> is_connected(fano_matroid())
-true
-
-julia> is_connected(uniform_matroid(3, 3))
-false
source
loopsMethod
loops(M::Matroid)

Return the loops of M. A loop is an element of the ground set that is not contained in any basis.

Examples

julia> loops(matroid_from_bases([[1,2]], 4))
-2-element Vector{Int64}:
- 3
- 4
-
-julia> loops(fano_matroid())
-Any[]
source
coloopsMethod
coloops(M::Matroid)

Return the coloops of M. A coloop is an element of the ground set that is contained in every basis.

Examples

julia> coloops(matroid_from_bases([[1,2]], 4))
-2-element Vector{Int64}:
- 1
- 2
-
-julia> coloops(fano_matroid())
-Any[]
source
is_looplessMethod
is_loopless(M::Matroid)

Check if M has a loop. Return true if M does not have a loop. See also loops.

Examples

julia> is_loopless(matroid_from_bases([[1,2]], 4))
-false
-
-julia> is_loopless(fano_matroid())
-true
source
is_colooplessMethod
is_coloopless(M::Matroid)

Check if M has a coloop. Return true if M does not have a coloop. See also coloops.

Examples

julia> is_coloopless(matroid_from_bases([[1,2]], 4))
-false
-
-julia> is_coloopless(fano_matroid())
-true
source
is_simpleMethod
is_simple(M::Matroid)

Check if M has is simple. A matroid is simple if it doesn't have loops and doesn't have parallel elements. Return true if M is simple. See also loops.

Examples

julia> is_simple(matroid_from_bases([[1,2]], 4))
-false
-
-julia> is_simple(fano_matroid())
-true
source
direct_sum_componentsMethod
direct_sum_components(M::Matroid)

Return the connected components of M as a list of matroids. See Section 4.1 in James Oxley (2011).

Examples

julia> direct_sum_components(fano_matroid())
-1-element Vector{Matroid}:
- Matroid of rank 3 on 7 elements
-
-julia> direct_sum_components(uniform_matroid(3, 3))
-3-element Vector{Matroid}:
- Matroid of rank 1 on 1 elements
- Matroid of rank 1 on 1 elements
- Matroid of rank 1 on 1 elements
source
connectivity_functionMethod
connectivity_function(M::Matroid, set::GroundsetType)

Return the value of the connectivity function of set in the matroid M. See Section 8.1 in James Oxley (2011).

Examples

julia> connectivity_function(fano_matroid(), [1,2,4])
-3
-
source
is_vertical_k_separationMethod
is_vertical_k_separation(M::Matroid, k::IntegerUnion, set::GroundsetType)

Check if set together with its complement defines a k separation in M See Section 8.6 in James Oxley (2011).

Examples

julia> is_vertical_k_separation(fano_matroid(), 2, [1,2,4])
-false
-
source
is_k_separationMethod
is_k_separation(M::Matroid, k::IntegerUnion, set::GroundsetType)

Check if set together with its complement defines a k separation in M See Section 8.1 in James Oxley (2011).

Examples

julia> is_k_separation(fano_matroid(), 2, [1,2,4])
-false
-
source
vertical_connectivityMethod
vertical_connectivity(M::Matroid)

If 'M' has two disjoint cocircuits, its vertical connectivity is defined to be least positive integer k such that M has a vertical k separation. Otherwise its vertical connectivity is defined to be the rank of M. See Section 8.6 in James Oxley (2011).

Examples

julia> vertical_connectivity(fano_matroid())
-3
-
source
girthFunction
girth(M::Matroid, set::GroundsetType)

Return the girth of set in the matroid M. This is the size of the smallest circuit contained in set and infinite otherwise. See Section 8.6 in James Oxley (2011).

Examples

julia> girth(fano_matroid(), [1,2,3,4])
-3
-
source
tutte_connectivityMethod
tutte_connectivity(M::Matroid)

The Tutte connectivity of M is the least integer k such that M has a k separation. It can be infinite if no k separation exists. See Section 8.6 in James Oxley (2011).

Examples

julia> tutte_connectivity(fano_matroid())
-3
-
-julia> tutte_connectivity(uniform_matroid(2,4))
-PosInf()
-
source
tutte_polynomialMethod
tutte_polynomial(M::Matroid)

Return the Tutte polynomial of M. This is polynomial in the variables x and y with integral coefficients. See Section 15.3 in James Oxley (2011).

Examples

julia> tutte_polynomial(fano_matroid())
-x^3 + 4*x^2 + 7*x*y + 3*x + y^4 + 3*y^3 + 6*y^2 + 3*y
-
source
characteristic_polynomialMethod
characteristic_polynomial(M::Matroid)

Return the characteristic polynomial of M. This is polynomial in the variable q with integral coefficients. It is computed as an evaluation of the Tutte polynmomial. See Section 15.2 in James Oxley (2011).

Examples

julia> characteristic_polynomial(fano_matroid())
-q^3 - 7*q^2 + 14*q - 8
-
source
reduced_characteristic_polynomialMethod
reduced_characteristic_polynomial(M::Matroid)

Return the reduced characteristic polynomial of M. This is the quotient of the characteristic polynomial by (q-1). See Section 15.2 in James Oxley (2011).

Examples

julia> reduced_characteristic_polynomial(fano_matroid())
-q^2 - 6*q + 8
-
source
revlex_basis_encodingMethod
revlex_basis_encoding(M::Matroid)

Computes the revlex basis encoding and the minimal revlex basis encoding among isomorphic matroids

Examples

To get the revlex basis encoding of the fano matroid and to preduce a matrod form the encoding write:

julia> string1, string2 = revlex_basis_encoding(fano_matroid())
-("0******0******0***0******0*0**0****", "0******0******0***0******0*0**0****")
-
-julia> matroid_from_revlex_basis_encoding(string2, 3, 7)
-Matroid of rank 3 on 7 elements
source
is_isomorphicMethod
is_isomorphic(M1::Matroid, M2::Matroid)

Checks if the matroid M1 is isomorphic to the matroid M2 under the action of the symmetric group that acts on their groundsets.

Examples

To compare two matrods write:

julia> H = [[1,2,4],[2,3,5],[1,3,6],[3,4,7],[1,5,7],[2,6,7],[4,5,6]];
-
-julia> M = matroid_from_hyperplanes(H,7);
-
-julia> is_isomorphic(M,fano_matroid())
-true
-
source
is_minorMethod
is_minor(M::Matroid, N::Matroid)

Checks if the matroid M is isomorphic to a minor of the matroid N.

Examples

julia> is_minor(direct_sum(uniform_matroid(0,1), uniform_matroid(2,2)), fano_matroid())
-false
-
-julia> is_minor(direct_sum(uniform_matroid(0,1), uniform_matroid(2,2)), parallel_extension(uniform_matroid(3,4), 1, 5))
-true
source

Chow Rings

chow_ringMethod
chow_ring(M::Matroid; ring::MPolyRing=nothing, extended::Bool=false)

Return the Chow ring of a matroid, optionally also with the simplicial generators and the polynomial ring.

See Karim Adiprasito, June Huh, Eric Katz (2018) and Spencer Backman, Christopher Eur, Connor Simpson (2019).

Examples

The following computes the Chow ring of the Fano matroid.

julia> M = fano_matroid();
-
-julia> R = chow_ring(M);
-
-julia> R[1]*R[8]
--x_{3,4,7}^2

The following computes the Chow ring of the Fano matroid including variables for the simplicial generators.

julia> M = fano_matroid();
-
-julia> R = chow_ring(M, extended=true);
-
-julia> f = R[22] + R[8] - R[29]
-x_{1,2,3} + h_{1,2,3} - h_{1,2,3,4,5,6,7}
-
-julia> f==0
-true

The following computes the Chow ring of the free matroid on three elements in a given graded polynomial ring.

julia> M = uniform_matroid(3,3);
-
-julia> GR, _ = graded_polynomial_ring(QQ,["a","b","c","d","e","f"]);
-
-julia> R = chow_ring(M, ring=GR);
-
-julia> hilbert_series_reduced(R)
-(t^2 + 4*t + 1, 1) 
-
source

Matroid strata and realization spaces

For a matroid $M$, of rank $d$ on a ground set $E$ of size $n$ realizable over a ring $K$, its matroid realization space $\mathsf{Gr}(M)$ is the locally closed subscheme of the Grassmannian $\mathsf{Gr}(d,K^n)$ of $d$-dimensional subspaces of $K^n$ realizing $M$. Precisely,

\[ \mathsf{Gr}(M) = \{F \in \mathsf{Gr}(d,K^n) \, : \, p_{I}(F) \neq 0 \text{ iff } I \in \mathcal{B}(M)\}\]

where $\mathcal{B}(M)$ denotes the set of bases of $M$ and $p_{I}(F)$ denotes the $I$th Pl\"ucker coordinate of the linear subspace $F \subset K^n$. The coordinate ring of $\mathsf{Gr}(M)$ can be computed using matrix coordinates, see Construction 2.2 of D. Corey (2021). The following function computes this ring.

matroid_stratum_matrix_coordinatesFunction
matroid_stratum_matrix_coordinates(M::Matroid, B::GroundsetType, F::AbstractAlgebra.Ring = ZZ)

Return the data of the coordinate ring of the matroid stratum of M in the Grassmannian with respect to matrix coordinates. Here, B is a basis of Mand the submatrix with columns indexed byB' is the identity. This function returns a pair (A, W) where A is the coordinate matrix, and W is the coordinate ring of the stratum, in general this is a localized quotient ring.

Examples

julia> M = fano_matroid();
-
-julia> (A, W) = matroid_stratum_matrix_coordinates(M, [1,2,4], GF(2));
-
-julia> A # The coordinate matrix with entries in the polynomial ring `R`.
-[1   0   x[1, 1]   0   x[1, 2]         0   x[1, 4]]
-[0   1   x[2, 1]   0         0   x[2, 3]   x[2, 4]]
-[0   0         0   1   x[3, 2]   x[3, 3]   x[3, 4]]
-
-julia> W # The coordinate ring of the stratum; in general a localized quotient ring `(R/I)[S⁻¹]`.
-Localization
-  of quotient of multivariate polynomial ring by ideal with 4 generators
-  at products of 28 elements
source

When the matroid $M$ is connected, the diagonal torus of $\mathsf{PGL}(n)$ acts freely on $\mathsf{Gr}(M)$ and its quotient is the realization space $R(M)$ of $M$. There are two main differences between the coordinate rings $K[\mathsf{Gr}(M)]$ and $K[R(M)]$.

  • To comupte $K[R(M)]$, we assume that $d+1$ columns $A = \{a_1,\ldots,a_{d+1}\}$ of the reference matrix $X$ are the unit vectors $e_1,\ldots,e_n$ and $e_1+ \cdots + e_n$. Note that every $d$ element subset of $A$ must be a basis of $M$. Disconnected matroids do not satisfy this property.
  • The columns of the reference matrix $X$ may be treated as projective coordinates.

The coordinate ring of $R(M)$ is computed in the following function.

matroid_realization_spaceFunction
matroid_realization_space(M::Matroid, A::GroundsetType, F::AbstractAlgebra.Ring=ZZ)

Return the data of the coordinate ring of the realization space of the matroid M using matrix coordinates. The matroid M should be a simple and connected matroid, say its rank is $d$, and ground set $[n]$. The vector A is rank(M)+1 consists of $d+1$ elements (in order) of $[n]$ such that each $d$-element subset is a basis of $M$.

This function returns a pair (X, W) where X is the reduced $d×n$ matrix of variables, and the coordinate ring of the matroid realization space is W.

Examples

julia> M = fano_matroid();
-
-julia> (X, W) = matroid_realization_space(M, [1,2,4,7], GF(2));
-
-julia> X # The coordinate matrix.
-[1   0   x[1, 1]   0   x[1, 2]         0   1]
-[0   1         1   0         0   x[2, 3]   1]
-[0   0         0   1         1         1   1]
-
-julia> W # The coordinate ring of the stratum.
-Localization
-  of quotient of multivariate polynomial ring by ideal with 4 generators
-  at products of 9 elements
source
automorphism_groupMethod
automorphism_group(m::Matroid)

Given a matroid m return its automorphism group as a PermGroup. The group acts on the elements of m.

Examples

julia> M = uniform_matroid(2, 4)
-Matroid of rank 2 on 4 elements
-
-julia> automorphism_group(M)
-Group([ (3,4), (1,2), (2,3) ])
source
diff --git a/previews/PR2578/Combinatorics/partitions/index.html b/previews/PR2578/Combinatorics/partitions/index.html deleted file mode 100644 index 560ea603ecce..000000000000 --- a/previews/PR2578/Combinatorics/partitions/index.html +++ /dev/null @@ -1,74 +0,0 @@ - -Partitions · Oscar.jl

Partitions

PartitionType
Partition{T<:IntegerUnion} <: AbstractVector{T}

A partition of a non-negative integer $n$ is a decreasing sequence $λ₁ ≥ λ₂ ≥ … ≥ λᵣ$ of positive integers $λᵢ$ such that $n = λ₁ + … + λᵣ$. The $λᵢ$ are called the parts of the partition and $r$ is called the length.

A partition can be encoded as an array with elements $λᵢ$. We provide the parametric type Partition{T} which is a subtype of AbstractVector{T} where T can be any subtype of IntegerUnion. All functions that can be used for vectors (1-dimensional arrays) can thus be used for partitions as well. There is no performance impact by using an own type for partitions rather than simply using arrays. The parametric type allows to increase performance by using smaller integer types. For efficiency, the Partition constructor does not check whether the given array is indeed a decreasing sequence.

A partition can be created by either calling partition on an array of integers or by calling partition with arguments being the sequence of parts, with the possibility to provide the element type as the first argument.

Examples

julia> P = partition([6,4,4,2]) #The partition 6+4+4+2 of 16.
-[6, 4, 4, 2]
-
-julia> P = partition(6,4,4,2) #Same as above but less to type
-[6, 4, 4, 2]
-
-julia> length(P)
-4
-
-julia> P[1]
-6

Usually, $|λ| ≔ n$ is called the size of $λ$. In Julia, the function size for arrays already exists and returns the dimension of an array. Instead, you can use the Julia function sum to get the sum of the parts.

julia> P = partition(6,4,4,2)
-[6, 4, 4, 2]
-
-julia> sum(P) 
-16

You can create partitions with smaller integer types as follows.

julia> P = partition(Int8,6,4,4,2) #Or partition(Int8[6,4,4,2])
-Int8[6, 4, 4, 2]

There is a unique partition of 0, namely the empty partition (of length 0). It can be created as follows.

julia> P = partition() #Or partition([])
-Int64[]
-julia> sum(P)
-0
-julia> length(P)
-0
-julia> P = partition(Int8) #Or partition(Int8[])
-Int8[]

References

  1. William Fulton (1997)
  2. Donald E. Knuth (2011), Section 7.2.1.4 (starting on page 390).
source
getindex_safeFunction
getindex_safe(P::Partition, i::IntegerUnion)

In algorithms involving partitions it is sometimes convenient to be able to access parts beyond the length of the partition and then one wants to get the value zero instead of an error. This function is a shortcut for

return (i>length(P.p) ? 0 : getindex(P.p,i))

If you are sure that P[i] exists, use getindex because this will be faster.

Examples

julia> P = partition([3,2,1])
-[3, 2, 1]
-
-julia> getindex_safe(P, 3)
-1
-
-julia> getindex_safe(P, 4)
-0
source

Generating and counting

partitionsMethod
partitions(n::IntegerUnion)

A list of all partitions of a non-negative integer n, produced in lexicographically descending order. This ordering is like in Sage, but opposite to GAP. You can apply the function reverse to reverse the order. As usual, you may increase performance by using smaller integer types.

Algorithm

The algorithm used is "Algorithm ZS1" by A. Zoghbi, I. Stojmenovic (1998). This algorithm is also discussed in Donald E. Knuth (2011), Algorithm P (page 392).

Examples

julia> partitions(4) # Use partitions(Int8(4)) to use 8-bit integers
-5-element Vector{Partition{Int64}}:
- [4]
- [3, 1]
- [2, 2]
- [2, 1, 1]
- [1, 1, 1, 1]
source
num_partitionsMethod
num_partitions(n::IntegerUnion)

The number of integer partitions of the non-negative integer n.

Examples

julia> num_partitions(1000)
-24061467864032622473692149727991

Algorithm

We use the function arith_number_of_partitions from W. B. Hart (2010) which is very fast. It is based on the Hardy-Ramanujan-Rademacher formula, see Fredrik Johansson (2012) for details.

Further references

  1. Donald E. Knuth (2011), Section 7.2.1.4 (starting on page 395).
  2. OEIS Foundation Inc. (2023), A000041
source

Partitions with restrictions

How many ways are there to pay one euro, using coins worth 1, 2, 5, 10, 20, 50, and/or 100 cents? What if you are allowed to use at most two of each coin?

This is Exercise 11 in Knu11, Section 7.2.1.4 (page 408). It goes back to the famous "Ways to change one dollar" problem, see Pol56. Generally, the problem is to generate and/or count partitions satisfying some restrictions. Of course, one could generate the list of all partitions of 100 (there are about 190 million) and then filter the result by the restrictions. But for certain types of restrictions there are much more efficient algorithms. The functions in this section implement some of these. In combination with Julia's filter function one can also handle more general types of restrictions.

For example, there are precisely six ways for the second question in the exercise quoted above:

julia> partitions(100, [1,2,5,10,20,50], [2,2,2,2,2,2])
-6-element Vector{Partition{Int64}}:
- [50, 50]
- [50, 20, 20, 10]
- [50, 20, 20, 5, 5]
- [50, 20, 10, 10, 5, 5]
- [50, 20, 20, 5, 2, 2, 1]
- [50, 20, 10, 10, 5, 2, 2, 1]

and there are 4562 ways for the first question in the exercise:

julia> length(partitions(100, [1,2,5,10,20,50]))
-4562

The original "Ways to change one dollar" problem has 292 solutions:

julia> length(partitions(100,[1,5,10,25,50]))
-292
partitionsMethod
partitions(m::T, n::IntegerUnion, l1::IntegerUnion, l2::IntegerUnion; only_distinct_parts::Bool = false) where T <: IntegerUnion

A list of all partitions of a non-negative integer m into n >= 0 parts with lower bound l1 >= 0 and upper bound l2 for the parts. There are two choices for the parameter only_distinct_parts:

  • false: no further restriction (default);
  • true: only distinct parts. The partitions are produced in decreasing order.

Examples

We compute all partitions of 7 into 3 parts where all parts are between 1 and 4:

julia> partitions(7, 3, 1, 4)
-3-element Vector{Partition{Int64}}:
- [4, 2, 1]
- [3, 3, 1]
- [3, 2, 2]

Same as above but requiring all parts to be distinct:

julia> partitions(7, 3, 1, 4 ; only_distinct_parts=true)
-1-element Vector{Partition{Int64}}:
- [4, 2, 1]

Algorithm

The algorithm used is "parta" in W. Riha, K. R. James (1976), de-gotoed from old ALGOL 60 code by E. Thiel.

source
partitionsMethod
partitions(m::T, n::IntegerUnion) where T<:IntegerUnion

All partitions of a non-negative integer m into n parts (no further restrictions).

Examples

# All partitions of 7 into 3 parts.
-julia> partitions(7, 3)
-4-element Vector{Partition{Int64}}:
- [5, 1, 1]
- [4, 2, 1]
- [3, 3, 1]
- [3, 2, 2]

Algorithm

This function is a shortcut for partitions(m,n,1,m;only_distinct_parts=false).

source
num_partitionsMethod
num_partitions(n::IntegerUnion, k::IntegerUnion)

The number of integer partitions of the non-negative integer n into k >= 0 parts.

Algorithm

We use the recurrence relation $p_k(n) = p_{k-1}(n-1) + p_k(n-k)$, where $p_k(n)$ denotes the number of partitions of $n$ into $k$ parts; see Donald E. Knuth (2011), Section 7.2.1.4, Equation (39) on page 399.

References

  1. OEIS Foundation Inc. (2023), A008284
source
partitionsMethod
partitions(m::T, n::IntegerUnion, v::Vector{T}, mu::Vector{S}) where {T<:IntegerUnion, S<:IntegerUnion}

All partitions of a non-negative integer m into n >= 0 parts, where each part is an element in the vector v of positive integers and each v[i] occurs a maximum of mu[i] > 0 times. We assume (without loss of generality) that the entries in v are strictly increasing. The partitions are produced in lexicographically decreasing order.

Examples

We compute the partitions of 100 into seven parts, where the parts are required to be elements from {1, 2, 5, 10, 20, 50} and each part is allowed to occur at most twice.

julia> partitions(100, 7, [1,2,5,10,20,50], [2,2,2,2,2,2])
-1-element Vector{Partition{Int64}}:
- [50, 20, 20, 5, 2, 2, 1]

Algorithm

The algorithm used is "partb" in W. Riha, K. R. James (1976), de-gotoed from old ALGOL 60 code by E. Thiel. The algorithm as published in the paper has several issues and we hope to have fixed them all, see the code for details. Some initial fixing was done by T. Schmit.

source
partitionsMethod
partitions(m::T, v::Vector{T}, mu::Vector{S}) where {T<:IntegerUnion,S<:IntegerUnion}

All partitions of a non-negative integer m where each part is an element in the vector v of positive integers and each v[i] occurs a maximum of mu[i] > 0 times. We assume (without loss of generality) that the entries in v are strictly increasing.

Example

We compute all partitions of 100 where the parts are from {1, 2, 5, 10, 20, 50} and each part is allowed to occur at most twice:

julia> partitions(100, [1,2,5,10,20,50], [2,2,2,2,2,2])
-6-element Vector{Partition{Int64}}:
- [50, 50]
- [50, 20, 20, 10]
- [50, 20, 20, 5, 5]
- [50, 20, 10, 10, 5, 5]
- [50, 20, 20, 5, 2, 2, 1]
- [50, 20, 10, 10, 5, 2, 2, 1]

Algorithm

We use the function partitions(m,n,v,mu), looping over the number of possible parts of partitions.

source
partitionsMethod
function partitions(m::T, v::Vector{T}) where T<:IntegerUnion

All partitions of a non-negative integer m where each part is an element in the vector v. We assume (without loss of generality) that the entries in v are strictly increasing.

Example

We compute the number of partitions of 100 where the parts are from {1, 2, 5, 10, 20, 50}:

julia> length(partitions(100, [1,2,5,10,20,50]))
-4562

Algorithm

We use the function partitions(m,n,v,mu), looping over the number of possible parts of partitions.

source

Operations

conjugateFunction
conjugate(lambda::Partition{T}) where T<:IntegerUnion

The conjugate of a partition is obtained by considering its Young diagram (see Tableaux) and then flipping it along its main diagonal.

Examples

julia> conjugate(partition(8,8,8,7,2,1,1))
-[7, 5, 4, 4, 4, 4, 4, 3]

References

  1. William Fulton (1997), page 2
  2. Donald E. Knuth (2011), Section 7.2.1.4, page 394.
source

Relations

dominatesFunction
dominates(lambda::Partition, mu::Partition)

The dominance order on partitions is the partial order $⊵$ defined by $λ ⊵ μ$ if and only if $λ₁ + … + λᵢ ≥ μ₁ + … + μᵢ$ for all i. If $λ ⊵ μ$ one says that $λ$ dominates $μ$. This function returns true if and only if lambda dominates mu.

Note that whereas the lexicographic ordering is a total ordering, the dominance ordering is not.

Examples

julia> dominates( partition(3,1), partition(2,2) )
-true
-
-julia> dominates( partition(4,1), partition(3,3) )
-false

Remarks

Donald E. Knuth (2011) says majorizes instead of dominates and uses the symbol $⪰$ instead of $⊵$.

References

  1. William Fulton (1997), page 26
  2. Donald E. Knuth (2011), Section 7.2.1.4, Exercise 54 (page 412)
source
diff --git a/previews/PR2578/Combinatorics/schur_polynomials/index.html b/previews/PR2578/Combinatorics/schur_polynomials/index.html deleted file mode 100644 index 57f1b81e2424..000000000000 --- a/previews/PR2578/Combinatorics/schur_polynomials/index.html +++ /dev/null @@ -1,18 +0,0 @@ - -Schur polynomials · Oscar.jl

Schur polynomials

schur_polynomialMethod
schur_polynomial(lambda::Partition{T}, n::Int=length(lambda)) where T<:Integer
-schur_polynomial(R::ZZMPolyRing, lambda::Partition{T}, n::Int=length(lambda)) where T<:Integer

Return the Schur polynomial $s_λ(x_1,x_2,...,x_n)$ in n variables.

If R is not given, the Schur polynomial will be over polynomial_ring(ZZ,n).

Examples

julia> R,x = polynomial_ring(ZZ, ["a","b","c"]);
-
-julia> schur_polynomial(R, partition([2,1]))
-a^2*b + a*b^2
-
-julia> schur_polynomial(R, partition([2,1]), 3)
-a^2*b + a^2*c + a*b^2 + 2*a*b*c + a*c^2 + b^2*c + b*c^2
-
-julia> schur_polynomial(partition([2]))
-x1^2

Algorithm

We use two different Algorithms, depending on the size of the input. The Combinatorial Algorithm is used for Partitions of small integers, or if $n ≥ 10$. In the other cases we use Cauchy's bialternant formula.

Combinatorial Algorithm

\[s_λ:=∑_T x_1^{m_1}…x_n^{m_n}\]

where the sum is taken over all semistandard tableaux $T$ of shape $λ$, and $m_i$ gives the weight of $i$ in $T$.

Cauchy's bialternant formula

\[s_\lambda(x_1,\dots,x_n) = \prod_{1\leq i < j \leq n} (x_i-x_j)^{-1} -\begin{vmatrix} -x_1^{λ_1+n-1} & x_2^{λ_1+n-1} & … & x_n^{λ_1+n-1} \\ -x_1^{λ_2+n-2} & x_2^{λ_2+n-2} & … & x_n^{λ_2+n-2} \\ -⋮ & ⋮ & ⋱ & ⋮ \\ -x_1^{λ_n} & x_2^{λ_n} & … & x_n^{λ_n} -\end{vmatrix}\]

source
diff --git a/previews/PR2578/Combinatorics/simplicialcomplexes/index.html b/previews/PR2578/Combinatorics/simplicialcomplexes/index.html deleted file mode 100644 index b209101251ee..000000000000 --- a/previews/PR2578/Combinatorics/simplicialcomplexes/index.html +++ /dev/null @@ -1,66 +0,0 @@ - -Simplicial Complexes · Oscar.jl

Simplicial Complexes

Introduction

Abstract simplicial complexes provide a combinatorial way to define topological spaces. By no means every topological space arises in this way, but this is a (most) natural choice in a computational setup.

A simplicial complex $K$ on a vertex set $V$ is a nonempty subset of $2^V$ such that for each $\sigma \in K$ and $\tau \subset\sigma$ we have $\tau\in K$. Here $V$ is usually $[n] = \{1,2,\dots,n\}$ for some $n\geq 0$.

General textbooks offering details on the theory include:

Construction

SimplicialComplexMethod
SimplicialComplex(generators::Union{Vector{Vector{Int}}, Vector{Set{Int}}})

Construct an abstract simplicial complex from a set of faces. While arbitrary nonnegative integers are allowed as vertices, they will be relabeled to consecutive integers starting at 1.

Examples

julia> K = SimplicialComplex([[1,2,3],[2,3,4]])
-Abstract simplicial complex of dimension 2 on 4 vertices

Simplicial complex comprising the empty set only:

julia> empty = SimplicialComplex(Vector{Set{Int}}([]))
-Abstract simplicial complex of dimension -1 on 0 vertices

The original vertices can be recovered:

julia> L = SimplicialComplex([[0,2,17],[2,17,90]]);
-
-julia> facets(L)
-2-element Vector{Set{Int64}}:
- Set([2, 3, 1])
- Set([4, 2, 3])
-
-julia> vertexindices(L)
-4-element Vector{Int64}:
-  0
-  2
- 17
- 90
source

Subcomplexes

star_subcomplexMethod
star_subcomplex(K::SimplicialComplex, sigma::Union{Vector{Int}, Set{Int}})

Return the star of the face sigma in the abstract simplicial complex K.

Examples

julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
-
-julia> star_subcomplex(K,[1])
-Abstract simplicial complex of dimension 2 on 3 vertices
source
link_subcomplexMethod
link_subcomplex(K::SimplicialComplex, sigma::Union{Vector{Int}, Set{Int}})

Return the link of the face sigma in the abstract simplicial complex K.

Examples

julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
-
-julia> link_subcomplex(K,[2,3])
-Abstract simplicial complex of dimension 0 on 2 vertices
source

Surface examples

torusMethod
torus()

Construct Möbius' (vertex-minimal) 7-vertex triangulation of the torus (surface).

source
klein_bottleMethod
klein_bottle()

Construct a 9-vertex triangulation of the Klein bottle.

source
real_projective_planeMethod
real_projective_plane()

Construct the (vertex-minimal) 6-vertex triangulation of the real projective plane.

source

Other examples

complex_projective_planeMethod
complex_projective_plane()

Construct the (vertex-minimal) 9-vertex triangulation of the complex projective plane.

source

Basic properties

nverticesMethod
nvertices(K::SimplicialComplex)

Return the number of vertices of the abstract simplicial complex K.

Examples

julia> nvertices(torus())
-7
source
dimMethod
dim(K::SimplicialComplex)

Return the dimension of the abstract simplicial complex K.

source
f_vectorMethod
f_vector(K::SimplicialComplex)

Return the face vector (number of faces per dimension) of the abstract simplicial complex K.

Examples

julia> f_vector(torus())
-3-element Vector{Int64}:
-  7
- 21
- 14
source
h_vectorMethod
h_vector(K::SimplicialComplex)

Return the h-vector of the abstract simplicial complex K.

Examples

julia> h_vector(torus())
-4-element Vector{Int64}:
-  1
-  4
- 10
- -1
source
euler_characteristicMethod
euler_characteristic(K::SimplicialComplex)

Return the reduced Euler characteristic of the abstract simplicial complex K.

Examples

julia> euler_characteristic(complex_projective_plane())
-2
source

Homology and cohomology

homologyMethod
homology(K::SimplicialComplex, i::Int)

Return i-th reduced integral homology group of K. Recall that the 0-th homology group is trivial if and only if K is connected.

Examples

julia> [ homology(real_projective_plane(), i) for i in [0,1,2] ]
-3-element Vector{GrpAbFinGen}:
- GrpAb: Z/1
- GrpAb: Z/2
- GrpAb: Z/1
source
betti_numbersMethod
betti_numbers(K::SimplicialComplex)

Return the reduced rational Betti numbers of the abstract simplicial complex K.

Examples

julia> betti_numbers(klein_bottle())
-3-element Vector{Int64}:
- 0
- 1
- 0
source
cohomologyMethod
cohomology(K::SimplicialComplex, i::Int)

Return i-th reduced integral cohomology group of K.

Examples

julia> K = SimplicialComplex([[0,1],[1,2],[0,2]]);
-
-julia> cohomology(K,1)
-GrpAb: Z
source

Fundamental group

fundamental_groupMethod
fundamental_group(K::SimplicialComplex)

Return the fundamental group of the abstract simplicial complex K.

Examples

julia> pi_1 = fundamental_group(torus());
-
-julia> describe(pi_1)
-"Z x Z"
source

Connection to commutative algebra

The complements of the minimal non-faces form the facets of the Alexander dual.

minimal_nonfacesMethod
minimal_nonfaces(K::SimplicialComplex)

Return the minimal non-faces of the abstract simplicial complex K.

Examples

julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
-
-julia> minimal_nonfaces(K)
-1-element Vector{Set{Int64}}:
- Set([4, 1])
source
alexander_dualMethod
alexander_dual(K::SimplicialComplex)

Return the Alexander dual of the abstract simplicial complex K.

Examples

julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
-
-julia> alexander_dual(K)
-Abstract simplicial complex of dimension 1 on 2 vertices
source

Let $K$ be a simplicial complex on $n$ vertices. The minimal non-faces of $K$ generate a square-free monomial ideal, known as the Stanley-Reisner ideal of $K$. The quotient of the polynomial ring (in $n$ variables, with integer coefficients) modulo that ideal is the Stanley-Reisner ring. For details see Chapter 5 of Winfried Bruns, Jürgen Herzog (2009).

stanley_reisner_idealMethod
stanley_reisner_ideal(K::SimplicialComplex)

Return the Stanley-Reisner ideal of the abstract simplicial complex K.

Examples

julia> stanley_reisner_ideal(real_projective_plane())
-ideal(x1*x2*x3, x1*x2*x4, x1*x5*x6, x2*x5*x6, x1*x3*x6, x1*x4*x5, x3*x4*x5, x3*x4*x6, x2*x3*x5, x2*x4*x6)
source
stanley_reisner_idealMethod
stanley_reisner_ideal(R::MPolyRing, K::SimplicialComplex)

Return the Stanley-Reisner ideal of the abstract simplicial complex K, in the given ring R.

Examples

julia> R, _ = QQ["a","b","c","d","e","f"];
-
-julia> stanley_reisner_ideal(R, real_projective_plane())
-ideal(a*b*c, a*b*d, a*e*f, b*e*f, a*c*f, a*d*e, c*d*e, c*d*f, b*c*e, b*d*f)
source
stanley_reisner_ringMethod
stanley_reisner_ring(K::SimplicialComplex)

Return the Stanley-Reisner ring of the abstract simplicial complex K.

Examples

julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
-
-julia> stanley_reisner_ring(K)
-(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from
-Multivariate polynomial ring in 4 variables over QQ to Quotient of multivariate polynomial ring by ideal with 1 generator defined by a julia-function with inverse)
source
stanley_reisner_ringMethod
stanley_reisner_ring(R::MPolyRing, K::SimplicialComplex)

Return the Stanley-Reisner ring of the abstract simplicial complex K, as a quotient of a given ring R.

Examples

julia>  R, _ = ZZ["a","b","c","d","e","f"];
-
-julia> stanley_reisner_ring(R, real_projective_plane())
-(Quotient of multivariate polynomial ring by ideal with 10 generators, Map from
-Multivariate polynomial ring in 6 variables over ZZ to Quotient of multivariate polynomial ring by ideal with 10 generators defined by a julia-function with inverse)
source

Saving and loading

Objects of type SimplicialComplex can be saved to a file and loaded with the two methods save and load. The file is in JSON format and contains the underlying polymake object. In particular, such a file can be read by both polymake and OSCAR.

diff --git a/previews/PR2578/Combinatorics/tableaux/index.html b/previews/PR2578/Combinatorics/tableaux/index.html deleted file mode 100644 index 39a75592c301..000000000000 --- a/previews/PR2578/Combinatorics/tableaux/index.html +++ /dev/null @@ -1,21 +0,0 @@ - -Tableaux · Oscar.jl

Tableaux

TableauType
Tableau{T} <: AbstractVector{AbstractVector{T}}

A Young diagram is a diagram of finitely many empty "boxes" arranged in left-justified rows, with the row lengths in non-increasing order. The box in row i and and column j has the coordinates (i,j). Listing the number of boxes in each row gives a partition $λ$ of a non-negative integer n (the total number of boxes of the diagram). The diagram is then said to be of shape $λ$. Conversely, one can associate to any partition $λ$ a Young diagram in the obvious way, so Young diagrams are just another way to look at partitions.

A Young tableau of shape $λ$ is a filling of the boxes of the Young diagram of $λ$ with elements from some set. After relabeling we can (and will) assume that we fill from a set of integers from $1$ up to some number, which in applications is often equal to n. We encode a tableau as an array of arrays and we have implemented an own type Tableau{T} as subtype of AbstractVector{AbstractVector{T}} to work with tableaux. As for partitions, you may increase performance by casting into smaller integer types, e.g.

For efficiency, we do not check whether the given array is really a tableau, i.e. whether the structure of the array defines a partition.

Examples

julia> tab=Tableau([[1,2,3],[4,5],[6]])
-[[1, 2, 3], [4, 5], [6]]
-
-julia> tab=Tableau(Vector{Int8}[[2,1], [], [3,2,1]]) #Using 8 bit integers
-Vector{Int8}[[2, 1], [], [3, 2, 1]]

References

  1. Wikipedia, Young tableau.
source

Operations

hook_lengthFunction
hook_length(lambda::Partition, i::Integer, j::Integer)

Consider the Young diagram of a partition $λ$. The hook length of a box, is the number of boxes to the right in the same row + the number of boxes below in the same column + 1. The function returns the hook length of the box with coordinates (i,j). The functions assumes that the box exists.

source
hook_length(tab::Tableau, i::Integer, j::Integer)

Shortcut for hook_length(shape(tab), i, j).

source
hook_lengthsFunction
hook_lengths(lambda::Partition)

Return the tableau of shape $λ$ in which the entry at position (i,j) is equal to the hook length of the corresponding box.

source
shapeFunction
shape(tab::Tableau{T})

Return the shape of a tableau, i.e. the partition given by the lengths of the rows of the tableau.

source
weightFunction
weight(tab::Tableau)

The weight of a tableau is the number of times each number appears in the tableau. The return value is an array whose i-th element gives the number of times the integer i appears in the tableau.

source
reading_wordFunction
reading_word(tab::Tableau)

The reading word of a tableau is the word obtained by concatenating the fillings of the rows, starting from the bottom row. The word is here returned as an array.

Examples

julia> reading_word(Tableau([ [1,2,3] , [4,5] , [6] ]))
-6-element Vector{Int64}:
- 6
- 4
- 5
- 1
- 2
- 3
source

Semistandard tableaux

is_semistandardFunction
is_semistandard(tab::Tableau)

A tableau is called semistandard if the entries weakly increase along each row and strictly increase down each column.

source
semistandard_tableauxFunction
semistandard_tableaux(shape::Partition{T}, max_val::T=sum(shape)) where T<:Integer

Return a list of all semistandard tableaux of given shape and filling elements bounded by max_val. By default, max_val is equal to the sum of the shape partition (the number of boxes in the Young diagram). The list of tableaux is in lexicographic order from left to right and top to bottom.

source
semistandard_tableaux(shape::Partition{T}, max_val::T=sum(shape)) where T<:Integer

Shortcut for semistandard_tableaux(Partition(shape), max_val).

source
semistandard_tableaux(box_num::T, max_val::T=box_num) where T<:Integer

Return a list of all semistandard tableaux consisting of box_num boxes and filling elements bounded by max_val.

source
semistandard_tableaux(s::Vector{T}, weight::Vector{T}) where T<:Integer

Return a list of all semistandard tableaux with shape s and given weight. This requires that sum(s) = sum(weight).

source

Standard tableaux

is_standardFunction
is_standard(tab::Tableau)

A tableau is called standard if it is semistandard and the entries are in bijection with $1,…,n$, where $n$ is the number of boxes.

source
standard_tableauxFunction
standard_tableaux(s::Partition)
-standard_tableaux(s::Vector{Integer})

Return a list of all standard tableaux of a given shape.

source
standard_tableaux(n::Integer)

Return a list of all standard tableaux with n boxes.

source
num_standard_tableauxFunction
num_standard_tableaux(lambda::Partition)

Return the number $f^λ$ of standard tableaux of shape $λ$ using the hook length formula

\[f^λ = \frac{n!}{\prod_{i,j} h_λ(i,j)},\]

where the product is taken over all boxes in the Young diagram of $λ$ and $h_λ$ denotes the hook length of the box (i,j).

References

  1. Wikipedia, Hook length formula.
source
schenstedFunction
schensted(sigma::Vector{Integer})
-schensted(sigma::Perm{T})

The Robinson–Schensted correspondence is a bijection between permutations and pairs of standard Young tableaux of the same shape. For a permutation sigma (given as an array), this function performs the Schnested algorithm and returns the corresponding pair of standard tableaux (the insertion and recording tableaux).

Examples

julia> P,Q = schensted([3,1,6,2,5,4]);
-
-julia> P
-[[1, 2, 4], [3, 5], [6]]
-
-julia> Q
-[[1, 3, 5], [2, 4], [6]]

References

  1. Wikipedia, Robinson–Schensted correspondence
source
bump!Function
bump!(tab::Tableau, x::Int)

Inserts the integer x into the tableau tab according to the bumping algorithm by applying the Schensted insertion.

References

  1. Wolfram MathWorld, Bumping Algorithm
source
bump!(tab::Tableau, x::Integer, Q::Tableau, y::Integer)

Inserts x into tab according to the bumping algorithm by applying the Schensted insertion. Traces the change with Q by inserting y at the same position in Q as x in tab.

source
diff --git a/previews/PR2578/CommutativeAlgebra/FrameWorks/module_localizations/index.html b/previews/PR2578/CommutativeAlgebra/FrameWorks/module_localizations/index.html deleted file mode 100644 index 7eb7d356b056..000000000000 --- a/previews/PR2578/CommutativeAlgebra/FrameWorks/module_localizations/index.html +++ /dev/null @@ -1,8 +0,0 @@ - -Localizations of modules over computable rings · Oscar.jl

Localizations of modules over computable rings

For localizations of modules, there exists a generic implementation of the common methods such as membership tests, kernel computations, etc. based on the work of Barakat, Posur, et. al; see Sebastian Posur (2018).

Let $R$ be a ring of type <:Ring, $U \subset R$ a multiplicative set of type <:AbsMultSet and $S = R[U^{-1}]$ the localization of $R$ at $U$. Recall that $R$ is computable if one can compute syzygies and lifts over $R$. The results from Sebastian Posur (2018), Theorem 3.9, assert that then also the localization $S$ is computable, provided that there exists a solution to the localization problem (Definition 3.8, Sebastian Posur (2018) and below).

The user who wishes to use the generic code for localizations therefore has to make sure the following two requirements are met:

  1. The code for finitely generated modules and ideals must be functional over $R$, including the computation of coordinates and kernel.

  2. The user has to solve the localization problem by implementing has_nonempty_intersection(U::MultSetType, I::IdealType) for the type MultSetType of multiplicative sets and the type IdealType of ideals in R that they would like to consider.

has_nonempty_intersectionMethod
has_nonempty_intersection(U::AbsMultSet, I::Ideal)

For a finitely generated ideal $I ⊂ R$ and a multiplicative set $U ⊂ R$, this checks whether the intersection $U ∩ I$ is nonempty and returns a triple

(success, f, a).

In the affirmative case, success is true, $f ∈ U ∩ I$ is some element in the intersection and $a ∈ R¹ˣᵏ$ is a Vector{elem_type(R)} such that $f = ∑ᵢ aᵢ⋅gᵢ$ where $gᵢ$ are the elements in gens(I).

When the intersection is empty, this returns (false, f, a) with meaningless values for $f$ and $a$.

Note: When implementing methods of this function, it is recommended to choose $f$ to be the 'least complex' in an appropriate sense for $R$.

source

Note: In order to clear denominators of row vectors, the generic code uses the method lcm(v::Vector{T}) where T = elem_type(R). If no such method already exists, this has to also be provided; in the worst case by simply returning the product of the denominators.

As soon as the above requirements are met, the methods

   represents_element(u::FreeModElem{T}, M::SubquoModule{T}) where {T<:AbsLocalizedRingElem}
-   coordinates(u::FreeModElem{T}, M::SubquoModule{T}) where {T<:AbsLocalizedRingElem}
-   kernel(f::FreeModuleHom{DomType, CodType, Nothing}) where {T, DomType<:FreeMod{T}, CodType<:SubquoModule{T}}
-   kernel(f::SubQuoHom{DomType, CodType, Nothing}) where {T, DomType<:FreeMod{T}, CodType<:SubquoModule{T}}
-   iszero(a::SubquoModuleElem{T}) where {T<:AbsLocalizedRingElem}

will be available for modules over $S$, i.e. for T = elem_type(S). As can easily be seen, having the first three of these methods is already equivalent to $S = R[U^{-1}]$ being computable; hence all higher methods can be derived from these basic ones.

The generic code makes use of a simple caching mechanism for the SubquoModules as follows. For a module $M = (G + N)/N$ with submodules $G, N \subset R^n$ of some free module, the localization $M[U^{-1}]$ over $S = R[U^{-1}]$ has an associated saturated module over $R$:

\[ M' = (G' + N')/N', \quad - G' = \{ a \in R^n | \exists u \in U : u \cdot a \in G + N\},\quad - N' = \{ b \in R^n | \exists u \in U : u \cdot b \in N\}.\]

While it might be difficult to compute such saturations, we have a generic algorithm to check membership for elements in $M'$ (via represents_element for $M[U^{-1}]$). It is assumed that such membership tests are cheaper for modules over $R$ compared to modules over $S$. For instance in the case where $R$ is a multivariate polynomial ring, once a (relative) groebner basis has been computed for $M$, membership test for $M$ is merely a reduction while for the localization $M[U^{-1}]$ it triggers another groebner basis computation a priori.

But for every element $a \in R^n$ that has already been shown to represent an element in the saturation $M'$, we can cache the results of the computation in an intermediate pre-saturated module $M \subset \tilde M \subset M'$ by adding the necessary generators to $G$ and $N$ for a representation of $a$. Then, checking membership for $a$ a second time will fall back to a membership test in $\tilde M$. For the latter, we assume some caching to already be implemented as, for instance, for the use of groebner bases in the polynomial case.

A sample implementation for various localizations of multivariate polynomial rings can be found in src/Modules/mpoly-localizations.jl. A modified version for localizations of affine algebras which also overwrites some of the generic methods, is in src/Modules/mpolyquo-localizations.jl.

diff --git a/previews/PR2578/CommutativeAlgebra/FrameWorks/ring_localizations/index.html b/previews/PR2578/CommutativeAlgebra/FrameWorks/ring_localizations/index.html deleted file mode 100644 index d6489bc8ab70..000000000000 --- a/previews/PR2578/CommutativeAlgebra/FrameWorks/ring_localizations/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -A Framework for Localizing Rings · Oscar.jl

A Framework for Localizing Rings

For the convenience of the developer, we outline a general framework for creating concrete instances of localized rings in OSCAR, addressing relevant abstract types as well as a standardized set of functions whose concrete behaviour must be implemented.

We roughly follow the outline of the previous subsection on localizing multivariate rings which provides illustrating examples. With regard to notation, the name Rloc will refer to the localization of a commutative ring R with 1.

Localized Rings

All multiplicatively closed subsets should belong to the AbsMultSet abstract type and all localized rings should belong to the AbsLocalizedRing abstract type.

The basic functionality that has to be realized for any concrete instance of AbsMultSet is the containment check for elements in multiplicatively closed subsets via the in function.

For each concrete instance of AbsLocalizedRing, the Localization constructor as well as the functions base_ring and inverted_set need to be implemented. Moreover, as for any other type of rings in OSCAR, methods for the standardized set of functions of OSCAR's general Ring Interface must be supplied.

Elements of Localized Rings

All elements of localized rings should belong to the AbsLocalizedRingElem abstract type.

Coercing (pairs of) elements of R into fractions in Rloc must be possible as indicated below:

   (Rloc::AbsLocalizedRing)(f::RingElem)
-   (Rloc::AbsLocalizedRing)(f::RingElem, g::RingElem; check::Bool=true)

The first constructor maps the element f of R to the fraction f//1 in Rloc. The second constructor takes a pair f, g of elements of R to the fraction f//g in Rloc. The default check = true stands for testing whether g is an admissible denominator. As this test is often expensive, it may be convenient to set check = false.

For any concrete instance of type AbsLocalizedRingElem, methods for the functions parent, numerator, and denominator must be provided. Moreover, if a cancellation function for the type of fractions under consideration is not yet available, such a function should be implemented and named reduce_fraction.

Homomorphisms From Localized Rings

The abstract type for homomorphisms from localized rings is MPolyLocalizedRingHom. For each concrete instance, the functions domain and codomain as well as restricted_map must be realized. Here, the latter function is meant to return the composition with the localization map.

Ideals in Localized Rings

All ideals in localized rings belong to the abstract type AbsLocalizedIdeal. For a concrete instance, the constructors to be implemented are:

   ideal(W::AbsLocalizedRing, f::AbsLocalizedRingElem)
-   ideal(W::AbsLocalizedRing, v::Vector{LocalizedRingElemType}) where {LocalizedRingElemType<:AbsLocalizedRingElem}

The usual getter functions base_ring, gens, ngens, and gen must be realized.

Moreover, a method for ideal membership via the in function is required.

diff --git a/previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html b/previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html deleted file mode 100644 index 91be19e48f64..000000000000 --- a/previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html +++ /dev/null @@ -1,429 +0,0 @@ - -Gröbner/Standard Bases Over Fields · Oscar.jl

Gröbner/Standard Bases Over Fields

We fix our notation in the context of standard (Gröbner) bases and present relevant OSCAR functions.

Let $K[x] = K[x_1, \dots, x_n]$ be a polynomial ring over a field $K$, and let $>$ be a monomial ordering on $\text{Mon}_n(x)$.

Given a polynomial $f\in K[x]\setminus \{0\}$, write $f$ as the sum of its nonzero terms as follows:

\[f = a_\alpha x^\alpha + a_{\beta_1} x^{\beta_1} + \dots + a_{\beta_s} x^{\beta_s},\quad x^\alpha > x^{\beta_1} > \dots > x^{\beta_s} .\]

Then, with respect to $>$, we refer to $\text{LT}_>(f) = a_\alpha x^\alpha$, $\text{LM}_>(f) = x^\alpha$, $\text{LE}_>(f) = \alpha$, $\text{LC}_>(f) = a_\alpha$, and $\text{tail}_>(f) = f - \text{LT}_>(f)$ as the leading term, the leading monomial, the leading exponent, the leading coefficient, and the tail of $f$, respectively.

Next note that the set

\[U_>:= \{u\in K[x]\setminus \{0\} \mid {\text{LM}}_>(u)=1 \}\]

is a multiplicatively closed subset of $K[x]$. Consider the localization

\[K[x]_>:= K[x][U^{-1}] = \left\{ \frac{f}{u} \:\bigg|\: f \in K[x], \, u\in U_>\right\}.\]

Then $K[x]\subseteq K[x]_>\subseteq K[x]_{\langle x \rangle},$ where $K[x]_{\langle x \rangle}$ is the localization of $K[x] $ at the maximal ideal $\langle x \rangle .$ Moreover,

  • $K[x] = K[x]_>$ iff $>$ is global, and

  • $K[x]_> = K[x]_{\langle x \rangle}$ iff $>$ is local.

Extending the notation introduced for polynomials, let now $f\in K[x]_>\setminus \{0\}$. Choose $u\in U_>$ such that $uf\in K[x]$. Then, with respect to $>$, the leading term of $f$ is defined to be $\text{LT}_>(f) = \text{LT}_>(uf)$ (this definition is independent of the choice of $u$). The leading monomial $\text{LM}_>(f)$, the leading exponent $\text{LE}_>(f)$, the leading coefficient $\text{LC}_>(f)$, and the tail $\text{tail}_>(f)$ of $f$ are defined similarly.

Note

Given a monomial ordering $>$ on a free $K[x]$-module $F = K[x]^p$ with basis $e_1, \dots, e_p$, the above notation extends naturally to elements of $K[x]^p$ and $K[x]_>^p$, respectively. There is one particularity: Given an element $f = K[x]^p\setminus \{0\}$ with leading term $\text{LT}(f) = x^\alpha e_i$, we write $\text{LE}_>(f) = (\alpha, i)$.

Default Orderings

Note

The OSCAR functions discussed in this section depend on a monomial ordering which is entered as a keyword argument. Given a polynomial ring $R$, the default_ordering for this is degrevlex except if $R$ is $\mathbb Z$-graded with positive weights. Then the corresponding wdegrevlex ordering is used. Given a free $R$-module $F$, the default_ordering is default_ordering(R)*lex(gens(F)).

Here are some illustrating OSCAR examples:

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> default_ordering(R)
-degrevlex([x, y, z])
-
-julia> F = free_module(R, 2)
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> default_ordering(F)
-degrevlex([x, y, z])*lex([gen(1), gen(2)])
-
-julia> S, _ = grade(R, [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> default_ordering(S)
-wdegrevlex([x, y, z], [1, 2, 3])

Monomials, Terms, and More

Here are examples which indicate how to recover monomials, terms, and more from a given polynomial.

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> f = 3*z^3+2*x*y+1
-2*x*y + 3*z^3 + 1
-
-julia> terms(f)
-terms iterator of 3*z^3 + 2*x*y + 1
-
-julia> collect(ans)
-3-element Vector{QQMPolyRingElem}:
- 3*z^3
- 2*x*y
- 1
-
-julia> monomials(f, ordering = lex(R))
-monomials iterator of 2*x*y + 3*z^3 + 1
-
-julia> coefficients(f)
-coefficients iterator of 3*z^3 + 2*x*y + 1
-
-julia> exponents(f, ordering = neglex(R))
-exponents iterator of 1 + 3*z^3 + 2*x*y
-
-julia> coefficients_and_exponents(f)
-coefficients and exponents iterator of 3*z^3 + 2*x*y + 1
-
-julia> collect(ans)
-3-element Vector{Tuple{QQFieldElem, Vector{Int64}}}:
- (3, [0, 0, 3])
- (2, [1, 1, 0])
- (1, [0, 0, 0])
-
-julia> leading_term(f)
-3*z^3
-
-julia> leading_monomial(f, ordering = lex(R))
-x*y
-
-julia> leading_exponent(f, ordering = neglex(R))
-3-element Vector{Int64}:
- 0
- 0
- 0
-
-julia> leading_coefficient(f)
-3
-
-julia> tail(f)
-2*x*y + 1
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> F = free_module(R, 3)
-Free module of rank 3 over Multivariate polynomial ring in 2 variables over QQ
-
-julia> f = (5*x*y^2-y^10+3)*F[1]+(4*x^3+2*y) *F[2]+16*x*F[3]
-(5*x*y^2 - y^10 + 3)*e[1] + (4*x^3 + 2*y)*e[2] + 16*x*e[3]
-
-julia> default_ordering(F)
-degrevlex([x, y])*lex([gen(1), gen(2), gen(3)])
-
-julia> collect(terms(f))
-6-element Vector{FreeModElem{QQMPolyRingElem}}:
- -y^10*e[1]
- 4*x^3*e[2]
- 5*x*y^2*e[1]
- 16*x*e[3]
- 2*y*e[2]
- 3*e[1]
-
-julia> collect(terms(f, ordering = lex(F)*lex(R)))
-6-element Vector{FreeModElem{QQMPolyRingElem}}:
- 5*x*y^2*e[1]
- -y^10*e[1]
- 3*e[1]
- 4*x^3*e[2]
- 2*y*e[2]
- 16*x*e[3]
-
-julia> tail(f)
-(5*x*y^2 + 3)*e[1] + (4*x^3 + 2*y)*e[2] + 16*x*e[3]
-
-julia> leading_exponent(f)
-([0, 10], 1)
-
-julia> leading_exponent(f, ordering = lex(F)*lex(R))
-([1, 2], 1)

Division With Remainder

The computation of Gröbner (standard) bases relies on multivariate division with remainder which is interesting in its own right. If a monomial ordering $>$ is given, the basic idea is to mimic Euclidean division with remainder, allowing more than one divisor: At each step of the resulting process, this amounts to removing the leading term of the intermediate dividend, using the leading term of some divisor by which it is divisible. In its basic form, the process works well if $>$ is global, but may not terminate for local and mixed orderings. In the latter case, Mora's division algorithm, which relies on a more restricted selection strategy for the divisors to be used, comes to our rescue.

We discuss this in more detail:

First suppose that $>$ is global and let polynomials $g\in K[x]$ and $f_1, \dots, f_r\in K[x]\setminus \{0\}$ be given. In this situation, multivariate division with remainder allows us to compute expressions

\[g = q_1f_1+\dots q_rf_r + h, \; h\in K[x], \;\text{ all }\; q_i \in K[x]\]

such that:

  • $\text{LM}_>(g) \ge \text{LM}_>(q_if_i)$ whenever both sides are nonzero.
  • If $h$ is nonzero, then $\text{LM}_>(h)$ is not divisible by any $\text{LM}_>(f_i)$.

Each such expression is called a standard representation for $g$ with quotients $q_i$ and remainder $h$ (on division by the $f_i$, with respect to $>$). If, at each step of the division process, we allow to remove some term of the current dividend instead of just focusing on its leading term, then the algorithm will return a standard expression in which the remainder is fully reduced. That is, $h$ satisfies the stronger condition below:

  • If $h$ is nonzero, then no term of $h$ is divisible by any $\text{LM}_>(f_i)$.

Without restrictions on $>$, let elements $g\in K[x]_>$ and $f_1, \dots, f_r\in K[x]\setminus \{0\}$ be given. In this situation, Mora division with remainder allows us to compute expressions

\[ug = q_1f_1+\dots q_rf_r + h, \; h\in K[x]_>, \;\text{ all }\; q_i \in K[x]_>\]

such that:

  • $u$ is a unit of $K[x]_>$, that is, $\text{LM}_>(u)=1$.
  • $\text{LM}_>(g) \ge \text{LM}_>(q_if_i)$ whenever both sides are nonzero.
  • If $h$ is nonzero, then $\text{LM}_>(h)$ is not divisible by any $\text{LM}_>(f_i)$.

Each such expression is called a weak standard representation for $g$ with quotients $q_i$ and remainder $h$ (on division by the $f_i$, with respect to $>$). If $g\in K[x]$, we speak of a polynomial weak standard representation if $u$ and the $q_i$ are elements of $K[x].$ Using power series expansions, it makes still sense to speak of fully reduced remainders. However, even if we start from polynomial data, such remainders may not be computable (in finitely many steps).

Note

Given a monomial ordering $>$ on a free $K[x]$-module $F = K[x]^p$ with basis $e_1, \dots, e_p$, the above notation and the division algorithms extend naturally to $K[x]^p$ and $K[x]_>^p$, respectively.

The OSCAR functions discussed below compute standard representations and polynomial weak standard representations, respectively. In the global case, they always return fully reduced remainders.

reduceMethod
reduce(g::T, F::Vector{T}; 
-       ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem

If ordering is global, return the remainder in a standard representation for g on division by the polynomials in F with respect to ordering. Otherwise, return the remainder in a weak standard representation for g on division by the polynomials in F with respect to ordering.

reduce(G::Vector{T}, F::Vector{T};
-       ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem

Return a Vector which contains, for each element g of G, a remainder as above.

Note

In the global case, the returned remainders are fully reduced.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> reduce(y^3, [x^2, x*y-y^3])
-x*y
-
-julia> reduce(y^3, [x^2, x*y-y^3], ordering = lex(R))
-y^3
julia> R, (z, y, x) = polynomial_ring(QQ, ["z", "y", "x"]);
-
-julia> f1 = y-x^2; f2 = z-x^3;
-
-julia> g = x^3*y-3*y^2*z^2+x*y*z;
-
-julia> reduce(g, [f1, f2], ordering = lex(R))
--3*x^10 + x^6 + x^5
source
reduce_with_quotientsMethod
reduce_with_quotients(g::T, F::Vector{T}; 
-       ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem

If ordering is global, return the quotients and the remainder in a standard representation for g on division by the polynomials in F with respect to ordering. Otherwise, return the quotients and the remainder in a weak standard representation for g on division by the polynomials in F with respect to ordering.

reduce_with_quotients(G::Vector{T}, F::Vector{T}; 
-       ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem

Return a Vector which contains, for each element g of G, quotients and a remainder as above.

Note

In the global case, the returned remainders are fully reduced.

Examples

julia> R, (z, y, x) = polynomial_ring(QQ, ["z", "y", "x"]);
-
-julia> f1 = y-x^2; f2 = z-x^3;
-
-julia> g = x^3*y-3*y^2*z^2+x*y*z;
-
-julia> Q, h = reduce_with_quotients(g, [f1, f2], ordering = lex(R));
-
-julia> Q
-[-3*y*x^6 - 3*x^8 + x^4 + x^3   -3*z*y^2 - 3*y^2*x^3 + y*x]
-
-julia> h
--3*x^10 + x^6 + x^5
-
-julia> g == Q[1]*f1+Q[2]*f2+h
-true
-
-julia> G = [g, x*y^3-3*x^2*y^2*z^2];
-
-julia> Q, H = reduce_with_quotients(G, [f1, f2], ordering = lex(R));
-
-julia> Q
-[          -3*y*x^6 - 3*x^8 + x^4 + x^3   -3*z*y^2 - 3*y^2*x^3 + y*x]
-[y^2*x - 3*y*x^8 + y*x^3 - 3*x^10 + x^5     -3*z*y^2*x^2 - 3*y^2*x^5]
-
-julia> H
-2-element Vector{QQMPolyRingElem}:
- -3*x^10 + x^6 + x^5
- -3*x^12 + x^7
-
-julia> G == Q*[f1, f2]+H
-true
source
reduce_with_quotients_and_unitMethod
reduce_with_quotients_and_unit(g::T, F::Vector{T};
-       ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem

Return the unit, the quotients and the remainder in a weak standard representation for g on division by the polynomials in F with respect to ordering.

reduce_with_quotients_and_unit(G::Vector{T}, F::Vector{T};
-       ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem

Return a Vector which contains, for each element g of G, a unit, quotients, and a remainder as above.

Note

In the global case, a standard representation with a fully reduced remainder is computed.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> f1 = x^2+x^2*y; f2 = y^3+x*y*z; f3 = x^3*y^2+z^4;
-
-julia> g = x^3*y+x^5+x^2*y^2*z^2+z^6;
-
-julia> u, Q, h = reduce_with_quotients_and_unit(g, [f1,f2, f3], ordering = negdegrevlex(R))
-([y+1], [x^3-x*y^2*z^2+x*y+y^2*z^2 0 y*z^2+z^2], 0)
-
-julia> u*g == Q[1]*f1+Q[2]*f2+Q[3]*f3+h
-true
-
-julia> G = [g, x*y^3-3*x^2*y^2*z^2];
-
-julia> U, Q,  H = reduce_with_quotients_and_unit(G, [f1, f2, f3], ordering = lex(R));
-
-julia> U
-[1   0]
-[0   1]
-
-julia> H
-2-element Vector{QQMPolyRingElem}:
- -z^9 + z^7 + z^6 + z^4
- -3*z^7 + z^6
-
-julia> U*G == Q*[f1, f2, f3]+H
-true
source

Computing Gröbner/Standard Bases

Still keeping the notation introduced at the beginning of this section, let $G$ be a subset of $K[x]_>$. Then the leading ideal of $G$ is the ideal of $K[x]$ defined by

\[\text{L}_>(G)=\langle \text{LT}_>(g) \mid g\in G\setminus\{0\}\rangle\subset K[x].\]

A finite subset $G$ of an ideal $I\subset K[x]_>$ is called a standard basis of $I$ (with respect to $>$) if $\text{L}_>(G) = \text{L}_>(I)$. A finite subset of $K[x]_>$ is a standard basis if it is a standard basis of the ideal it generates. A standard basis with respect to a global monomial ordering is also called a Gröbner basis.

Note

Every standard basis of $I$ generates $I$.

Note

Gröbner bases (standard bases) can be computed using Buchberger's algorithm (Buchberger's algorithm as enhanced by Mora).

We call a standard basis $G = \{g_1,\dots, g_r\}\subset K[x]_>\setminus \{0\}$ minimal if $\text{LM}_>(g_i)\neq \text{LM}_>(g_j)$ for $i\neq j$.

Note

The definition of minimal above deviates from the definition in most textbooks as we do not ask that the leading coefficients of the standard basis elements are 1.

Note

The standard bases returned by OSCAR are always minimal in the sense above.

We call a standard basis $G = \{g_1,\dots, g_r\}$ with respect to a global monomial ordering reduced if it is minimal and no term of $g_i$ is divisible by $\text{LM}_>(g_j)$, for $i\neq j$. Using power series expansions, we may extend this notion to local and mixed orderings. However, while reduced standard bases can be computed in the global case, they may not be computable (in finitely many steps) in the other cases.

Note

Given a monomial ordering $>$ on a free $K[x]$-module $F = K[x]^p$ with basis $e_1, \dots, e_p$, the above notation and results extend naturally to submodules of $K[x]_>^p$.

Here are the relevant OSCAR functions for computing Gröbner and standard bases. The elements of a computed basis can be retrieved by using the elements function or its alias gens.

groebner_basisMethod
groebner_basis(I::MPolyIdeal;
-  ordering::MonomialOrdering = default_ordering(base_ring(I)),
-  complete_reduction::Bool = false, algorithm::Symbol = :buchberger)

If ordering is global, return a Gröbner basis of I with respect to ordering.

The keyword algorithm can be set to

  • :buchberger (implementation of Buchberger's algorithm in Singular),
  • :hilbert (implementation of a Hilbert driven Gröbner basis computation in Singular),
  • :fglm (implementation of the FGLM algorithm in Singular), and
  • :f4 (implementation of Faugère's F4 algorithm in the msolve package).
Note

See the description of the functions groebner_basis_hilbert_driven, fglm, and f4 in the OSCAR documentation for some more details and for restrictions on the input data when using these versions of the standard basis algorithm.

Note

The returned Gröbner basis is reduced if complete_reduction = true.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> I = ideal(R, [y-x^2, z-x^3]);
-
-julia> G = groebner_basis(I)
-Gröbner basis with elements
-1 -> y^2 - x*z
-2 -> x*y - z
-3 -> x^2 - y
-with respect to the ordering
-degrevlex([x, y, z])
-
-julia> elements(G)
-3-element Vector{QQMPolyRingElem}:
- -x*z + y^2
- x*y - z
- x^2 - y
-
-julia> elements(G) == gens(G)
-true
-
-julia> groebner_basis(I, ordering = lex(R))
-Gröbner basis with elements
-1 -> y^3 - z^2
-2 -> x*z - y^2
-3 -> x*y - z
-4 -> x^2 - y
-with respect to the ordering
-lex([x, y, z])
julia> R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"], [1, 3]);
-
-julia> I = ideal(R, [x*y-3*x^4,y^3-2*x^6*y]);
-
-julia> groebner_basis(I)
-Gröbner basis with elements
-1 -> 3*x^4 - x*y
-2 -> 2*x^3*y^2 - 3*y^3
-3 -> x*y^3
-4 -> y^4
-with respect to the ordering
-wdegrevlex([x, y], [1, 3])
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> V = [3*x^3*y+x^3+x*y^3+y^2*z^2, 2*x^3*z-x*y-x*z^3-y^4-z^2,
-               2*x^2*y*z-2*x*y^2+x*z^2-y^4];
-
-julia> I = ideal(R, V);
-
-julia> G = groebner_basis(I, ordering = lex(R), algorithm = :fglm);
-
-julia> length(G)
-8
-
-julia> total_degree(G[8])
-34
-
-julia> leading_coefficient(G[8])
--91230304237130414552564280286681870842473427917231798336639893796481988733936505735341479640589040146625319419037353645834346047404145021391726185993823650399589880820226804328750
source
standard_basisMethod
standard_basis(I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(base_ring(I)),
-               complete_reduction::Bool = false, algorithm::Symbol = :buchberger)

Return a standard basis of I with respect to ordering.

The keyword algorithm can be set to

  • :buchberger (implementation of Buchberger's algorithm in Singular),
  • :hilbert (implementation of a Hilbert driven Gröbner basis computation in Singular),
  • :fglm (implementation of the FGLM algorithm in Singular), and
  • :f4 (implementation of Faugère's F4 algorithm in the msolve package).
Note

See the description of the functions groebner_basis_hilbert_driven, fglm, and f4 in the OSCAR documentation for some more details and for restrictions on the input data when using these versions of the standard basis algorithm.

Note

The returned standard basis is reduced if ordering is global and complete_reduction = true.

Examples

julia> R,(x,y) = polynomial_ring(QQ, ["x","y"]);
-
-julia> I = ideal([x*(x+1), x^2-y^2+(x-2)*y]);
-
-julia> standard_basis(I, ordering = negdegrevlex(R))
-Standard basis with elements
-1 -> x
-2 -> y
-with respect to the ordering
-negdegrevlex([x, y])
source

Gröbner Bases with transformation matrix

groebner_basis_with_transformation_matrixMethod
groebner_basis_with_transformation_matrix(I::MPolyIdeal;
-  ordering::MonomialOrdering = default_ordering(base_ring(I)),
-  complete_reduction::Bool=false)

Return a pair G, T, say, where G is a Gröbner basis of I with respect to ordering, and T is a transformation matrix from gens(I) to G. That is, gens(I)*T == G.

Note

The returned Gröbner basis is reduced if complete_reduction = true.

Examples

julia> R,(x,y) = polynomial_ring(QQ,["x","y"]);
-
-julia> I = ideal([x*y^2-1,x^3+y^2+x*y]);
-
-julia> G, T = groebner_basis_with_transformation_matrix(I)
-(Gröbner basis with elements
-1 -> x*y^2 - 1
-2 -> x^3 + x*y + y^2
-3 -> y^4 + x^2 + y
-with respect to the ordering
-degrevlex([x, y]), [1 0 -x^2-y; 0 1 y^2])
-
-julia> gens(I)*T == gens(G)
-true
source
standard_basis_with_transformation_matrixMethod
standard_basis_with_transformation_matrix(I::MPolyIdeal;
-  ordering::MonomialOrdering = default_ordering(base_ring(I)),
-  complete_reduction::Bool=false)

Return a pair G, T, say, where G is a standard basis of I with respect to ordering, and T is a transformation matrix from gens(I) to G. That is, gens(I)*T == G.

Note

The returned Gröbner basis is reduced if ordering is a global monomial odering and complete_reduction = true.

Examples

julia> R,(x,y) = polynomial_ring(QQ,["x","y"]);
-
-julia> I = ideal([x*y^2-1,x^3+y^2+x*y]);
-
-julia> G, T = standard_basis_with_transformation_matrix(I, ordering=neglex(R))
-(Standard basis with elements
-1 -> 1 - x*y^2
-with respect to the ordering
-neglex([x, y]), [-1; 0])
-
-julia> gens(I)*T == gens(G)
-true
source

Gröbner Basis Conversion Algorithms

The performance of Buchberger's Gröbner basis algorithm is sensitive to the choice of monomial ordering. A Gröbner basis computation with respect to a less favorable ordering such as lex may easily run out of time or memory even in cases where a Gröbner basis computation with respect to a more efficient ordering such as degrevlex is very well feasible. Gröbner basis conversion algorithms and the Hilbert driven Buchberger algorithm discussed subsequently take their cue from this observation.

Gröbner basis conversion algorithms proceed along the following lines:

  • Given an ideal $I$ of a multivariate polynomial ring over a field and a slow destination_ordering, compute a Gröbner basis for $I$ with respect to an appropriately chosen fast start_ordering.
  • Convert the result to a Gröbner basis with respect to the given slow destination_ordering.

The algorithms differ in how they perform the conversion.

The FGLM Algorithm

fglmMethod
fglm(I::MPolyIdeal; start_ordering::MonomialOrdering = default_ordering(base_ring(I)),
-                    destination_ordering::MonomialOrdering)

Given a zero-dimensional ideal I, return the reduced Gröbner basis of I with respect to destination_ordering.

Note

Both start_ordering and destination_ordering must be global and the base ring of I must be a polynomial ring over a field.

Note

The function implements the Gröbner basis conversion algorithm by Faugère, Gianni, Lazard, and Mora. See J.C. Faugère, P. Gianni, D. Lazard, T. Mora (1993) for more information.

Examples

julia> R, (a, b, c, d, e) = polynomial_ring(QQ, ["a", "b", "c", "d", "e"]);
-
-julia> f1 = a+b+c+d+e;
-
-julia> f2 = a*b+b*c+c*d+a*e+d*e;
-
-julia> f3 = a*b*c+b*c*d+a*b*e+a*d*e+c*d*e;
-
-julia> f4 = b*c*d+a*b*c*e+a*b*d*e+a*c*d*e+b*c*d*e;
-
-julia> f5 = a*b*c*d*e-1;
-
-julia> I = ideal(R, [f1, f2, f3, f4, f5]);
-
-julia> G = fglm(I, destination_ordering = lex(R));
-
-julia> length(G)
-8
-
-julia> total_degree(G[8])
-60
-
-julia> leading_coefficient(G[8])
-83369589588385815165248207597941242098312973356252482872580035860533111990678631297423089011608753348453253671406641805924218003925165995322989635503951507226650115539638517111445927746874479234
source

Gröbner Walk Algorithms

The Hilbert driven Buchberger Algorithm

Calling the functions standard_basis and groebner_basis with algorithm = :hilbert in OSCAR triggers a version of the Hilbert driven Gröbner basis algorithm which proceeds along the following lines.

  1. Given an ideal $I$ of a multivariate polynomial ring $R$ over a field $K$ and a slow destination_ordering, check whether $I$ is homogeneous with respect to the standard $\mathbb Z$-grading on $R$. If so, set start_ordering to degrevlex and go to step 3.

  2. Check whether there exists a $\mathbb Z$-grading on $R$ with positive weights such that $I$ is homogeneous with respect to this grading. If so, let start_ordering be the corresponding weight ordering. If not, go to step 5.

  3. Compute a Gröbner basis of $I$ with respect to start_ordering and use this Gröbner basis to compute the Hilbert function of $R/I$.

  4. Compute a Gröbner basis with respect to destination_ordering, proceeding by increasing (weighted) degree, and skipping all further Buchberger tests in a given (weighted) degree as soon as the leading terms found so far account for the Hilbert function in that (weighted) degree. Return the computed Gröbner basis.

  5. Extend $R$ to a polynomial ring $S$ by appending an extra variable, equip $S$ with the standard $\mathbb Z$-grading, and let $I^{h}\subset S$ be the homogenization of $I$ with respect to the extra variable. Compute a Gröbner basis of $I$ with respect to degrevlex on R, and homogenize its elements to obtain a Gröbner basis of $I^{h}$ with respect to degrevlex on $S$. Use the latter basis to compute the Hilbert function of $S/I^{h}$. Extend destination_ordering to a block ordering on S. Following the recipe in step 4, compute a Gröbner basis of $S/I^{h}$ with respect to the extended ordering. Return the dehomogenization of this basis with respect to the extra variable.

If the characteristic of $K$ is zero, by semi-continuity of the Hilbert function, it is sufficient to perform step 3 for the reduction of $I$ modulo a conveniently chosen prime number rather than for $I$ itself.

Note

If appropriate weights and/or the Hilbert function with respect to appropriate weights are already known to the user, this information can be entered when calling the Hilbert driven Gröbner basis algorithm as follows:

groebner_basis_hilbert_drivenMethod
groebner_basis_hilbert_driven(I::MPolyIdeal{P}; destination_ordering::MonomialOrdering,
-                complete_reduction::Bool = false,
-                weights::Vector{Int} = ones(Int, ngens(base_ring(I))),
-                hilbert_numerator::Union{Nothing, ZZPolyRingElem} = nothing) 
-                where {P <: MPolyRingElem}

Return a Gröbner basis of I with respect to destination_ordering.

Note

The function implements a version of the Hilbert driven Gröbner basis algorithm. See the corresponding section of the OSCAR documentation for some details.

Note

All weights must be positive. If no weight vector is entered by the user, all weights are set to 1. An error is thrown if the generators of I are not homogeneous with respect to the corresponding (weighted) degree.

Note

If $R$ denotes the parent ring of $I$, and $p, q\in\mathbb Z[t]$ are polynomials such that $p/q$ represents the Hilbert series of $R/I$ as a rational function with denominator $q = (1-t^{w_1})\cdots (1-t^{w_n}),$ where $n$ is the number of variables of $R$, and $w_1, \dots, w_n$ are the assigned weights, then hilbert_numerator is meant to be $p$. If this numerator is not entered by the user, it will be computed internally.

Examples

julia> R, (a, b, c, d, e, f, g) = polynomial_ring(QQ, ["a", "b", "c", "d", "e", "f", "g"]);
-
-julia> V = [-3*a^2+2*f*b+3*f*d, (3*g*b+3*g*e)*a-3*f*c*b,
-                      -3*g^2*a^2-c*b^2*a-g^2*f*e-g^4, e*a-f*b-d*c];
-
-julia> I = ideal(R, V);
-
-julia> o = degrevlex([a, b, c])*degrevlex([d, e, f, g]);
-
-julia> G = groebner_basis_hilbert_driven(I, destination_ordering = o);
-
-julia> length(G)
-296
-
-julia> total_degree(G[49])
-30
julia> R, (x, y, z) = polynomial_ring(GF(32003), ["x", "y", "z"]);
-
-julia> f1 = x^2*y+169*y^21+151*x*y*z^10;
-
-julia> f2 = 6*x^2*y^4+x*z^14+3*z^24;
-
-julia> f3 = 11*x^3+5*x*y^10*z^10+2*y^20*z^10+y^10*z^20;
-
-julia> I = ideal(R, [f1, f2,f3]);
-
-julia> W = [10, 1, 1];
-
-julia> GB = groebner_basis_hilbert_driven(I, destination_ordering = lex(R), weights = W);
-
-julia> length(GB)
-40
julia> R, (x, y, z) = polynomial_ring(GF(32003), ["x", "y", "z"]);
-
-julia> f1 = x^2*y+169*y^21+151*x*y*z^10;
-
-julia> f2 = 6*x^2*y^4+x*z^14+3*z^24;
-
-julia> f3 = 11*x^3+5*x*y^10*z^10+2*y^20*z^10+y^10*z^20;
-
-julia> I = ideal(R, [f1, f2,f3]);
-
-julia> W = [10, 1, 1];
-
-julia> S, t = polynomial_ring(ZZ, "t")
-(Univariate polynomial ring in t over ZZ, t)
-
-julia> hn = -t^75 + t^54 + t^51 + t^45 - t^30 - t^24 - t^21 + 1
--t^75 + t^54 + t^51 + t^45 - t^30 - t^24 - t^21 + 1
-
-julia> GB = groebner_basis_hilbert_driven(I, destination_ordering = lex(R), weights = W, hilbert_numerator = hn);
-
-julia> length(GB)
-40
source

Faugère's F4 Algorithm

Expert function for computing Gröbner bases

With many adjustable keyword arguments, the following function provides low-level implementations of various versions of the Gröbner basis algorithm. Use these functions only if you know what you are doing.

groebner_basis_f4Method
groebner_basis_f4(I::MPolyIdeal, <keyword arguments>)

Compute a Gröbner basis of I with respect to degrevlex using Faugère's F4 algorithm. See Jean-Charles Faugère (1999) for more information.

Note

At current state only prime fields of characteristic 0 < p < 2^{31} are supported.

Possible keyword arguments

  • initial_hts::Int=17: initial hash table size log_2.
  • nr_thrds::Int=1: number of threads for parallel linear algebra.
  • max_nr_pairs::Int=0: maximal number of pairs per matrix, only bounded by minimal degree if 0.
  • la_option::Int=2: linear algebra option: exact sparse-dense (1), exact sparse (2, default), probabilistic sparse-dense (42), probabilistic sparse(44).
  • eliminate::Int=0: size of first block of variables to be eliminated.
  • complete_reduction::Bool=true: compute a reduced Gröbner basis for I
  • info_level::Int=0: info level printout: off (0, default), summary (1), detailed (2).

Examples

julia> R,(x,y,z) = polynomial_ring(GF(101), ["x","y","z"], ordering=:degrevlex)
-(Multivariate polynomial ring in 3 variables over GF(101), fpMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x+2*y+2*z-1, x^2+2*y^2+2*z^2-x, 2*x*y+2*y*z-y])
-ideal(x + 2*y + 2*z + 100, x^2 + 2*y^2 + 2*z^2 + 100*x, 2*x*y + 2*y*z + 100*y)
-
-julia> groebner_basis_f4(I)
-Gröbner basis with elements
-1 -> x + 2*y + 2*z + 100
-2 -> y*z + 82*z^2 + 10*y + 40*z
-3 -> y^2 + 60*z^2 + 20*y + 81*z
-4 -> z^3 + 28*z^2 + 64*y + 13*z
-with respect to the ordering
-degrevlex([x, y, z])
source

Leading Ideals

leading_idealMethod
leading_ideal(G::Vector{T}; ordering::MonomialOrdering = default_ordering(parent(G[1]))) 
-                            where T <: MPolyRingElem

Return the leading ideal of G with respect to ordering.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> L = leading_ideal([x*y^2-3*x, x^3-14*y^5], ordering=degrevlex(R))
-ideal(x*y^2, y^5)
-
-julia> L = leading_ideal([x*y^2-3*x, x^3-14*y^5], ordering=lex(R))
-ideal(x*y^2, x^3)
source
leading_idealMethod
leading_ideal(I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(base_ring(I)))

Return the leading ideal of I with respect to ordering.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R,[x*y^2-3*x, x^3-14*y^5])
-ideal(x*y^2 - 3*x, x^3 - 14*y^5)
-
-julia> L = leading_ideal(I, ordering=degrevlex(R))
-ideal(x*y^2, x^4, y^5)
-
-julia> L = leading_ideal(I, ordering=lex(R))
-ideal(y^7, x*y^2, x^3)
source

Normal Forms

Given a polynomial $g\in K[x]$, an ideal $I\subset K[x]$, and a global monomial ordering $>$ on the monomials in $x$, the fully reduced remainder $h$ in a standard expression on division by the elements of a Gröbner basis of $I$ with respect to $>$ is uniquely determined by $g$, $I$, and $>$ (and does not depend on the choice of Gröbner basis). We refer to such a remainder as the normal form of $g$ mod $I$, with respect to $>$.

normal_formMethod
normal_form(g::T, I::MPolyIdeal; 
-  ordering::MonomialOrdering = default_ordering(base_ring(I))) where T <: MPolyRingElem

Compute the normal form of g mod I with respect to ordering.

normal_form(G::Vector{T}, I::MPolyIdeal; 
-  ordering::MonomialOrdering = default_ordering(base_ring(I))) where T <: MPolyRingElem

Return a Vector which contains for each element g of G a normal form as above.

Examples

julia> R,(a,b,c) = polynomial_ring(QQ,["a","b","c"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[a, b, c])
-
-julia> J = ideal(R,[-1+c+b,-1+b+c*a+2*a*b])
-ideal(b + c - 1, 2*a*b + a*c + b - 1)
-
-julia> gens(groebner_basis(J))
-2-element Vector{QQMPolyRingElem}:
- b + c - 1
- a*c - 2*a + c
-
-julia> normal_form(-1+c+b+a^3, J)
-a^3
-
-julia> R,(a,b,c) = polynomial_ring(QQ,["a","b","c"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[a, b, c])
-
-julia> A = [-1+c+b+a^3,-1+b+c*a+2*a^3,5+c*b+c^2*a]
-3-element Vector{QQMPolyRingElem}:
- a^3 + b + c - 1
- 2*a^3 + a*c + b - 1
- a*c^2 + b*c + 5
-
-julia> J = ideal(R,[-1+c+b,-1+b+c*a+2*a*b])
-ideal(b + c - 1, 2*a*b + a*c + b - 1)
-
-julia> gens(groebner_basis(J))
-2-element Vector{QQMPolyRingElem}:
- b + c - 1
- a*c - 2*a + c
-
-julia> normal_form(A, J)
-3-element Vector{QQMPolyRingElem}:
- a^3
- 2*a^3 + 2*a - 2*c
- 4*a - 2*c^2 - c + 5
source

Syzygies

We refer to the section on modules for more on syzygies.

syzygy_generatorsMethod
syzygy_generators(G::Vector{<:MPolyRingElem})

Return generators for the syzygies on the polynomials given as elements of G.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> S = syzygy_generators([x^3+y+2,x*y^2-13*x^2,y-14])
-3-element Vector{FreeModElem{QQMPolyRingElem}}:
- (-y + 14)*e[2] + (-13*x^2 + x*y^2)*e[3]
- (-169*y + 2366)*e[1] + (-13*x*y + 182*x - 196*y + 2744)*e[2] + (13*x^2*y^2 - 2548*x^2 + 196*x*y^2 + 169*y + 338)*e[3]
- (-13*x^2 + 196*x)*e[1] + (-x^3 - 16)*e[2] + (x^4*y + 14*x^4 + 13*x^2 + 16*x*y + 28*x)*e[3]
source
diff --git a/previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html b/previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html deleted file mode 100644 index eb6e0b824db3..000000000000 --- a/previews/PR2578/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html +++ /dev/null @@ -1,22 +0,0 @@ - -Gröbner/Standard Bases Over mathbb Z · Oscar.jl

Gröbner/Standard Bases Over $\mathbb Z$

In this section, we consider a polynomial ring $\mathbb Z[x] = \mathbb Z[x_1, \dots, x_n]$ over the integers. As in the previous section on Gröbner/standard bases over fields, let $>$ be a monomial ordering on $\text{Mon}_n(x)$. With respect to this ordering, the localization $\mathbb Z[x]_>$ and, given a nonzero element $f \in \mathbb Z[x]_>$, the notions leading term, leading monomial, leading exponent, leading coefficient, and tail of $f$ are defined as before.

Note

Over $\mathbb Z$, the basic idea of multivariate polynomial division with remainder in OSCAR is as follows: If $ax^\alpha$ is the leading term of the intermediate dividend, $f_i$ is some divisor whose leading monomial equals $x^\alpha$, say $\text{LT}(f_i) = bx^\alpha$, and $r$ is the remainder of $a$ on division by $b$ in $\mathbb Z$, then $ax^\alpha$ is replaced by $rx^\alpha$.

Examples
julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]);
-
-julia> reduce(3*x, [2*x])
-x
-
-julia> reduce(6*x, [5*x, 2*x])
-0

The notion of leading ideals as formulated in the previous section and the definitions of standard bases (Gröbner bases) carry over: A standard basis for an ideal $I\subset K[x]_>$ with respect to $>$ is a finite subset $G$ of $I$ such that $\text{L}_>(G) = \text{L}_>(I)$ (a standard basis with respect to a global monomial ordering is also called a Gröbner basis).

There is, however, a sublety: Over a field, the defining condition of a standard basis as stated above is equivalent to saying that the $\text{LT}_>(g)$, $g\in G\setminus\{0\}$ generate $\text{L}_>(I)$. Over $\mathbb Z$, the latter condition implies the former one, but not vice versa. Consequently, over $\mathbb Z$, a finite subset $G$ of $I$ satisfying the latter condition is called a strong standard basis for $I$ (with respect to $>$).

We refer to the textbook William W. Adams, Philippe Loustaunau (1994) for more on this.

Note

Over $\mathbb Z$, the standard bases returned by OSCAR are strong in the sense above.

Examples
julia> R, (x,y) = polynomial_ring(ZZ, ["x","y"])
-(Multivariate polynomial ring in 2 variables over ZZ, ZZMPolyRingElem[x, y])
-
-julia> I = ideal(R, [3*x^2*y+7*y, 4*x*y^2-5*x])
-ideal(3*x^2*y + 7*y, 4*x*y^2 - 5*x)
-
-julia> G = groebner_basis(I, ordering = lex(R))
-Gröbner basis with elements
-1 -> 28*y^3 - 35*y
-2 -> 4*x*y^2 - 5*x
-3 -> 15*x^2 + 28*y^2
-4 -> 3*x^2*y + 7*y
-5 -> x^2*y^2 - 5*x^2 - 7*y^2
-with respect to the ordering
-lex([x, y])
diff --git a/previews/PR2578/CommutativeAlgebra/GroebnerBases/orderings/index.html b/previews/PR2578/CommutativeAlgebra/GroebnerBases/orderings/index.html deleted file mode 100644 index b1d1014d085e..000000000000 --- a/previews/PR2578/CommutativeAlgebra/GroebnerBases/orderings/index.html +++ /dev/null @@ -1,443 +0,0 @@ - -Monomial Orderings · Oscar.jl

Monomial Orderings

Given a coefficient ring $C$ as in the previous section, let $C[x]=C[x_1, \ldots, x_n]$ be the polynomial ring over $C$ in the set of variables $x=\{x_1, \ldots, x_n\}$. Monomials in $x=\{x_1, \ldots, x_n\}$ are written using multi–indices: If $\alpha=(\alpha_1, \ldots, \alpha_n)\in \N^n$, set $x^\alpha=x_1^{\alpha_1}\cdots x_n^{\alpha_n}$ and

\[\text{Mon}_n(x) := \text{Mon}(x_1, \ldots, x_n) := \{x^\alpha \mid \alpha \in \N^n\}.\]

A monomial ordering on $\text{Mon}_n(x)$ is a total ordering $>$ on $\text{Mon}_n(x)$ such that

\[x^\alpha > x^\beta \Longrightarrow x^\gamma x^\alpha > x^\gamma x^\beta, -\; \text{ for all }\; \alpha, \beta, \gamma \in \mathbb N^n.\]

A monomial ordering $>$ on $\text{Mon}_n(x)$ is called

  • global if $x^\alpha > 1$ for all $\alpha \not = (0, \dots, 0)$,
  • local if $x^\alpha < 1$ for all $\alpha \not = (0, \dots, 0)$, and
  • mixed if it is neither global nor local.
Note
  • A monomial ordering on $\text{Mon}_n(x)$ is global iff it is a well-ordering.
  • To give a monomial ordering on $\text{Mon}_n(x)$ means to give a total ordering $>$ on $ \N^n$ such that $\alpha > \beta$ implies $ \gamma + \alpha > \gamma + \beta$ for all $\alpha , \beta, \gamma \in \N^n.$ Rather than speaking of a monomial ordering on $\text{Mon}_n(x)$, we may, thus, also speak of a (global, local, mixed) monomial ordering on $\N^n$.
Note

By a result of Robbiano, every monomial ordering can be realized as a matrix ordering.

Note

The lexicograpical monomial ordering specifies the default way of storing and displaying multivariate polynomials in OSCAR (terms are sorted in descending order). The other orderings which can be attached to a multivariate polynomial ring are the degree lexicographical ordering and the degree reverse lexicographical ordering. Independently of the attached orderings, Gröbner bases can be computed with respect to any monomial ordering. See the section on Gröbner bases.

In this section, we show how to create monomial orderings in OSCAR.

Note

For the convenient construction of block orderings on the set of monomials in the variables of a given multivariate polynomial ring, we allow to construct orderings on the monomials in blocks of variables, viewing these orderings as partial orderings on the monomials in all variables.

Here are some illustrating examples:

Examples
julia> S, (w, x) = polynomial_ring(QQ, ["w", "x"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[w, x])
-
-julia> o = lex([w, x])
-lex([w, x])
-
-julia> canonical_matrix(o)
-[1   0]
-[0   1]
-
-julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = degrevlex([w, x])
-degrevlex([w, x])
-
-julia> is_global(o1)
-true
-
-julia> canonical_matrix(o1)
-[1    1   0   0]
-[0   -1   0   0]
-
-julia> o2 = neglex([y, z])
-neglex([y, z])
-
-julia> is_local(o2)
-true
-
-julia> canonical_matrix(o2)
-[0   0   -1    0]
-[0   0    0   -1]
-
-julia> o3 = o1*o2
-degrevlex([w, x])*neglex([y, z])
-
-julia> canonical_matrix(o3)
-[1    1    0    0]
-[0   -1    0    0]
-[0    0   -1    0]
-[0    0    0   -1]
-
-julia> is_mixed(o3)
-true

Monomial Comparisons

The cmp function should be used for comparing two monomials with regard to a monomial ordering.

cmpMethod
cmp(ord::MonomialOrdering, a::MPolyRingElem, b::MPolyRingElem)
-
-cmp(ord::ModuleOrdering, a::FreeModElem{T}, b::FreeModElem{T}) where T <: MPolyRingElem

Compare monomials a and b with regard to the ordering ord: Return -1 for a < b and 1 for a > b and 0 for a == b. An error is thrown if ord is a partial ordering that does not distinguish a from b.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> cmp(lex([x,y]), x, one(R))
-1
-
-julia> try cmp(lex([x,y]), z, one(R)); catch e; e; end
-ErrorException("z and 1 are incomparable with respect to lex([x, y])")
-
-julia> cmp(lex([x,y,z]), z, one(R))
-1
-
-julia> F = free_module(R, 2)
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> cmp(lex(R)*revlex(F), F[1], F[2])
--1
source

Matrix Orderings

Given a matrix $M\in \text{Mat}(k\times n,\mathbb R)$ of rank $n$, with rows $m_1,\dots,m_k$, the matrix ordering defined by $M$ is obtained by setting

\[x^\alpha>_M x^\beta \Leftrightarrow \;\exists\; 1\leq i\leq k: m_1\alpha=m_1\beta,\ldots, -m_{i-1}\alpha\ =m_{i-1}\beta,\ m_i\alpha>m_i\beta\]

(here, $\alpha$ and $\beta$ are regarded as column vectors).

Note

By a theorem of Robbiano, every monomial ordering arises as a matrix ordering as above with $M\in \text{GL}(n,\mathbb R)$.

Note

To create matrix orderings, OSCAR allows for matrices with integer coefficients as input matrices.

Note

For orderings such as lex and degrevlex which are predefined in OSCAR, using the predefined version is much faster than using a representation as a matrix ordering.

matrix_orderingMethod
matrix_ordering(R::MPolyRing, M::Union{Matrix{T}, MatElem{T}}; check::Bool = true) where T -> MonomialOrdering

Given an integer matrix M such that nvars(R) = ncols(M) = rank(M), return the matrix ordering on the set of variables of R which is defined by M.

matrix_ordering(V::AbstractVector{<:MPolyRingElem}, M::Union{Matrix{T}, MatElem{T}}; check::Bool = true) where T -> MonomialOrdering

Given a vector V of variables and an integer matrix M such that length(V) = ncols(M) = rank(M), return the matrix ordering on the set of monomials in the given variables which is defined by M.

Note

The matrix M need not be square.

Note

If check = false is supplied, the rank check is omitted, and the resulting ordering may only be partial.

Examples

julia> R, (w, x, y, z) = QQ["w", "x", "y", "z"];
-
-julia> M =[1 1 1 1; 0 -1 -1 -1; 0 0 -1 -1; 0 0 0 -1]
-4×4 Matrix{Int64}:
- 1   1   1   1
- 0  -1  -1  -1
- 0   0  -1  -1
- 0   0   0  -1
-
-julia> o1 = matrix_ordering(R, M)
-matrix_ordering([w, x, y, z], [1 1 1 1; 0 -1 -1 -1; 0 0 -1 -1; 0 0 0 -1])
-
-julia> N =[1 1; 0 -1]
-2×2 Matrix{Int64}:
- 1   1
- 0  -1
-
-julia> o2 = matrix_ordering([w, x], N)
-matrix_ordering([w, x], [1 1; 0 -1])
-
-julia> canonical_matrix(o2)
-[1    1   0   0]
-[0   -1   0   0]
-
-julia> o3 = matrix_ordering(gens(R)[3:4], N)
-matrix_ordering([y, z], [1 1; 0 -1])
-
-julia> o3 = matrix_ordering(gens(R)[3:4], N)
-matrix_ordering([y, z], [1 1; 0 -1])
-
-julia> canonical_matrix(o3)
-[0   0   1    1]
-[0   0   0   -1]
source

As already shown above, OSCAR provides functions to recover defining matrices from given monomial orderings:

matrixMethod
matrix(ord::MonomialOrdering)

Return a matrix defining ord as a matrix ordering.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> o1 = degrevlex(R)
-degrevlex([x, y, z])
-
-julia> matrix(o1)
-[ 1    1    1]
-[ 0    0   -1]
-[ 0   -1    0]
-[-1    0    0]
-
-julia> o2 = degrevlex([x, y])
-degrevlex([x, y])
-
-julia> matrix(o2)
-[ 1    1   0]
-[ 0   -1   0]
-[-1    0   0]
source
canonical_matrixMethod
canonical_matrix(ord::MonomialOrdering)

Return the canonical matrix defining ord as a matrix ordering.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> o1 = degrevlex(R)
-degrevlex([x, y, z])
-
-julia> canonical_matrix(o1)
-[1    1    1]
-[0    0   -1]
-[0   -1    0]
-
-julia> o2 = degrevlex([x, y])
-degrevlex([x, y])
-
-julia> canonical_matrix(o2)
-[1    1   0]
-[0   -1   0]
source

Predefined Global Orderings

The Lexicographical Ordering

The lexicographical ordering lex is defined by setting

\[x^\alpha > x^\beta \; \Leftrightarrow \;\exists \; 1 \leq i \leq n: \alpha_1 = \beta_1, \dots, \alpha_{i-1} = \beta_{i-1}, \alpha_i > \beta_i.\]

lexMethod
lex(R::MPolyRing) -> MonomialOrdering

Return the lexicographical ordering on the set of monomials in the variables of R.

lex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the lexicographical ordering on the set of monomials in these variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = lex(R)
-lex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[1   0   0   0]
-[0   1   0   0]
-[0   0   1   0]
-[0   0   0   1]
-
-julia> o2 = lex([w, x])
-lex([w, x])
-
-julia> o3 = lex(gens(R)[3:4])
-lex([y, z])
source

The Degree Lexicographical Ordering

The degree lexicographical ordering deglex is defined by setting $\;\deg(x^\alpha) = \alpha_1 + \cdots + \alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \deg(x^\alpha) > \deg(x^\beta) \;\text{ or }\; \exists \; 1 \leq i \leq n: \alpha_1 = \beta_1, \dots, \alpha_{i-1} = \beta_{i-1}, \alpha_i > \beta_i.\]

deglexMethod
deglex(R::MPolyRing) -> MonomialOrdering

Return the degree lexicographical ordering on the set of monomials in the variables of R.

deglex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the degree lexicographical ordering on the set of monomials in these variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = deglex(R)
-deglex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[1    1    1    1]
-[0   -1   -1   -1]
-[0    0   -1   -1]
-[0    0    0   -1]
-
-julia> o2 = deglex([w, x])
-deglex([w, x])
-
-julia> o3 = deglex(gens(R)[3:4])
-deglex([y, z])
source

The Reverse Lexicographical Ordering

The reverse lexicographical ordering revlex is defined by setting

\[x^\alpha > x^\beta \; \Leftrightarrow \;\exists \; 1 \leq i \leq n: \alpha_n = \beta_n, \dots, \alpha_{i+1} = \beta_{i+1}, \alpha_i > \beta_i.\]

revlexMethod
revlex(R::MPolyRing) -> MonomialOrdering

Return the reverse lexicographical ordering on the set of monomials in the variables of R.

revlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the reverse lexicographical ordering on the set of monomials in these variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = revlex(R)
-revlex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[0   0   0   1]
-[0   0   1   0]
-[0   1   0   0]
-[1   0   0   0]
-
-julia> o2 = revlex([w, x])
-revlex([w, x])
-
-julia> o3 = revlex(gens(R)[3:4])
-revlex([y, z])
source

The Degree Reverse Lexicographical Ordering

The degree reverse lexicographical ordering degrevlex is defined by setting $\;\deg(x^\alpha) = \alpha_1 + \cdots + \alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \deg(x^\alpha) > \deg(x^\beta) \;\text{ or }\;\exists \; 1 \leq i \leq n: \alpha_n = \beta_n, \dots, \alpha_{i+1} = \beta_{i+1}, \alpha_i < \beta_i.\]

degrevlexMethod
degrevlex(R::MPolyRing) -> MonomialOrdering

Return the degree reverse lexicographical ordering on the set of monomials in the variables of R.

degrevlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the degree reverse lexicographical ordering on the set of monomials in these variables

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = degrevlex(R)
-degrevlex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[1    1    1    1]
-[0    0    0   -1]
-[0    0   -1    0]
-[0   -1    0    0]
-
-julia> o2 = degrevlex([w, x])
-degrevlex([w, x])
-
-julia> o3 = degrevlex(gens(R)[3:4])
-degrevlex([y, z])
source

Weighted Lexicographical Orderings

If W is a vector of positive integers $w_1, \dots, w_n$, the corresponding weighted lexicographical ordering wdeglex(W) is defined by setting $\;\text{wdeg}(x^\alpha) = w_1\alpha_1 + \cdots + w_n\alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \text{wdeg}(x^\alpha) > \text{wdeg}(x^\beta) \;\text{ or }\;\\ -(\text{wdeg}(x^\alpha) = \text{wdeg}(x^\beta) \;\text{ and }\; \exists \; 1 \leq i \leq n: \alpha_1 = \beta_1, \dots, \alpha_{i-1} = \beta_{i-1}, \alpha_i > \beta_i).\]

wdeglexMethod
wdeglex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering

If W is a vector of positive integers, return the corresponding weighted lexicographical ordering on the set of monomials in the variables of R.

wdeglex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering

Given a vector V of variables and a vector W of positive integers, return the corresponding weighted lexicographical ordering on the set of monomials in the given variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = wdeglex(R, [1, 2, 3, 4])
-wdeglex([w, x, y, z], [1, 2, 3, 4])
-
-julia> canonical_matrix(o1)
-[1    2    3    4]
-[0   -2   -3   -4]
-[0    0   -3   -4]
-[0    0    0   -1]
-
-julia> o2 = wdeglex([w, x], [1, 2])
-wdeglex([w, x], [1, 2])
-
-julia> o3 = wdeglex(gens(R)[3:4], [3, 4])
-wdeglex([y, z], [3, 4])
source

Weighted Reverse Lexicographical Orderings

If W is a vector of positive integers $w_1, \dots, w_n$, the corresponding weighted reverse lexicographical ordering wdegrevlex is defined by setting $\;\text{wdeg}(x^\alpha) = w_1\alpha_1 + \cdots + w_n\alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \text{wdeg}(x^\alpha) > \text{wdeg}(x^\beta) \;\text{ or }\;\\ -(\text{wdeg}(x^\alpha) = \text{wdeg}(x^\beta) \;\text{ and }\; \exists \; 1 \leq i \leq n: \alpha_n = \beta_n, \dots, \alpha_{i+1} = \beta_{i+1}, \alpha_i < \beta_i).\]

wdegrevlexMethod
wdegrevlex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering

If W is a vector of positive integers, return the corresponding weighted reverse lexicographical ordering on the set of monomials in the variables of R.

wdegrevlex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering

Given a vector V of variables and a vector W of positive integers, return the corresponding weighted reverse lexicographical ordering on the set of monomials in the given variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = wdegrevlex(R, [1, 2, 3, 4])
-wdegrevlex([w, x, y, z], [1, 2, 3, 4])
-
-julia> canonical_matrix(o1)
-[1    2    3    4]
-[0    0    0   -1]
-[0    0   -1    0]
-[0   -1    0    0]
-
-julia> o2 = wdegrevlex([w, x], [1, 2])
-wdegrevlex([w, x], [1, 2])
-
-julia> o3 = wdegrevlex(gens(R)[3:4], [3, 4])
-wdegrevlex([y, z], [3, 4])
source

Predefined Local Orderings

The Negative Lexicographical Ordering

The negative lexicographical ordering neglex is defined by setting

\[x^\alpha > x^\beta \; \Leftrightarrow \;\exists \; 1 \leq i \leq n: \alpha_1 = \beta_1, \dots, \alpha_{i-1} = \beta_{i-1}, \alpha_i < \beta_i.\]

neglexMethod
neglex(R::MPolyRing) -> MonomialOrdering

Return the negative lexicographical ordering on the set of monomials in the variables of R.

neglex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the negative lexicographical ordering on the set of monomials in these variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = neglex(R)
-neglex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[-1    0    0    0]
-[ 0   -1    0    0]
-[ 0    0   -1    0]
-[ 0    0    0   -1]
-
-julia> o2 = neglex([w, x])
-neglex([w, x])
-
-julia> o3 = neglex(gens(R)[3:4])
-neglex([y, z])
source

The Negative Degree Lexicographical Ordering

The negative degree lexicographical ordering negdeglex is defined by setting $\;\deg(x^\alpha) = \alpha_1 + \cdots + \alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \deg(x^\alpha) < \deg(x^\beta) \;\text{ or }\; \exists \; 1 \leq i \leq n: \alpha_1 = \beta_1, \dots, \alpha_{i-1} = \beta_{i-1}, \alpha_i > \beta_i.\]

negdeglexMethod
negdeglex(R::MPolyRing) -> MonomialOrdering

Return the negative degree lexicographical ordering on the set of monomials in the variables of R.

negdeglex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the negative degree lexicographical ordering on the set of monomials in these variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = negdeglex(R)
-negdeglex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[-1   -1   -1   -1]
-[ 0   -1   -1   -1]
-[ 0    0   -1   -1]
-[ 0    0    0   -1]
-
-julia> o2 = negdeglex([w, x])
-negdeglex([w, x])
-
-julia> o3 = negdeglex(gens(R)[3:4])
-negdeglex([y, z])
source

The Negative Reverse Lexicographical Ordering

The negative reverse lexicographical ordering negrevlex is defined by setting

\[x^\alpha > x^\beta \; \Leftrightarrow \;\exists \; 1 \leq i \leq n: \alpha_n = \beta_n, \dots, \alpha_{i+1} = \beta_{i+1}, \alpha_i < \beta_i.\]

negrevlexMethod
negrevlex(R::MPolyRing) -> MonomialOrdering

Return the negative reverse lexicographical ordering on the set of monomials in the variables of R.

negrevlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the negative reverse lexicographical ordering on the set of monomials in these variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = negrevlex(R)
-negrevlex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[ 0    0    0   -1]
-[ 0    0   -1    0]
-[ 0   -1    0    0]
-[-1    0    0    0]
-
-julia> o2 = negrevlex([w, x])
-negrevlex([w, x])
-
-julia> o3 = negrevlex(gens(R)[3:4])
-negrevlex([y, z])
source

The Negative Degree Reverse Lexicographical Ordering

The negative degree reverse lexicographical ordering negdegrevlex is defined by setting $\;\deg(x^\alpha) = \alpha_1 + \cdots + \alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \deg(x^\alpha) < \deg(x^\beta) \;\text{ or }\;\exists \; 1 \leq i \leq n: \alpha_n = \beta_n, \dots, \alpha_{i+1} = \beta_{i+1}, \alpha_i < \beta_i.\]

negdegrevlexMethod
negdegrevlex(R::MPolyRing) -> MonomialOrdering

Return the negative degree reverse lexicographical ordering on the set of monomials in the variables of R.

negdegrevlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the negative degree reverse lexicographical ordering on the set of monomials in these variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = negdegrevlex(R)
-negdegrevlex([w, x, y, z])
-
-julia> canonical_matrix(o1)
-[-1   -1   -1   -1]
-[ 0    0    0   -1]
-[ 0    0   -1    0]
-[ 0   -1    0    0]
-
-julia> o2 = negdegrevlex([w, x])
-negdegrevlex([w, x])
-
-julia> o3 = negdegrevlex(gens(R)[3:4])
-negdegrevlex([y, z])
source

Negative Weighted Lexicographical Orderings

If W is a vector of positive integers $w_1, \dots, w_n$, the corresponding negative weighted lexicographical ordering negwdeglex(W) is defined by setting $\;\text{wdeg}(x^\alpha) = w_1\alpha_1 + \cdots + w_n\alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \text{wdeg}(x^\alpha) < \text{wdeg}(x^\beta) \;\text{ or }\;\\ -(\text{wdeg}(x^\alpha) = \text{wdeg}(x^\beta) \;\text{ and }\; \exists \; 1 \leq i \leq n: \alpha_1 = \beta_1, \dots, \alpha_{i-1} = \beta_{i-1}, \alpha_i > \beta_i).\]

negwdeglexMethod
negwdeglex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering

If W is a vector of positive integers, return the corresponding negative weighted lexicographical ordering on the set of monomials in the variables of R.

negwdeglex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering

Given a vector V of variables and a vector W of positive integers, return the corresponding negative weighted lexicographical ordering on the set of monomials in the given variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = negwdeglex(R, [1, 2, 3, 4])
-negwdeglex([w, x, y, z], [1, 2, 3, 4])
-
-julia> canonical_matrix(o1)
-[-1   -2   -3   -4]
-[ 0   -2   -3   -4]
-[ 0    0   -3   -4]
-[ 0    0    0   -1]
-
-julia> o2 = negwdeglex([w, x], [1, 2])
-negwdeglex([w, x], [1, 2])
-
-julia> o3 = negwdeglex(gens(R)[3:4], [3, 4])
-negwdeglex([y, z], [3, 4])
source

Negative Weighted Reverse Lexicographical Orderings

If W is a vector of positive integers $w_1, \dots, w_n$, the corresponding negative weighted reverse lexicographical ordering negwdegrevlex(W) is defined by setting $\;\text{wdeg}(x^\alpha) = w_1\alpha_1 + \cdots + w_n\alpha_n\;$ and

\[x^\alpha > x^\beta \; \Leftrightarrow \; \text{wdeg}(x^\alpha) < \text{wdeg}(x^\beta) \;\text{ or }\;\\ -(\text{wdeg}(x^\alpha) = \text{wdeg}(x^\beta) \;\text{ and }\; \exists \; 1 \leq i \leq n: \alpha_n = \beta_n, \dots, \alpha_{i+1} = \beta_{i+1}, \alpha_i < \beta_i).\]

negwdegrevlexMethod
negwdegrevlex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering

If W is a vector of positive integers, return the corresponding negative weighted reverse lexicographical ordering on the set of monomials in the variables of R.

negwdegrevlex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering

Given a vector V of variables and a vector W of positive integers, return the corresponding negative weighted reverse lexicographical ordering on the set of monomials in the given variables.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o1 = negwdegrevlex(R, [1, 2, 3, 4])
-negwdegrevlex([w, x, y, z], [1, 2, 3, 4])
-
-julia> canonical_matrix(o1)
-[-1   -2   -3   -4]
-[ 0    0    0   -1]
-[ 0    0   -1    0]
-[ 0   -1    0    0]
-
-julia> o2 = negwdegrevlex([w, x], [1, 2])
-negwdegrevlex([w, x], [1, 2])
-
-julia> o3 = negwdegrevlex(gens(R)[3:4], [3, 4])
-negwdegrevlex([y, z], [3, 4])
source

Weight Orderings

If $W$ is a vector of integers $w_1, \dots, w_n$, and $>$ is a monomial ordering on $\text{Mon}_n(x)$, then the corresponding weight ordering is defined by setting $\;\text{wdeg}(x^\alpha) = w_1\alpha_1 + \cdots + w_n\alpha_n\;$ and

\[x^\alpha >_{W} x^\beta \; \Leftrightarrow \; \text{wdeg}(x^\alpha) > \text{wdeg}(x^\beta) \;\text{ or }\; -(\text{wdeg}(x^\alpha) = \text{wdeg}(x^\beta) \;\text{ and }\; x^\alpha > x^\beta).\]

weight_orderingMethod
weight_ordering(W::Vector{Int}, ord::MonomialOrdering) -> MonomialOrdering

Given an integer vector W and a monomial ordering ord on a set of monomials in length(W) variables, return the monomial ordering ord_W on this set of monomials which is obtained by first comparing the W-weighted degrees and then using ord in the case of a tie.

Note

The ordering ord_W is

  • global if all entries of W are positive, or if they are all non-negative and ord is global,
  • an elimination ordering for the set of variables which correspond to positive entries of W.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> W = [1, 0, -1];
-
-julia> o = lex(R)
-lex([x, y, z])
-
-julia> matrix(o)
-[1   0   0]
-[0   1   0]
-[0   0   1]
-
-julia> oW = weight_ordering(W, o)
-matrix_ordering([x, y, z], [1 0 -1])*lex([x, y, z])
-
-julia> matrix(oW)
-[1   0   -1]
-[1   0    0]
-[0   1    0]
-[0   0    1]
-
-julia> canonical_matrix(oW)
-[1   0   -1]
-[0   0    1]
-[0   1    0]
-
-julia> o2 = weight_ordering([1, -1], lex([x, z]))
-matrix_ordering([x, z], [1 -1])*lex([x, z])
-
-julia> canonical_matrix(o2)
-[1   0   -1]
-[0   0    1]
source

Block Orderings

The concept of block orderings (product orderings) allows one to construct new monomial orderings from already given ones: If $>_1$ and $>_2$ are monomial orderings on $\text{Mon}_s(x_1, \ldots, x_s)$ and $\text{Mon}_{n-s}(x_{s+1}, \ldots, x_n)$, respectively, then the block ordering $> \; = \; (>_1, >_2)$ on $\text{Mon}_n(x)=\text{Mon}_n(x_1, \ldots, x_n)$ is defined by setting

\[x^\alpha>x^\beta \;\Leftrightarrow\; x_1^{\alpha_1}\cdots x_s^{\alpha_s} >_1 x_1^{\beta_1}\cdots x_s^{\beta_s} \;\text{ or }\; -\bigl(x_1^{\alpha_1}\cdots x_s^{\alpha_s} = x_1^{\beta_1}\cdots x_s^{\beta_s} \text{ and } x_{s+1}^{\alpha_{s+1}}\cdots x_n^{\alpha_n} >_2 -x_{s+1}^{\beta_{s+1}}\cdots x_n^{\beta_n}\bigr).\]

Note

The ordering $(>_1, >_2)$

  • is global (local) iff both $>_1$ and $>_2$ are global (local). Mixed orderings arise by choosing one of $>_1$ and $>_2$ global and the other one local,
  • is an elimination ordering for the first block of variables iff $>_1$ is global.
Note
  • The definition of a block ordering above subdivides $x$ into a block of initial variables and its complementary block of variables. Block orderings for a subdivision of $x$ into any block of variables and its complementary block are defined similarly and have similar properties.
  • Inductively, one obtains block orderings composed of more than two individual orderings.

In OSCAR, block orderings are obtained by the concatenation of individual orderings using the * operator.

Examples
julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])
-
-julia> o = degrevlex([w, x])*degrevlex([y, z])
-degrevlex([w, x])*degrevlex([y, z])
-

Elimination Orderings

Let $C[x]=C[x_1, \ldots, x_n]$ be a multivariate polynomial ring with coefficient ring $C$. Fix a subset $\sigma\subset \{1,\dots, n\}$ and write $x_\sigma$ for the set of variables $x_i$ with $i\in\sigma$. An elimination ordering for $x\smallsetminus x_\sigma$ is a monomial ordering $>$ on $\text{Mon}_n(x)$ which satisfies the following property: If $a$ is a monomial involving one of the variables in $x\smallsetminus x_\sigma$ , and $b$ is a monomial depending only on the variables in $x_\sigma$, then $a > b.$ Computing a Gröbner basis of $I$ with respect to such an ordering provides one way of finding the intersection $I\cap C[x_\sigma]$, that is, of eliminating the variables in $x\smallsetminus x_\sigma$ from $I$: The Gröbner basis elements which only depend on the variables in $x_\sigma$ form a Gröbner basis for $I\cap C[x_\sigma]$ with respect to the restriction of $>$ to the set of monomials in $I\cap C[x_\sigma]$.

Note

The lexicographical ordering is an elimination ordering for each initial set of variables $x_1, \dots, x_k$. If only a fixed subset of variables is considered, suitable weight or block orderings as discussed above are more effective. The documentation of the is_elimination_ordering function below offers examples and non-examples.

Tests on Monomial Orderings

is_elimination_orderingMethod
is_elimination_ordering(ord::MonomialOrdering, V::Vector{<:MPolyRingElem})

Given a vector V of polynomials which are variables, return true if ord is an elimination ordering for the variables in V. Return false, otherwise.

is_elimination_ordering(ord::MonomialOrdering, V:Vector{Int})

Given a vector V of indices which specify variables, return true if ord is an elimination ordering for the specified variables. Return false, otherwise.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> o1 = lex(R)
-lex([w, x, y, z])
-
-julia> is_elimination_ordering(o1, [w, x])
-true
-
-julia> o2 = weight_ordering([1, 1, 0, 0], degrevlex(R))
-matrix_ordering([w, x, y, z], [1 1 0 0])*degrevlex([w, x, y, z])
-
-julia> is_elimination_ordering(o2, [w, x])
-true
-
-julia> o3 = weight_ordering([1, -1, 0, 0], degrevlex(R))
-matrix_ordering([w, x, y, z], [1 -1 0 0])*degrevlex([w, x, y, z])
-
-julia> is_elimination_ordering(o3, [w, x])
-false
-
-julia> o4 = degrevlex([w, x])*degrevlex([y, z])
-degrevlex([w, x])*degrevlex([y, z])
-
-julia> is_elimination_ordering(o4, [w, x])
-true
-
-julia> o5 = degrevlex([w, x])*negdegrevlex([y, z])
-degrevlex([w, x])*negdegrevlex([y, z])
-
-julia> is_elimination_ordering(o5, [w, x])
-true
-
-julia> o6 = negdegrevlex([w, x])*negdegrevlex([y, z])
-negdegrevlex([w, x])*negdegrevlex([y, z])
-
-julia> is_elimination_ordering(o6, [w, x])
-false
source
is_globalMethod
is_global(ord::MonomialOrdering)

Return true if ord is global, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> o = matrix_ordering(R, [1 1; 0 -1])
-matrix_ordering([x, y], [1 1; 0 -1])
-
-julia> is_global(o)
-true
source
is_localMethod
is_local(ord::MonomialOrdering)

Return true if ord is local, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> o = matrix_ordering(R, [-1 -1; 0 -1])
-matrix_ordering([x, y], [-1 -1; 0 -1])
-
-julia> is_local(o)
-true
source
is_mixedMethod
is_mixed(ord::MonomialOrdering)

Return true if ord is mixed, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> o = matrix_ordering(R, [1 -1; 0 -1])
-matrix_ordering([x, y], [1 -1; 0 -1])
-
-julia> is_mixed(o)
-true
source

Transferring an ordering from another ring

induceMethod
induce(vars::AbstractVector{<:MPolyRingElem}, ord::ModuleOrdering)

Return the monomial ordering on the variables vars induced by transferring the ordering ord.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> S, (a, b, c) = polynomial_ring(GF(5), ["a", "b", "c"]);
-
-julia> ord = degrevlex([x, y])*neglex([z]);
-
-julia> induce([a, b, c], ord)
-degrevlex([a, b])*neglex([c])
source

Module Orderings

Let $R = C[x]=C[x_1, \ldots, x_n]$ be a multivariate polynomial ring with coefficient ring $C$. Referring to the section on free modules for details, we recall that by a free $R$-module we mean a free module of type $R^p$ , where we think of $R^p$ as a free module with a given basis, namely the basis of standard unit vectors. In what follows, $F$ will denote such free $R$-module, and $\{e_1 ,\dots , e_p\}$ will denote the given basis.

A monomial in $F$, involving the basis element $e_i$, is a monomial in $R$ times $e_i$. A term in $F$ is a monomial in $F$ multiplied by a coefficient $c\in C$. Every nonzero element $f\in F$ can be uniquely expressed as the sum of finitely many nonzero terms involving distinct monomials. These terms (monomials) are called the terms (monomials} of $f$.

A monomial ordering on $F$ is a total ordering $>$ on the set of monomials in $F$ such that if $x^\alpha e_i$ and $x^\beta e_j$ are monomials in $F$, and $x^\gamma$ is a monomial in $R$, then

\[x^\alpha e_i > x^\beta e_j \Longrightarrow x^\gamma x^\alpha e_i > x^\gamma x^\beta e_j.\]

In OSCAR, we require in addition that

\[x^\alpha e_i > x^\beta e_i \;\text{ iff }\; x^\alpha e_j > x^\beta e_j \;\text{ for all }\; i,j.\]

Then $>$ induces a unique monomial ordering on $R$ in the obvious way, and we say that $>$ is global, local, or mixed if the induced ordering on $R$ is global, local, or mixed.

One way of getting a monomial ordering on $F$ is to pick a monomial ordering $>$ on $R$, and extend it to $F$. For instance, setting

\[x^\alpha e_i > x^\beta e_j \iff x^\alpha > x^\beta \;\text{ or }\; (x^\alpha = x^\beta \;\text{ and }\; i > j)\]

gives priority to the monomials in $R$, whereas the ordering defined below gives priority to the components of $F$:

\[x^\alpha e_i > x^\beta e_j \iff i > j \;\text{ or }\; (i = j\;\text{ and } x^\alpha > x^\beta).\]

Alternatively, we may wish to use $i < j$ instead of $i > j$ in this definition.

In other words, these orderings are obtained by concatenating a monomial ordering on the monomials of $R$ with a way of ordering the basis vectors of $F$ or vice versa. In OSCAR, we refer to the $i < j$ ordering on the basis vectors as lex, and to the $i > j$ ordering as revlex. And, we use the * operator for concatenation.

Examples
julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> F = free_module(R, 3)
-Free module of rank 3 over Multivariate polynomial ring in 4 variables over QQ
-
-julia> o1 = degrevlex(R)*revlex(gens(F))
-degrevlex([w, x, y, z])*revlex([gen(1), gen(2), gen(3)])
-
-julia> o2 = revlex(gens(F))*degrevlex(R)
-revlex([gen(1), gen(2), gen(3)])*degrevlex([w, x, y, z])
-

The induced ordering on the given polynomial ring is recovered as follows:

induced_ring_orderingMethod
induced_ring_ordering(ord::ModuleOrdering)

Return the ring ordering induced by ord.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> F = free_module(R, 3)
-Free module of rank 3 over Multivariate polynomial ring in 4 variables over QQ
-
-julia> o = revlex(gens(F))*degrevlex(R)
-revlex([gen(1), gen(2), gen(3)])*degrevlex([w, x, y, z])
-
-julia> induced_ring_ordering(o)
-degrevlex([w, x, y, z])
source

The comparison function cmp as well as the tests is_global, is_local, and is_mixed are also available for module orderings.

diff --git a/previews/PR2578/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html b/previews/PR2578/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html deleted file mode 100644 index 9cdaec088270..000000000000 --- a/previews/PR2578/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html +++ /dev/null @@ -1,106 +0,0 @@ - -Binomial Primary Decomposition · Oscar.jl

Binomial Primary Decomposition

Introduction

A binomial is a polynomial consisting of at most two terms. A binomial ideal is an ideal which can be generated by binomials. A binomial primary decomposition is a primary decomposition of a binomial ideal into primary ideals which are binomial as well. In this section, focusing on polynomial rings over fields, we discuss functionality for computing such decompositions.

We begin by recalling that a proper ideal $I$ of a polynomial ring $K[x_1, \dots, x_n]$ over a field $K$ is called cellular if each variable $x_i$ is either a nonzerodivisor or nilpotent modulo $I$. In this case, we refer to the nonzerodivisors among the variables as the cell variables with respect to $I$. A cellular decomposition of a proper binomial ideal $I$ of $K[x_1, \dots, x_n]$ is a decomposition of $I$ into cellular binomial ideals. Using Noetherian induction, it is not too difficult to show that such decompositions exist.

With this notation, the algorithms for computing binomial primary decompositions proceed in two main steps:

  • First, compute a cellular decomposition of the given binomial ideal.
  • Then, decompose each cellular component into primary binomial ideals.

While the first step can be performed over any ground field for which Gröbner bases are implemented, the second step may require a field extension: From a theoretical point of view, the existence of binomial primary decompositions is only guaranteed if the ground field is algebraically closed.

Note

A pure difference binomial is a binomial which is the difference of two monomials. A unital binomial ideal is an ideal which can be generated by pure difference binomials and monomials. Note that cellular components of unital binomial ideals are unital as well. For unital binomial ideals in $\mathbb Q[x_1, \dots, x_n]$, binomial primary decompositions exist already over cyclotomic extensions of $\mathbb Q$. In particular, any such ideal can be decomposed over the abelian closure $\mathbb Q^{\text{ab}}$ of $\mathbb Q$. While OSCAR offers functionality for doing this, computing binomial primary decompositions in other cases is not yet supported.

See the number theory chapter for how to deal with $\mathbb Q^{\text{ab}}$.

Note

Binomial primary decompositions computed with OSCAR are not necessarily minimal.

Papers offering details on theory and algorithms as well as examples include:

Basic Tests

Binomiality Test

is_binomialMethod
is_binomial(f::MPolyRingElem)

Return true if f consists of at most 2 terms, false otherwise.

source
is_binomialMethod
is_binomial(I::MPolyIdeal)

Return true if I can be generated by polynomials consisting of at most 2 terms, false otherwise.

source
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> f = 2*x+y
-2*x + y
-
-julia> is_binomial(f)
-true
-
-julia> J = ideal(R, [x^2-y^3, z^2])
-ideal(x^2 - y^3, z^2)
-
-julia> is_binomial(J)
-true
-

Cellularity Test

is_cellularMethod
is_cellular(I::MPolyIdeal)

Given a binomial ideal I, return true together with the indices of the cell variables if I is cellular. Return false together with the index of a variable which is a zerodivisor but not nilpotent modulo I, otherwise (return (false, [-1]) if I is not proper).

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:6)
-(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])
-
-julia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])
-ideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])
-
-julia> is_cellular(I)
-(true, [1, 2, 3, 4])
-
-julia> R, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x-y,x^3-1,z*y^2-z])
-ideal(x - y, x^3 - 1, y^2*z - z)
-
-julia> is_cellular(I)
-(false, [3])
source

Unitality Test

is_unitalMethod
is_unital(I::MPolyIdeal)

Given a binomial ideal I, return true if I can be generated by differences of monomials and monomials.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x+y])
-ideal(x + y)
-
-julia> is_unital(I)
-false
-
-julia> J = ideal(R, [x^2-y^3, z^2])
-ideal(x^2 - y^3, z^2)
-
-julia> is_unital(J)
-true
source

Cellular Decomposition

cellular_decompositionMethod
cellular_decomposition(I::MPolyIdeal)

Given a binomial ideal I, return a cellular decomposition of I.

Examples

julia> R, (x,y,z) =  polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x-y,x^3-1,z*y^2-z])
-ideal(x - y, x^3 - 1, y^2*z - z)
-
-julia> cellular_decomposition(I)
-2-element Vector{MPolyIdeal{QQMPolyRingElem}}:
- ideal(y - 1, x - 1)
- ideal(x - y, x^3 - 1, y^2*z - z, z)
source

Primary Decomposition of Cellular Ideals

cellular_hullMethod
cellular_hull(I::MPolyIdeal{QQMPolyRingElem})

Given a cellular binomial ideal I, return the intersection of the minimal primary components of I.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:6)
-(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])
-
-julia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])
-ideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])
-
-julia> is_cellular(I)
-(true, [1, 2, 3, 4])
-
-julia> cellular_hull(I)
-ideal(x[6], x[5])
source
cellular_associated_primesMethod
cellular_associated_primes(I::MPolyIdeal{QQMPolyRingElem})

Given a cellular binomial ideal I, return the associated primes of I.

The result is defined over the abelian closure of $\mathbb Q$. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:6)
-(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])
-
-julia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])
-ideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])
-
-julia> cellular_associated_primes(I)
-5-element Vector{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}:
- ideal(x[5], x[6])
- ideal(x[1] - x[2], x[5], x[6])
- ideal(x[1] - zeta(3)*x[2], x[5], x[6])
- ideal(x[1] + (zeta(3) + 1)*x[2], x[5], x[6])
- ideal(x[3] - x[4], x[5], x[6])
source
cellular_minimal_associated_primesMethod
cellular_minimal_associated_primes(I::MPolyIdeal{QQMPolyRingElem})

Given a cellular binomial ideal I, return the minimal associated primes of I.

The result is defined over the abelian closure of $\mathbb Q$. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:6)
-(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])
-
-julia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])
-ideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])
-
-julia> cellular_minimal_associated_primes(I::MPolyIdeal{QQMPolyRingElem})
-1-element Vector{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}:
- ideal(x[5], x[6])
source
cellular_primary_decompositionMethod
cellular_primary_decomposition(I::MPolyIdeal{QQMPolyRingElem})

Given a cellular binomial ideal I, return a binomial primary decomposition of I.

The result is defined over the abelian closure of $\mathbb Q$. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:6)
-(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])
-
-julia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])
-ideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])
-
-julia> cellular_primary_decomposition(I)
-5-element Vector{Tuple{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}}:
- (ideal(x[6], x[5]), ideal(x[5], x[6]))
- (ideal(x[6], x[1] - x[2], x[5]^2), ideal(x[1] - x[2], x[5], x[6]))
- (ideal(x[6], x[1] - zeta(3)*x[2], x[5]^2), ideal(x[1] - zeta(3)*x[2], x[5], x[6]))
- (ideal(x[6], x[1] + (zeta(3) + 1)*x[2], x[5]^2), ideal(x[1] + (zeta(3) + 1)*x[2], x[5], x[6]))
- (ideal(x[5], x[3] - x[4], x[6]^2), ideal(x[3] - x[4], x[5], x[6]))
source

Primary Decomposition of Binomial Ideals

binomial_primary_decompositionMethod
binomial_primary_decomposition(I::MPolyIdeal{QQMPolyRingElem})

Given a binomial ideal I, return a binomial primary decomposition of I.

The result is defined over the abelian closure of $\mathbb Q$. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.

Examples

julia> R, (x,y,z) =  polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x-y,x^3-1,z*y^2-z])
-ideal(x - y, x^3 - 1, y^2*z - z)
-
-julia> binomial_primary_decomposition(I)
-3-element Vector{Tuple{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}}:
- (ideal(z, y - zeta(3), x - zeta(3)), ideal(y - zeta(3), x - zeta(3), z))
- (ideal(z, y + zeta(3) + 1, x + zeta(3) + 1), ideal(y + zeta(3) + 1, x + zeta(3) + 1, z))
- (ideal(y - 1, x - 1), ideal(y - 1, x - 1, x*y - 1))
source
diff --git a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/complexes/index.html b/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/complexes/index.html deleted file mode 100644 index a1992b95d918..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/complexes/index.html +++ /dev/null @@ -1,119 +0,0 @@ - -Chain and Cochain Complexes · Oscar.jl

Chain and Cochain Complexes

The general OSCAR type ComplexOfMorphisms{T} allows one to model both chain complexes and cochain complexes (the T refers to the type of the differentials of the complex). In the context of commutative algebra, we handle complexes of modules and module homomorphisms over multivariate polynomial rings. In this section, we first show how to create such complexes. Then we discuss functionality for dealing with the constructed complexes, mainly focusing on chain complexes. Cochain complexes can be handled similarly.

Constructors

chain_complexMethod
chain_complex(V::ModuleFPHom...; seed::Int = 0)

Given a tuple V of module homorphisms between successive modules over a multivariate polynomial ring, return the chain complex defined by these homomorphisms.

chain_complex(V::Vector{<:ModuleFPHom}; seed::Int = 0)

Given a vector V of module homorphisms between successive modules over a multivariate polynomial ring, return the chain complex defined by these homomorphisms.

Note

The integer seed indicates the lowest homological degree of a module in the complex.

Note

The function checks whether successive homomorphisms indeed compose to zero.

source
cochain_complexMethod
cochain_complex(V::ModuleFPHom...; seed::Int = 0)

Given a tuple V of module homorphisms between successive modules over a multivariate polynomial ring, return the cochain complex defined by these homomorphisms.

cochain_complex(V::Vector{<:ModuleFPHom}; seed::Int = 0)

Given a vector V of module homorphisms between successive modules over a multivariate polynomial ring, return the cochain complex defined by these homomorphisms.

Note

The integer seed indicates the lowest cohomological degree of a module of the complex.

Note

The function checks whether successive homomorphisms indeed compose to zero.

source

Data Associated to Complexes

Given a complex C,

  • range(C) refers to the range of C,
  • obj(C, i) and C[i] to the i-th module of C, and
  • map(C, i) to the i-th differential of C.
Examples
julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> F = free_module(R, 1);
-
-julia> A, _ = quo(F, [x^4*F[1]]);
-
-julia> B, _ = quo(F, [x^3*F[1]]);
-
-julia> a = hom(A, B, [x^2*B[1]]);
-
-julia> b = hom(B, B, [x^2*B[1]]);
-
-julia> C = chain_complex([a, b]; seed = 3)
-C_3 <---- C_4 <---- C_5
-
-julia> range(C)
-5:-1:3
-
-julia> C[5]
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 1 generator
-1 -> x^4*e[1]
-
-julia> delta = map(C, 5)
-Map with following data
-Domain:
-=======
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 1 generator
-1 -> x^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 1 generator
-1 -> x^3*e[1]
-
-julia> matrix(delta)
-[x^2]

Operations on Complexes

shift(C::ComplexOfMorphisms{T}, d::Int) where T

Return the complex obtained from C by shifting the homological degrees d steps, with maps multiplied by $(-1)^d$.

Examples
julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> F = free_module(R, 1);
-
-julia> A, _ = quo(F, [x^4*F[1]]);
-
-julia> B, _ = quo(F, [x^3*F[1]]);
-
-julia> a = hom(A, B, [x^2*B[1]]);
-
-julia> b = hom(B, B, [x^2*B[1]]);
-
-julia> C = chain_complex([a, b]; seed = 3);
-
-julia> range(C)
-5:-1:3
-
-julia> D = shift(C, 3);
-
-julia> range(D)
-8:-1:6
homMethod
hom(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)

Return the complex obtained by applying $\text{Hom}(-,$ M$)$ to C.

If C is a chain complex, return a cochain complex. If C is a cochain complex, return a chain complex.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> F = free_module(R, 1);
-
-julia> A, _ = quo(F, [x^4*F[1]]);
-
-julia> B, _ = quo(F, [x^3*F[1]]);
-
-julia> a = hom(A, B, [x^2*B[1]]);
-
-julia> b = hom(B, B, [x^2*B[1]]);
-
-julia> C = chain_complex([a, b]; seed = 3);
-
-julia> range(C)
-5:-1:3
-
-julia> D = hom(C, A);
-
-julia> range(D)
-3:5
source
hom_without_reversing_directionMethod
hom_without_reversing_direction(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)

Return the complex obtained by applying $\text{Hom}(-,$ M$)$ to C.

If C is a chain complex, return a chain complex. If C is a cochain complex, return a cochain complex.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> F = free_module(R, 1);
-
-julia> A, _ = quo(F, [x^4*F[1]]);
-
-julia> B, _ = quo(F, [x^3*F[1]]);
-
-julia> a = hom(A, B, [x^2*B[1]]);
-
-julia> b = hom(B, B, [x^2*B[1]]);
-
-julia> C = chain_complex([a, b]; seed = 3);
-
-julia> range(C)
-5:-1:3
-
-julia> D = hom_without_reversing_direction(C, A);
-
-julia> range(D)
--3:-1:-5
source
homMethod
hom(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})

Return the complex obtained by applying $\text{Hom}($M, $-)$ to C.

source
tensor_productMethod
tensor_product(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)

Return the complex obtained by applying $\bullet\;\! \otimes$ M to C.

source
tensor_productMethod
tensor_product(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})

Return the complex obtained by applying M $\otimes\;\! \bullet$ to C.

source

Tests on Complexes

The functions below check properties of complexes:

is_chain_complex(C::ComplexOfMorphisms{ModuleFP})
is_cochain_complex(C::ComplexOfMorphisms{ModuleFP})
is_exact(C::ComplexOfMorphisms{ModuleFP})
Examples
julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> F = free_module(R, 1);
-
-julia> A, _ = quo(F, [x^4*F[1]]);
-
-julia> B, _ = quo(F, [x^3*F[1]]);
-
-julia> a = hom(A, B, [x^2*B[1]]);
-
-julia> b = hom(B, B, [x^2*B[1]]);
-
-julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> C = chain_complex([a, b]);
-
-julia> is_cochain_complex(C)
-false

Maps of Complexes

Types

Constructors

diff --git a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html b/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html deleted file mode 100644 index e4364a6a8320..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html +++ /dev/null @@ -1,404 +0,0 @@ - -Free Modules · Oscar.jl

Free Modules

In this section, the expression free module refers to a free module of finite rank over a ring of type MPolyRing, MPolyQuoRing, MPolyLocRing, or MPolyQuoLocRing. More concretely, given a ring $R$ of one of these types, the free $R$-modules considered are of type $R^p$, where we think of $R^p$ as a free module with a given basis, namely the basis of standard unit vectors. Accordingly, elements of free modules are represented by coordinate vectors, and homomorphisms between free modules by matrices.

Note

By convention, vectors are row vectors, and matrices operate by multiplication on the right.

Types

All OSCAR types for the modules considered here belong to the abstract type ModuleFP{T}, where T is the element type of the underlying ring. Graded or not, the free modules belong to the abstract subtype AbstractFreeMod{T} <: ModuleFP{T}, they are modelled as objects of the concrete type FreeMod{T} <: AbstractFreeMod{T}.

Note

Canonical maps such us the canonical projection onto a quotient module arise in many constructions in commutative algebra. The FreeMod type is designed so that it allows for the caching of such maps when executing functions. The direct_sum function discussed in this section provides an example.

Constructors

free_moduleFunction
free_module(R::MPolyRing, p::Int, name::VarName = :e; cached::Bool = false)
-free_module(R::MPolyQuoRing, p::Int, name::VarName = :e; cached::Bool = false)
-free_module(R::MPolyLocRing, p::Int, name::VarName = :e; cached::Bool = false)
-free_module(R::MPolyQuoLocRing, p::Int, name::VarName = :e; cached::Bool = false)

Return the free $R$-module $R^p$, created with its basis of standard unit vectors.

The string name specifies how the basis vectors are printed.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> FR = free_module(R, 2)
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> x*FR[1]
-x*e[1]
-
-julia> P = ideal(R, [x, y, z]);
-
-julia> U = complement_of_prime_ideal(P);
-
-julia> RL, _ = Localization(R, U);
-
-julia> FRL = free_module(RL, 2, "f")
-Free module of rank 2 over Localization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal
-
-julia> RL(x)*FRL[1]
-x*f[1]
-
-julia> RQ, _ = quo(R, ideal(R, [2*x^2-y^3, 2*x^2-y^5]));
-
-julia> FRQ =  free_module(RQ, 2, "g")
-Free module of rank 2 over RQ
-
-julia> RQ(x)*FRQ[1]
-x*g[1]
-
-julia> RQL, _ = Localization(RQ, U);
-
-julia> FRQL =  free_module(RQL, 2, "h")
-Free module of rank 2 over Localization of quotient of multivariate polynomial ring at complement of prime ideal
-
-julia> RQL(x)*FRQL[1]
-x*h[1]
source

Over graded multivariate polynomial rings and their quotients, there are two basic ways of creating graded free modules: While the grade function allows one to create a graded free module by assigning a grading to a free module already constructed, the graded_free_module function is meant to create a graded free module all at once.

gradeMethod
grade(F::FreeMod, W::Vector{GrpAbFinGenElem})

Given a free module F over a graded ring with grading group G, say, and given a vector W of ngens(F) elements of G, create a G-graded free module by assigning the entries of W as weights to the generators of F. Return the new module.

grade(F::FreeMod)

As above, with all weights set to zero(G).

Note

The function applies to free modules over both graded multivariate polynomial rings and their quotients.

Examples

julia> R, x, y = polynomial_ring(QQ, "x" => 1:2, "y" => 1:3);
-
-julia> G = abelian_group([0, 0])
-GrpAb: Z^2
-
-julia> g = gens(G)
-2-element Vector{GrpAbFinGenElem}:
- Element of G with components [1 0]
- Element of G with components [0 1]
-
-julia> W = [g[1], g[1], g[2], g[2], g[2]];
-
-julia> S, _ = grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], y[1], y[2], y[3]])
-
-julia> F = free_module(S, 3)
-Free module of rank 3 over S
-
-julia> FF = grade(F)
-Graded free module S^3([0 0]) of rank 3 over S
-
-julia> F
-Free module of rank 3 over S
source
gradeMethod
grade(F::FreeMod, W::Vector{<:Vector{<:IntegerUnion}})

Given a free module F over a graded ring with grading group $G = \mathbb Z^m$, and given a vector W of ngens(F) integer vectors of the same size m, say, define a $G$-grading on F by converting the vectors in W to elements of $G$, and assigning these elements as weights to the variables. Return the new module.

grade(F::FreeMod, W::Union{ZZMatrix, Matrix{<:IntegerUnion}})

As above, converting the columns of W.

grade(F::FreeMod, W::Vector{<:IntegerUnion})

Given a free module F over a graded ring with grading group $G = \mathbb Z$, and given a vector W of ngens(F) integers, define a $G$-grading on F converting the entries of W to elements of G, and assigning these elements as weights to the variables. Return the new module.

Note

The function applies to free modules over both graded multivariate polynomial rings and their quotients.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"],  [1 0 1; 0 1 1])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> F = free_module(R, 2)
-Free module of rank 2 over R
-
-julia> FF = grade(F,  [[1, 0], [0, 1]])
-Graded free module R^1([-1 0]) + R^1([0 -1]) of rank 2 over R
-
-julia> FFF = grade(F,  [1 0; 0 1])
-Graded free module R^1([-1 0]) + R^1([0 -1]) of rank 2 over R
julia> R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"])
-(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])
-
-julia> S, _ = quo(R, [x*y])
-(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from
-R to S defined by a julia-function with inverse)
-
-julia> F = free_module(S, 2)
-Free module of rank 2 over S
-
-julia> FF = grade(F, [1, 2])
-Graded free module S^1([-1]) + S^1([-2]) of rank 2 over S
source
graded_free_moduleFunction
graded_free_module(R::Ring, p::Int, W::Vector{GrpAbFinGenElem}=[grading_group(R)[0] for i in 1:p], name::String="e")

Given a graded ring R with grading group G, say, and given a vector W with p elements of G, create the free module $R^p$ equipped with its basis of standard unit vectors, and assign weights to these vectors according to the entries of W. Return the resulting graded free module.

graded_free_module(R::Ring, W::Vector{GrpAbFinGenElem}, name::String="e")

As above, with p = length(W).

Note

The function applies to graded multivariate polynomial rings and their quotients.

The string name specifies how the basis vectors are printed.

Examples

julia> R, (x,y) = graded_polynomial_ring(QQ, ["x", "y"])
-(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])
-
-julia> graded_free_module(R,3)
-Graded free module R^3([0]) of rank 3 over R
-
-julia> G = grading_group(R)
-GrpAb: Z
-
-julia> graded_free_module(R, [G[1], 2*G[1]])
-Graded free module R^1([-1]) + R^1([-2]) of rank 2 over R
source
graded_free_moduleFunction
graded_free_module(R::Ring, W::Vector{<:Vector{<:IntegerUnion}}, name::String="e")

Given a graded ring R with grading group $G = \mathbb Z^m$, and given a vector W of integer vectors of the same size p, say, create the free module $R^p$ equipped with its basis of standard unit vectors, and assign weights to these vectors according to the entries of W, converted to elements of G. Return the resulting graded free module.

graded_free_module(R::Ring, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String="e")

As above, converting the columns of W.

graded_free_module(R::Ring, W::Vector{<:IntegerUnion}, name::String="e")

Given a graded ring R with grading group $G = \mathbb Z$, and given a vector W of integers, set p = length(W), create the free module $R^p$ equipped with its basis of standard unit vectors, and assign weights to these vectors according to the entries of W, converted to elements of G. Return the resulting graded free module.

The string name specifies how the basis vectors are printed.

Note

The function applies to graded multivariate polynomial rings and their quotients.

Examples

julia> R, (x,y) = graded_polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = graded_free_module(R, [1, 2])
-Graded free module R^1([-1]) + R^1([-2]) of rank 2 over R
julia> S, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1 0 1; 0 1 1]);
-
-julia> FF = graded_free_module(S, [[1, 2], [-1, 3]])
-Graded free module S^1([-1 -2]) + S^1([1 -3]) of rank 2 over S
-
-julia> FFF = graded_free_module(S, [1 -1; 2 3])
-Graded free module S^1([-1 -2]) + S^1([1 -3]) of rank 2 over S
-
-julia> FF == FFF
-true
source

Data Associated to Free Modules

If F is a free R-module, then

  • base_ring(F) refers to R,
  • basis(F), gens(F) to the basis vectors of F,
  • rank(F), ngens(F), dim(F) to the number of these vectors, and
  • F[i], basis(F, i), gen(F, i) to the i-th such vector.
Examples
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = free_module(R, 3);
-
-julia> basis(F)
-3-element Vector{FreeModElem{QQMPolyRingElem}}:
- e[1]
- e[2]
- e[3]
-
-julia> rank(F)
-3

In the graded case, we also have:

grading_groupMethod
grading_group(F::FreeMod)

Return the grading group of base_ring(F).

Examples

julia> R, (x,y) = graded_polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = graded_free_module(R, 3)
-Graded free module R^3([0]) of rank 3 over R
-
-julia> grading_group(F)
-GrpAb: Z
source
degrees_of_generatorsMethod
degrees_of_generators(F::FreeMod)

Return the degrees of the generators of F.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = graded_free_module(R, 2)
-Graded free module R^2([0]) of rank 2 over R
-
-julia> degrees_of_generators(F)
-2-element Vector{GrpAbFinGenElem}:
- [0]
- [0]
source

Elements of Free Modules

All OSCAR types for elements of the modules considered here belong to the abstract type ModuleElemFP{T}, where T is the element type of the underlying ring. The free modules belong to the abstract subtype AbstractFreeModElem{T} <: ModuleFPElem{T}. They are modelled as objects of the concrete type FreeModElem{T} <: AbstractFreeModElem{T} which implements an element $f$ of a free module $F$ as a sparse row, that is, as an object of type SRow{T}. This object specifies the coordinates of $f$ with respect to the basis of standard unit vectors of $F$. To create an element, enter its coordinates as a sparse row or a vector:

(F::FreeMod{T})(c::SRow{T}) where T
(F::FreeMod{T})(c::Vector{T}) where T

Alternatively, directly write the element as a linear combination of basis vectors of $F$:

Examples
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = free_module(R, 3);
-
-julia> f = F(sparse_row(R, [(1,x),(3,y)]))
-x*e[1] + y*e[3]
-
-julia> g = F([x, zero(R), y])
-x*e[1] + y*e[3]
-
-julia> h = x*F[1] + y*F[3]
-x*e[1] + y*e[3]
-
-julia> f == g == h
-true

Given an element f of a free module F over a multivariate polynomial ring with element type T,

  • parent(f) refers to F, and
  • coordinates(f) to the coordinate vector of f, returned as an object of type SRow{T}.
Examples
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = free_module(R, 3);
-
-julia> f = x*F[1] + y*F[3]
-x*e[1] + y*e[3]
-
-julia> parent(f)
-Free module of rank 3 over Multivariate polynomial ring in 2 variables over QQ
-
-julia> coordinates(f)
-Sparse row with positions [1, 3] and values QQMPolyRingElem[x, y]
-

The zero element of a free module is obtained as follows:

zeroMethod
zero(F::AbstractFreeMod)

Return the zero element of F.

source

Whether a given element of a free module is zero can be tested as follows:

is_zeroMethod
is_zero(f::AbstractFreeModElem)

Return true if f is zero, false otherwise.

source

In the graded case, we additionally have:

is_homogeneousMethod
is_homogeneous(f::FreeModElem)

Given an element f of a graded free module, return true if f is homogeneous, false otherwise.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3]);
-
-julia> F = free_module(R, 2)
-Free module of rank 2 over R
-
-julia> FF = grade(F, [1,4])
-Graded free module R^1([-1]) + R^1([-4]) of rank 2 over R
-
-julia> f = y^2*2*FF[1]-x*FF[2]
-2*y^2*e[1] - x*e[2]
-
-julia> is_homogeneous(f)
-true
source
degreeMethod
degree(f::FreeModElem)

Given a homogeneous element f of a graded free module, return the degree of f.

degree(::Type{Vector{Int}}, f::FreeModElem)

Given a homogeneous element f of a $\mathbb Z^m$-graded free module, return the degree of f, converted to a vector of integer numbers.

degree(::Type{Int}, f::FreeModElem)

Given a homogeneous element f of a $\mathbb Z$-graded free module, return the degree of f, converted to an integer number.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> f = y^2*z − x^2*w
--w*x^2 + y^2*z
-
-julia> degree(f)
-[3]
-
-julia> typeof(degree(f))
-GrpAbFinGenElem
-
-julia> degree(Int, f)
-3
-
-julia> typeof(degree(Int, f))
-Int64
source

Tests on Free Modules

The tests is_graded, is_standard_graded, is_z_graded, and is_zm_graded carry over analogously to free modules. They return true if the corresponding property is satisfied, and false otherwise. In addition, we have:

==Method
==(F::FreeMod, G::FreeMod)

Return true if F and G are equal, false otherwise.

Here, F and G are equal iff either

  • both modules are ungraded and their base rings, ranks, and names for printing the basis elements are equal,

or else

  • both modules are graded, the above holds, and for each $i$, the degrees of the $i$-th basis elements are equal.
source
is_isomorphicMethod
is_isomorphic(F::FreeMod, G::FreeMod)

Return true if F and G are isomorphic as (graded) modules, false otherwise.

That is, either

  • both modules are ungraded and their base rings and ranks are equal,

or else

  • both modules are graded, the above holds, and the multisets of the degrees of the basis elements are equal.

Examples

julia> R, _= polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z)=grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F = graded_free_module(Rg, [1,1,3,2]);
-
-julia> G1 = graded_free_module(Rg, [1,1,2,3]);
-
-julia> is_isomorphic(F, G1)
-true
-
-julia> G2 = graded_free_module(Rg, [1,1,5,6]);
-
-julia> is_isomorphic(F, G2)
-false
source
is_zeroMethod
is_zero(F::AbstractFreeMod)

Return true if F is the zero module, false otherwise.

source

Homomorphisms from Free Modules

All OSCAR types for homomorphisms of the modules considered here belong to the abstract type ModuleFPHom{T1, T2}, where T1 and T2 are the types of domain and codomain respectively. A homomorphism $F\to M$ from a free module $F$ is determined by specifying the images of the basis vectors of $F$ in $M$. For such homomorphisms, OSCAR provides the concrete type FreeModuleHom{T1, T2} <: ModuleFPHom{T1, T2} as well as the following constructors:

homMethod
hom(F::FreeMod, M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T

Given a vector V of rank(F) elements of M, return the homomorphism F $\to$ M which sends the i-th basis vector of F to the i-th entry of V.

hom(F::FreeMod, M::ModuleFP{T}, A::MatElem{T}) where T

Given a matrix A with rank(F) rows and ngens(M) columns, return the homomorphism F $\to$ M which sends the i-th basis vector of F to the linear combination $\sum_j A[i,j]*M[j]$ of the generators M[j] of M.

Note

The module M may be of type FreeMod or SubquoMod. If both modules F and M are graded, the data must define a graded module homomorphism of some degree. If this degree is the zero element of the (common) grading group, we refer to the homomorphism under consideration as a homogeneous module homomorphism.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 3)
-Free module of rank 3 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> G = free_module(R, 2)
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]
-3-element Vector{FreeModElem{QQMPolyRingElem}}:
- y*e[1]
- x*e[1] + y*e[2]
- z*e[2]
-
-julia> a = hom(F, G, V)
-Map with following data
-Domain:
-=======
-Free module of rank 3 over Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> a(F[2])
-x*e[1] + y*e[2]
-
-julia> B = R[y 0; x y; 0 z]
-[y   0]
-[x   y]
-[0   z]
-
-julia> b = hom(F, G, B)
-Map with following data
-Domain:
-=======
-Free module of rank 3 over Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> a == b
-true
julia> R, _= polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F1 = graded_free_module(Rg, 3)
-Graded free module Rg^3([0]) of rank 3 over Rg
-
-julia> G1 = graded_free_module(Rg, 2)
-Graded free module Rg^2([0]) of rank 2 over Rg
-
-julia> V1 = [y*G1[1], (x+y)*G1[1]+y*G1[2], z*G1[2]]
-3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- (x + y)*e[1] + y*e[2]
- z*e[2]
-
-julia> a1 = hom(F1, G1, V1)
-F1 -> G1
-e[1] -> y*e[1]
-e[2] -> (x + y)*e[1] + y*e[2]
-e[3] -> z*e[2]
-Graded module homomorphism of degree [1]
-
-julia> F2 = graded_free_module(Rg, [1,1,1])
-Graded free module Rg^3([-1]) of rank 3 over Rg
-
-julia> G2 = graded_free_module(Rg, [0,0])
-Graded free module Rg^2([0]) of rank 2 over Rg
-
-julia> V2 = [y*G2[1], (x+y)*G2[1]+y*G2[2], z*G2[2]]
-3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- (x + y)*e[1] + y*e[2]
- z*e[2]
-
-julia> a2 = hom(F2, G2, V2)
-F2 -> G2
-e[1] -> y*e[1]
-e[2] -> (x + y)*e[1] + y*e[2]
-e[3] -> z*e[2]
-Homogeneous module homomorphism
-
-julia> B = Rg[y 0; x+y y; 0 z]
-[    y   0]
-[x + y   y]
-[    0   z]
-
-julia> b = hom(F2, G2, B)
-F2 -> G2
-e[1] -> y*e[1]
-e[2] -> (x + y)*e[1] + y*e[2]
-e[3] -> z*e[2]
-Homogeneous module homomorphism
-
-julia> a2 == b
-true
source
homMethod
hom(F::FreeMod, M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, h::RingMapType) where {T, RingMapType}

Given a vector V of rank(F) elements of M and a ring map h from base_ring(F) to base_ring(M), return the base_ring(F)-homomorphism F $\to$ M which sends the i-th basis vector of F to the i-th entry of V, and the scalars in base_ring(F) to their images under h.

hom(F::FreeMod, M::ModuleFP{T}, A::MatElem{T}, h::RingMapType) where {T, RingMapType}

Given a matrix A over base_ring(M) with rank(F) rows and ngens(M) columns and a ring map h from base_ring(F) to base_ring(M), return the base_ring(F)-homomorphism F $\to$ M which sends the i-th basis vector of F to the linear combination $\sum_j A[i,j]*M[j]$ of the generators M[j] of M, and the scalars in base_ring(F) to their images under h.

Note

The module M may be of type FreeMod or SubquoMod. If both modules F and M are graded, the data must define a graded module homomorphism of some degree. If this degree is the zero element of the (common) grading group, we refer to the homomorphism under consideration as a homogeneous module homomorphism.

source

Given a homomorphism of type FreeModuleHom, a matrix representing it is recovered by the following function:

matrixMethod
matrix(a::FreeModuleHom)

Given a homomorphism a : F → M of type FreeModuleHom, return a matrix A over base_ring(M) with rank(F) rows and ngens(M) columns such that $a(F[i]) = \sum_j A[i,j]*M[j]$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 3)
-Free module of rank 3 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> G = free_module(R, 2)
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]];
-
-julia> a = hom(F, G, V);
-
-julia> matrix(a)
-[y   0]
-[x   y]
-[0   z]
source

The domain and codomain of a homomorphism a of type FreeModuleHom can be recovered by entering domain(a) and codomain(a), respectively.

The functions below test whether a homomorphism of type FreeModuleHom is graded and homogeneous, respectively.

is_gradedMethod
is_graded(a::FreeModuleHom)

Return true if a is graded, false otherwise.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = graded_free_module(R, 3)
-Graded free module R^3([0]) of rank 3 over R
-
-julia> G = graded_free_module(R, 2)
-Graded free module R^2([0]) of rank 2 over R
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]
-3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- x*e[1] + y*e[2]
- z*e[2]
-
-julia> a = hom(F, G, V)
-F -> G
-e[1] -> y*e[1]
-e[2] -> x*e[1] + y*e[2]
-e[3] -> z*e[2]
-Graded module homomorphism of degree [1]
-
-julia> is_graded(a)
-true
source
is_homogeneousMethod
is_homogeneous(a::FreeModuleHom)

Return true if a is homogeneous, false otherwise

Here, if G is the grading group of a, a is homogeneous if a is graded of degree zero(G).

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = graded_free_module(R, 3)
-Graded free module R^3([0]) of rank 3 over R
-
-julia> G = graded_free_module(R, 2)
-Graded free module R^2([0]) of rank 2 over R
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]
-3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- x*e[1] + y*e[2]
- z*e[2]
-
-julia> a = hom(F, G, V)
-F -> G
-e[1] -> y*e[1]
-e[2] -> x*e[1] + y*e[2]
-e[3] -> z*e[2]
-Graded module homomorphism of degree [1]
-
-julia> is_homogeneous(a)
-false
source

In the graded case, we additionally have:

degreeMethod
degree(a::FreeModuleHom)

If a is graded, return the degree of a.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = graded_free_module(R, 3)
-Graded free module R^3([0]) of rank 3 over R
-
-julia> G = graded_free_module(R, 2)
-Graded free module R^2([0]) of rank 2 over R
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]
-3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- x*e[1] + y*e[2]
- z*e[2]
-
-julia> a = hom(F, G, V)
-F -> G
-e[1] -> y*e[1]
-e[2] -> x*e[1] + y*e[2]
-e[3] -> z*e[2]
-Graded module homomorphism of degree [1]
-
-julia> degree(a)
-[1]
source
grading_groupMethod
grading_group(a::FreeModuleHom)

If a is graded, return the grading group of a.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = graded_free_module(R, 3)
-Graded free module R^3([0]) of rank 3 over R
-
-julia> G = graded_free_module(R, 2)
-Graded free module R^2([0]) of rank 2 over R
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]
-3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- x*e[1] + y*e[2]
- z*e[2]
-
-julia> a = hom(F, G, V)
-F -> G
-e[1] -> y*e[1]
-e[2] -> x*e[1] + y*e[2]
-e[3] -> z*e[2]
-Graded module homomorphism of degree [1]
-
-julia> is_graded(a)
-true
-
-julia> grading_group(a)
-GrpAb: Z
source
diff --git a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/index.html b/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/index.html deleted file mode 100644 index 83f83d4cb414..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Operations on Module Maps · Oscar.jl

Operations on Module Maps

If module homomorphisms a and b with codomain(a) === domain(b) are given, then compose(a, b) refers to the composition b $\circ$ a. If an isomorphism of modules a is given, then inv(a) refers to its inverse.

hom_productMethod
hom_product(M::ModuleFP, N::ModuleFP, A::Matrix{<:ModuleFPHom})

Given modules M, N which are products with the same number of factors, say $M = \prod_{i=1}^r M_i$, $N = \prod_{j=1}^r N_j$, and given a matrix A of homomorphisms $a_{ij} : M_i \to N_j$, return the homomorphism $M \to N$ with $ij$-components $a_{ij}$.

source
hom_tensorMethod
hom_tensor(M::ModuleFP, N::ModuleFP, V::Vector{ <: ModuleFPHom})

Given modules M, N which are tensor products with the same number of factors, say $M = M_1 \otimes \cdots \otimes M_r$, $N = N_1 \otimes \cdots \otimes N_r$, and given a vector V of homomorphisms $a_i : M_i \to N_i$, return $a_1 \otimes \cdots \otimes a_r$.

source
lift_homomorphism_contravariantMethod
lift_homomorphism_contravariant(Hom_MP::ModuleFP, Hom_NP::ModuleFP, a::ModuleFPHom)

Given modules of homomorphism, say, Hom_MP $= \text{Hom}(M,P)$ and Hom_NP $= \text{Hom}(N,P)$, and given a homomorphism a $: N \to M$, return the induced homomorphism $\text{Hom}(M,P) \to \text{Hom}(N,P)$.

source
lift_homomorphism_covariantMethod
lift_homomorphism_covariant(Hom_PM::ModuleFP, Hom_PN::ModuleFP, a::ModuleFPHom)

Given modules of homomorphism, say, Hom_PM $= \text{Hom}(P,M)$ and Hom_PN $= \text{Hom}(P,N)$, and given a homomorphism a $: M \to N$, return the induced homomorphism $\text{Hom}(P,M) \to \text{Hom}(P,N)$.

source
diff --git a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/index.html b/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/index.html deleted file mode 100644 index b2d77fd07244..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/index.html +++ /dev/null @@ -1,728 +0,0 @@ - -Homological Algebra · Oscar.jl

Homological Algebra

Some OSCAR functions which are fundamental to homological algebra such as the kernel function and basic functions for handling chain and cochain complexes have already been discussed in previous sections. Building on these functions, we now introduce further OSCAR functionality supporting computations in homological algebra.

Presentations

presentationMethod
presentation(M::ModuleFP)

Return a free presentation of $M$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A = R[x; y];
-
-julia> B = R[x^2; y^3; z^4];
-
-julia> M = SubquoModule(A, B);
-
-julia> P = presentation(M)
-0 <---- M <---- R^2 <---- R^5
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, [1,2,2]);
-
-julia> p = presentation(F)
-0 <---- F <---- F <---- 0
-
-julia> p[-2]
-Graded free module Rg^0 of rank 0 over Rg
-
-julia> p[-1]
-Graded free module Rg^1([-1]) + Rg^2([-2]) of rank 3 over Rg
-
-julia> p[0]
-Graded free module Rg^1([-1]) + Rg^2([-2]) of rank 3 over Rg
-
-julia> p[1]
-Graded free module Rg^0 of rank 0 over Rg
-
-julia> map(p,-1)
-F -> 0
-e[1] -> 0
-e[2] -> 0
-e[3] -> 0
-Homogeneous module homomorphism
-
-julia> map(p,0)
-F -> F
-e[1] -> e[1]
-e[2] -> e[2]
-e[3] -> e[3]
-Homogeneous module homomorphism
-
-julia> map(p,1)
-0 -> F
-Homogeneous module homomorphism
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> P = presentation(M)
-0 <---- M <---- Rg^2 <---- Rg^5
-
-julia> P[-2]
-Graded free module Rg^0 of rank 0 over Rg
-
-julia> P[-1]
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> P[0]
-Graded free module Rg^2([-1]) of rank 2 over Rg
-
-julia> P[1]
-Graded free module Rg^2([-2]) + Rg^1([-3]) + Rg^2([-5]) of rank 5 over Rg
-
-julia> map(P,-1)
-M -> 0
-x*e[1] -> 0
-y*e[1] -> 0
-Homogeneous module homomorphism
-
-julia> map(P,0)
-Rg^2 -> M
-e[1] -> x*e[1]
-e[2] -> y*e[1]
-Homogeneous module homomorphism
-
-julia> map(P,1)
-Rg^5 -> Rg^2
-e[1] -> x*e[1]
-e[2] -> -y*e[1] + x*e[2]
-e[3] -> y^2*e[2]
-e[4] -> z^4*e[1]
-e[5] -> z^4*e[2]
-Homogeneous module homomorphism
source

Representation as Cokernel

present_as_cokernelFunction
present_as_cokernel(M::SubquoModule, task::Symbol = :none)

Return a subquotient C which is isomorphic to M, and whose generators are the standard unit vectors of its ambient free module.

Additionally,

  • return an isomorphism M $\to$ C if task = :with_morphism,
  • return and cache an isomorphism M $\to$ C if task = :cache_morphism,
  • do none of the above if task = :none (default).

If task = :only_morphism, return only an isomorphism.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A = R[x; y];
-
-julia> B = R[x^2; y^3; z^4];
-
-julia> M = SubquoModule(A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> C = present_as_cokernel(M)
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 5 generators
-1 -> x*e[1]
-2 -> -y*e[1] + x*e[2]
-3 -> y^2*e[2]
-4 -> z^4*e[1]
-5 -> z^4*e[2]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> present_as_cokernel(M, :with_morphism)
-(Graded subquotient of submodule of Rg^2 generated by
-1 -> e[1]
-2 -> e[2]
-by submodule of Rg^2 generated by
-1 -> x*e[1]
-2 -> -y*e[1] + x*e[2]
-3 -> y^2*e[2]
-4 -> z^4*e[1]
-5 -> z^4*e[2], Graded subquotient of submodule of Rg^2 generated by
-1 -> e[1]
-2 -> e[2]
-by submodule of Rg^2 generated by
-1 -> x*e[1]
-2 -> -y*e[1] + x*e[2]
-3 -> y^2*e[2]
-4 -> z^4*e[1]
-5 -> z^4*e[2] -> M
-e[1] -> x*e[1]
-e[2] -> y*e[1]
-Homogeneous module homomorphism)
source

Syzygies and Free Resolutions

free_resolutionMethod
free_resolution(M::SubquoModule{<:MPolyRingElem}; 
-    ordering::ModuleOrdering = default_ordering(M),
-    length::Int=0, algorithm::Symbol=:fres
-  )

Return a free resolution of M.

If length != 0, the free resolution is only computed up to the length-th free module. At the moment, algorithm only allows the option :fres.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; x*y; y^2; z^4]
-[x^2]
-[x*y]
-[y^2]
-[z^4]
-
-julia> M = SubquoModule(A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 4 generators
-1 -> x^2*e[1]
-2 -> x*y*e[1]
-3 -> y^2*e[1]
-4 -> z^4*e[1]
-
-julia> fr = free_resolution(M, length=1)
-Free resolution of M
-R^2 <---- R^6
-0         1
-
-julia> is_complete(fr)
-false
-
-julia> fr[4]
-Free module of rank 0 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> fr
-C_-2 <---- C_-1 <---- C_0 <---- C_1 <---- C_2 <---- C_3 <---- C_4
-
-julia> is_complete(fr)
-true
-
-julia> fr = free_resolution(M, algorithm=:fres)
-Free resolution of M
-R^2 <---- R^6 <---- R^6 <---- R^2 <---- 0
-0         1         2         3         4

Note: Over rings other than polynomial rings, the method will default to a lazy, iterative kernel computation.

source

Betti Diagrams

cm_regularityMethod
cm_regularity(M::ModuleFP)

Given a finitely presented graded module M over a standard $\mathbb Z$-graded multivariate polynomial ring, return the Castelnuovo-Mumford regularity of M.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = graded_free_module(R, 1);
-
-julia> M, _ = quo(F, [x^2*F[1], y^2*F[1], z^2*F[1]])
-(Graded subquotient of submodule of F generated by
-1 -> e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^2*e[1]
-3 -> z^2*e[1], F -> M
-e[1] -> e[1]
-Homogeneous module homomorphism)
-
-julia> cm_regularity(M)
-3
-
-julia> minimal_betti_table(M);
source

Homology

homologyMethod
homology(C::ComplexOfMorphisms{<:ModuleFP})

Return the homology of C.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> F = free_module(R, 1);
-
-julia> A, _ = quo(F, [x^4*F[1]]);
-
-julia> B, _ = quo(F, [x^3*F[1]]);
-
-julia> a = hom(A, B, [x^2*B[1]]);
-
-julia> b = hom(B, B, [x^2*B[1]]);
-
-julia> C = ComplexOfMorphisms(ModuleFP, [a, b]);
-
-julia> H = homology(C)
-3-element Vector{SubquoModule{QQMPolyRingElem}}:
- Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 1 generator
-1 -> x^4*e[1]
- Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 2 generators
-1 -> x^3*e[1]
-2 -> x^2*e[1]
- Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 2 generators
-1 -> x^3*e[1]
-2 -> x^2*e[1]
source
homologyMethod
homology(C::ComplexOfMorphisms{<:ModuleFP}, i::Int)

Return the i-th homology module of C.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> F = free_module(R, 1);
-
-julia> A, _ = quo(F, [x^4*F[1]]);
-
-julia> B, _ = quo(F, [x^3*F[1]]);
-
-julia> a = hom(A, B, [x^2*B[1]]);
-
-julia> b = hom(B, B, [x^2*B[1]]);
-
-julia> C = ComplexOfMorphisms(ModuleFP, [a, b]);
-
-julia> H = homology(C, 1)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 2 generators
-1 -> x^3*e[1]
-2 -> x^2*e[1]
source

Hom and Ext

homFunction
hom(M::ModuleFP, N::ModuleFP)

Return the module Hom(M,N) as an object of type SubquoModule.

Additionally, if H is that object, return the map which sends an element of H to the corresponding homomorphism M $\to$N.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = FreeMod(R, 2);
-
-julia> V = [x*F[1], y^2*F[2]];
-
-julia> M = quo(F, V)[1]
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 2 generators
-1 -> x*e[1]
-2 -> y^2*e[2]
-
-julia> H = hom(M, M)[1]
-hom of (M, M)
-
-julia> gens(H)
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- (e[1] -> e[1])
- (e[2] -> e[2])
-
-julia> relations(H)
-4-element Vector{FreeModElem{QQMPolyRingElem}}:
- x*(e[1] -> e[1])
- y^2*(e[1] -> e[2])
- x*(e[2] -> e[1])
- y^2*(e[2] -> e[2])
source
element_to_homomorphismMethod
element_to_homomorphism(f::ModuleFPElem)

If f is an element of a module created via hom(M,N), for some modules M and N, return the homomorphism M $\to$ N corresponding to f.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = FreeMod(R, 2);
-
-julia> V = [x*F[1], y^2*F[2]];
-
-julia> M = quo(F, V)[1]
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 2 generators
-1 -> x*e[1]
-2 -> y^2*e[2]
-
-julia> H = hom(M, M)[1];
-
-julia> gens(H)
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- (e[1] -> e[1])
- (e[2] -> e[2])
-
-julia> relations(H)
-4-element Vector{FreeModElem{QQMPolyRingElem}}:
- x*(e[1] -> e[1])
- y^2*(e[1] -> e[2])
- x*(e[2] -> e[1])
- y^2*(e[2] -> e[2])
-
-julia> a = element_to_homomorphism(H[1]+y*H[2])
-Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 2 generators
-1 -> x*e[1]
-2 -> y^2*e[2]
-Codomain:
-=========
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 2 generators
-1 -> x*e[1]
-2 -> y^2*e[2]
-
-julia> matrix(a)
-[1   0]
-[0   y]
source
homomorphism_to_elementMethod
homomorphism_to_element(H::ModuleFP, a::ModuleFPHom)

If the module H is created via hom(M,N), for some modules M and N, and a: M $\to$ N is a homomorphism, then return the element of H corresponding to a.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = FreeMod(R, 2);
-
-julia> V = [x*F[1], y^2*F[2]];
-
-julia> M = quo(F, V)[1]
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 2 generators
-1 -> x*e[1]
-2 -> y^2*e[2]
-
-julia> H = hom(M, M)[1];
-
-julia> gens(H)
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- (e[1] -> e[1])
- (e[2] -> e[2])
-
-julia> relations(H)
-4-element Vector{FreeModElem{QQMPolyRingElem}}:
- x*(e[1] -> e[1])
- y^2*(e[1] -> e[2])
- x*(e[2] -> e[1])
- y^2*(e[2] -> e[2])
-
-julia> W =  [M[1], y*M[2]];
-
-julia> a = hom(M, M, W);
-
-julia> iswelldefined(a)
-true
-
-julia> matrix(a)
-[1   0]
-[0   y]
-
-julia> m = homomorphism_to_element(H, a)
-(e[1] -> e[1]) + y*(e[2] -> e[2])
source
extMethod
ext(M::ModuleFP, N::ModuleFP, i::Int)

Return $\text{Ext}^i(M,N)$.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = FreeMod(R, 1);
-
-julia> V = [x*F[1], y*F[1]];
-
-julia> M = quo(F, V)[1]
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-
-julia> ext(M, M, 0)
-Subquotient of Submodule with 1 generator
-1 -> (e[1] -> e[1])
-by Submodule with 2 generators
-1 -> x*(e[1] -> e[1])
-2 -> y*(e[1] -> e[1])
-
-julia> ext(M, M, 1)
-Subquotient of Submodule with 2 generators
-1 -> (e[2] -> e[1])
-2 -> (e[1] -> e[1])
-by Submodule with 4 generators
-1 -> x*(e[1] -> e[1])
-2 -> y*(e[1] -> e[1])
-3 -> x*(e[2] -> e[1])
-4 -> y*(e[2] -> e[1])
-
-julia> ext(M, M, 2)
-Subquotient of Submodule with 1 generator
-1 -> (e[1] -> e[1])
-by Submodule with 3 generators
-1 -> x*(e[1] -> e[1])
-2 -> y*(e[1] -> e[1])
-3 -> -x*(e[1] -> e[1])
-
-julia> ext(M, M, 3)
-Submodule with 0 generators
-represented as subquotient with no relations.
source

Tensorproduct and Tor

tensor_productMethod
tensor_product(M::ModuleFP...; task::Symbol = :none)

Given a collection of modules, say, $M_1, \dots, M_n$ over a ring $R$, return $M_1\otimes_R \cdots \otimes_R M_n$.

If task = :map, additionally return the map which sends a tuple $(m_1,\dots, m_n)$ of elements $m_i\in M_i$ to the pure tensor $m_1\otimes\dots\otimes m_n$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> A = R[x; y];
-
-julia> B = R[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> gens(M)
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x*e[1]
- y*e[1]
-
-julia> T, t = tensor_product(M, M; task = :map);
-
-julia> gens(T)
-4-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x^2*e[1] \otimes e[1]
- x*y*e[1] \otimes e[1]
- x*y*e[1] \otimes e[1]
- y^2*e[1] \otimes e[1]
-
-julia> domain(t)
-parent of tuples of type Tuple{SubquoModuleElem{QQMPolyRingElem}, SubquoModuleElem{QQMPolyRingElem}}
-
-julia> t((M[1], M[2]))
-x*y*e[1] \otimes e[1]
source
torMethod
tor(M::ModuleFP, N::ModuleFP, i::Int)

Return $\text{Tor}_i(M,N)$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A = R[x; y];
-
-julia> B = R[x^2; y^3; z^4];
-
-julia> M = SubquoModule(A, B);
-
-julia> F = free_module(R, 1);
-
-julia> Q, _ = quo(F, [x*F[1]]);
-
-julia> T0 = tor(Q, M, 0)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1] \otimes e[1]
-2 -> y*e[1] \otimes e[1]
-by Submodule with 4 generators
-1 -> x^2*e[1] \otimes e[1]
-2 -> y^3*e[1] \otimes e[1]
-3 -> z^4*e[1] \otimes e[1]
-4 -> x*y*e[1] \otimes e[1]
-
-julia> T1 = tor(Q, M, 1)
-Subquotient of Submodule with 1 generator
-1 -> -x*e[1] \otimes e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1] \otimes e[1]
-2 -> y^3*e[1] \otimes e[1]
-3 -> z^4*e[1] \otimes e[1]
-
-julia> T2 =  tor(Q, M, 2)
-Submodule with 0 generators
-represented as subquotient with no relations.
source

Fitting Ideals

fitting_idealMethod
 fitting_ideal(M::ModuleFP{T}, i::Int) where T <: MPolyRingElem

Return the i-th Fitting ideal of M.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = free_module(R, 2);
-
-julia> o = zero(R)
-0
-
-julia> U = matrix([x^3-y^2 o; o x^3-y^2; -x^2 y; -y x])
-[x^3 - y^2           0]
-[        0   x^3 - y^2]
-[     -x^2           y]
-[       -y           x]
-
-julia> M = quo(F,U)[1]
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 4 generators
-1 -> (x^3 - y^2)*e[1]
-2 -> (x^3 - y^2)*e[2]
-3 -> -x^2*e[1] + y*e[2]
-4 -> -y*e[1] + x*e[2]
-
-julia> fitting_ideal(M, -1)
-ideal(0)
-
-julia> fitting_ideal(M, 0)
-ideal(x^3 - y^2)
-
-julia> fitting_ideal(M, 1)
-ideal(y, x)
-
-julia> fitting_ideal(M, 2)
-ideal(1)
source

Flatness

Checking flatness in OSCAR relies on characterizing flatness in terms of Fitting ideals.

is_flatMethod
 is_flat(M::ModuleFP{T}) where T <: MPolyRingElem

Return true if M is flat, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = free_module(R, 2);
-
-julia> o = zero(R)
-0
-
-julia> U = matrix([x^3-y^2 o; o x^3-y^2; -x^2 y; -y x])
-[x^3 - y^2           0]
-[        0   x^3 - y^2]
-[     -x^2           y]
-[       -y           x]
-
-julia> M = quo(F,U)[1]
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 4 generators
-1 -> (x^3 - y^2)*e[1]
-2 -> (x^3 - y^2)*e[2]
-3 -> -x^2*e[1] + y*e[2]
-4 -> -y*e[1] + x*e[2]
-
-julia> is_flat(M)
-false
source
non_flat_locusMethod
 non_flat_locus(M::ModuleFP{T}) where T <: MPolyRingElem

Return an ideal of base_ring(M) which defines the non-flat-locus of M in the sense that the localization of M at a prime ideal of base_ring(M) is non-flat iff the prime ideal contains the returned ideal.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> F = free_module(R, 2);
-
-julia> o = zero(R)
-0
-
-julia> U = matrix([x^3-y^2 o; o x^3-y^2; -x^2 y; -y x])
-[x^3 - y^2           0]
-[        0   x^3 - y^2]
-[     -x^2           y]
-[       -y           x]
-
-julia> M = quo(F,U)[1]
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 4 generators
-1 -> (x^3 - y^2)*e[1]
-2 -> (x^3 - y^2)*e[2]
-3 -> -x^2*e[1] + y*e[2]
-4 -> -y*e[1] + x*e[2]
-
-julia> non_flat_locus(M)
-ideal(x^3 - y^2)
source

Regular Sequence Test

is_regular_sequenceMethod
 is_regular_sequence(V::Vector{T}, M::ModuleFP{T}) where T <: MPolyRingElem

Return true if the elements of V form, in the given order, a regular sequence on M. Return false, otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> V =  [x*z-z, x*y-y, x]
-3-element Vector{QQMPolyRingElem}:
- x*z - z
- x*y - y
- x
-
-julia> is_regular_sequence(V, F)
-false
-
-julia> W = [x*z-z, x, x*y-y]
-3-element Vector{QQMPolyRingElem}:
- x*z - z
- x
- x*y - y
-
-julia> is_regular_sequence(W, F)
-true
source

Koszul Complex

koszul_matrixMethod
 koszul_matrix(V::Vector{T}, p::Int) where T <: MPolyRingElem

If $f_1, \dots, f_r$ are the entries of V in the given order, return the matrix representing the p-th map of the Koszul complex $K(f_1, \dots, f_r)$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> V = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x
- y
- z
-
-julia> koszul_matrix(V, 3)
-[z   -y   x]
-
-julia> koszul_matrix(V, 2)
-[-y    x   0]
-[-z    0   x]
-[ 0   -z   y]
-
-julia> koszul_matrix(V, 1)
-[x]
-[y]
-[z]
source
koszul_complexMethod
 koszul_complex(V::Vector{T}) where T <: MPolyRingElem

If $f_1, \dots, f_r$ are the entries of V in the given order, return the Koszul complex $K(f_1, \dots, f_r)$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> V = gens(R)
-3-element Vector{QQMPolyRingElem}:
- x
- y
- z
-
-julia> K = koszul_complex(V);
-
-julia> matrix(map(K, 2))
-[-y    x   0]
-[-z    0   x]
-[ 0   -z   y]
-
-julia> Kd = hom(K, free_module(R, 1));
-
-julia> matrix(map(Kd, 1))
-[-y   -z    0]
-[ x    0   -z]
-[ 0    x    y]
source

Koszul Homology

koszul_homologyMethod
 koszul_homology(V::Vector{T}, M::ModuleFP{T}, p::Int) where T <: MPolyRingElem

If $f_1, \dots, f_r$ are the entries of V in the given order, return the p-th homology module of the complex $K(f_1, \dots, f_r)\otimes_R M$, where $K(f_1, \dots, f_r)$ is the Koszul complex defined by $f_1, \dots, f_r$.

Note

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> V =  [x*y, x*z, y*z]
-3-element Vector{QQMPolyRingElem}:
- x*y
- x*z
- y*z
-
-julia> koszul_homology(V, F, 0)
-Submodule with 3 generators
-1 -> y*z*e[1]
-2 -> x*z*e[1]
-3 -> x*y*e[1]
-represented as subquotient with no relations.
-
-julia> koszul_homology(V, F, 1)
-Submodule with 3 generators
-1 -> -z*e[1] + z*e[2]
-2 -> y*e[2]
-3 -> x*e[1]
-represented as subquotient with no relations.
-
-julia> koszul_homology(V, F, 2)
-Submodule with 1 generator
-1 -> 0
-represented as subquotient with no relations.
julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> TC = ideal(R, [x*z-y^2, w*z-x*y, w*y-x^2]);
-
-julia> F = free_module(R, 1);
-
-julia> koszul_homology(gens(TC), F, 0)
-Submodule with 3 generators
-1 -> (-x*z + y^2)*e[1]
-2 -> (-w*z + x*y)*e[1]
-3 -> (-w*y + x^2)*e[1]
-represented as subquotient with no relations.
-
-julia> koszul_homology(gens(TC), F, 1)
-Submodule with 3 generators
-1 -> y*e[1] - z*e[2]
-2 -> x*e[1] - y*e[2]
-3 -> w*e[1] - x*e[2]
-represented as subquotient with no relations.
-
-julia> koszul_homology(gens(TC), F, 2)
-Submodule with 1 generator
-1 -> 0
-represented as subquotient with no relations.
source

Depth

The computation of depth in OSCAR relies on expressing depth in terms of Koszul cohomology.

depthMethod
 depth(I::MPolyIdeal{T}, M::ModuleFP{T}) where T <: MPolyRingElem

Return the depth of I on M.

Examples

julia> R, (w, x, y, z) = polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> TC = ideal(R, [x*z-y^2, w*z-x*y, w*y-x^2]);
-
-julia> dim(TC)
-2
-
-julia> F = free_module(R, 1);
-
-julia> U = collect(gen(TC, i)*F[1] for i in 1:ngens(TC));
-
-julia> M, _ = quo(F, U);
-
-julia> I = ideal(R, gens(R))
-ideal(w, x, y, z)
-
-julia> depth(I, M)
-2
julia> S, x, y = polynomial_ring(QQ, "x" => 1:3, "y" => 1:5);
-
-julia> W = [y[1]-x[1]^2,  y[2]-x[2]^2,   y[3]-x[3]^2, y[4]-x[2]*(x[1]-x[3]),  y[5]-(x[1]-x[2])*x[3]];
-
-julia> J = eliminate(ideal(S, W), x);
-
-julia> R, y = polynomial_ring(QQ, "y" => 1:5);
-
-julia> W = append!(repeat([zero(R)], 3), gens(R))
-8-element Vector{QQMPolyRingElem}:
- 0
- 0
- 0
- y[1]
- y[2]
- y[3]
- y[4]
- y[5]
-
-julia> P = hom(S, R, W);
-
-julia> VP4 = P(J);
-
-julia> dim(VP4)
-3
-
-julia> F = free_module(R, 1);
-
-julia> U = collect(gen(VP4, i)*F[1] for i in 1:ngens(VP4));
-
-julia> M, _ = quo(F, U);
-
-julia> I = ideal(R, gens(R))
-ideal(y[1], y[2], y[3], y[4], y[5])
-
-julia> depth(I, M)
-1
source
diff --git a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/intro/index.html b/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/intro/index.html deleted file mode 100644 index d6a48af1df5d..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Our focus in this section is on finitely presented modules over rings from the following list:

  • multivariate polynomial rings (OSCAR type MPolyRing),
  • quotients of multivariate polynomial rings (OSCAR type MPolyQuoRing), and
  • localizations of the above rings (OSCAR types MPolyLocRing, MPolyQuoLocRing).

Hence, if not mentioned otherwise, the word module refers to a finitely presented module over a ring of one of the above types. Offering a sparse way of implementing free modules, the OSCAR type FreeMod provides the basis for implementing all modules discussed here. More concretely, the general way of implementing a module is to represent it as a subquotient, that is, as a submodule of a quotient of a free module. Note that subquotients form the smallest class of modules which naturally includes both submodules and quotients of free modules.

Note

Most functions in this section rely on Gröbner (standard) bases techniques. Thus, the functions should not be applied to modules over rings other than those from the list above. See the Linear Algebra chapter for module types which are designed to handle modules over Euclidean domains.

Note

For simplicity of the presentation in what follows, functions are often only illustrated by examples with focus on modules over multivariate polynomial rings, but work similarly for modules over a ring of any of the above types.

diff --git a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html b/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html deleted file mode 100644 index 70f1ad7a0dd2..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html +++ /dev/null @@ -1,411 +0,0 @@ - -Operations on Modules · Oscar.jl

Operations on Modules

Kernel

kernelMethod
kernel(a::ModuleFPHom)

Return the kernel of a as an object of type SubquoModule.

Additionally, if K denotes this object, return the inclusion map K $\to$ domain(a).

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 3);
-
-julia> G = free_module(R, 2);
-
-julia> W = R[y 0; x y; 0 z]
-[y   0]
-[x   y]
-[0   z]
-
-julia> a = hom(F, G, W);
-
-julia> K, incl = kernel(a);
-
-julia> K
-Submodule with 1 generator
-1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]
-represented as subquotient with no relations.
-
-julia> incl
-Map with following data
-Domain:
-=======
-Submodule with 1 generator
-1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]
-represented as subquotient with no relations.
-Codomain:
-=========
-Free module of rank 3 over Multivariate polynomial ring in 3 variables over QQ
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x*N[2]]
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x*y^2*e[1]
- x*y*e[1]
-
-julia> a = hom(M, N, V);
-
-julia> K, incl = kernel(a);
-
-julia> K
-Subquotient of Submodule with 3 generators
-1 -> (-x + y^2)*e[1]
-2 -> x*y*e[1]
-3 -> -x*y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> incl
-Map with following data
-Domain:
-=======
-Subquotient of Submodule with 3 generators
-1 -> (-x + y^2)*e[1]
-2 -> x*y*e[1]
-3 -> -x*y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> Z = abelian_group(0)
-GrpAb: Z
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> kernel(a)
-(Graded subquotient of submodule of F generated by
-1 -> -y*e[1]
-2 -> (x^2 - y^2)*e[1]
-3 -> -x*y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Graded subquotient of submodule of F generated by
-1 -> -y*e[1]
-2 -> (x^2 - y^2)*e[1]
-3 -> -x*y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> M
--y*e[1] -> -y*e[1]
-(x^2 - y^2)*e[1] -> (x^2 - y^2)*e[1]
--x*y*e[1] -> -x*y*e[1]
-Homogeneous module homomorphism)
-
source

Image

imageMethod
image(a::ModuleFPHom)

Return the image of a as an object of type SubquoModule.

Additionally, if I denotes this object, return the inclusion map I $\to$ codomain(a).

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 3);
-
-julia> G = free_module(R, 2);
-
-julia> W = R[y 0; x y; 0 z]
-[y   0]
-[x   y]
-[0   z]
-
-julia> a = hom(F, G, W);
-
-julia> I, incl = image(a);
-
-julia> I
-Submodule with 3 generators
-1 -> y*e[1]
-2 -> x*e[1] + y*e[2]
-3 -> z*e[2]
-represented as subquotient with no relations.
-
-julia> incl
-Map with following data
-Domain:
-=======
-Submodule with 3 generators
-1 -> y*e[1]
-2 -> x*e[1] + y*e[2]
-3 -> z*e[2]
-represented as subquotient with no relations.
-Codomain:
-=========
-Free module of rank 2 over Multivariate polynomial ring in 3 variables over QQ
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x*N[2]]
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x*y^2*e[1]
- x*y*e[1]
-
-julia> a = hom(M, N, V);
-
-julia> I, incl = image(a);
-
-julia> I
-Subquotient of Submodule with 2 generators
-1 -> x*y^2*e[1]
-2 -> x*y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> incl
-Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> x*y^2*e[1]
-2 -> x*y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> Z = abelian_group(0)
-GrpAb: Z
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> image(a)
-(Graded subquotient of submodule of F generated by
-1 -> x*y^2*e[1]
-2 -> x^2*y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Graded subquotient of submodule of F generated by
-1 -> x*y^2*e[1]
-2 -> x^2*y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> M
-x*y^2*e[1] -> x*y^2*e[1]
-x^2*y*e[1] -> x^2*y*e[1]
-Homogeneous module homomorphism)
source

Cokernel

cokernelMethod
cokernel(a::ModuleFPHom)

Return the cokernel of a as an object of type SubquoModule.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 3);
-
-julia> G = free_module(R, 2);
-
-julia> W = R[y 0; x y; 0 z]
-[y   0]
-[x   y]
-[0   z]
-
-julia> a = hom(F, G, W);
-
-julia> cokernel(a)
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 3 generators
-1 -> y*e[1]
-2 -> x*e[1] + y*e[2]
-3 -> z*e[2]
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x*N[2]]
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x*y^2*e[1]
- x*y*e[1]
-
-julia> a = hom(M, N, V);
-
-julia> cokernel(a)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 5 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-4 -> x*y^2*e[1]
-5 -> x*y*e[1]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F = graded_free_module(Rg, 3);
-
-julia> G = graded_free_module(Rg, 2);
-
-julia> W = Rg[y 0; x y; 0 z]
-[y   0]
-[x   y]
-[0   z]
-
-julia> a = hom(F, G, W)
-F -> G
-e[1] -> y*e[1]
-e[2] -> x*e[1] + y*e[2]
-e[3] -> z*e[2]
-Graded module homomorphism of degree [1]
-
-julia> M = cokernel(a)
-Graded subquotient of submodule of G generated by
-1 -> e[1]
-2 -> e[2]
-by submodule of G generated by
-1 -> y*e[1]
-2 -> x*e[1] + y*e[2]
-3 -> z*e[2]
-
source

Direct Sums and Products

direct_sumMethod
direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T

Given modules $M_1\dots M_n$, say, return the direct sum $\bigoplus_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical injections $M_i\to\bigoplus_{i=1}^n M_i$ if task = :sum (default),
  • a vector containing the canonical projections $\bigoplus_{i=1}^n M_i\to M_i$ if task = :prod,
  • two vectors containing the canonical injections and projections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_productMethod
direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T

Given modules $M_1\dots M_n$, say, return the direct product $\prod_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical projections $\prod_{i=1}^n M_i\to M_i$ if task = :prod (default),
  • a vector containing the canonical injections $M_i\to\prod_{i=1}^n M_i$ if task = :sum,
  • two vectors containing the canonical projections and injections, respectively, if task = :both,
  • none of the above maps if task = :none.
source

Truncation

truncateFunction
truncate(M::ModuleFP, g::GrpAbFinGenElem, task::Symbol = :with_morphism)

Given a finitely presented graded module M over a $\mathbb Z$-graded multivariate polynomial ring with positive weights, return the truncation of M at degree g.

Put more precisely, return the truncation as an object of type SubquoModule.

Additionally, if N denotes this object,

  • return the inclusion map N $\to$ M if task = :with_morphism (default),
  • return and cache the inclusion map N $\to$ M if task = :cache_morphism,
  • do none of the above if task = :none.

If task = :only_morphism, return only the inclusion map.

truncate(M::ModuleFP, d::Int, task::Symbol = :with_morphism)

Given a module M as above, and given an integer d, convert d into an element g of the grading group of base_ring(I) and proceed as above.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = graded_free_module(R, 1)
-Graded free module R^1([0]) of rank 1 over R
-
-julia> V = [x*F[1]; y^4*F[1]; z^5*F[1]];
-
-julia> M, _ = quo(F, V);
-
-julia> M[1]
-e[1]
-
-julia> MT = truncate(M, 3);
-
-julia> MT[1]
-Graded subquotient of submodule of F generated by
-1 -> z^3*e[1]
-2 -> y*z^2*e[1]
-3 -> y^2*z*e[1]
-4 -> y^3*e[1]
-5 -> x*z^2*e[1]
-6 -> x*y*z*e[1]
-7 -> x*y^2*e[1]
-8 -> x^2*z*e[1]
-9 -> x^2*y*e[1]
-10 -> x^3*e[1]
-by submodule of F generated by
-1 -> x*e[1]
-2 -> y^4*e[1]
-3 -> z^5*e[1]
source
diff --git a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html b/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html deleted file mode 100644 index f4b8e3d6b79e..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html +++ /dev/null @@ -1,1416 +0,0 @@ - -Subquotients · Oscar.jl

Subquotients

A subquotient is a submodule of a quotient of a free module. In this section, the expression subquotient refers to a subquotient over a ring of type MPolyRing, MPolyQuoRing, MPolyLocRing, or MPolyQuoLocRing. That is, given a ring $R$ of one of these types, a subquotient $M$ over $R$ is a module of type

\[M = (\text{im } a + \text{im } b)/\text{im } b,\]

where

\[a:R^s ⟶R^p \;\text{ and }\; b:R^t ⟶R^p\]

are two homomorphisms of free $R$-modules with the same codomain. We then refer to

  • the module $M$ as the subquotient defined by $a$ and $b$,
  • the codomain $R^p$ as the ambient free module of $M$,
  • the images of the canonical basis vectors of $R^s$ in $R^p$ as the ambient representatives of the generators of $M$, and
  • the images of the canonical basis vectors of $R^t$ in $R^p$ as the relations of $M$.

Alternatively, we speak of the subquotient of $\;\text{im } a\;$ by $\;\text{im } b\;$ or the subquotient defined by $A$ and $B$, where $A$ and $B$ are the matrices representing $a$ and $b$, respectively.

Finally, we refer to

  • the quotient of $R^p$ by the submodule generated by the relations of $M$ as the ambient module of $M$,

and regard $M$ as a submodule of that ambient module, embedded in the natural way.

Note

Recall from the section on free modules that by a free $R$-module we mean a free module of type $R^p$ , where we think of $R^p$ as a free module with a given basis, namely the basis of standard unit vectors. Accordingly, elements of free modules are represented by coordinate vectors, and homomorphisms between free modules by matrices. Here, by convention, vectors are row vectors, and matrices operate by multiplication on the right.

Note

Over a graded ring $R$, we work with graded free modules $R^s$, $R^p$, $R^t$ and graded homomorphisms $a$, $b$. As a consequence, every module involved in the construction of the subquotient defined by $a$ and $b$ carries an induced grading. In particular, the subquotient itself carries an induced grading.

Types

All OSCAR types for the finitely presented modules considered here belong to the abstract type ModuleFP{T}, where T is the element type of the underlying ring. Graded or not, the subquotients belong to the abstract subtype AbstractSubQuo{T} <: ModuleFP{T}, they are modelled as objects of the concrete type SubquoModule{T} <: AbstractSubQuo{T}.

Note

Canonical maps such us the canonical projection onto a quotient module arise in many constructions in commutative algebra. The SubquoModule type is designed so that it allows for the caching of such maps when executing functions. The tensor_product function discussed in this section provides an example.

Constructors

subquotientMethod
subquotient(a::FreeModuleHom, b::FreeModuleHom)

Given homomorphisms a and b between free modules such that codomain(a) === codomain(b), return $(\text{im } a + \text{im } b)/\text{im } b$.

subquotient(F::FreeMod{T}, A::MatElem{T}, B::MatElem{T}) where T

Given matrices A and B with rank F columns, return $(\text{im } a + \text{im } b)/\text{im } b$, where a and b are free module homomorphisms with codomain F represented by A and B.

subquotient(A::MatElem{T}, B::MatElem{T}) where T

Given matrices A and B with the same number of columns, create a free module F whose rank is that number, and return $(\text{im } a + \text{im } b)/\text{im } b$, where a and b are free module homomorphisms with codomain F represented by A and B.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> FR = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AR = R[x; y]
-[x]
-[y]
-
-julia> BR = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> MR = SubquoModule(FR, AR, BR)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> P = ideal(R, [x, y, z]);
-
-julia> U = complement_of_prime_ideal(P);
-
-julia> RL, _ = Localization(R, U);
-
-julia> FRL = free_module(RL, 1)
-Free module of rank 1 over Localization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal
-
-julia> ARL = RL[x; y]
-[x]
-[y]
-
-julia> BRL = RL[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> MRL = SubquoModule(FRL, ARL, BRL)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> RQ, _ = quo(R, ideal(R, [2*x^2-y^3, 2*x^2-y^5]));
-
-julia> FRQ = free_module(RQ, 1)
-Free module of rank 1 over RQ
-
-julia> ARQ = RQ[x; y]
-[x]
-[y]
-
-julia> BRQ = RQ[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> MRQ = SubquoModule(FRQ, ARQ, BRQ)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> 2*x^2*e[1]
-3 -> z^4*e[1]
-
-julia> RQL, _ = Localization(RQ, U);
-
-julia> FRQL = free_module(RQL, 1)
-Free module of rank 1 over Localization of quotient of multivariate polynomial ring at complement of prime ideal
-
-julia> ARQL = RQL[x; y]
-[x]
-[y]
-
-julia> BRQL = RQL[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> MRQL = SubquoModule(FRQL, ARQL, BRQL)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> 0
-2 -> 0
-3 -> z^4*e[1]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F1 = graded_free_module(Rg, [2,2,2]);
-
-julia> F2 = graded_free_module(Rg, [2]);
-
-julia> G = graded_free_module(Rg, [1,1]);
-
-julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]]
-3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- (x + y)*e[1] + y*e[2]
- z*e[2]
-
-julia> V2 = [z*G[2]+y*G[1]]
-1-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1] + z*e[2]
-
-julia> a1 = hom(F1, G, V1)
-F1 -> G
-e[1] -> y*e[1]
-e[2] -> (x + y)*e[1] + y*e[2]
-e[3] -> z*e[2]
-Homogeneous module homomorphism
-
-julia> a2 = hom(F2, G, V2)
-F2 -> G
-e[1] -> y*e[1] + z*e[2]
-Homogeneous module homomorphism
-
-julia> V = subquotient(a1,a2)
-Graded subquotient of submodule of G generated by
-1 -> y*e[1]
-2 -> (x + y)*e[1] + y*e[2]
-3 -> z*e[2]
-by submodule of G generated by
-1 -> y*e[1] + z*e[2]
-
-julia> A1 = Rg[x y; 2*x^2 3*y^2]
-[    x       y]
-[2*x^2   3*y^2]
-
-julia> A2 = Rg[x^3 x^2*y; (2*x^2+x*y)*x (2*y^3+y*x^2)]
-[          x^3           x^2*y]
-[2*x^3 + x^2*y   x^2*y + 2*y^3]
-
-julia> B = Rg[4*x*y^3 (2*x+y)^4]
-[4*x*y^3   16*x^4 + 32*x^3*y + 24*x^2*y^2 + 8*x*y^3 + y^4]
-
-julia> F2 = graded_free_module(Rg,[0,0])
-Graded free module Rg^2([0]) of rank 2 over Rg
-
-julia> M1 = SubQuo(F2, A1, B)
-Graded subquotient of submodule of F2 generated by
-1 -> x*e[1] + y*e[2]
-2 -> 2*x^2*e[1] + 3*y^2*e[2]
-by submodule of F2 generated by
-1 -> 4*x*y^3*e[1] + (16*x^4 + 32*x^3*y + 24*x^2*y^2 + 8*x*y^3 + y^4)*e[2]
source

Data Associated to Subqotients

If M is a subquotient with ambient free R-module F, then

  • base_ring(M) refers to R,
  • ambient_free_module(M) to F,
  • gens(M) to the generators of M,
  • ngens(M) to the number of these generators,
  • M[i], gen(M, i) to the ith such generator,
  • ambient_representatives_generators(M) to the ambient representatives of the generators of M in F,
  • relations(M) to the relations of M, and
  • ambient_module(M) to the ambient module of M.
Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> base_ring(M)
-Multivariate polynomial ring in 3 variables x, y, z
-  over rational field
-
-julia> F === ambient_free_module(M)
-true
-
-julia> gens(M)
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x*e[1]
- y*e[1]
-
-julia> ngens(M)
-2
-
-julia> gen(M, 2)
-y*e[1]
-
-julia> ambient_representatives_generators(M)
-2-element Vector{FreeModElem{QQMPolyRingElem}}:
- x*e[1]
- y*e[1]
-
-julia> relations(M)
-3-element Vector{FreeModElem{QQMPolyRingElem}}:
- x^2*e[1]
- y^3*e[1]
- z^4*e[1]
-
-julia> ambient_module(M)
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]

In the graded case, we also have:

grading_groupMethod
grading_group(M::SubquoModule)

Return the grading group of base_ring(M).

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F1 = graded_free_module(Rg, [2,2,2]);
-
-julia> F2 = graded_free_module(Rg, [2]);
-
-julia> G = graded_free_module(Rg, [1,1]);
-
-julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];
-
-julia> V2 = [z*G[2]+y*G[1]];
-
-julia> a1 = hom(F1, G, V1);
-
-julia> a2 = hom(F2, G, V2);
-
-julia> M = subquotient(a1,a2);
-
-julia> grading_group(M)
-GrpAb: Z
source
degrees_of_generatorsMethod
degrees_of_generators(M::SubquoModule)

Return the degrees of the generators of M.

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F1 = graded_free_module(Rg, [2,2,2]);
-
-julia> F2 = graded_free_module(Rg, [2]);
-
-julia> G = graded_free_module(Rg, [1,1]);
-
-julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];
-
-julia> V2 = [z*G[2]+y*G[1]];
-
-julia> a1 = hom(F1, G, V1);
-
-julia> a2 = hom(F2, G, V2);
-
-julia> M = subquotient(a1,a2);
-
-julia> degrees_of_generators(M)
-3-element Vector{GrpAbFinGenElem}:
- Element of Z with components [2]
- Element of Z with components [2]
- Element of Z with components [2]
-
-julia> gens(M)
-3-element Vector{SubquoModuleElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y*e[1]
- (x + y)*e[1] + y*e[2]
- z*e[2]
source

Elements of Subqotients

All OSCAR types for elements of finitely presented modules considered here belong to the abstract type ModuleElemFP{T}, where T is the element type of the polynomial ring. For elements of subquotients, there are the abstract subtype AbstractSubQuoElem{T} <: ModuleFPElem{T} and its concrete descendant SubquoModuleElem{T} which implements an element $m$ of a subquotient $M$ over a ring $R$ as a sparse row, that is, as an object of type SRow{T}. This object specifies the coefficients of an $R$-linear combination of the generators of $M$ giving $m$. To create an element, enter the coefficients as a sparse row or a vector:

(M::SubquoModule{T})(c::SRow{T}) where T
(M::SubquoModule{T})(c::Vector{T}) where T

Alternatively, directly write the element as an $R$-linear combination of generators of $M$.

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> m = M(sparse_row(R, [(1,z),(2,one(R))]))
-(x*z + y)*e[1]
-
-julia> n = M([z, one(R)])
-(x*z + y)*e[1]
-
-julia> o = z*M[1] + M[2]
-(x*z + y)*e[1]
-
-julia> m == n == o
-true
-

Given an element m of a subquotient M over a ring $R$ with element type T,

  • parent(m) refers to M,
  • coordinates(m) to an object of type SRow{T} specifying the coefficients of an $R$-linear combination of the generators of $M$ which gives $m$, and
  • ambient_representative(m) to an element of the ambient free module of M which represents m.

Given an element f of the ambient free module of a subquotient M such that f represents an element of M, the function below creates the represented element:

(M::SubquoModule{T})(f::FreeModElem{T}; check::Bool = true) where T

By default (check = true), it is tested whether f indeed represents an element of M. If this is already clear, it may be convenient to omit the test (check = false).

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> m = z*M[1] + M[2]
-(x*z + y)*e[1]
-
-julia> parent(m)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> coordinates(m)
-Sparse row with positions [1, 2] and values QQMPolyRingElem[z, 1]
-
-julia> fm = ambient_representative(m)
-(x*z + y)*e[1]
-
-julia> typeof(m)
-SubquoModuleElem{QQMPolyRingElem}
-
-julia> typeof(fm)
-FreeModElem{QQMPolyRingElem}
-
-julia> parent(fm) === ambient_free_module(M)
-true
-
-julia> F = ambient_free_module(M)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> f = x*F[1]
-x*e[1]
-
-julia> M(f)
-x*e[1]
-
-julia> typeof(f)
-FreeModElem{QQMPolyRingElem}
-
-julia> typeof(M(f))
-SubquoModuleElem{QQMPolyRingElem}
-

The zero element of a subquotient is obtained as follows:

zeroMethod
zero(M::SubquoModule)

Return the zero element of M.

source

Whether a given element of a subquotient is zero can be tested as follows:

is_zeroMethod
is_zero(m::SubquoModuleElem)

Return true if m is zero, false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> is_zero(M[1])
-false
-
-julia> is_zero(x*M[1])
-true
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1)
-Graded free module Rg^1([0]) of rank 1 over Rg
-
-julia> A = Rg[x; y]
-[x]
-[y]
-
-julia> B = Rg[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> is_zero(M[1])
-false
-
-julia> is_zero(x*M[1])
-true
-
source

In the graded case, we additionally have:

is_homogeneousMethod
is_homogeneous(m::SubquoModuleElem)

Return true if m is homogeneous, false otherwise.

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F1 = graded_free_module(Rg, [2,2,2]);
-
-julia> F2 = graded_free_module(Rg, [2]);
-
-julia> G = graded_free_module(Rg, [1,1]);
-
-julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];
-
-julia> V2 = [z*G[2]+y*G[1]];
-
-julia> a1 = hom(F1, G, V1);
-
-julia> a2 = hom(F2, G, V2);
-
-julia> M = subquotient(a1,a2);
-
-julia> m1 = x*M[1]+y*M[2]+z*M[3]
-(2*x*y + y^2)*e[1] + (y^2 + z^2)*e[2]
-
-julia> is_homogeneous(m1)
-true
-
-julia> is_homogeneous(zero(M))
-true
-
-julia> m2 = M[1]+x*M[2]
-(x^2 + x*y + y)*e[1] + x*y*e[2]
-
-julia> is_homogeneous(m2)
-false
-
-julia> m3 = x*M[1]+M[2]+x*M[3]
-(x*y + x + y)*e[1] + (x*z + y)*e[2]
-
-julia> is_homogeneous(m3)
-true
-
-julia> simplify(m3)
-x*e[1] + (y - z)*e[2]
source
degreeMethod
degree(m::SubquoModuleElem)

Given a homogeneous element m of a graded subquotient, return the degree of m.

degree(::Type{Vector{Int}}, m::SubquoModuleElem)

Given a homogeneous element m of a $\mathbb Z^m$-graded subquotient, return the degree of m, converted to a vector of integer numbers.

degree(::Type{Int}, m::SubquoModuleElem)

Given a homogeneous element m of a $\mathbb Z$-graded subquotient, return the degree of m, converted to an integer number.

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);
-
-julia> F1 = graded_free_module(Rg, [2,2,2]);
-
-julia> F2 = graded_free_module(Rg, [2]);
-
-julia> G = graded_free_module(Rg, [1,1]);
-
-julia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];
-
-julia> V2 = [z*G[2]+y*G[1]];
-
-julia> a1 = hom(F1, G, V1);
-
-julia> a2 = hom(F2, G, V2);
-
-julia> M = subquotient(a1,a2);
-
-julia> m = x*y*z*M[1]
-x*y^2*z*e[1]
-
-julia> degree(m)
-Element of Z with components [5]
-
-julia> degree(Int, m)
-5
-
-julia> m3 = x*M[1]+M[2]+x*M[3]
-(x*y + x + y)*e[1] + (x*z + y)*e[2]
-
-julia> degree(m3)
-Element of Z with components [2]
source

Tests on Subqotients

The functions is_graded, is_standard_graded, is_z_graded, and is_zm_graded carry over analogously to subquotients. They return true if the respective property is satisfied, and false otherwise. In addition, we have:

==Method
==(M::SubquoModule{T}, N::SubquoModule{T}) where {T}

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return true if M equals N, where M and N are regarded as submodules of the common ambient module.

Here, ambient_module(M) == ambient_module(N) if

  • ambient_free_module(M) === ambient_free_module(N), and
  • the submodules of the common ambient free module generated by the relations of M and N, respectively, are equal.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[x; y]
-[x]
-[y]
-
-julia> BN = R[x^2+y^4; y^3; z^4]
-[x^2 + y^4]
-[      y^3]
-[      z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> (x^2 + y^4)*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> M == N
-false
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1], Z[1], Z[1]]);
-
-julia> F = graded_free_module(Rg,2);
-
-julia> O1 = [x*F[1]+y*F[2],y*F[2]];
-
-julia> O1a = [x*F[1],y*F[2]];
-
-julia> O2 = [x^2*F[1]+y^2*F[2],y^2*F[2]];
-
-julia> M1 = SubquoModule(F, O1, O2)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1] + y*e[2]
-2 -> y*e[2]
-by submodule of F generated by
-1 -> x^2*e[1] + y^2*e[2]
-2 -> y^2*e[2]
-
-julia> M2 = SubquoModule(F, O1a, O2)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[2]
-by submodule of F generated by
-1 -> x^2*e[1] + y^2*e[2]
-2 -> y^2*e[2]
-
-julia> M1 == M2
-true
source
is_subsetMethod
is_subset(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return true if M is contained in N, where M and N are regarded as submodules of the common ambient module.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[x; y]
-[x]
-[y]
-
-julia> BN = R[x^2+y^4; y^3; z^4]
-[x^2 + y^4]
-[      y^3]
-[      z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> (x^2 + y^4)*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> is_subset(M, N)
-true
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1], Z[1], Z[1]]);
-
-julia> F = graded_free_module(Rg,2);
-
-julia> O1 = [x*F[1]+y*F[2],y*F[2]];
-
-julia> O1a = [x*F[1],y*F[2]];
-
-julia> O2 = [x^2*F[1]+y^2*F[2],y^2*F[2]];
-
-julia> M1 = SubquoModule(F, O1, O2)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1] + y*e[2]
-2 -> y*e[2]
-by submodule of F generated by
-1 -> x^2*e[1] + y^2*e[2]
-2 -> y^2*e[2]
-
-julia> M2 = SubquoModule(F, O1a, O2)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[2]
-by submodule of F generated by
-1 -> x^2*e[1] + y^2*e[2]
-2 -> y^2*e[2]
-
-julia> is_subset(M1,M2)
-true
-
-julia> is_subset(M2,M1)
-true
-
-julia> M1 == M2
-true
source
is_zeroMethod
is_zero(M::SubquoModule)

Return true if M is the zero module, false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x^2+y^2;]
-[x^2 + y^2]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 1 generator
-1 -> (x^2 + y^2)*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> is_zero(M)
-false
source

Basic Operations on Subquotients

+Method
+(M::SubquoModule{T},N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the sum of M and N regarded as submodules of the common ambient module.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[y;]
-[y]
-
-julia> BN = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> O = M + N
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> AM = Rg[x;];
-
-julia> BM = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, AM, BM)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = Rg[y;];
-
-julia> BN = Rg[x^2; y^3; z^4];
-
-julia> N = SubquoModule(F, AN, BN)
-Graded subquotient of submodule of F generated by
-1 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> M + N
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
source
sumMethod
sum(M::SubquoModule{T},N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the sum of M and N regarded as submodules of the common ambient module.

Additionally, return the inclusion maps M $\to$ M + N and N $\to$ M + N.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[y;]
-[y]
-
-julia> BN = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> O = sum(M, N);
-
-julia> O[1]
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> O[2]
-Map with following data
-Domain:
-=======
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> O[3]
-Map with following data
-Domain:
-=======
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> AM = Rg[x;];
-
-julia> BM = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, AM, BM)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = Rg[y;];
-
-julia> BN = Rg[x^2; y^3; z^4];
-
-julia> N = SubquoModule(F, AN, BN)
-Graded subquotient of submodule of F generated by
-1 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> sum(M, N)
-(Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], M -> Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-x*e[1] -> x*e[1]
-Homogeneous module homomorphism, N -> Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-y*e[1] -> y*e[1]
-Homogeneous module homomorphism)
-
source
intersectMethod
intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.

Additionally, return the inclusion maps M $\cap$ N $\to$ M and M $\cap$ N $\to$ N.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[y;]
-[y]
-
-julia> BN = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-, Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-)
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> AM = Rg[x;];
-
-julia> BM = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, AM, BM)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = Rg[y;];
-
-julia> BN = Rg[x^2; y^3; z^4];
-
-julia> N = SubquoModule(F, AN, BN)
-Graded subquotient of submodule of F generated by
-1 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> M
--x*y*e[1] -> -x*y*e[1]
-x*z^4*e[1] -> x*z^4*e[1]
-Homogeneous module homomorphism, Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> N
--x*y*e[1] -> x*y*e[1]
-x*z^4*e[1] -> 0
-Homogeneous module homomorphism)
-
source

Submodules and Quotients

subMethod
sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T

Given a vector V of (homogeneous) elements of M, return the (graded) submodule of M generated by these elements.

Put more precisely, return this submodule as an object of type SubquoModule.

Additionally, if N denotes this object,

  • return the inclusion map N $\to$ M if task = :with_morphism (default),
  • return and cache the inclusion map N $\to$ M if task = :cache_morphism,
  • do none of the above if task = :none.

If task = :only_morphism, return only the inclusion map.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];
-
-julia> N, incl = sub(F, V);
-
-julia> N
-Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-represented as subquotient with no relations.
-
-julia> incl
-Map with following data
-Domain:
-=======
-Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-represented as subquotient with no relations.
-Codomain:
-=========
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
source
quoMethod
quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T

Given a vector V of (homogeneous) elements of M, return the quotient of M by the (graded) submodule of M which is generated by these elements.

Put more precisely, return the quotient as an object of type SubquoModule.

Additionally, if N denotes this object,

  • return the projection map M $\to$ N if task = :with_morphism (default),
  • return and cache the projection map M $\to$ N if task = :cache_morphism,
  • do none of the above if task = :none or task = :module.

If task = :only_morphism, return only the projection map.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];
-
-julia> N, proj = quo(F, V);
-
-julia> N
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> proj
-Map with following data
-Domain:
-=======
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
source

Homomorphisms From Subqotients

All OSCAR types for homomorphisms of finitely presented modules considered here belong to the abstract type ModuleFPHom{T1, T2}, where T1 and T2 are the types of domain and codomain respectively. For homomorphisms from subquotients, OSCAR provides the concrete type SubQuoHom{T1, T2} <: ModuleFPHom{T1, T2} as well as the following constructors:

homMethod
hom(M::SubquoModule{T}, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T

Given a vector V of ngens(M) elements of N, return the homomorphism M $\to$ N which sends the i-th generator M[i] of M to the i-th entry of V.

hom(M::SubquoModule{T}, N::ModuleFP{T},  A::MatElem{T})) where T

Given a matrix A with ngens(M) rows and ngens(N) columns, return the homomorphism M $\to$ N which sends the i-th generator M[i] of M to the linear combination $\sum_j A[i,j]*N[j]$ of the generators N[j] of N.

Note

The module N may be of type FreeMod or SubquoMod. If both modules M and N are graded, the data must define a graded module homomorphism of some degree. If this degree is the zero element of the (common) grading group, we refer to the homomorphism under consideration as a homogeneous module homomorphism.

Warning

The functions do not check whether the resulting homomorphism is well-defined, that is, whether it sends the relations of M into the relations of N.

If you are uncertain with regard to well-definedness, use the function below. Note, however, that the check performed by the function requires a Gröbner basis computation. This may take some time.

is_welldefined(a::ModuleFPHom)

Return true if a is well-defined, and false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x*N[2]]
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x*y^2*e[1]
- x*y*e[1]
-
-julia> a = hom(M, N, V)
-Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> is_welldefined(a)
-true
-
-julia> W = R[y^2 0; 0 x]
-[y^2   0]
-[  0   x]
-
-julia> b = hom(M, N, W);
-
-julia> a == b
-true
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x; y];
-
-julia> B = R[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> N = M;
-
-julia> W = [y*N[1], x*N[2]]
-2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
- x*y*e[1]
- x*y*e[1]
-
-julia> c = hom(M, N, W);
-
-julia> is_welldefined(c)
-false
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> is_welldefined(a)
-true
-
-julia> W = Rg[y^2 0; 0 x^2]
-[y^2     0]
-[  0   x^2]
-
-julia> b = hom(M, N, W)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> a == b
-true
-
-julia> W = [y*N[1], x*N[2]]
-2-element Vector{SubquoModuleElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- x*y*e[1]
- x*y*e[1]
-
-julia> c = hom(M, N, W)
-M -> M
-x*e[1] -> x*y*e[1]
-y*e[1] -> x*y*e[1]
-Graded module homomorphism of degree [1]
-
-julia> is_welldefined(c)
-false
source

Given a homomorphism of type SubQuoHom, a matrix A representing it is recovered by the following function:

matrixMethod
matrix(a::SubQuoHom)

Given a homomorphism a of type SubQuoHom with domain M and codomain N, return a matrix A with ngens(M) rows and ngens(N) columns such that a == hom(M, N, A).

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> A = R[x; y]
-[x]
-[y]
-
-julia> B = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, A, B)
-Subquotient of Submodule with 2 generators
-1 -> x*e[1]
-2 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x*N[2]];
-
-julia> a = hom(M, N, V);
-
-julia> A = matrix(a)
-[y^2   0]
-[  0   x]
-
-julia> a(M[1])
-x*y^2*e[1]
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-2 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> matrix(a)
-[y^2     0]
-[  0   x^2]
-
source

The domain and codomain of a homomorphism a of type SubQuoHom can be recovered by entering domain(a) and codomain(a), respectively.

The functions below test whether a homomorphism of type SubQuoHom is graded and homogeneous, respectively.

is_gradedMethod
is_graded(a::SubQuoHom)

Return true if a is graded, false otherwise.

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> is_graded(a)
-true
source
is_homogeneousMethod
is_homogeneous(a::SubQuoHom)

Return true if a is homogeneous, false otherwise

Here, if G is the grading group of a, a is homogeneous if a is graded of degree zero(G).

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> is_homogeneous(a)
-false
source

In the graded case, we additionally have:

degreeMethod
degree(a::SubQuoHom)

If a is graded, return the degree of a.

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> degree(a)
-Element of Z with components [2]
source
grading_groupMethod
grading_group(a::SubQuoHom)

If a is graded, return the grading group of a.

Examples

julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> A = Rg[x; y];
-
-julia> B = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, A, B);
-
-julia> N = M;
-
-julia> V = [y^2*N[1], x^2*N[2]];
-
-julia> a = hom(M, N, V)
-M -> M
-x*e[1] -> x*y^2*e[1]
-y*e[1] -> x^2*y*e[1]
-Graded module homomorphism of degree [2]
-
-julia> grading_group(a)
-GrpAb: Z
source
diff --git a/previews/PR2578/CommutativeAlgebra/affine_algebras/index.html b/previews/PR2578/CommutativeAlgebra/affine_algebras/index.html deleted file mode 100644 index db957d50e570..000000000000 --- a/previews/PR2578/CommutativeAlgebra/affine_algebras/index.html +++ /dev/null @@ -1,1123 +0,0 @@ - -Affine Algebras and Their Ideals · Oscar.jl

Affine Algebras and Their Ideals

With regard to notation, we use affine algebra as a synonym for quotient of a multivariate polynomial ring by an ideal. More specifically, if $R$ is a multivariate polynomial ring with coefficient ring $C$, and $A=R/I$ is the quotient of $R$ by an ideal $I$ of $R$, we refer to $A$ as an affine algebra over $C$, or an affine $C$-algebra. In this section, we discuss functionality for handling such algebras in OSCAR.

Note

To emphasize this point: In this section, we view $R/I$ together with its ring structure. Realizing $R/I$ as an $R$-module means to implement it as the quotient of a free $R$-module of rank 1. See the section on modules.

Note

Most functions discussed here rely on Gröbner basis techniques. In particular, they typically make use of a Gröbner basis for the modulus of the quotient. Nevertheless, the construction of quotients is lazy in the sense that the computation of such a Gröbner basis is delayed until the user performs an operation that indeed requires it (the Gröbner basis is then computed with respect to the default_ordering on the underlying polynomial ring; see the section on Gröbner/Standard Bases for default orderings in OSCAR). Once computed, the Gröbner basis is cached for later reuse.

Note

Recall that Gröbner basis methods are implemented for multivariate polynomial rings over fields (exact fields supported by OSCAR) and, where not indicated otherwise, for multivariate polynomial rings over the integers.

Note

In OSCAR, elements of a quotient $A = R/I$ are not necessarily represented by polynomials which are reduced with regard to $I$. That is, if $f\in R$ is the internal polynomial representative of an element of $A$, then $f$ may not be the normal form mod $I$ with respect to the default ordering on $R$ (see the section on Gröbner/Standard Bases for normal forms). Operations involving Gröbner basis computations may lead to (partial) reductions. The function simplify discussed in this section computes fully reduced representatives.

Note

Each grading on a multivariate polynomial ring R in OSCAR descends to a grading on the affine algebra A = R/I (recall that OSCAR ideals of graded polynomial rings are required to be homogeneous). Functionality for dealing with such gradings and our notation for describing this functionality descend accordingly. This applies, in particular, to the functions is_graded, is_standard_graded, is_z_graded, is_zm_graded, and is_positively_graded which will not be discussed again here.

Types

The OSCAR type for quotients of multivariate polynomial rings is of parametrized form MPolyQuoRing{T}, with elements of type MPolyQuoRingElem{T}. Here, T is the element type of the polynomial ring.

Constructors

quoMethod
quo(R::MPolyRing, I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(R)) -> MPolyQuoRing, Map

Create the quotient ring R/I and return the new ring as well as the projection map R $\to$ R/I. Computations inside R/I are done w.r.t. ordering.

quo(R::MPolyRing, V::Vector{MPolyRingElem}) -> MPolyQuoRing, Map

As above, where I is the ideal of R generated by the polynomials in V.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, p = quo(R, ideal(R, [x^2-y^3, x-y]));
-
-julia> A
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ
-  by ideal(x^2 - y^3, x - y)
-
-julia> typeof(A)
-MPolyQuoRing{QQMPolyRingElem}
-
-julia> typeof(x)
-QQMPolyRingElem
-
-julia> p
-Map from
-Multivariate polynomial ring in 2 variables over QQ to A defined by a julia-function with inverse
-
-julia> p(x)
-x
-
-julia> typeof(p(x))
-MPolyQuoRingElem{QQMPolyRingElem}
julia> S, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> B, _ = quo(S, ideal(S, [x^2*z-y^3, x-y]))
-(Quotient of multivariate polynomial ring by ideal with 2 generators, Map from
-S to B defined by a julia-function with inverse)
-
-julia> typeof(B)
-MPolyQuoRing{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}
source

Data Associated to Affine Algebras

Basic Data

If A=R/I is the quotient of a multivariate polynomial ring R modulo an ideal I of R, then

  • base_ring(A) refers to R,
  • modulus(A) to I,
  • gens(A) to the generators of A,
  • ngens(A) to the number of these generators, and
  • gen(A, i) as well as A[i] to the i-th such generator.
Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
-
-julia> base_ring(A)
-Multivariate polynomial ring in 3 variables x, y, z
-  over rational field
-
-julia> modulus(A)
-ideal(-x^2 + y, -x^3 + z)
-
-julia> gens(A)
-3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x
- y
- z
-
-julia> ngens(A)
-3
-
-julia> gen(A, 2)
-y
-

In the graded case, we additionally have:

grading_groupMethod
grading_group(A::MPolyQuoRing{<:MPolyDecRingElem})

If A is, say, G-graded, return G.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [x^2*z-y^3, x-y]));
-
-julia> grading_group(A)
-GrpAb: Z
source
monomial_basisMethod
monomial_basis(A::MPolyQuoRing, g::GrpAbFinGenElem)

Given an affine algebra A over a field which is graded by a free group of type GrpAbFinGen, and given an element g of that group, return a vector of monomials of R such that the residue classes of these monomials form a K-basis of the graded part of A of degree g.

monomial_basis(A::MPolyQuoRing, W::Vector{<:IntegerUnion})

Given a $\mathbb Z^m$-graded affine algebra A over a field and a vector W of $m$ integers, convert W into an element g of the grading group of A and proceed as above.

monomial_basis(A::MPolyQuoRing, d::IntegerUnion)

Given a $\mathbb Z$-graded affine algebra A over a field and an integer d, convert d into an element g of the grading group of A and proceed as above.

Note

If the component of the given degree is not finite dimensional, an error message will be thrown.

Examples

julia> R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"]);
-
-julia> I = ideal(R, [x^2])
-ideal(x^2)
-
-julia> A, _ = quo(R, I)
-(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from
-R to A defined by a julia-function with inverse)
-
-julia> L = monomial_basis(A, 3)
-2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- y^3
- x*y^2
source
homogeneous_componentMethod
homogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::GrpAbFinGenElem)

Given a graded quotient A of a multivariate polynomial ring over a field, where the grading group is free of type GrpAbFinGen, and given an element g of that group, return the homogeneous component of A of degree g. Additionally, return the embedding of the component into A.

homogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::Vector{<:IntegerUnion})

Given a $\mathbb Z^m$-graded quotient A of a multivariate polynomial ring over a field, and given a vector g of $m$ integers, convert g into an element of the grading group of A, and return the homogeneous component of A whose degree is that element. Additionally, return the embedding of the component into A.

homogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::IntegerUnion)

Given a $\mathbb Z$-graded quotient A of a multivariate polynomial ring over a field, and given an integer g, convert g into an element of the grading group of A, and return the homogeneous component of A whose degree is that element. Additionally, return the embedding of the component into A.

Note

If the component is not finite dimensional, an error message will be thrown.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"])
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[w, x, y, z])
-
-julia> L = homogeneous_component(R, 2);
-
-julia> HC = gens(L[1]);
-
-julia> EMB = L[2]
-Map from
-R_[2] of dim 10 to R defined by a julia-function with inverse
-
-julia> for i in 1:length(HC) println(EMB(HC[i])) end
-z^2
-y*z
-y^2
-x*z
-x*y
-x^2
-w*z
-w*y
-w*x
-w^2
-
-julia> PTC = ideal(R, [-x*z + y^2, -w*z + x*y, -w*y + x^2]);
-
-julia> A, _ = quo(R, PTC);
-
-julia> L = homogeneous_component(A, 2);
-
-julia> HC = gens(L[1]);
-
-julia> EMB = L[2]
-Map from
-Quotient space over:
-Rational field with 7 generators and no relations to A defined by a julia-function with inverse
-
-julia> for i in 1:length(HC) println(EMB(HC[i])) end
-z^2
-y*z
-x*z
-w*z
-w*y
-w*x
-w^2
julia> R, x, y = polynomial_ring(QQ, "x" => 1:2, "y" => 1:3);
-
-julia> G = abelian_group([0, 0])
-GrpAb: Z^2
-
-julia> g = gens(G)
-2-element Vector{GrpAbFinGenElem}:
- Element of G with components [1 0]
- Element of G with components [0 1]
-
-julia> W = [g[1], g[1], g[2], g[2], g[2]];
-
-julia> S, _ = grade(R, W);
-
-julia> L = homogeneous_component(S, [2,1]);
-
-julia> HC = gens(L[1]);
-
-julia> EMB = L[2]
-Map from
-homogeneous component of Graded multivariate polynomial ring in 5 variables over QQ of degree Element of G with components [2 1]
- to S defined by a julia-function with inverse
-
-julia> for i in 1:length(HC) println(EMB(HC[i])) end
-x[2]^2*y[3]
-x[2]^2*y[2]
-x[2]^2*y[1]
-x[1]*x[2]*y[3]
-x[1]*x[2]*y[2]
-x[1]*x[2]*y[1]
-x[1]^2*y[3]
-x[1]^2*y[2]
-x[1]^2*y[1]
-
-julia> I = ideal(S, [x[1]*y[1]-x[2]*y[2]]);
-
-julia> A, = quo(S, I);
-
-julia> L = homogeneous_component(A, [2,1]);
-
-julia> HC = gens(L[1]);
-
-julia> EMB = L[2]
-Map from
-Quotient space over:
-Rational field with 7 generators and no relations to A defined by a julia-function with inverse
-
-julia> for i in 1:length(HC) println(EMB(HC[i])) end
-x[2]^2*y[3]
-x[2]^2*y[2]
-x[2]^2*y[1]
-x[1]*x[2]*y[3]
-x[1]*x[2]*y[2]
-x[1]^2*y[3]
-x[1]^2*y[2]
source

Dimension

dimMethod
dim(A::MPolyQuoRing)

Return the Krull dimension of A.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
-
-julia> dim(A)
-1
source
vector_space_dimensionMethod
vector_space_dimension(A::MPolyQuoRing)

If, say, A = R/I, where R is a multivariate polynomial ring over a field K, and I is a zero-dimensional ideal of R, return the dimension of A as a K-vector space.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [x^3+y^3+z^3-1, x^2+y^2+z^2-1, x+y+z-1]));
-
-julia> vector_space_dimension(A)
-6
-
-julia> I = modulus(A)
-ideal(x^3 + y^3 + z^3 - 1, x^2 + y^2 + z^2 - 1, x + y + z - 1)
-
-julia> groebner_basis(I, ordering = lex(base_ring(I)))
-Gröbner basis with elements
-1 -> z^3 - z^2
-2 -> y^2 + y*z - y + z^2 - z
-3 -> x + y + z - 1
-with respect to the ordering
-lex([x, y, z])
source
monomial_basisMethod
monomial_basis(A::MPolyQuoRing)

If, say, A = R/I, where R is a multivariate polynomial ring over a field K, and I is a zero-dimensional ideal of R, return a vector of monomials of R such that the residue classes of these monomials form a basis of A as a K-vector space.

Examples

julia> R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"]);
-
-julia> I = ideal(R, [x^2, y^3])
-ideal(x^2, y^3)
-
-julia> A, _ = quo(R, I)
-(Quotient of multivariate polynomial ring by ideal with 2 generators, Map from
-R to A defined by a julia-function with inverse)
-
-julia> L = monomial_basis(A)
-6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x*y^2
- y^2
- x*y
- y
- x
- 1
source

Elements of Affine Algebras

Types

The OSCAR type for elements of quotients of multivariate polynomial rings is of parametrized form MPolyQuoRing{T}, where T is the element type of the polynomial ring.

Creating Elements of Affine Algebras

Elements of an affine algebra A=R/I are created as images of elements of R under the projection map or by directly coercing elements of R into A.

Examples
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, p = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
-
-julia> f = p(x^3*y^2-y^3*x^2+x*y)
-x^3*y^2 - x^2*y^3 + x*y
-
-julia> typeof(f)
-MPolyQuoRingElem{QQMPolyRingElem}
-
-julia> g = A(x^3*y^2-y^3*x^2+x*y)
-x^3*y^2 - x^2*y^3 + x*y
-
-julia> f == g
-true
-

Reducing Polynomial Representatives

simplifyMethod
simplify(f::MPolyQuoRingElem{T}) where {S<:Union{FieldElem, ZZRingElem}, T<:MPolyRingElem{S}}

If f is an element of the quotient of a multivariate polynomial ring R by an ideal I of R, say, replace the internal polynomial representative of f by its normal form mod I with respect to the default_ordering on R.

Note

Since this method only has a computational backend for quotients of polynomial rings over a field, it is not implemented generically.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> A, p = quo(R, ideal(R, [x^4]));
-
-julia> f = p(2*x^6 + x^3 + x)
-2*x^6 + x^3 + x
-
-julia> simplify(f)
-x^3 + x
-
-julia> f
-x^3 + x
source

Tests on Elements of Affine Algebras

==Method
==(f::MPolyQuoRingElem{T}, g::MPolyQuoRingElem{T}) where T

Return true if f is equal to g, false otherwise.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> A, p = quo(R, ideal(R, [x^4]));
-
-julia> f = p(x-x^6)
--x^6 + x
-
-julia> g = p(x)
-x
-
-julia> f == g
-true
source

In the graded case, we additionally have:

is_homogeneousMethod
is_homogeneous(f::MPolyQuoRingElem{<:MPolyDecRingElem})

Given an element f of a graded affine algebra, return true if f is homogeneous, false otherwise.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));
-
-julia> f = p(y^2-x^2+z^4)
--x^2 + y^2 + z^4
-
-julia> is_homogeneous(f)
-true
-
-julia> f
-z^4
source

Data associated to Elements of Affine Algebras

Given an element f of an affine algebra A,

  • parent(f) refers to A.

In the graded case, we also have:

homogeneous_componentsMethod
homogeneous_components(f::MPolyQuoRingElem{<:MPolyDecRingElem})

Given an element f of a graded affine algebra, return the homogeneous components of f.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));
-
-julia> f = p(y^2-x^2+x*y*z+z^4)
--x^2 + x*y*z + y^2 + z^4
-
-julia> homogeneous_components(f)
-Dict{GrpAbFinGenElem, MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}} with 2 entries:
-  [4] => z^4
-  [3] => y^2*z
source
homogeneous_componentMethod
homogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::GrpAbFinGenElem)

Given an element f of a graded affine algebra, and given an element g of the grading group of that algebra, return the homogeneous component of f of degree g.

homogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::Vector{<:IntegerUnion})

Given an element f of a $\mathbb Z^m$-graded affine algebra A, say, and given a vector g of $m$ integers, convert g into an element of the grading group of A, and return the homogeneous component of f whose degree is that element.

homogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::IntegerUnion)

Given an element f of a $\mathbb Z$-graded affine algebra A, say, and given an integer g, convert g into an element of the grading group of A, and return the homogeneous component of f whose degree is that element.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));
-
-julia> f = p(y^2-x^2+x*y*z+z^4)
--x^2 + x*y*z + y^2 + z^4
-
-julia> homogeneous_component(f, 4)
-z^4
source
degreeMethod
degree(f::MPolyQuoRingElem{<:MPolyDecRingElem})

Given a homogeneous element f of a graded affine algebra, return the degree of f.

degree(::Type{Vector{Int}}, f::MPolyQuoRingElem{<:MPolyDecRingElem})

Given a homogeneous element f of a $\mathbb Z^m$-graded affine algebra, return the degree of f, converted to a vector of integer numbers.

degree(::Type{Int}, f::MPolyQuoRingElem{<:MPolyDecRingElem})

Given a homogeneous element f of a $\mathbb Z$-graded affine algebra, return the degree of f, converted to an integer number.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"] );
-
-julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]))
-(Quotient of multivariate polynomial ring by ideal with 2 generators, Map from
-R to A defined by a julia-function with inverse)
-
-julia> f = p(y^2-x^2+z^4)
--x^2 + y^2 + z^4
-
-julia> degree(f)
-[4]
-
-julia> typeof(degree(f))
-GrpAbFinGenElem
-
-julia> degree(Int, f)
-4
-
-julia> typeof(degree(Int, f))
-Int64
source

Ideals in Affine Algebras

Constructors

idealMethod
ideal(A::MPolyQuoRing{T}, V::Vector{T}) where T <: MPolyRingElem

Given a (graded) quotient ring A=R/I and a vector V of (homogeneous) polynomials in R, create the ideal of A which is generated by the images of the entries of V.

ideal(A::MPolyQuoRing{T}, V::Vector{MPolyQuoRingElem{T}}) where T <: MPolyRingElem

Given a (graded) quotient ring A and a vector V of (homogeneous) elements of A, create the ideal of A which is generated by the entries of V.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
-
-julia> I = ideal(A, [x^2-y])
-ideal(x^2 - y)
julia> S, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> B, _ = quo(S, ideal(S, [x^2*z-y^3, x-y]));
-
-julia> J = ideal(B, [x^2-y^2])
-ideal(x^2 - y^2)
source

Reducing Polynomial Representatives of Generators

simplifyMethod
simplify(a::MPolyQuoIdeal)

If a is an ideal of the quotient of a multivariate polynomial ring R by an ideal I of R, say, replace the internal polynomial representative of each generator of a by its normal form mod I with respect to the default_ordering on R.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
-
-julia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])
-ideal(x^3*y^4 - x + y, x*y^2 + x*y)
-
-julia> gens(a)
-2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x^3*y^4 - x + y
- x*y^2 + x*y
-
-julia> simplify(a)
-ideal(x^2*y^3 - x + y, x*y^2 + x*y)
-
-julia> gens(a)
-2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x^2*y^3 - x + y
- x*y^2 + x*y
source

Data Associated to Ideals in Affine Algebras

Basic Data

If a is an ideal of the affine algebra A, then

  • base_ring(a) refers to A,
  • gens(a) to the generators of a,
  • ngens(a) to the number of these generators, and
  • gen(a, i) as well as a[i] to the i-th such generator.
Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
-
-julia> a = ideal(A, [x-y, z^4])
-ideal(x - y, z^4)
-
-julia> base_ring(a)
-Quotient
-  of multivariate polynomial ring in 3 variables over QQ
-  by ideal(-x^2 + y, -x^3 + z)
-
-julia> gens(a)
-2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x - y
- z^4
-
-julia> ngens(a)
-2
-
-julia> gen(a, 2)
-z^4
-

Dimension of Ideals in Affine Algebras

dimMethod
dim(a::MPolyQuoIdeal)

Return the Krull dimension of a.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
-
-julia> a = ideal(A, [x-y])
-ideal(x - y)
-
-julia> dim(a)
-0
source

Minimal Sets of Generators

In the graded case, we have:

minimal_generating_setMethod
minimal_generating_set(I::MPolyQuoIdeal{<:MPolyDecRingElem})

Given a homogeneous ideal I of a graded affine algebra over a field, return an array containing a minimal set of generators of I. If I is the zero ideal an empty list is returned.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, p = quo(R, ideal(R, [x-y]));
-
-julia> V = [x, z^2, x^3+y^3, y^4, y*z^5];
-
-julia> a = ideal(A, V);
-
-julia> minimal_generating_set(a)
-2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- y
- z^2
-
-julia> a = ideal(A, [x-y])
-ideal(x - y)
-
-julia> minimal_generating_set(a)
-MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}[]
source

Operations on Ideals in Affine Algebras

Simple Ideal Operations in Affine Algebras

Powers of Ideal
^Method
:^(a::MPolyQuoIdeal, m::Int)

Return the m-th power of a.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, [x^2-y, y^2-x+y]);
-
-julia> a = ideal(A, [x+y])
-ideal(x + y)
-
-julia> a^2
-ideal(x^2 + 2*x*y + y^2)
source
Sum of Ideals
+Method
:+(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T

Return the sum of a and b.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, [x^2-y, y^2-x+y]);
-
-julia> a = ideal(A, [x+y])
-ideal(x + y)
-
-julia> b = ideal(A, [x^2+y^2, x+y])
-ideal(x^2 + y^2, x + y)
-
-julia> a+b
-ideal(x + y, x^2 + y^2)
source
Product of Ideals
*Method
:*(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T

Return the product of a and b.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, [x^2-y, y^2-x+y]);
-
-julia> a = ideal(A, [x+y])
-ideal(x + y)
-
-julia> b = ideal(A, [x^2+y^2, x+y])
-ideal(x^2 + y^2, x + y)
-
-julia> a*b
-ideal(x^3 + x^2*y + x*y^2 + y^3, x^2 + 2*x*y + y^2)
source

Intersection of Ideals

intersectMethod
intersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T
-intersect(V::Vector{MPolyQuoIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
-
-julia> a = ideal(A, [y^2])
-ideal(y^2)
-
-julia> b = ideal(A, [x])
-ideal(x)
-
-julia> intersect(a,b)
-ideal(x*y)
-
-julia> intersect([a,b])
-ideal(x*y)
source
intersectMethod
intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T
-intersect(V::Vector{MPolyIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2;
-
-julia> J = ideal(R, [y^2-x^3+x]);
-
-julia> intersect(I, J)
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> intersect([I, J])
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
source
intersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T
-intersect(V::Vector{MPolyQuoIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
-
-julia> a = ideal(A, [y^2])
-ideal(y^2)
-
-julia> b = ideal(A, [x])
-ideal(x)
-
-julia> intersect(a,b)
-ideal(x*y)
-
-julia> intersect([a,b])
-ideal(x*y)
source
intersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}
-intersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}

Return the intersection of two or more ideals.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"]);
-
-julia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))
-left_ideal(-x^3 + dy^2 + x)
source
intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.

Additionally, return the inclusion maps M $\cap$ N $\to$ M and M $\cap$ N $\to$ N.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[y;]
-[y]
-
-julia> BN = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-, Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-)
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> AM = Rg[x;];
-
-julia> BM = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, AM, BM)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = Rg[y;];
-
-julia> BN = Rg[x^2; y^3; z^4];
-
-julia> N = SubquoModule(F, AN, BN)
-Graded subquotient of submodule of F generated by
-1 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> M
--x*y*e[1] -> -x*y*e[1]
-x*z^4*e[1] -> x*z^4*e[1]
-Homogeneous module homomorphism, Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> N
--x*y*e[1] -> x*y*e[1]
-x*z^4*e[1] -> 0
-Homogeneous module homomorphism)
-
source
intersect(T1, T2)

Intersect two tropical varieties.

Examples

julia> RR = TropicalSemiring(min)
-Tropical semiring (min)
-
-julia> S,(x,y) = RR["x","y"]
-(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])
-
-julia> f1 = x+y+1
-x + y + (1)
-
-julia> f2 = x^2+y^2+RR(-6)
-x^2 + y^2 + (-6)
-
-julia> hyp1 = TropicalHypersurface(f1)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> hyp2 = TropicalHypersurface(f2)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> tv12 = intersect(hyp1, hyp2)
-min tropical variety of dimension 1 embedded in 2-dimensional Euclidean space
source
intersect(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl

Returns $a \cap b$.

intersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl

Returns $a \cap b$.

Ideal Quotients

quotientMethod
quotient(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T

Return the ideal quotient of a by b. Alternatively, use a:b.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
-
-julia> a = ideal(A, [y^2])
-ideal(y^2)
-
-julia> b = ideal(A, [x])
-ideal(x)
-
-julia> a:b
-ideal(y)
source

Tests on Ideals in Affine Algebras

Basic Tests

is_zeroMethod
is_zero(a::MPolyQuoIdeal)

Return true if a is the zero ideal, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, [x^2-y, y^2-x+y]);
-
-julia> a = ideal(A, [x^2+y^2, x+y])
-ideal(x^2 + y^2, x + y)
-
-julia> is_zero(a)
-false
-
-julia> b = ideal(A, [x^2-y])
-ideal(x^2 - y)
-
-julia> is_zero(b)
-true
source

Containment of Ideals in Affine Algebras

is_subsetMethod
is_subset(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T

Return true if a is contained in b, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
-
-julia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])
-ideal(x^3*y^4 - x + y, x*y^2 + x*y)
-
-julia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])
-ideal(x^3*y^3 - x + y, x^2*y + x*y^2)
-
-julia> is_subset(a,b)
-false
-
-julia> is_subset(b,a)
-true
source

Equality of Ideals in Affine Algebras

==Method
==(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T

Return true if a is equal to b, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
-
-julia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])
-ideal(x^3*y^4 - x + y, x*y^2 + x*y)
-
-julia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])
-ideal(x^3*y^3 - x + y, x^2*y + x*y^2)
-
-julia> a == b
-false
source

Ideal Membership

ideal_membershipMethod
ideal_membership(f::MPolyQuoRingElem{T}, a::MPolyQuoIdeal{T}) where T

Return true if f is contained in a, false otherwise. Alternatively, use f in a.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
-
-julia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])
-ideal(x^3*y^4 - x + y, x*y^2 + x*y)
-
-julia> f = A(x^2*y^3-x+y)
-x^2*y^3 - x + y
-
-julia> f in a
-true
source

Homomorphisms From Affine Algebras

If $A=R/I$ is an affine $C$-algebra, and $S$ is any ring, then defining a ring homomorphism $\overline{\phi}: A \to S$ means to define a ring homomorphism $\phi: R \to S$ such that $I\subset \ker(\phi)$. Thus, $\overline{\phi} $ is determined by specifying its restriction to $C$, and by assigning an image to each generator of $A$. In OSCAR, such homomorphisms are created as follows:

homMethod
hom(A::MPolyQuoRing, S::NCRing, coeff_map, images::Vector; check::Bool = true)
-
-hom(A::MPolyQuoRing, S::NCRing, images::Vector; check::Bool = true)

Given a homomorphism coeff_map from C to S, where C is the coefficient ring of the base ring of A, and given a vector images of ngens(A) elements of S, return the homomorphism A $\to$ S whose restriction to C is coeff_map, and which sends the i-th generator of A to the i-th entry of images.

If no coefficient map is entered, invoke a canonical homomorphism of C to S, if such a homomorphism exists, and throw an error, otherwise.

Note

The function returns a well-defined homomorphism A $\to$ S iff the given data defines a homomorphism from the base ring of A to S whose kernel contains the modulus of A. This condition is checked by the function in case check = true (default).

Note

In case check = true (default), the function also checks the conditions below:

  • If S is graded, the assigned images must be homogeneous with respect to the given grading.
  • If S is noncommutative, the assigned images must pairwise commute.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"] );
-
-julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
-
-julia> S, (s, t) = polynomial_ring(QQ, ["s", "t"]);
-
-julia> F = hom(A, S, [s, s^2, s^3])
-Map with following data
-Domain:
-=======
-A
-Codomain:
-=========
-Multivariate polynomial ring in 2 variables over QQ
source

Given a ring homomorphism F : R $\to$ S as above, domain(F) and codomain(F) refer to R and S, respectively. Given ring homomorphisms F : R $\to$ S and G : S $\to$ T as above, compose(F, G) refers to their composition.

Homomorphisms of Affine Algebras

The OSCAR homomorphism type AffAlgHom models ring homomorphisms R $\to$ S such that the type of both R and S is a subtype of Union{MPolyRing{T}, MPolyQuoRing{U}}, where T <: FieldElem and U <: MPolyRingElem{T}. Functionality for these homomorphism is discussed in what follows.

Data Associated to Homomorphisms of Affine Algebras

preimageMethod
preimage(F::AffAlgHom, I::U) where U <: Union{MPolyIdeal, MPolyQuoIdeal}

Return the preimage of the ideal I under F.

source
kernelMethod
kernel(F::AffAlgHom)

Return the kernel of F.

source
Examples
julia> D1, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> C1, (s,t) = graded_polynomial_ring(QQ, ["s", "t"]);
-
-julia> V1 = [s^3, s^2*t, s*t^2, t^3];
-
-julia> para = hom(D1, C1, V1)
-Map with following data
-Domain:
-=======
-Graded multivariate polynomial ring in 4 variables over QQ
-Codomain:
-=========
-Graded multivariate polynomial ring in 2 variables over QQ
-
-julia> twistedCubic = kernel(para)
-ideal(-x*z + y^2, -w*z + x*y, -w*y + x^2)
-
-julia> C2, p2 = quo(D1, twistedCubic);
-
-julia> D2, (a, b, c) = graded_polynomial_ring(QQ, ["a", "b", "c"]);
-
-julia> V2 = [p2(w-y), p2(x), p2(z)];
-
-julia> proj = hom(D2, C2, V2)
-Map with following data
-Domain:
-=======
-Graded multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Quotient of multivariate polynomial ring by ideal with 3 generators
-
-julia> nodalCubic = kernel(proj)
-ideal(-a^2*c + b^3 - 2*b^2*c + b*c^2)
-
julia> D3,y = polynomial_ring(QQ, "y" => 1:3);
-
-julia> C3, x = polynomial_ring(QQ, "x" => 1:3);
-
-julia> V3 = [x[1]*x[2], x[1]*x[3], x[2]*x[3]];
-
-julia> F3 = hom(D3, C3, V3)
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Multivariate polynomial ring in 3 variables over QQ
-
-julia> sphere = ideal(C3, [x[1]^3 + x[2]^3  + x[3]^3 - 1])
-ideal(x[1]^3 + x[2]^3 + x[3]^3 - 1)
-
-julia> steinerRomanSurface = preimage(F3, sphere)
-ideal(y[1]^6*y[2]^6 + 2*y[1]^6*y[2]^3*y[3]^3 + y[1]^6*y[3]^6 + 2*y[1]^3*y[2]^6*y[3]^3 + 2*y[1]^3*y[2]^3*y[3]^6 - y[1]^3*y[2]^3*y[3]^3 + y[2]^6*y[3]^6)
-

Tests on Homomorphisms of Affine Algebras

is_injectiveMethod
is_injective(F::AffAlgHom)

Return true if F is injective, false otherwise.

source
is_surjectiveMethod
is_surjective(F::AffAlgHom)

Return true if F is surjective, false otherwise.

source
is_bijectiveMethod
is_bijective(F::AffAlgHom)

Return true if F is bijective, false otherwise.

source
is_finiteMethod
is_finite(F::AffAlgHom)

Return true if F is finite, false otherwise.

source
Examples
julia> D, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> S, (a, b, c) = polynomial_ring(QQ, ["a", "b", "c"]);
-
-julia> C, p = quo(S, ideal(S, [c-b^3]));
-
-julia> V = [p(2*a + b^6), p(7*b - a^2), p(c^2)];
-
-julia> F = hom(D, C, V)
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Quotient of multivariate polynomial ring by ideal with 1 generator
-
-julia> is_surjective(F)
-true
-
-julia> D1, _ = quo(D, kernel(F));
-
-julia> F1 = hom(D1, C, V);
-
-julia> is_bijective(F1)
-true
-
julia> R, (x, y, z) = polynomial_ring(QQ, [ "x", "y", "z"]);
-
-julia> C, (s, t) = polynomial_ring(QQ, ["s", "t"]);
-
-julia> V = [s*t, t, s^2];
-
-julia> paraWhitneyUmbrella = hom(R, C, V)
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Multivariate polynomial ring in 2 variables over QQ
-
-julia> D, _ = quo(R, kernel(paraWhitneyUmbrella));
-
-julia> is_finite(hom(D, C, V))
-true

Inverting Homomorphisms of Affine Algebras

inverseMethod
inverse(F::AffAlgHom)

If F is bijective, return its inverse.

Examples

julia> D1, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> D, _ = quo(D1, [y-x^2, z-x^3]);
-
-julia> C, (t,) = polynomial_ring(QQ, ["t"]);
-
-julia> F = hom(D, C, [t, t^2, t^3]);
-
-julia> is_bijective(F)
-true
-
-julia> G = inverse(F)
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 1 variable over QQ
-Codomain:
-=========
-D
-
-julia> G(t)
-x
source

Subalgebras

Subalgebra Membership

subalgebra_membershipMethod
subalgebra_membership(f::T, V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}

Given an element f of a multivariate polynomial ring over a field, or of a quotient of such a ring, and given a vector V of further elements of that ring, consider the subalgebra generated by the entries of V in the given ring. If f is contained in the subalgebra, return (true, h), where h is giving the polynomial relation. Return, (false, 0), otherwise.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:3);
-
-julia> f = x[1]^6*x[2]^6-x[1]^6*x[3]^6;
-
-julia> V = [x[1]^3*x[2]^3-x[1]^3*x[3]^3, x[1]^3*x[2]^3+x[1]^3*x[3]^3]
-2-element Vector{QQMPolyRingElem}:
- x[1]^3*x[2]^3 - x[1]^3*x[3]^3
- x[1]^3*x[2]^3 + x[1]^3*x[3]^3
-
-julia> subalgebra_membership(f, V)
-(true, t1*t2)
source

Minimal Subalgebra Generators

minimal_subalgebra_generatorsMethod
minimal_subalgebra_generators(V::Vector{T}; check::Bool = true) where T <: Union{MPolyRingElem, MPolyQuoRingElem}

Given a vector V of homogeneous elements of a positively graded multivariate polynomial ring, or of a quotient of such a ring, return a minimal subset of the elements in V which, in the given ring, generate the same subalgebra as all elements in V.

If check is true (default), the conditions on V and the given ring are checked.

Examples

julia> R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"]);
-
-julia> V = [x, y, x^2+y^2]
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x
- y
- x^2 + y^2
-
-julia> minimal_subalgebra_generators(V)
-2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x
- y
source

Noether Normalization

noether_normalizationMethod
noether_normalization(A::MPolyQuoRing)

Given an affine algebra $A=R/I$ over a field $K$, return a triple $(V,F,G)$ such that:

  • $V$ is a vector of $d=\dim A$ elements of $A$, represented by linear forms $l_i\in R$, and such that $K[V]\hookrightarrow A$ is a Noether normalization for $A$;
  • $F: A=R/I \to B = R/\phi(I)$ is an isomorphism, induced by a linear change $ \phi $ of coordinates of $R$ which maps the $l_i$ to the the last $d$ variables of $R$;
  • $G = F^{-1}.$
Warning

The algorithm may not terminate over a small finite field. If it terminates, the result is correct.

source
Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [x*y, x*z]));
-
-julia> L = noether_normalization(A);
-
-julia> L[1]
-2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- -2*x + y
- -5*y + z
-
-julia> L[2]
-Map with following data
-Domain:
-=======
-Quotient of multivariate polynomial ring by ideal with 2 generators
-Codomain:
-=========
-Quotient of multivariate polynomial ring by ideal with 2 generators
-
-julia> L[3]
-Map with following data
-Domain:
-=======
-Quotient of multivariate polynomial ring by ideal with 2 generators
-Codomain:
-=========
-Quotient of multivariate polynomial ring by ideal with 2 generators
-

Normalization

normalizationMethod
normalization(A::MPolyQuoRing; algorithm = :equidimDec)

Find the normalization of a reduced affine algebra over a perfect field $K$. That is, given the quotient $A=R/I$ of a multivariate polynomial ring $R$ over $K$ modulo a radical ideal $I$, compute the integral closure $\overline{A}$ of $A$ in its total ring of fractions $Q(A)$, together with the embedding $f: A \to \overline{A}$.

Implemented Algorithms and how to Read the Output

The function relies on the algorithm of Greuel, Laplagne, and Seelisch which proceeds by finding a suitable decomposition $I=I_1\cap\dots\cap I_r$ into radical ideals $I_k$, together with maps $A = R/I \to A_k=\overline{R/I_k}$ which give rise to the normalization map of $A$:

\[A\hookrightarrow A_1\times \dots\times A_r=\overline{A}\]

For each $k$, the function specifies two representations of $A_k$: It returns an array of triples $(A_k, f_k, \mathfrak a_k)$, where $A_k$ is represented as an affine $K$-algebra, and $f_k$ as a map of affine $K$-algebras. The third entry $\mathfrak a_k$ is a tuple $(d_k, J_k)$, consisting of an element $d_k\in A$ and an ideal $J_k\subset A$, such that $\frac{1}{d_k}J_k = A_k$ as $A$-submodules of the total ring of fractions of $A$.

By default (algorithm = :equidimDec), as a first step on its way to find the decomposition $I=I_1\cap\dots\cap I_r$, the algorithm computes an equidimensional decomposition of the radical ideal $I$. Alternatively, if specified by algorithm = :primeDec, the algorithm computes $I=I_1\cap\dots\cap I_r$ as the prime decomposition of the radical ideal $I$.

See Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010).

Warning

The function does not check whether $A$ is reduced. Use is_reduced(A) in case you are unsure (this may take some time).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]));
-
-julia> L = normalization(A);
-
-julia> size(L)
-(2,)
-
-julia> LL = normalization(A, algorithm = :primeDec);
-
-julia> size(LL)
-(3,)
-
-julia> LL[1][1]
-Quotient
-  of multivariate polynomial ring in 3 variables over QQ
-  by ideal(-T(1)*y + x, -T(1)*x + y^2, T(1)^2 - y, -x^2 + y^3)
-
-julia> LL[1][2]
-Map with following data
-Domain:
-=======
-A
-Codomain:
-=========
-Quotient of multivariate polynomial ring by ideal with 4 generators
-
-julia> LL[1][3]
-(y, ideal(x, y))
source
normalization_with_deltaMethod
normalization_with_delta(A::MPolyQuoRing; algorithm::Symbol = :equidimDec)

Compute the normalization

\[A\hookrightarrow A_1\times \dots\times A_r=\overline{A}\]

of $A$ as does normalize(A), but return additionally the delta invariant of $A$, that is, the dimension

\[\dim_K(\overline{A}/A)\]

.

How to Read the Output

The return value is a tuple whose first element is normalize(A), whose second element is an array containing the delta invariants of the $A_k$, and whose third element is the (total) delta invariant of $A$. The return value -1 in the third element indicates that the delta invariant is infinite.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]));
-
-julia> L = normalization_with_delta(A);
-
-julia> L[2]
-3-element Vector{Int64}:
- 1
- 1
- 0
-
-julia> L[3]
-13
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [z^3-x*y^4]));
-
-julia> L = normalization_with_delta(A);
-
-julia> L[3]
--1
source

Integral Bases

integral_basisMethod
integral_basis(f::MPolyRingElem, i::Int; algorithm::Symbol = :normal_local)

Given a polynomial $f$ in two variables with coefficients in a perfect field $K$, and given an integer $i\in\{1,2\}$ specifying one of the variables, $f$ must be irreducible and monic in the specified variable: Say, $f\in\mathbb K[x,y]$ is monic in $y$. Then the normalization of $A = K[x,y]/\langle f \rangle$, that is, the integral closure $\overline{A}$ of $A$ in its quotient field, is a free module over $K[x]$ of finite rank, and any set of free generators for $\overline{A}$ over $K[x]$ is called an integral basis for $\overline{A}$ over $K[x]$. The function returns a pair $(d, V)$, where $d$ is an element of $A$, and $V$ is a vector of elements in $A$, such that the fractions $v/d, v\in V$, form an integral basis for $\overline{A}$ over $K[x]$.

By default (algorithm = :normal_local), the function relies on the local-to-global approach to normalization presented in Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Andreas Steenpaß, Stefan Steidel (2013). Alternatively, if specified by algorithm = :normal_global, the global normalization algorithm in Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010) is used. If $K = \mathbb Q$, it is recommended to apply the algorithm in Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister (2019), which makes use of Puiseux expansions and Hensel lifting (algorithm = :hensel).

Note

The conditions on $f$ are automatically checked.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> f = (y^2-2)^2 + x^5
-x^5 + y^4 - 4*y^2 + 4
-
-julia> integral_basis(f, 2)
-(x^2, MPolyQuoRingElem{QQMPolyRingElem}[x^2, x^2*y, y^2 - 2, y^3 - 2*y])
source

Tests on Affine Algebras

Reducedness Test

is_reducedMethod
is_reduced(A::MPolyQuoRing)

Given an affine algebra A, return true if A is reduced, false otherwise.

Warning

The function computes the radical of the modulus of A. This may take some time.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> A, _ = quo(R, ideal(R, [x^4]));
-
-julia> is_reduced(A)
-false
source

Normality Test

is_normalMethod
is_normal(A::MPolyQuoRing)

Given an affine algebra A over a perfect field, return true if A is normal, false otherwise.

Note

This function performs the first step of the normalization algorithm of Greuel, Laplagne, and Seelisch Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010) and may, thus, be more efficient than computing the full normalization of A.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [z^2-x*y]));
-
-julia> is_normal(A)
-true
source

Cohen-Macaulayness Test

is_cohen_macaulayMethod
 is_cohen_macaulay(A::MPolyQuoRing)

Given a $\mathbb Z$-graded affine algebra A = R/I over a field, say, K, where the grading is inherited from the standard $\mathbb Z$-grading on the polynomial ring R, return true if A is a Cohen-Macaulay ring, false otherwise.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> I = ideal(R, [x*z-y^2, w*z-x*y, w*y-x^2]);
-
-julia> A, _ = quo(R, I);
-
-julia> is_cohen_macaulay(A)
-true
julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> I = ideal(R, [x*z, y*z]);
-
-julia> A, _ = quo(R, I);
-
-julia> is_cohen_macaulay(A)
-false
source

Hilbert Series and Hilbert Polynomial

Given a multivariate polynomial ring $R$ over a field $K$ together with a (multi)grading on $R$ by a finitely generated abelian group $G$, let $I$ be an ideal of $R$ which is homogeneous with respect to this grading. Then the affine $K-$algebra $A=R/I$ inherits the grading: $A = \bigoplus_{g\in G} A_g$. Suppose now that $R$ is positively graded by $G$. That is, $G$ is free and each graded piece $R_g$ has finite dimension. Then also $A_g$ is a finite dimensional $K$-vector space for each $g$, and we have the well-defined Hilbert function of $A$,

\[H(A, \underline{\phantom{d}}): G \to \N, \; g\mapsto \dim_K(A_g).\]

The Hilbert series of $A$ is the generating function

\[H_A(\mathbb t)=\sum_{g\in G} H(A, g) \mathbb t^g\]

(see Section 8.2 in Ezra Miller, Bernd Sturmfels (2005) for a formal discussion extending the classical case of $\mathbb Z$-gradings with positive weights to the more general case of multigradings). As in the classical case, the infinitely many values of the Hilbert function can be expressed in finite terms by representing the Hilbert series as a rational function (see Theorem 8.20 in Ezra Miller, Bernd Sturmfels (2005) for a precise statement).

By a result of Macaulay, if $A = R/I$ is an affine algebra, and $L_{>}(I)$ is the leading ideal of $I$ with respect to a global monomial ordering $>$, then the Hilbert function of $A$ equals that of $R/L_{>}(I)$ (see Theorem 15.26 in David Eisenbud (1995)). Thus, using Gröbner bases, the computation of Hilbert series can be reduced to the case where the modulus of the affine algebra is a monomial ideal. In the latter case, we face a problem of combinatorial nature, and there are various strategies of how to proceed (see Martin Kreuzer, Lorenzo Robbiano (2005)). The functions hilbert_series, hilbert_series_reduced, hilbert_series_expanded, hilbert_function, hilbert_polynomial, and degree address the case of $\mathbb Z$-gradings with positive weights, relying on corresponding Singular functionality. The functions multi_hilbert_series, multi_hilbert_series_reduced, and multi_hilbert_function offer a variety of different strategies and allow one to handle positive gradings in general.

$\mathbb Z$-Gradings With Positive Weights

Let $R=K[x_1, \dots x_n]$ be a polynomial ring in $n$ variables over a field $K$. Assign positive integer weights $w_i$ to the variables $x_i$, and grade $R=\bigoplus_{d\in \mathbb Z} R_d=\bigoplus_{d\geq 0} R_d$ according to the corresponding weighted degree. Let $I$ be an ideal of $R$ which is homogeneous with respect to this grading. Then the affine $K$-algebra $A=R/I$ inherits the grading: $A = \bigoplus_{d\geq 0} A_d$, where each graded piece $A_d$ is a finite dimensional $K$-vector space. In this situation, the Hilbert function of $A$ is of type

\[H(A, \underline{\phantom{d}}): \N \to \N, \;d \mapsto \dim_K(d),\]

and the Hilbert series of $A$ is the formal power series

\[H_A(t)=\sum_{d\geq 0} H(A, d) t^d\in\mathbb Z[[t]].\]

The Hilbert series can be written as a rational function $p(t)/q(t)$, with denominator

\[q(t) = (1-t^{w_1})\cdots (1-t^{w_n}).\]

In the standard $\mathbb Z$-graded case, where the weights on the variables are all 1, the Hilbert function is of polynomial nature: There exists a unique polynomial $P_A(t)\in\mathbb{Q}[t]$, the Hilbert polynomial, which satisfies $H(M,d)=P_M(d)$ for all $d \gg 0$. Furthermore, the degree of $A$ is defined as the dimension of $A$ over $K$ if this dimension is finite, and as the integer $d$ such that the leading term of the Hilbert polynomial has the form $d t^e/e!$, otherwise.

hilbert_seriesMethod
hilbert_series(A::MPolyQuoRing; backend::Symbol=:Singular, algorithm::Symbol=:BayerStillmanA)

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return a pair $(p,q)$, say, of univariate polynomials $p, q\in\mathbb Z[t]$ such that $p/q$ represents the Hilbert series of $A$ as a rational function with denominator

\[q = (1-t^{w_1})\cdots (1-t^{w_n}),\]

where $n$ is the number of variables of $R$, and $w_1, \dots, w_n$ are the assigned weights.

See also hilbert_series_reduced.

Note

The advanced user can select different backends for the computation (:Singular and :Abbott for the moment), as well as different algorithms. The latter might be ignored for certain backends.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> hilbert_series(A)
-(2*t^3 - 3*t^2 + 1, (-t + 1)^4)
-
-julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3]);
-
-julia> A, _ = quo(R, ideal(R, [x*y*z]));
-
-julia> hilbert_series(A)
-(-t^6 + 1, (-t^2 + 1)^1*(-t + 1)^1*(-t^3 + 1)^1)
source
hilbert_series_reducedMethod
hilbert_series_reduced(A::MPolyQuoRing)

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return a pair $(p,q)$, say, of univariate polynomials $p, q\in\mathbb Z[t]$ such that $p/q$ represents the Hilbert series of $A$ as a rational function written in lowest terms.

See also hilbert_series.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> hilbert_series_reduced(A)
-(2*t + 1, t^2 - 2*t + 1)
-
-julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3]);
-
-julia> A, _ = quo(R, ideal(R, [x*y*z]));
-
-julia> hilbert_series(A)
-(-t^6 + 1, (-t^2 + 1)^1*(-t + 1)^1*(-t^3 + 1)^1)
-
-julia> hilbert_series_reduced(A)
-(t^2 - t + 1, t^2 - 2*t + 1)
source
hilbert_series_expandedMethod
hilbert_series_expanded(A::MPolyQuoRing, d::Int)

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return the Hilbert series of $A$ to precision $d$.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> hilbert_series_expanded(A, 7)
-1 + 4*t + 7*t^2 + 10*t^3 + 13*t^4 + 16*t^5 + 19*t^6 + 22*t^7 + O(t^8)
-
-julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3]);
-
-julia> A, _ = quo(R, ideal(R, [x*y*z]));
-
-julia> hilbert_series_expanded(A, 5)
-1 + t + 2*t^2 + 3*t^3 + 4*t^4 + 5*t^5 + O(t^6)
source
hilbert_functionMethod
hilbert_function(A::MPolyQuoRing, d::Int)

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return the value $H(A, d),$ where

\[H(A, \underline{\phantom{d}}): \N \to \N, \; d \mapsto \dim_K A_d,\]

is the Hilbert function of $A$.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> hilbert_function(A,7)
-22
-
-julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3]);
-
-julia> A, _ = quo(R, ideal(R, [x*y*z]));
-
-julia> hilbert_function(A, 5)
-5
source
hilbert_polynomialMethod
 hilbert_polynomial(A::MPolyQuoRing)

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from the standard $\mathbb Z$-grading on the polynomial ring $R$, return the Hilbert polynomial of $A$.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> hilbert_polynomial(A)
-3*t + 1
source
degreeMethod
degree(A::MPolyQuoRing)

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from the standard $\mathbb Z$-grading on the polynomial ring $R$, return the degree of $A$.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> degree(A)
-3
source

Positive Gradings in General

multi_hilbert_seriesMethod
multi_hilbert_series(A::MPolyQuoRing; algorithm::Symbol=:BayerStillmanA, parent::Union{Nothing,Ring}=nothing)

Return the Hilbert series of the graded affine algebra A.

Note

The advanced user can select an algorithm for the computation; see the code for details.

Examples

julia> W = [1 1 1; 0 0 -1];
-
-julia> R, x = graded_polynomial_ring(QQ, ["x[1]", "x[2]", "x[3]"], W)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])
-
-julia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);
-
-julia> A, _ = quo(R, I);
-
-julia> H = multi_hilbert_series(A);
-
-julia> H[1][1]
--t[1]^7*t[2]^-2 + t[1]^6*t[2]^-1 + t[1]^6*t[2]^-2 + t[1]^5*t[2]^-4 - t[1]^4 + t[1]^4*t[2]^-2 - t[1]^4*t[2]^-4 - t[1]^3*t[2]^-1 - t[1]^3*t[2]^-2 + 1
-
-julia> H[1][2]
-(-t[1] + 1)^2*(-t[1]*t[2]^-1 + 1)^1
-
-julia> H[2][1]
-GrpAb: Z^2
-
-julia> H[2][2]
-Identity map with
-
-Domain:
-=======
-GrpAb: Z^2
-
-julia> G = abelian_group(ZZMatrix([1 -1]));
-
-julia> g = gen(G, 1)
-Element of G with components [0 1]
-
-julia> W = [g, g, g, g];
-
-julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"], W);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> (num, den), (H, iso) = multi_hilbert_series(A);
-
-julia> num
-2*t^3 - 3*t^2 + 1
-
-julia> den
-(-t + 1)^4
-
-julia> H
-GrpAb: Z
-
-julia> iso
-Map with following data
-Domain:
-=======
-H
-Codomain:
-=========
-G
source
multi_hilbert_series_reducedMethod
multi_hilbert_series_reduced(A::MPolyQuoRing; algorithm::Symbol=:BayerStillmanA)

Return the reduced Hilbert series of the positively graded affine algebra A.

Note

The advanced user can select a algorithm for the computation; see the code for details.

Examples

julia> W = [1 1 1; 0 0 -1];
-
-julia> R, x = graded_polynomial_ring(QQ, ["x[1]", "x[2]", "x[3]"], W)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])
-
-julia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);
-
-julia> A, _ = quo(R, I);
-
-julia> H = multi_hilbert_series_reduced(A);
-
-
-julia> H[1][1]
--t[1]^5*t[2]^-1 + t[1]^3 + t[1]^3*t[2]^-3 + t[1]^2 + t[1]^2*t[2]^-1 + t[1]^2*t[2]^-2 + t[1] + t[1]*t[2]^-1 + 1
-
-julia> H[1][2]
--t[1] + 1
-
-julia> H[2][1]
-GrpAb: Z^2
-
-julia> H[2][2]
-Identity map with
-
-Domain:
-=======
-GrpAb: Z^2
-
-julia> G = abelian_group(ZZMatrix([1 -1]));
-
-julia> g = gen(G, 1)
-Element of G with components [0 1]
-
-julia> W = [g, g, g, g];
-
-julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"], W);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> H = multi_hilbert_series_reduced(A);
-
-julia> H[1][1]
-2*t + 1
-
-julia> H[1][2]
-t^2 - 2*t + 1
-
-julia> H[2][1]
-GrpAb: Z
-
-julia> H[2][2]
-Map with following data
-Domain:
-=======
-Abelian group with structure: Z
-Codomain:
-=========
-G
source
multi_hilbert_functionMethod
multi_hilbert_function(A::MPolyQuoRing, g::GrpAbFinGenElem)

Given a positively graded affine algebra $A$ over a field $K$ with grading group $G$, say, and given an element $g$ of $G$, return the value $H(A, g)$ of the Hilbert function

\[H(A, \underline{\phantom{d}}): G \to \N, \; g\mapsto \dim_K(A_g).\]

multi_hilbert_function(A::MPolyQuoRing, g::Vector{<:IntegerUnion})

Given a positively $\mathbb Z^m$-graded affine algebra $A$ over a field $K$, and given a vector $g$ of $m$ integers, convert $g$ into an element of the grading group of $A$, and return the value $H(A, g)$ as above.

multi_hilbert_function(A::MPolyQuoRing, g::IntegerUnion)

Given a positively $\mathbb Z$-graded affine algebra $A$ over a field $K$, and given an integer $g$, convert $g$ into an element of the grading group of $A$, and return the value $H(A, g)$ as above.

Examples

julia> W = [1 1 1; 0 0 -1];
-
-julia> R, x = graded_polynomial_ring(QQ, ["x[1]", "x[2]", "x[3]"], W)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])
-
-julia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);
-
-julia> A, _ = quo(R, I);
-
-julia> multi_hilbert_function(A::MPolyQuoRing, [1, 0])
-2
julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"], [-1, -1, -1, -1]);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> multi_hilbert_function(A, -7)
-22
julia> G = abelian_group(ZZMatrix([1 -1]));
-
-julia> g = gen(G, 1);
-
-julia> W = [g, g, g, g];
-
-julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"], W);
-
-julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
-
-julia> multi_hilbert_function(A, 7*g)
-22
source
diff --git a/previews/PR2578/CommutativeAlgebra/ideals/index.html b/previews/PR2578/CommutativeAlgebra/ideals/index.html deleted file mode 100644 index b144117d4968..000000000000 --- a/previews/PR2578/CommutativeAlgebra/ideals/index.html +++ /dev/null @@ -1,811 +0,0 @@ - -Ideals in Multivariate Rings · Oscar.jl

Ideals in Multivariate Rings

Types

The OSCAR type for ideals in multivariate polynomial rings is of parametrized form MPolyIdeal{T}, where T is the element type of the polynomial ring.

Constructors

idealMethod
ideal(R::MPolyRing, V::Vector)

Given a vector V of polynomials in R, return the ideal of R generated by these polynomials.

Note

In the graded case, the entries of V must be homogeneous.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x*y-3*x,y^3-2*x^2*y])
-ideal(x*y - 3*x, -2*x^2*y + y^3)
-
-julia> typeof(I)
-MPolyIdeal{QQMPolyRingElem}
-
-julia> S, (x, y) = graded_polynomial_ring(QQ, ["x", "y"],  [1, 2])
-(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])
-
-julia> J = ideal(S, [(x^2+y)^2])
-ideal(x^4 + 2*x^2*y + y^2)
-
-julia> typeof(J)
-MPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}
source

Data Associated to Ideals

Basic Data

If I is an ideal of a multivariate polynomial ring R, then

  • base_ring(I) refers to R,
  • gens(I) to the generators of I,
  • ngens(I) to the number of these generators, and
  • gen(I, k) as well as I[k] to the k-th such generator.
Examples
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> base_ring(I)
-Multivariate polynomial ring in 2 variables x, y
-  over rational field
-
-julia> gens(I)
-3-element Vector{QQMPolyRingElem}:
- x^2
- x*y
- y^2
-
-julia> ngens(I)
-3
-
-julia> gen(I, 2)
-x*y
-

Dimension

dimMethod
dim(I::MPolyIdeal)

Return the Krull dimension of I.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [y-x^2, x-z^3])
-ideal(-x^2 + y, x - z^3)
-
-julia> dim(I)
-1
source

Codimension

codimMethod
codim(I::MPolyIdeal)

Return the codimension of I.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [y-x^2, x-z^3])
-ideal(-x^2 + y, x - z^3)
-
-julia> codim(I)
-2
source

In the graded case, we additionally have:

Minimal Sets of Generators

minimal_generating_setMethod
minimal_generating_set(I::MPolyIdeal{<:MPolyDecRingElem})

Given a (homogeneous) ideal I in a graded multivariate polynomial ring over a field, return an array containing a minimal set of generators of I. If I is the zero ideal, an empty list is returned.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> V = [x, z^2, x^3+y^3, y^4, y*z^5];
-
-julia> I = ideal(R, V)
-ideal(x, z^2, x^3 + y^3, y^4, y*z^5)
-
-julia> minimal_generating_set(I)
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x
- z^2
- y^3
-
-julia> I = ideal(R, zero(R))
-ideal(0)
-
-julia> minimal_generating_set(I)
-MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[]
source

Castelnuovo-Mumford Regularity

cm_regularityMethod
cm_regularity(I::MPolyIdeal)

Given a (homogeneous) ideal I in a standard $\mathbb Z$-graded multivariate polynomial ring, return the Castelnuovo-Mumford regularity of I.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> I = ideal(R, [y^2*z − x^2*w, z^4 − x*w^3]);
-
-julia> cm_regularity(I)
-6
-
-julia> minimal_betti_table(I);
source

Degree

degreeMethod
degree(I::MPolyIdeal)

Given a (homogeneous) ideal I in a standard $\mathbb Z$-graded multivariate polynomial ring, return the degree of I (that is, the degree of the quotient of base_ring(I) modulo I). Otherwise, return the degree of the homogenization of I with respect to the standard $\mathbb Z$-grading.

Note

Geometrically, the degree of a homogeneous ideal as above is the number of intersection points of its projective variety with a generic linear subspace of complementary dimension (counted with multiplicities). See also Mateusz Michałek, Bernd Sturmfels (2021).

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [y-x^2, x-z^3])
-ideal(-x^2 + y, x - z^3)
-
-julia> degree(I)
-6
source

Operations on Ideals

Simple Ideal Operations

Powers of Ideal

^Method
^(I::MPolyIdeal, m::Int)

Return the m-th power of I.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x, y])
-ideal(x, y)
-
-julia> I^3
-ideal(x^3, x^2*y, x*y^2, y^3)
source

Sum of Ideals

+Method
+(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T

Return the sum of I and J.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x, y])
-ideal(x, y)
-
-julia> J = ideal(R, [z^2])
-ideal(z^2)
-
-julia> I+J
-ideal(x, y, z^2)
source

Product of Ideals

*Method
*(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T

Return the product of I and J.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x, y])
-ideal(x, y)
-
-julia> J = ideal(R, [z^2])
-ideal(z^2)
-
-julia> I*J
-ideal(x*z^2, y*z^2)
source

Intersection of Ideals

intersectMethod
intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T
-intersect(V::Vector{MPolyIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2;
-
-julia> J = ideal(R, [y^2-x^3+x]);
-
-julia> intersect(I, J)
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> intersect([I, J])
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
source
intersectMethod
intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T
-intersect(V::Vector{MPolyIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2;
-
-julia> J = ideal(R, [y^2-x^3+x]);
-
-julia> intersect(I, J)
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> intersect([I, J])
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
source
intersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T
-intersect(V::Vector{MPolyQuoIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
-
-julia> a = ideal(A, [y^2])
-ideal(y^2)
-
-julia> b = ideal(A, [x])
-ideal(x)
-
-julia> intersect(a,b)
-ideal(x*y)
-
-julia> intersect([a,b])
-ideal(x*y)
source
intersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}
-intersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}

Return the intersection of two or more ideals.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"]);
-
-julia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))
-left_ideal(-x^3 + dy^2 + x)
source
intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.

Additionally, return the inclusion maps M $\cap$ N $\to$ M and M $\cap$ N $\to$ N.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[y;]
-[y]
-
-julia> BN = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-, Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-)
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> AM = Rg[x;];
-
-julia> BM = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, AM, BM)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = Rg[y;];
-
-julia> BN = Rg[x^2; y^3; z^4];
-
-julia> N = SubquoModule(F, AN, BN)
-Graded subquotient of submodule of F generated by
-1 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> M
--x*y*e[1] -> -x*y*e[1]
-x*z^4*e[1] -> x*z^4*e[1]
-Homogeneous module homomorphism, Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> N
--x*y*e[1] -> x*y*e[1]
-x*z^4*e[1] -> 0
-Homogeneous module homomorphism)
-
source
intersect(T1, T2)

Intersect two tropical varieties.

Examples

julia> RR = TropicalSemiring(min)
-Tropical semiring (min)
-
-julia> S,(x,y) = RR["x","y"]
-(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])
-
-julia> f1 = x+y+1
-x + y + (1)
-
-julia> f2 = x^2+y^2+RR(-6)
-x^2 + y^2 + (-6)
-
-julia> hyp1 = TropicalHypersurface(f1)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> hyp2 = TropicalHypersurface(f2)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> tv12 = intersect(hyp1, hyp2)
-min tropical variety of dimension 1 embedded in 2-dimensional Euclidean space
source
intersect(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl

Returns $a \cap b$.

intersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl

Returns $a \cap b$.

Ideal Quotients

Given two ideals $I, J$ of a ring $R$, the ideal quotient of $I$ by $J$ is the ideal

\[I:J= \bigl\{f \in R\:\big|\: f J \subset I\bigr\}\subset R.\]

quotientMethod
quotient(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T

Return the ideal quotient of I by J. Alternatively, use I:J.

quotient(I::MPolyIdeal{T}, f::MPolyRingElem{T}) where T

Return the ideal quotient of I by the ideal generated by f. Alternatively, use I:f.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [x^4+x^2*y*z+y^3*z, y^4+x^3*z+x*y^2*z, x^3*y+x*y^3])
-ideal(x^4 + x^2*y*z + y^3*z, x^3*z + x*y^2*z + y^4, x^3*y + x*y^3)
-
-julia> J = ideal(R, [x, y, z])^2
-ideal(x^2, x*y, x*z, y^2, y*z, z^2)
-
-julia> L = quotient(I, J)
-ideal(x^3*z + x*y^2*z + y^4, x^3*y + x*y^3, x^4 + x^2*y*z + y^3*z, x^3*z^2 - x^2*y*z^2 + x*y^2*z^2 - y^3*z^2, x^2*y^2*z - x^2*y*z^2 - y^3*z^2, x^3*z^2 + x^2*y^3 - x^2*y^2*z + x*y^2*z^2)
-
-julia> I:J
-ideal(x^3*z + x*y^2*z + y^4, x^3*y + x*y^3, x^4 + x^2*y*z + y^3*z, x^3*z^2 - x^2*y*z^2 + x*y^2*z^2 - y^3*z^2, x^2*y^2*z - x^2*y*z^2 - y^3*z^2, x^3*z^2 + x^2*y^3 - x^2*y^2*z + x*y^2*z^2)
-
-julia> I:x
-ideal(x^2*y + y^3, x^3*z + x*y^2*z + y^4, x^2*z^2 + x*y^3 - x*y^2*z + y^2*z^2, x^4, x^3*z^2 - x^2*z^3 + 2*x*y^2*z^2 - y^2*z^3, -x^2*z^4 + x*y^2*z^3 - y^2*z^4)
source

Saturation

Given two ideals $I, J$ of a ring $R$, the saturation of $I$ with respect to $J$ is the ideal

\[I:J^{\infty} = \bigl\{ f \in R \:\big|\: f J^k \!\subset I {\text{ for some }}k\geq 1 \bigr\} = \textstyle{\bigcup\limits_{k=1}^{\infty} (I:J^k)}.\]

saturationMethod
saturation(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T

Return the saturation of I with respect to J.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y])
-ideal(z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y)
-
-julia> J = ideal(R, [x, y, z])
-ideal(x, y, z)
-
-julia> K = saturation(I, J)
-ideal(z, x*y)
source
saturation_with_indexMethod
saturation_with_index(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T

Return $I:J^{\infty}$ together with the smallest integer $m$ such that $I:J^m = I:J^{\infty}$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> I = ideal(R, [z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y])
-ideal(z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y)
-
-julia> J = ideal(R, [x, y, z])
-ideal(x, y, z)
-
-julia> K, m = saturation_with_index(I, J)
-(ideal(z, x*y), 2)
source

Elimination

eliminateMethod
eliminate(I::MPolyIdeal{T}, V::Vector{T}) where T <: MPolyRingElem

Given a vector V of polynomials which are variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.

eliminate(I::MPolyIdeal, V::AbstractVector{Int})

Given a vector V of indices which specify variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.

Note

The return value is an ideal of the original ring.

Examples

julia> R, (t, x, y, z) = polynomial_ring(QQ, ["t", "x", "y", "z"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[t, x, y, z])
-
-julia> I = ideal(R, [t-x, t^2-y, t^3-z])
-ideal(t - x, t^2 - y, t^3 - z)
-
-julia> A = [t]
-1-element Vector{QQMPolyRingElem}:
- t
-
-julia> TC = eliminate(I, A)
-ideal(-x*z + y^2, x*y - z, x^2 - y)
-
-julia> A = [1]
-1-element Vector{Int64}:
- 1
-
-julia> TC = eliminate(I, A)
-ideal(-x*z + y^2, x*y - z, x^2 - y)
-
-julia> base_ring(TC)
-Multivariate polynomial ring in 4 variables t, x, y, z
-  over rational field
source

Truncation

truncateMethod
truncate(I::MPolyIdeal, g::GrpAbFinGenElem)

Given a (homogeneous) ideal I in a $\mathbb Z$-graded multivariate polynomial ring with positive weights, return the truncation of I at degree g.

truncate(I::MPolyIdeal, d::Int)

Given an ideal I as above, and given an integer d, convert d into an element g of the grading group of base_ring(I) and proceed as above.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> I = ideal(R, [x, y^4, z^6])
-ideal(x, y^4, z^6)
-
-julia> truncate(I, 3)
-ideal(x*z^2, x*y*z, x*y^2, x^2*z, x^2*y, x^3, y^4, z^6)
julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [3,2,1]);
-
-julia> I = ideal(R, [x, y^4, z^6])
-ideal(x, y^4, z^6)
-
-julia> truncate(I, 3)
-ideal(x, y^4, z^6)
-
-julia> truncate(I, 4)
-ideal(x*z, z^6, y^4)
source

Tests on Ideals

Basic Tests

is_zeroMethod
is_zero(I::MPolyIdeal)

Return true if I is the zero ideal, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, y-x^2)
-ideal(-x^2 + y)
-
-julia> is_zero(I)
-false
source
is_oneMethod
is_one(I::MPolyIdeal)

Return true if I is generated by 1, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, x + y, y - 1])
-ideal(x, x + y, y - 1)
-
-julia> is_one(I)
-true
source
is_monomialMethod
is_monomial(f::MPolyRingElem)

Return true if f is a monomial, false otherwise.

is_monomial(I::MPolyIdeal)

Return true if I can be generated by monomials, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> f = 2*x+y
-2*x + y
-
-julia> g = y
-y
-
-julia> is_monomial(f)
-false
-
-julia> is_monomial(g)
-true
-
-julia> is_monomial(ideal(R, [f, g]))
-true
source

Containment of Ideals

is_subsetMethod
is_subset(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T

Return true if I is contained in J, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x^2])
-ideal(x^2)
-
-julia> J = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> is_subset(I, J)
-true
source

Equality of Ideals

==Method
==(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T

Return true if I is equal to J, false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x^2])
-ideal(x^2)
-
-julia> J = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> I == J
-false
source

Ideal Membership

ideal_membershipMethod
ideal_membership(f::T, I::MPolyIdeal{T}) where T

Return true if f is contained in I, false otherwise. Alternatively, use f in I.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> f = x^2
-x^2
-
-julia> I = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> ideal_membership(f, I)
-true
-
-julia> g = x
-x
-
-julia> g in I
-false
source

Radical Membership

radical_membershipMethod
radical_membership(f::T, I::MPolyIdeal{T}) where T

Return true if f is contained in the radical of I, false otherwise. Alternatively, use inradical(f, I).

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"])
-(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])
-
-julia> f = x
-x
-
-julia> I = ideal(R,  [x^2])
-ideal(x^2)
-
-julia> radical_membership(f, I)
-true
-
-julia> g = x+1
-x + 1
-
-julia> inradical(g, I)
-false
source

Primality Test

is_primeMethod
is_prime(I::MPolyIdeal)

Return true if I is prime, false otherwise.

Warning

The function computes the minimal associated primes of I. This may take some time.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> is_prime(I)
-false
source

Primary Test

is_primaryMethod
is_primary(I::MPolyIdeal)

Return true if I is primary, false otherwise.

Warning

The function computes a primary decomposition of I. This may take some time.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> is_primary(I)
-true
source

Decomposition of Ideals

We discuss various decomposition techniques. They are implemented for polynomial rings over fields and, if explicitly mentioned, also for polynomial rings over the integers. See Wolfram Decker, Gert-Martin Greuel, Gerhard Pfister (1999) for a survey.

Radical

radicalMethod
radical(I::MPolyIdeal)

Return the radical of I.

Implemented Algorithms

If the base ring of I is a polynomial ring over a field, a combination of the algorithms of Krick and Logar (with modifications by Laplagne) and Kemper is used. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Teresa Krick, Alessandro Logar (1991), Gregor Kemper (2002), and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> I = intersect(I, ideal(R, [x-y-1])^2)
-ideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)
-
-julia> RI = radical(I)
-ideal(x^4 - x^3*y - x^3 - x^2 - x*y^2 + x*y + x + y^3 + y^2)
julia> R, (a, b, c, d) = polynomial_ring(ZZ, ["a", "b", "c", "d"])
-(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])
-
-julia> I = intersect(ideal(R, [9,a,b]), ideal(R, [3,c]))
-ideal(9, 3*b, 3*a, b*c, a*c)
-
-julia> I = intersect(I, ideal(R, [11,2a,7b]))
-ideal(99, 3*b, 3*a, b*c, a*c)
-
-julia> I = intersect(I, ideal(R, [13a^2,17b^4]))
-ideal(39*a^2, 13*a^2*c, 51*b^4, 17*b^4*c, 3*a^2*b^4, a^2*b^4*c)
-
-julia> I = intersect(I, ideal(R, [9c^5,6d^5]))
-ideal(78*a^2*d^5, 117*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 6*a^2*b^4*d^5, 9*a^2*b^4*c^5, 39*a^2*c^5*d^5, 51*b^4*c^5*d^5, 3*a^2*b^4*c^5*d^5)
-
-julia> I = intersect(I, ideal(R, [17,a^15,b^15,c^15,d^15]))
-ideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)
-
-julia> RI = radical(I)
-ideal(102*b*d, 78*a*d, 51*b*c, 39*a*c, 6*a*b*d, 3*a*b*c)
source

Primary Decomposition

primary_decompositionMethod
primary_decomposition(I::MPolyIdeal; algorithm = :GTZ, cache=true)

Return a minimal primary decomposition of I.

The decomposition is returned as a vector of tuples $(Q_1, P_1), \dots, (Q_t, P_t)$, say, where each $Q_i$ is a primary ideal with associated prime $P_i$, and where the intersection of the $Q_i$ is I.

Implemented Algorithms

If the base ring of I is a polynomial ring over a field, the algorithm of Gianni, Trager, and Zacharias is used by default (algorithm = :GTZ). Alternatively, the algorithm by Shimoyama and Yokoyama can be used by specifying algorithm = :SY. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Patrizia Gianni, Barry Trager, Gail Zacharias (1988), Takeshi Shimoyama, Kazuhiro Yokoyama (1996), and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).

Warning

The algorithm of Gianni, Trager, and Zacharias may not terminate over a small finite field. If it terminates, the result is correct.

If cache=false is set, the primary decomposition is recomputed and not cached.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> I = intersect(I, ideal(R, [x-y-1])^2)
-ideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)
-
-julia> L = primary_decomposition(I)
-3-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}}}:
- (ideal(x^3 - x - y^2), ideal(x^3 - x - y^2))
- (ideal(x^2 - 2*x*y - 2*x + y^2 + 2*y + 1), ideal(x - y - 1))
- (ideal(y, x^2), ideal(x, y))
-
-julia> L = primary_decomposition(I, algorithm = :SY, cache=false)
-3-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}}}:
- (ideal(x^3 - x - y^2), ideal(x^3 - x - y^2))
- (ideal(x^2 - 2*x*y - 2*x + y^2 + 2*y + 1), ideal(x - y - 1))
- (ideal(y, x^2), ideal(y, x))
julia> R, (a, b, c, d) = polynomial_ring(ZZ, ["a", "b", "c", "d"])
-(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])
-
-julia> I = ideal(R, [1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5,
-       663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15,
-       78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15,
-       39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5,
-       6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15,
-       3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5])
-ideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)
-
-julia> L = primary_decomposition(I)
-8-element Vector{Tuple{MPolyIdeal{ZZMPolyRingElem}, MPolyIdeal{ZZMPolyRingElem}}}:
- (ideal(d^5, c^5), ideal(d, c))
- (ideal(a^2, b^4), ideal(b, a))
- (ideal(2, c^5), ideal(2, c))
- (ideal(3), ideal(3))
- (ideal(13, b^4), ideal(13, b))
- (ideal(17, a^2), ideal(17, a))
- (ideal(17, d^15, c^15, b^15, a^15), ideal(17, d, c, b, a))
- (ideal(9, 3*d^5, d^10), ideal(3, d))
source

Absolute Primary Decomposition

absolute_primary_decompositionMethod
absolute_primary_decomposition(I::MPolyIdeal{<:MPolyRingElem{QQFieldElem}})

Given an ideal I in a multivariate polynomial ring over the rationals, return an absolute minimal primary decomposition of I.

Return the decomposition as a vector of tuples $(Q_i, P_i, P_{ij}, d_{ij})$, say, where $(Q_i, P_i)$ is a (primary, prime) tuple as returned by primary_decomposition(I), and $P_{ij}$ represents a corresponding class of conjugated absolute associated primes defined over a number field of degree $d_{ij}$ whose generator prints as _a.

Implemented Algorithms

The implementation combines the algorithm of Gianni, Trager, and Zacharias for primary decomposition with absolute polynomial factorization.

Examples

julia> R, (y, z) = polynomial_ring(QQ, ["y", "z"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[y, z])
-
-julia> p = z^2+1
-z^2 + 1
-
-julia> q = z^3+2
-z^3 + 2
-
-julia> I = ideal(R, [p*q^2, y-z^2])
-ideal(z^8 + z^6 + 4*z^5 + 4*z^3 + 4*z^2 + 4, y - z^2)
-
-julia> L = primary_decomposition(I)
-2-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}}}:
- (ideal(z^2 + 1, y - z^2), ideal(z^2 + 1, y - z^2))
- (ideal(z^6 + 4*z^3 + 4, y - z^2), ideal(z^3 + 2, y - z^2))
-
-julia> AL = absolute_primary_decomposition(I)
-2-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{nf_elem}}, Int64}}:
- (ideal(z^2 + 1, y + 1), ideal(z^2 + 1, y + 1), ideal(z - _a, y + 1), 2)
- (ideal(z^6 + 4*z^3 + 4, y - z^2), ideal(z^3 + 2, y - z^2), ideal(z - _a, y - _a*z), 3)
-
-julia> AP = AL[1][3]
-ideal(z - _a, y + 1)
-
-julia> RAP = base_ring(AP)
-Multivariate polynomial ring in 2 variables y, z
-  over number field of degree 2 over QQ
-
-julia> NF = coefficient_ring(RAP)
-Number field with defining polynomial x^2 + 1
-  over rational field
-
-julia> a = gen(NF)
-_a
-
-julia> minpoly(a)
-x^2 + 1
julia> R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"])
-(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])
-
-julia> I = ideal(R, [x^2+y^2])
-ideal(x^2 + y^2)
-
-julia> AL = absolute_primary_decomposition(I)
-1-element Vector{Tuple{MPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}, MPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}, MPolyIdeal{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}, Int64}}:
- (ideal(x^2 + y^2), ideal(x^2 + y^2), ideal(x + _a*y), 2)
-
-julia> AP = AL[1][3]
-ideal(x + _a*y)
-
-julia> RAP = base_ring(AP)
-Multivariate polynomial ring in 2 variables over number field graded by 
-  x -> [1]
-  y -> [1]
source

Minimal Associated Primes

minimal_primesMethod
minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ)

Return a vector containing the minimal associated prime ideals of I.

Implemented Algorithms

If the base ring of I is a polynomial ring over a field, the algorithm of Gianni, Trager, and Zacharias is used by default (algorithm = :GTZ). Alternatively, characteristic sets can be used by specifying algorithm = :charSets. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Patrizia Gianni, Barry Trager, Gail Zacharias (1988) and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> I = intersect(I, ideal(R, [x-y-1])^2)
-ideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)
-
-julia> L = minimal_primes(I)
-2-element Vector{MPolyIdeal{QQMPolyRingElem}}:
- ideal(x - y - 1)
- ideal(x^3 - x - y^2)
-
-julia> L = minimal_primes(I, algorithm = :charSets)
-2-element Vector{MPolyIdeal{QQMPolyRingElem}}:
- ideal(x - y - 1)
- ideal(x^3 - x - y^2)
julia> R, (a, b, c, d) = polynomial_ring(ZZ, ["a", "b", "c", "d"])
-(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])
-
-julia> I = ideal(R, [1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5,
-       663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15,
-       78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15,
-       39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5,
-       6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15,
-       3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5])
-ideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)
-
-julia> L = minimal_primes(I)
-6-element Vector{MPolyIdeal{ZZMPolyRingElem}}:
- ideal(d, c)
- ideal(b, a)
- ideal(2, c)
- ideal(3)
- ideal(13, b)
- ideal(17, a)
source

Weak Equidimensional Decomposition

equidimensional_decomposition_weakMethod
equidimensional_decomposition_weak(I::MPolyIdeal)

Return a vector of equidimensional ideals where the last entry is the equidimensional hull of I, that is, the intersection of the primary components of I of maximal dimension. Each of the previous entries is an ideal of lower dimension whose associated primes are exactly the associated primes of I of that dimension.

Implemented Algorithms

The implementation relies on ideas of Eisenbud, Huneke, and Vasconcelos. See David Eisenbud, Craig Huneke, Wolmer Vasconcelos (1992).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> I = intersect(I, ideal(R, [x-y-1])^2)
-ideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)
-
-julia> L = equidimensional_decomposition_weak(I)
-2-element Vector{MPolyIdeal{QQMPolyRingElem}}:
- ideal(y, x)
- ideal(x^5 - 2*x^4*y - 2*x^4 + x^3*y^2 + 2*x^3*y - x^2*y^2 + 2*x^2*y + 2*x^2 + 2*x*y^3 + x*y^2 - 2*x*y - x - y^4 - 2*y^3 - y^2)
source

Equidimensional Decomposition of radical

equidimensional_decomposition_radicalMethod
equidimensional_decomposition_radical(I::MPolyIdeal)

Return a vector of equidimensional radical ideals increasingly ordered by dimension. For each dimension, the returned radical ideal is the intersection of the associated primes of I of that dimension.

Implemented Algorithms

The implementation combines the algorithms of Krick and Logar (with modifications by Laplagne) and Kemper. See Teresa Krick, Alessandro Logar (1991) and Gregor Kemper (2002).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> I = intersect(I, ideal(R, [x-y-1])^2)
-ideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)
-
-julia> L = equidimensional_decomposition_radical(I)
-2-element Vector{MPolyIdeal{QQMPolyRingElem}}:
- ideal(y, x)
- ideal(x^4 - x^3*y - x^3 - x^2 - x*y^2 + x*y + x + y^3 + y^2)
source

Equidimensional Hull

equidimensional_hullMethod
equidimensional_hull(I::MPolyIdeal)

If the base ring of I is a polynomial ring over a field, return the intersection of the primary components of I of maximal dimension. In the case of polynomials over the integers, return the intersection of the primary components of I of minimal height. If I is the unit ideal, return [ideal(1)].

Implemented Algorithms

For polynomial rings over a field, the implementation relies on ideas as used by Gianni, Trager, and Zacharias or Krick and Logar. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Patrizia Gianni, Barry Trager, Gail Zacharias (1988), Teresa Krick, Alessandro Logar (1991), and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> I = intersect(I, ideal(R, [x-y-1])^2)
-ideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)
-
-julia> L = equidimensional_hull(I)
-ideal(x^5 - 2*x^4*y - 2*x^4 + x^3*y^2 + 2*x^3*y - x^2*y^2 + 2*x^2*y + 2*x^2 + 2*x*y^3 + x*y^2 - 2*x*y - x - y^4 - 2*y^3 - y^2)
julia> R, (a, b, c, d) = polynomial_ring(ZZ, ["a", "b", "c", "d"])
-(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])
-
-julia> I = ideal(R, [1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5,
-       663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15,
-       78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15,
-       39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5,
-       6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15,
-       3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5])
-ideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)
-
-julia> L = equidimensional_hull(I)
-ideal(3)
source

Radical of the Equidimensional Hull

equidimensional_hull_radicalMethod
equidimensional_hull_radical(I::MPolyIdeal)

Return the intersection of the associated primes of I of maximal dimension. If I is the unit ideal, return [ideal(1)].

Implemented Algorithms

The implementation relies on a combination of the algorithms of Krick and Logar (with modifications by Laplagne) and Kemper. See Teresa Krick, Alessandro Logar (1991) and Gregor Kemper (2002).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> I = intersect(I, ideal(R, [x-y-1])^2)
-ideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)
-
-julia> L = equidimensional_hull_radical(I)
-ideal(x^4 - x^3*y - x^3 - x^2 - x*y^2 + x*y + x + y^3 + y^2)
source

Homogenization and Dehomogenization

Referring to Martin Kreuzer, Lorenzo Robbiano (2005) for definitions and technical details, we discuss homogenization and dehomogenization in the context of $\mathbb Z^m$-gradings.

homogenizationMethod
homogenization(f::MPolyRingElem, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName; pos::Int)
-homogenization(f::MPolyRingElem, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName)

If $m$ is the number of rows of W, extend the parent polynomial ring of f by inserting $m$ extra variables, starting at position pos (if pos is not specified, it defaults to the position after the last variable). Correspondingly, extend the integer matrix W by inserting the standard unit vectors of size $m$ as new columns, starting at column pos. Grade the extended ring by converting the columns of the extended matrix to elements of the group $\mathbb Z^m$ and assigning these as weights to the variables. Homogenize f with respect to the induced $\mathbb Z^m$-grading on the original ring, using the extra variables as homogenizing variables. Return the result as an element of the extended ring with its $\mathbb Z^m$-grading. If $m=1$, the extra variable prints as var. Otherwise, the extra variables print as var[$i$], for $i = 1 \dots m$.

homogenization(V::Vector{T},  W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName; pos::Int) where {T <: MPolyRingElem}
-homogenization(V::Vector{T},  W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName) where {T <: MPolyRingElem}

Given a vector V of elements in a common polynomial ring, create an extended ring with $\mathbb Z^m$-grading as above. Homogenize the elements of V correspondingly, and return the vector of homogenized elements.

homogenization(I::MPolyIdeal{T},  W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName; pos::Int) where {T <: MPolyRingElem}
-homogenization(I::MPolyIdeal{T},  W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName) where {T <: MPolyRingElem}

Return the homogenization of I in an extended ring with $\mathbb Z^m$-grading as above.

Note

If W comprises a single row of positive weights then the method used is essentially the same as for the standard-graded case: compute a wdegrevlex Groebner basis then homogenize its elements. Otherwise applied to an ideal I, the function first homogenizes the generators of I in the extended ring. It then creates the ideal generated by these homogenizations, and saturates this ideal with respect to the ideal which is generated by the product of the homogenizing variables. Source: Kreuzer+Robbiano (vol 2) Cor 4.3.8(a), Defn 4.4.1, Cor 4.4.9, Tutorial 37(g)

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> f = x^3+x^2*y+x*y^2+y^3
-x^3 + x^2*y + x*y^2 + y^3
-
-julia> W = [1 2; 3 4]
-2×2 Matrix{Int64}:
- 1  2
- 3  4
-
-julia> F = homogenization(f, W, "z"; pos=3)
-x^3*z[1]^3*z[2]^3 + x^2*y*z[1]^2*z[2]^2 + x*y^2*z[1]*z[2] + y^3
-
-julia> parent(F)
-Multivariate polynomial ring in 4 variables over QQ graded by
-  x -> [1 3]
-  y -> [2 4]
-  z[1] -> [1 0]
-  z[2] -> [0 1]
source
homogenizationMethod
homogenization(f::MPolyRingElem, var::VarName)
-homogenization(f::MPolyRingElem, var::VarName; pos::Int)
-
-homogenization(V::Vector{T}, var::VarName) where {T <: MPolyRingElem}
-homogenization(V::Vector{T}, var::VarName; pos::Int) where {T <: MPolyRingElem}
-
-homogenization(I::MPolyIdeal{T}, var::VarName; ordering::Symbol = :degrevlex) where {T <: MPolyRingElem}
-homogenization(I::MPolyIdeal{T}, var::VarName; pos::Int, ordering::Symbol = :degrevlex) where {T <: MPolyRingElem}

Homogenize f, V, or I with respect to the standard $\mathbb Z$-grading using a homogenizing variable printing as var. Return the result as an element of a graded polynomial ring with the homogenizing variable at position pos; if pos is not specified it defaults to just after the last variable.

Note

Applied to an ideal I, the function proceeds by homogenizing the elements of a Gröbner basis of I with respect to a degree compatible monomial ordering such as degrevlex (default). If a Gröbner basis with respect to the specified ordering has not yet been computed and, thus, not yet been cached, executing the homogenization function with argument I may take some time. The degree compatibility of the specified ordering is not checked by the function.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> f = x^3-y^2-z
-x^3 - y^2 - z
-
-julia> F = homogenization(f, "w"; pos=4)
-x^3 - y^2*w - z*w^2
-
-julia> parent(F)
-Multivariate polynomial ring in 4 variables over QQ graded by
-  x -> [1]
-  y -> [1]
-  z -> [1]
-  w -> [1]
-
-julia> V = [y-x^2, z-x^3]
-2-element Vector{QQMPolyRingElem}:
- -x^2 + y
- -x^3 + z
-
-julia> homogenization(V, "w")
-2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- -x^2 + y*w
- -x^3 + z*w^2
-
-julia> I = ideal(R, V)
-ideal(-x^2 + y, -x^3 + z)
-
-julia> PTC = homogenization(I, "w")
-ideal(-x*z + y^2, x*y - z*w, x^2 - y*w)
-
-julia> parent(PTC[1])
-Multivariate polynomial ring in 4 variables over QQ graded by
-  x -> [1]
-  y -> [1]
-  z -> [1]
-  w -> [1]
-
-julia> homogenization(I, "w"; ordering = deglex(gens(base_ring(I))))
-ideal(x*z - y^2, x*y - z*w, x^2 - y*w, y^3 - z^2*w)
source
dehomogenizationMethod
dehomogenization(F::MPolyDecRingElem, pos::Int)

Given an element F of a $\mathbb Z^m$-graded ring, where the generators of $\mathbb Z^m$ are the assigned weights to the variables at positions pos, $\dots$, pos $-1+m$, dehomogenize F using the variables at these positions. Return the result as an element of a polynomial ring not depending on the variables at these positions.

dehomogenization(V::Vector{T}, pos::Int) where {T <: MPolyDecRingElem}

Given a vector V of elements in a common graded polynomial ring, create a polynomial ring not depending on the variables at positions pos, $\dots$, pos $-1+m$. Dehomogenize the elements of V correspondingly, and return the vector of dehomogenized elements.

dehomogenization(I::MPolyIdeal{T}, pos::Int) where {T <: MPolyDecRingElem}

Return the dehomogenization of I in a polynomial ring as above.

Examples

julia> S, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> F = x^3-x^2*y-x*z^2
-x^3 - x^2*y - x*z^2
-
-julia> f = dehomogenization(F, 1)
--y - z^2 + 1
-
-julia> parent(f)
-Multivariate polynomial ring in 2 variables y, z
-  over rational field
-
-julia> V = [x*y-z^2, x^2*z-x^3]
-2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x*y - z^2
- -x^3 + x^2*z
-
-julia> dehomogenization(V, 3)
-2-element Vector{QQMPolyRingElem}:
- x*y - 1
- -x^3 + x^2
-
-julia> I = ideal(S, V)
-ideal(x*y - z^2, -x^3 + x^2*z)
-
-julia> dehomogenization(I, 3)
-ideal(x*y - 1, -x^3 + x^2)
-
-julia> W = [1 2 1 0; 3 4 0 1]
-2×4 Matrix{Int64}:
- 1  2  1  0
- 3  4  0  1
-
-julia> S, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"], W)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[w, x, y, z])
-
-julia> F = w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3
-w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3
-
-julia> dehomogenization(F, 3)
-w^3 + w^2*x + w*x^2 + x^3
source

Generating Special Ideals

Katsura-n

These systems appeared in a problem of magnetism in physics. For a given $n$ katsura(n) has $2^n$ solutions and is defined in a polynomial ring with $n+1$ variables over the rational numbers. For a given polynomial ring R with $n$ variables katsura(R) defines the corresponding system with $2^{n-1}$ solutions.

katsuraMethod
katsura(n::Int)

Given a natural number n return the Katsura ideal over the rational numbers generated by $u_m - \sum_{l=-n}^n u_{l-m} u_l$, $1 - \sum_{l = -n}^n u_l$ where $u_{-i} = u_i$, and $u_i = 0$ for $i > n$ and $m \in \{-n, \ldots, n\}$.

Note that indices have been shifted to start from 1.

Examples

julia> I = katsura(2)
-ideal(x1 + 2*x2 + 2*x3 - 1, x1^2 - x1 + 2*x2^2 + 2*x3^2, 2*x1*x2 + 2*x2*x3 - x2)
-julia> base_ring(I)
-Multivariate polynomial ring in 3 variables x1, x2, x3
-  over rational field
source
katsuraMethod
katsura(R::MPolyRing)

Return the Katsura ideal in the given polynomial ring R.

Examples

julia> R, _ = QQ["x", "y", "z"]
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> katsura(R)
-ideal(x + 2*y + 2*z - 1, x^2 - x + 2*y^2 + 2*z^2, 2*x*y + 2*y*z - y)
source
diff --git a/previews/PR2578/CommutativeAlgebra/intro/index.html b/previews/PR2578/CommutativeAlgebra/intro/index.html deleted file mode 100644 index 0f83e0098309..000000000000 --- a/previews/PR2578/CommutativeAlgebra/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The commutative algebra part of OSCAR provides functionality for dealing with

  • multivariate polynomial rings and their ideals,
  • quotients of multivariate polynomial rings modulo ideals and ideals of such quotients,
  • localizations of the above rings and ideals of such localizations, and
  • modules over all rings above.

We use affine algebra as a synonym for quotient of a multivariate polynomial ring modulo an ideal.

Fundamental to computational commutative algebra is the concept of standard bases. Each such basis is defined relative to a monomial ordering. If this ordering is a well-ordering, a standard basis is also called a Gröbner basis. We refer to the corresponding section in this chapter for details.

Note

Each multivariate polynomial ring in OSCAR comes equipped with a monomial ordering according to which the polynomials are stored and displayed. Independently of this ordering, standard bases can be computed with respect to any monomial ordering: The groebner_basis and standard_basis functions provided by OSCAR allow one to specify the desired monomial ordering as a key word argument. Typically, however, the user does not have to worry about Gröbner (standard) bases: The functions discussed in this chapter compute such bases behind the scenes when needed. Once computed, each such basis is cached for later reuse.

Note

In Oscar, it is possible to equip multivariate polynomial rings with gradings by finitely presented groups. Most functions discussed in this chapter apply to both ungraded and graded polynomial rings. However, for simplicity of the presentation, in this documentation, the functions are often only illustrated by examples with focus on the former case, but work similarly for homogeneous ideals and graded modules in the latter case.

Note

Our main focus in this chapter is on multivariate polynomial rings over fields (exact fields supported by OSCAR). Where not indicated otherwise, the presented functions also apply to polynomial rings over $\mathbb Z$.

General textbooks offering details on theory and algorithms include:

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/CommutativeAlgebra/localizations/index.html b/previews/PR2578/CommutativeAlgebra/localizations/index.html deleted file mode 100644 index 7bc53241b08b..000000000000 --- a/previews/PR2578/CommutativeAlgebra/localizations/index.html +++ /dev/null @@ -1,487 +0,0 @@ - -Localized Rings and Their Ideals · Oscar.jl

Localized Rings and Their Ideals

We recall the definition of localization. All rings considered are commutative, with multiplicative identity 1. Let $R$ be a ring, and let $U \subset R$ be a multiplicatively closed subset. That is,

\[1 \in U \;\text{ and }\; u, v \in U \;\Rightarrow \; u\cdot v \in U.\]

Consider the equivalence relation on $R\times U$ defined by setting

\[(r,u)\sim (r', u') \;\text{ iff }\; v(r u'-u r')=0 \;{\text{ for some }}\; v\in U.\]

Write $\frac{r}{u}$ for the equivalence class of $(r, u)$ and $R[U^{-1}]$ for the set of all equivalence classes. Mimicking the standard arithmetic for fractions, $R[U^{-1}]$ can be made into a ring. This ring is called the localization of $R$ at $U$. It comes equipped with the natural ring homomorphism

\[\iota : R\to R[U^{-1}],\; r \mapsto \frac{r}{1}.\]

Given an $R$-module $M$, the analogous construction yields an $R[U^{-1}]$-module $M[U^{-1}]$ which is called the localization of $M$ at $U$. See the section on modules.

Our focus in this section is on localizing multivariate polynomial rings and their quotients. The starting point for this is to provide functionality for handling (several types of) multiplicatively closed subsets of multivariate polynomial rings. Given such a polynomial ring R and a multiplicatively closed subset U of R whose type is supported by OSCAR, entering localization(R, U) creates the localization of R at U. Given a quotient RQ of R, with projection map p : R $\to$ RQ, and given a multiplicatively closed subset U of R, entering localization(RQ, U) creates the localization of RQ at p(U): Since every multiplicatively closed subset of RQ is of type p(U) for some U, there is no need to support an extra type for multiplicatively closed subsets of quotients.

Note

Most functions described here rely on the computation of standard bases. Recall that OSCAR supports standard bases for multivariate polynomial rings over fields (exact fields supported by OSCAR) and for multivariate polynomial rings over the integers.

Types

The OSCAR types discussed in this section are all parametrized. To simplify the presentation, details on the parameters are omitted.

All types for multiplicatively closed subsets of rings belong to the abstract type AbsMultSet. For multiplicatively closed subsets of multivariate polynomial rings, there are the abstract subtype AbsPolyMultSet and its concrete descendants MPolyComplementOfKPointIdeal, MPolyComplementOfPrimeIdeal, and MPolyPowersOfElement.

The general abstract type for localizations of rings is AbsLocalizedRing. For localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocRing. For localizations of quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocRing.

Constructors

Multiplicatively Closed Subsets

In accordance with the above mentioned types, we have the following constructors for multiplicatively closed subsets of multivariate polynomial rings.

complement_of_point_idealMethod
complement_of_point_ideal(R::MPolyRing, a::Vector)

Given a polynomial ring $R$, say $R = K[x_1,\dots, x_n]$, and given a vector $a = (a_1, \dots, a_n)$ of $n$ elements of $K$, return the multiplicatively closed subset $R\setminus m$, where $m$ is the maximal ideal

\[m = \langle x_1-a_1,\dots, x_n-a_n\rangle \subset R.\]

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> U = complement_of_point_ideal(R, [0, 0 ,0])
-Complement
-  of maximal ideal corresponding to rational point with coordinates (0, 0, 0)
-  in multivariate polynomial ring in 3 variables over QQ
-
source
complement_of_prime_idealMethod
complement_of_prime_ideal(P::MPolyIdeal; check::Bool=false)

Given a prime ideal $P$ of a polynomial ring $R$, say, return the multiplicatively closed subset $R\setminus P.$

Note

If check is set to true, the function checks whether $P$ is indeed a prime ideal.

This may take some time.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> P = ideal(R, [x])
-ideal(x)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(x)
-  in multivariate polynomial ring in 3 variables over QQ
source
powers_of_elementMethod
powers_of_element(f::MPolyRingElem)

Given an element f of a polynomial ring, return the multiplicatively closed subset of the polynomial ring which is formed by the powers of f.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> f = x
-x
-
-julia> U = powers_of_element(f)
-Multiplicative subset
-  of multivariate polynomial ring in 3 variables over QQ
-  given by the products of [x]
source

It is also possible to build products of multiplicatively closed sets already given:

productMethod
product(T::AbsMPolyMultSet, U::AbsMPolyMultSet)

Return the product of the multiplicative subsets T and U.

Alternatively, write T*U.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> T = complement_of_point_ideal(R, [0, 0 ,0])
-Complement
-  of maximal ideal corresponding to rational point with coordinates (0, 0, 0)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> f = x
-x
-
-julia> U = powers_of_element(f)
-Multiplicative subset
-  of multivariate polynomial ring in 3 variables over QQ
-  given by the products of [x]
-
-julia> S = product(T, U)
-Product of the multiplicative sets
-  complement of maximal ideal of point (0, 0, 0)
-  products of 1 element
source

Containment in multiplicatively closed subsets can be checked via the in function:

inMethod
in(f::MPolyRingElem, U::AbsMPolyMultSet)

Return true if f is contained in U, false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> S = complement_of_point_ideal(R, [0, 0 ,0])
-Complement
-  of maximal ideal corresponding to rational point with coordinates (0, 0, 0)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> y in S
-false
-
-julia> P = ideal(R, [x])
-ideal(x)
-
-julia> T = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(x)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> y in T
-true
-
-julia> U = powers_of_element(x)
-Multiplicative subset
-  of multivariate polynomial ring in 3 variables over QQ
-  given by the products of [x]
-
-julia> x^3 in U
-true
-
-julia> (1+y)*x^2 in product(S, U)
-true
source

Localized Rings

localizationMethod
localization(R::MPolyRing, U::AbsMPolyMultSet)

Return the localization of R at U, together with the localization map.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> P = ideal(R, [x])
-ideal(x)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(x)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> Rloc, iota = localization(R, U);
-
-julia> Rloc
-Localization
-  of multivariate polynomial ring in 3 variables over QQ
-  at complement of prime ideal(x)
-
-julia> iota
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Localization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal
source
localizationMethod
localization(RQ::MPolyQuoRing, U::AbsMPolyMultSet)

Given a quotient RQ of a multivariate polynomial ring R with projection map p : R -> RQ, say, and given a multiplicatively closed subset U of R, return the localization of RQ at p(U), together with the localization map.

Examples

julia> T, t = polynomial_ring(QQ, "t");
-
-julia> K, a =  number_field(2*t^2-1, "a");
-
-julia> R, (x, y) = polynomial_ring(K, ["x", "y"]);
-
-julia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])
-ideal(2*x^2 - y^3, 2*x^2 - y^5)
-
-julia> P = ideal(R, [y-1, x-a])
-ideal(y - 1, x - a)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(y - 1, x - a)
-  in multivariate polynomial ring in 2 variables over number field
-
-julia> RQ, _ = quo(R, I);
-
-julia> RQL, iota = localization(RQ, U);
-
-julia> RQL
-Localization
-  of quotient of multivariate polynomial ring by ideal with 2 generators
-  at complement of prime ideal(y - 1, x - a)
-
-julia> iota
-Map from
-RQ to Localization of quotient of multivariate polynomial ring at complement of prime ideal defined by a julia-function
source

Data associated to Localized Rings

If Rloc is the localization of a multivariate polynomial ring R at a multiplicatively closed subset U of R, then

  • base_ring(Rloc) refers to R, and
  • inverted_set(Rloc) to U.

If RQ is a quotient of a multivariate polynomial ring R, p : R $\to$ RQ is the projection map, U is a multiplicatively closed subset of R, and RQL is the localization of RQ at p(U), then

  • base_ring(RQL) refers to R, and
  • inverted_set(RQL) to U.

This reflects the way of creating localizations of quotients of multivariate polynomial rings in OSCAR.

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> P = ideal(R, [x])
-ideal(x)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(x)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> Rloc, _ = localization(U);
-
-julia> R === base_ring(Rloc)
-true
-
-julia> U === inverted_set(Rloc)
-true
julia> T, t = polynomial_ring(QQ, "t");
-
-julia> K, a =  number_field(2*t^2-1, "a");
-
-julia> R, (x, y) = polynomial_ring(K, ["x", "y"]);
-
-julia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])
-ideal(2*x^2 - y^3, 2*x^2 - y^5)
-
-julia> P = ideal(R, [y-1, x-a])
-ideal(y - 1, x - a)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(y - 1, x - a)
-  in multivariate polynomial ring in 2 variables over number field
-
-julia> RQ, _ = quo(R, I);
-
-julia> RQL, _ = localization(RQ, U);
-
-julia> R == base_ring(RQL)
-true
-
-julia> U == inverted_set(RQL)
-true

Elements of Localized Rings

Types

The general abstract type for elements of localizations of rings is AbsLocalizedRingElem. For elements of localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocRingElem. For elements of localizations of quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocRingElem.

Creating Elements of Localized Rings

If Rloc is the localization of a multivariate polynomial ring R at a multiplicatively closed subset U of R, then elements of Rloc are created as (fractions of) images of elements of R under the localization map or by coercing (pairs of) elements of R into fractions.

If RQ is a quotient of a multivariate polynomial ring R, p : R $\to$ RQ is the projection map, U is a multiplicatively closed subset of R, and RQL is the localization of RQ at p(U), then elements of RQL are created similarly, starting from elements of R.

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> P = ideal(R, [x])
-ideal(x)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(x)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> Rloc, iota = localization(U);
-
-julia> iota(x)
-x
-
-julia> Rloc(x)
-x
-
-julia> f = iota(y)/iota(z)
-y/z
-
-julia> g = Rloc(y, z)
-y/z
-
-julia> X, Y, Z = Rloc.(gens(R));
-
-julia> h = Y/Z
-y/z
-
-julia> f == g == h
-true
-
-julia> f+g
-2*y/z
-
-julia> f*g
-y^2/z^2
julia> T, t = polynomial_ring(QQ, "t");
-
-julia> K, a =  number_field(2*t^2-1, "a");
-
-julia> R, (x, y) = polynomial_ring(K, ["x", "y"]);
-
-julia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])
-ideal(2*x^2 - y^3, 2*x^2 - y^5)
-
-julia> P = ideal(R, [y-1, x-a])
-ideal(y - 1, x - a)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(y - 1, x - a)
-  in multivariate polynomial ring in 2 variables over number field
-
-julia> RQ, p = quo(R, I);
-
-julia> RQL, iota = Localization(RQ, U);
-
-julia> phi = compose(p, iota);
-
-julia> phi(x)
-x
-
-julia> RQL(x)
-x
-
-julia> f = phi(x)/phi(y)
-x/y
-
-julia> g = RQL(x, y)
-x/y
-
-julia> X, Y = gens(RQL);
-
-julia> h = X/Y
-x/y
-
-julia> f == g == h
-true
-
-julia> f+g
-2*x/y
-
-julia> f*g
-x^2/y^2

Data Associated to Elements of Localized Rings

If Rloc is a localization of a multivariate polynomial ring R, and f is an element of Rloc, internally represented by a pair (r, u) of elements of R, then

  • parent(f) refers to Rloc,
  • numerator(f) to r, and
  • denominator(f) to u.

If RQL is a localization of a quotient RQ of a multivariate polynomial ring R, and f is an element of RQL, internally represented by a pair (r, u) of elements of R, then

  • parent(f) refers to RQL,
  • numerator(f) to the image of r in RQ, and
  • denominator(f) to the image of u in RQ.

That is, the behaviour of the functions numerator and denominator reflects the mathematical viewpoint of representing f by pairs of elements of RQ and not the internal representation of f as pairs of elements of R.

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> P = ideal(R, [x])
-ideal(x)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(x)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> Rloc, iota = localization(U);
-
-julia> f = iota(x)/iota(y)
-x/y
-
-julia> parent(f)
-Localization
-  of multivariate polynomial ring in 3 variables over QQ
-  at complement of prime ideal(x)
-
-julia> g = iota(y)/iota(z)
-y/z
-
-julia> r = numerator(f*g)
-x
-
-julia> u = denominator(f*g)
-z
-
-julia> typeof(r) == typeof(u) <: MPolyRingElem
-true
julia> T, t = polynomial_ring(QQ, "t");
-
-julia> K, a =  number_field(2*t^2-1, "a");
-
-julia> R, (x, y) = polynomial_ring(K, ["x", "y"]);
-
-julia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])
-ideal(2*x^2 - y^3, 2*x^2 - y^5)
-
-julia> P = ideal(R, [y-1, x-a])
-ideal(y - 1, x - a)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(y - 1, x - a)
-  in multivariate polynomial ring in 2 variables over number field
-
-julia> RQ, p = quo(R, I);
-
-julia> RQL, iota = Localization(RQ, U);
-
-julia> phi = compose(p, iota);
-
-julia> f = phi(x)
-x
-
-julia> parent(f)
-Localization
-  of quotient of multivariate polynomial ring by ideal with 2 generators
-  at complement of prime ideal(y - 1, x - a)
-
-julia> g = f/phi(y)
-x/y
-
-julia> r = numerator(f*g)
-x^2
-
-julia> u = denominator(f*g)
-y
-
-julia> typeof(r) == typeof(u) <: MPolyQuoRingElem
-true

Tests on Elements of Localized Rings

is_unitMethod
is_unit(f::MPolyLocRingElem)

Return true, if f is a unit of parent(f), false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> P = ideal(R, [x])
-ideal(x)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(x)
-  in multivariate polynomial ring in 3 variables over QQ
-
-julia> Rloc, iota = localization(U);
-
-julia> is_unit(iota(x))
-false
-
-julia> is_unit(iota(y))
-true
source
is_unitMethod
is_unit(f::MPolyQuoLocRingElem)

Return true, if f is a unit of parent(f), true otherwise.

Examples

julia> T, t = polynomial_ring(QQ, "t");
-
-julia> K, a =  number_field(2*t^2-1, "a");
-
-julia> R, (x, y) = polynomial_ring(K, ["x", "y"]);
-
-julia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])
-ideal(2*x^2 - y^3, 2*x^2 - y^5)
-
-julia> P = ideal(R, [y-1, x-a])
-ideal(y - 1, x - a)
-
-julia> U = complement_of_prime_ideal(P)
-Complement
-  of prime ideal(y - 1, x - a)
-  in multivariate polynomial ring in 2 variables over number field
-
-julia> RQ, p = quo(R, I);
-
-julia> RQL, iota = Localization(RQ, U);
-
-julia> is_unit(iota(p(x)))
-true
source

Homomorphisms from Localized Rings

The general abstract type for ring homomorphisms starting from localized rings is AbsLocalizedRingHom. For ring homomorphisms starting from localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocalizedRingHom. For ring homomorphisms starting from quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocalizedRingHom. We describe the construction of such homomorphisms. Let

  • R be a multivariate polynomial ring
  • U be a multiplicatively closed subset of R,
  • RQ = R/I be a quotient of R with projection map p : R $\to$ RQ,
  • Rloc (RQL) be the localization of R at U (of RQ at p(U)), and
  • S be another ring.

Then, to give a ring homomorphism PHI from Rloc to S (fromRQL to S) is the same as to give a ring homomorphism phi from R to S which sends elements of U to units in S (and elements of I to zero). That is, PHI is determined by composing it with the localization map R $\to$ Rloc (by composing it with the composition of the localization map RQ $\to$ RQL and the projection map R $\to$ RQ). The constructors below take this into account.

homMethod
hom(Rloc::MPolyLocRing, S::Ring, phi::Map)

Given a localized ring Rlocof type MPolyLocRing, say Rloc is the localization of a multivariate polynomial ring R at the multiplicatively closed subset U of R, and given a homomorphism phi from R to S sending elements of U to units in S, return the homomorphism from Rloc to S whose composition with the localization map is phi.

hom(Rloc::MPolyLocRing, S::Ring, V::Vector)

Given a localized ring Rloc as above, and given a vector V of nvars elements of S, let phi be the homomorphism from R to S which is determined by the entries of V as the images of the generators of R, and proceed as above.

hom(RQL::MPolyQuoLocRing, S::Ring, phi::Map)

Given a localized ring RQLof type MPolyQuoLocRing, say RQL is the localization of a quotient ring RQ of a multivariate polynomial ring R at the multiplicatively closed subset U of R, and given a homomorphism phi from R to S sending elements of U to units in S and elements of the modulus of RQ to zero, return the homomorphism from Rloc to S whose composition with the localization map RQ -> RQL and the projection map R -> RQ is phi.

hom(RQL::MPolyQuoLocRing, S::Ring, V::Vector)

Given a localized ring RQLas above, and given a vector V of nvars elements of S, let phi be the homomorphism from R to S which is determined by the entries of V as the images of the generators of R, and proceed as above.

Warning

Except from the case where the type of U is <: MPolyPowersOfElement, the condition on phi requiring that elements of U are send to units in S is not checked by the hom constructor.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> I = ideal(R, [y-x^2, z-x^3]);
-
-julia> RQ, p = quo(R, I);
-
-julia> UR = complement_of_point_ideal(R, [0, 0, 0]);
-
-julia> RQL, _ = localization(RQ, UR);
-
-julia> T, (t,) =  polynomial_ring(QQ, ["t"]);
-
-julia> UT = complement_of_point_ideal(T, [0]);
-
-julia> TL, _ =  localization(T, UT);
-
-julia> PHI = hom(RQL, TL, TL.([t, t^2, t^3]))
-Ring homomorphism
-  from localization of quotient of multivariate polynomial ring at complement of maximal ideal
-  to   localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal
-defined by
-  x -> t
-  y -> t^2
-  z -> t^3
-
-julia> PSI = hom(TL, RQL, RQL.([x]))
-Ring homomorphism
-  from localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal
-  to   localization of quotient of multivariate polynomial ring at complement of maximal ideal
-defined by
-  t -> x
-
-julia> PHI(RQL(z))
-t^3
-
-julia> PSI(TL(t))
-x
source

Given a ring homomorphism PHI from Rloc to S (from RQL to S), domain(PHI) and codomain(PHI) refer to Rloc and S (RQL and S), respectively. The corresponding homomorphism phi from R to S is recovered as follows:

restricted_mapMethod
restricted_map(PHI::MPolyLocalizedRingHom)
-
-restricted_map(PHI::MPolyQuoLocalizedRingHom)

Given a ring homomorphism PHI starting from a localized multivariate polynomial ring (a localized quotient of a multivariate polynomial ring), return the composition of PHI with the localization map (with the composition of the localization map and the projection map).

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> I = ideal(R, [y-x^2, z-x^3]);
-
-julia> RQ, p = quo(R, I);
-
-julia> UR = complement_of_point_ideal(R, [0, 0, 0]);
-
-julia> RQL, _ = localization(RQ, UR);
-
-julia> T, (t,) =  polynomial_ring(QQ, ["t"]);
-
-julia> UT = complement_of_point_ideal(T, [0]);
-
-julia> TL, _ =  localization(T, UT);
-
-julia> PHI = hom(RQL, TL, TL.([t, t^2, t^3]));
-
-julia> PSI = hom(TL, RQL, RQL.([x]));
-
-julia> phi = restricted_map(PHI)
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 3 variables over QQ
-Codomain:
-=========
-Localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal
-
-julia> psi = restricted_map(PSI)
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 1 variable over QQ
-Codomain:
-=========
-Localization of quotient of multivariate polynomial ring at complement of maximal ideal
source

Ideals in Localized Rings

Types

The general abstract type for ideals in localized rings is AbsLocalizedIdeal. For ideals in localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocalizedIdeal. For ideals in localizations of quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocalizedIdeal.

Constructors

Given a localization Rloc of a multivariate polynomial ring R, and given a vector V of elements of Rloc (of R), the ideal of Rloc which is generated by (the images) of the entries of V is created by entering ideal(Rloc, V). The construction of ideals in localizations of quotients of multivariate polynomial rings is similar..

Examples
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> f = x^3+y^4
-x^3 + y^4
-
-julia> V = [derivative(f, i) for i=1:2]
-2-element Vector{QQMPolyRingElem}:
- 3*x^2
- 4*y^3
-
-julia> U = complement_of_point_ideal(R, [0, 0]);
-
-julia> Rloc, _ = localization(R, U);
-
-julia> MI = ideal(Rloc, V)
-Ideal
-  of localized ring
-with 2 generators
-  3*x^2
-  4*y^3

Data Associated to Ideals

If I is an ideal of a localized multivariate polynomial ring Rloc, then

  • base_ring(I) refers to Rloc,
  • gens(I) to the generators of I,
  • ngens(I) to the number of these generators, and
  • gen(I, k) as well as I[k] to the k-th such generator.

Similarly, if I is an ideal of a localized quotient of a multivariate polynomial ring.

Operations on Ideals

If I, J are ideals of a localized multivariate polynomial ring Rloc, then

  • I^k refers to the k-th power of I,
  • I+J, I*J, and intersect(I, J) to the sum, product, and intersection of I and J, and
  • quotient(I, J) as well as I:J to the ideal quotient of I by J.

Similarly, if I and J are ideals of a localized quotient of a multivariate polynomial ring.

Tests on Ideals

The usual tests f in J, issubset(I, J), and I == J are available.

Saturation

If $Rloc$ is the localization of a multivariate polynomial ring $R$ at a multiplicative subset $U$ of $R$, then the ideal theory of $Rloc$ is a simplified version of the ideal theory of $R$ (see, for instance, David Eisenbud (1995)). In particular, each ideal $I$ of $Rloc$ is the extension $J\cdot Rloc$ of an ideal $J$ of $R$. The ideal

\[\{f\in R \mid uf\in J \text{ for some } u\in U\}\]

is independent of the choice of $J$ and is the largest ideal of $R$ which extends to $I$. It is, thus, the contraction of $I$ to $R$, that is, the preimage of $I$ under the localization map. We call this ideal the saturation of $I$ over $R$. In OSCAR, it is obtained by entering saturated_ideal(I).

If $RQL$ is the localization of a quotient $RQ$ of a multivariate polynomial ring $R$, and $I$ is an ideal of $RQL$, then the return value of saturated_ideal(I) is the preimage of the saturation of $I$ over $RQ$ under the projection map $R \to RQ$ (and not the saturation of $I$ over $RQ$ itself).

saturated_idealMethod
saturated_ideal(I::MPolyLocalizedIdeal)

Given an ideal I of a localization, say, Rloc of a multivariate polynomial ring, say, R, return the saturation of I over R. That is, return the largest ideal of R whose extension to Rloc is I. This is the preimage of I under the localization map.

saturated_ideal(I::MPolyQuoLocalizedIdeal)

Given an ideal I of a localization, say, RQL of a quotient, say, RQ of a multivariate polynomial ring, say, R, return the preimage of the saturation of I over RQ under the projection map R -> RQ.

Examples

julia> R, (x,) = polynomial_ring(QQ, ["x"]);
-
-julia> U = powers_of_element(x)
-Multiplicative subset
-  of multivariate polynomial ring in 1 variable over QQ
-  given by the products of [x]
-
-julia> Rloc, iota = localization(R, U);
-
-julia> I = ideal(Rloc, [x+x^2])
-Ideal
-  of localized ring
-with 1 generator
-  x^2 + x
-
-julia> SI = saturated_ideal(I)
-ideal(x + 1)
-
-julia> base_ring(SI)
-Multivariate polynomial ring in 1 variable x
-  over rational field
-
-julia> U = complement_of_point_ideal(R, [0])
-Complement
-  of maximal ideal corresponding to rational point with coordinates (0)
-  in multivariate polynomial ring in 1 variable over QQ
-
-julia> Rloc, iota = localization(R, U);
-
-julia> I = ideal(Rloc, [x+x^2])
-Ideal
-  of localized ring
-with 1 generator
-  x^2 + x
-
-julia> saturated_ideal(I)
-ideal(x)
source
diff --git a/previews/PR2578/CommutativeAlgebra/rings/index.html b/previews/PR2578/CommutativeAlgebra/rings/index.html deleted file mode 100644 index 661c9240ab59..000000000000 --- a/previews/PR2578/CommutativeAlgebra/rings/index.html +++ /dev/null @@ -1,626 +0,0 @@ - -Creating Multivariate Rings · Oscar.jl

Creating Multivariate Rings

In this section, for the convenience of the reader, we recall from the chapters on rings and fields how to create multivariate polynomial rings and their elements, adding illustrating examples. At the same time, we introduce and illustrate a ring type for modelling multivariate polynomial rings with gradings.

Types

OSCAR provides types for dense univariate and sparse multivariate polynomials. The univariate ring types belong to the abstract type PolyRing{T}, their elements have abstract type PolyRingElem{T}. The multivariate ring types belong to the abstract type MPolyRing{T}, their elements have abstract type MPolyRingElem{T}. Here, T is the element type of the coefficient ring of the polynomial ring.

Constructors

The basic constructor below allows one to build multivariate polynomial rings:

polynomial_ring(C::Ring, V::Vector{String}; ordering=:lex, cached::Bool = true)

Its return value is a tuple, say R, vars, consisting of a polynomial ring R with coefficient ring C and a vector vars of generators (variables) which print according to the strings in the vector V . The input ordering=:lex refers to the lexicograpical monomial ordering which specifies the default way of storing and displaying polynomials in OSCAR (terms are sorted in descending order). The other possible choices are :deglex and :degrevlex. Gröbner bases, however, can be computed with respect to any monomial ordering. See the section on Gröbner bases.

Note

Caching is used to ensure that a given ring constructed from given parameters is unique in the system. For example, there is only one ring of multivariate polynomials over $\mathbb{Z}$ with variables printing as x, y, z, and with ordering=:lex.

Examples
julia> R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])
-
-julia> typeof(R)
-ZZMPolyRing
-
-julia> typeof(x)
-ZZMPolyRingElem
-
-julia> S, (a, b, c) = polynomial_ring(ZZ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])
-
-julia> T, _ = polynomial_ring(ZZ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])
-
-julia> R === S === T
-true
julia> R1, x = polynomial_ring(QQ, ["x"])
-(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])
-
-julia> typeof(x)
-Vector{QQMPolyRingElem} (alias for Array{QQMPolyRingElem, 1})
-
-julia> R2, (x,) = polynomial_ring(QQ, ["x"])
-(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])
-
-julia> typeof(x)
-QQMPolyRingElem
-
-julia> R3, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over QQ, x)
-
-julia> typeof(x)
-QQPolyRingElem
-
julia> T, x = polynomial_ring(GF(3), ["x[1]", "x[2]"]);
-
-julia> x
-2-element Vector{fpMPolyRingElem}:
- x[1]
- x[2]
-

The constructor illustrated below allows for the convenient handling of variables with multi-indices:

julia> R, x, y, z = polynomial_ring(QQ, "x" => (1:3, 1:4), "y" => 1:2, "z" => (1:1, 1:1, 1:1));
-
-julia> x
-3×4 Matrix{QQMPolyRingElem}:
- x[1, 1]  x[1, 2]  x[1, 3]  x[1, 4]
- x[2, 1]  x[2, 2]  x[2, 3]  x[2, 4]
- x[3, 1]  x[3, 2]  x[3, 3]  x[3, 4]
-
-julia> y
-2-element Vector{QQMPolyRingElem}:
- y[1]
- y[2]
-
-julia> z
-1×1×1 Array{QQMPolyRingElem, 3}:
-[:, :, 1] =
- z[1, 1, 1]
-

Coefficient Rings

Gröbner and standard bases are implemented for multivariate polynomial rings over the fields and rings below:

The field of rational numbers $\mathbb{Q}$

julia> QQ
-Rational field
-

Finite fields $\mathbb{F_p}$, $p$ a prime

julia> GF(3)
-Finite field of characteristic 3
-
-julia> GF(ZZ(2)^127 - 1)
-Finite field of characteristic 170141183460469231731687303715884105727
-

Finite fields $\mathbb{F}_{p^n}$ with $p^n$ elements, $p$ a prime

julia> FiniteField(2, 70, "a")
-(Finite field of degree 70 over GF(2), a)
-

Simple algebraic extensions of $\mathbb{Q}$ or $\mathbb{F}_p$

julia> T, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over QQ, t)
-
-julia> K, a = number_field(t^2 + 1, "a")
-(Number field of degree 2 over QQ, a)
-
-julia> F = GF(3)
-Finite field of characteristic 3
-
-julia> T, t = polynomial_ring(F, "t")
-(Univariate polynomial ring in t over GF(3), t)
-
-julia> K, a = FiniteField(t^2 + 1, "a")
-(Finite field of degree 2 over GF(3), a)
-

Purely transcendental extensions of $\mathbb{Q}$ or $\mathbb{F}_p$

julia> T, t = polynomial_ring(QQ, "t")
-(Univariate polynomial ring in t over QQ, t)
-
-julia> QT = fraction_field(T)
-Fraction field
-  of univariate polynomial ring in t over QQ
-
-julia> parent(t)
-Univariate polynomial ring in t over QQ
-
-julia> parent(1//t)
-Fraction field
-  of univariate polynomial ring in t over QQ
-
-julia> T, (s, t) = polynomial_ring(GF(3), ["s", "t"]);
-
-julia> QT = fraction_field(T)
-Fraction field
-  of multivariate polynomial ring in 2 variables over GF(3)
-

The ring of integers $\mathbb{Z}$

julia> ZZ
-Integer Ring
-

Gradings

Given a polynomial ring $R = C[x_1, \dots, x_n]$, we may endow $R$ with various gradings. The standard $\mathbb Z$-grading on $R$ is the decomposition $R=\bigoplus_{d\in \mathbb Z} R_d=\bigoplus_{d\geq 0} R_d$ by the usual degree of polynomials. More general $\mathbb Z$-gradings are obtained by assigning integer weights to the variables and considering the corresponding weighted degrees. Even more generally, we may consider multigradings: Given a finitely generated abelian group $G$, a multigrading on $R$ by $G$, or a $G$-grading, or simply a grading, corresponds to a semigroup homomorphism $\phi: \mathbb N^n \to G$: Given $\phi$, the degree of a monomial $x^\alpha$ is the image $\deg(x^\alpha):=\phi(\alpha)\in G$; the induced $G$-grading on $R$ is the decomposition $R = \bigoplus_{g\in G} R_g$ satisfying $R_g\cdot R_h\subset R_{g+h}$, where $R_g$ is the free $C$-module generated by the monomials of degree $g$. This grading is determined by assigning the weights $\deg(x_i)$ to the $x_i$. In other words, it is determined by the weight vector $W = (\deg(x_1), \dots, \deg(x_n))\in G^n.$

We refer to the textbooks Ezra Miller, Bernd Sturmfels (2005) and Martin Kreuzer, Lorenzo Robbiano (2005) for details on multigradings. With respect to notation, we follow the former book.

Note

Given a $G$-grading on $R$, we refer to $G$ as the grading group of $R$. Moreover, we then say that $R$ is $G$-graded, or simply that $R$ is graded. If $R$ is a polynomial ring over a field, we say that a $G$-grading on $R$ is positive if $G$ is free and each graded part $R_g$, $g\in G$, has finite dimension. We then also say that $R$ is positively graded (by $G$). Note that the positivity condition can be equivalently expressed by asking that $G$ is free and that the degree zero part consists of the constants only (see Theorem 8.6 in Ezra Miller, Bernd Sturmfels (2005)).

Note

Given a G-grading on R in OSCAR, we say that R is $\mathbb Z^m$-graded if is_free(G) && ngens(G) == rank(G) == m evaluates to true. In this case, conversion routines allow one to switch back and forth between elements of G and integer vectors of length m. Specifically, if R is $\mathbb Z$-graded, that is, is_free(G) && ngens(G) == rank(G) == 1 evaluates to true, elements of G may be converted to integers and vice versa.

Types

Multivariate rings with gradings are modelled by objects of type MPolyDecRing{T, S} :< MPolyRing{T}, with elements of type MPolyRingElem_dec{T, S} :< MPolyRingElem{T}. Here, S is the element type of the multivariate ring, and T is the element type of its coefficient ring as above.

Note

The types MPolyDecRing{T, S} and MPolyRingElem_dec{T, S} are also meant to eventually model multivariate rings with filtrations and their elements.

The following function allows one, in particular, to distinguish between graded and filtered rings.

is_gradedMethod
is_graded(R::MPolyRing)

Return true if R is graded, false otherwise.

source

Constructors for Graded Rings

There are two basic ways of creating multivariate rings with gradings: While the grade function allows one to create a graded ring by assigning a grading to a polynomial ring already constructed, the graded_polynomial_ring function is meant to create a graded polynomial ring all at once.

gradeMethod
grade(R::MPolyRing, W::Vector{GrpAbFinGenElem})

Given a vector W of ngens(R) elements of a finitely presented group G, say, create a G-graded ring by assigning the entries of W as weights to the variables of R. Return the new ring as an object of type MPolyDecRing, together with the vector of variables.

Examples

julia> R, (t, x, y) = polynomial_ring(QQ, ["t", "x", "y"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[t, x, y])
-
-julia> typeof(R)
-QQMPolyRing
-
-julia>  typeof(x)
-QQMPolyRingElem
-
-julia> G = abelian_group([0])
-GrpAb: Z
-
-julia> g = gen(G, 1)
-Element of G with components [1]
-
-julia> S, (t, x, y) = grade(R, [-g, g, g])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[t, x, y])
-
-julia> typeof(S)
-MPolyDecRing{QQFieldElem, QQMPolyRing}
-
-julia> S isa MPolyRing
-true
-
-julia> typeof(x)
-MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}
-
-julia> R, x, y = polynomial_ring(QQ, "x" => 1:2, "y" => 1:3)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2]], QQMPolyRingElem[y[1], y[2], y[3]])
-
-julia> G = abelian_group([0, 0])
-GrpAb: Z^2
-
-julia> g = gens(G)
-2-element Vector{GrpAbFinGenElem}:
- Element of G with components [1 0]
- Element of G with components [0 1]
-
-julia> W = [g[1], g[1], g[2], g[2], g[2]];
-
-julia> S, _ = grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], y[1], y[2], y[3]])
-
-julia> typeof(x[1])
-QQMPolyRingElem
-
-julia> x = map(S, x)
-2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x[1]
- x[2]
-
-julia> y = map(S, y)
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- y[1]
- y[2]
- y[3]
-
-julia> typeof(x[1])
-MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}
-
-julia> R, x = polynomial_ring(QQ, "x" => 1:5)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])
-
-julia> G = abelian_group([0, 0, 2, 2])
-(General) abelian group with relation matrix
-[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
-
-julia> g = gens(G)
-4-element Vector{GrpAbFinGenElem}:
- Element of G with components [1 0 0 0]
- Element of G with components [0 1 0 0]
- Element of G with components [0 0 1 0]
- Element of G with components [0 0 0 1]
-
-julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
-
-julia> S, x = grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])
source
gradeMethod
grade(R::MPolyRing, W::Vector{<:Vector{<:IntegerUnion}})

Given a vector W of ngens(R) integer vectors of the same size m, say, create a free abelian group of type GrpAbFinGen given by m free generators, and convert the vectors in W to elements of that group. Then create a $\mathbb Z^m$-graded ring by assigning the group elements as weights to the variables of R, and return the new ring, together with the vector of variables.

grade(R::MPolyRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}})

As above, converting the columns of W.

Examples

julia> R, x, y = polynomial_ring(QQ, "x" => 1:2, "y" => 1:3)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2]], QQMPolyRingElem[y[1], y[2], y[3]])
-
-julia> W = [1 1 0 0 0; 0 0 1 1 1]
-2×5 Matrix{Int64}:
- 1  1  0  0  0
- 0  0  1  1  1
-
-julia> grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], y[1], y[2], y[3]])
source
gradeMethod
grade(R::MPolyRing, W::Vector{<:IntegerUnion})

Given a vector W of ngens(R) integers, create a free abelian group of type GrpAbFinGen given by one free generator, and convert the entries of W to elements of that group. Then create a $\mathbb Z$-graded ring by assigning the group elements as weights to the variables of R, and return the new ring, together with the vector of variables.

grade(R::MPolyRing)

As above, where the grading is the standard $\mathbb Z$-grading on R.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> W = [1, 2, 3];
-
-julia> S, (x, y, z) = grade(R, W)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> T, (x, y, z) = grade(R)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
source
graded_polynomial_ringMethod
graded_polynomial_ring(C::Ring, V, W; ordering=:lex)
-graded_polynomial_ring(C::Ring, n::Int, s::T, W; ordering=:lex) where T<:VarName

Create a multivariate polynomial_ring with coefficient ring C and variables which print according to the variable names in V (respectively as "$(s)1" up to "$s$n"), and grade this ring according to the data provided by W. Return the graded ring as an object of type MPolyDecRing, together with the vector of variables.

graded_polynomial_ring(C::Ring, V; ordering=:lex)

As above, where the grading is the standard $\mathbb Z$-grading.

Examples

julia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]
-4-element Vector{Vector{Int64}}:
- [1, 0]
- [0, 1]
- [1, 0]
- [4, 1]
-
-julia> R, x = graded_polynomial_ring(QQ, 4, :x, W)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x1, x2, x3, x4])
-
-julia> S, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z], [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> T, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
source

Tests on Graded Rings

is_standard_gradedMethod
is_standard_graded(R::MPolyDecRing)

Return true if R is standard $\mathbb Z$-graded, false otherwise.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> W = [1, 2, 3];
-
-julia> S, (x, y, z) = grade(R, W)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> is_standard_graded(S)
-false
source
is_z_gradedMethod
is_z_graded(R::MPolyDecRing)

Return true if R is $\mathbb Z$-graded, false otherwise.

Note

Writing G = grading_group(R), we say that R is $\mathbb Z$-graded if is_free(G) && ngens(G) == rank(G) == 1 evaluates to true.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> W = [1, 2, 3];
-
-julia> S, (x, y, z) = grade(R, W)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> is_z_graded(S)
-true
source
is_zm_gradedMethod
is_zm_graded(R::MPolyDecRing)

Return true if R is $\mathbb Z^m$-graded for some $m$, false otherwise.

Note

Writing G = grading_group(R), we say that R is $\mathbb Z^m$-graded if is_free(G) && ngens(G) == rank(G) == m evaluates to true.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:5)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])
-
-julia> G = abelian_group([0, 0, 2, 2])
-(General) abelian group with relation matrix
-[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
-
-julia> g = gens(G);
-
-julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
-
-julia> S, x = grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])
-
-julia> is_zm_graded(S)
-false
-
-julia> G = abelian_group(ZZMatrix([1 -1]));
-
-julia> g = gen(G, 1)
-Element of G with components [0 1]
-
-julia> W = [g, g, g, g];
-
-julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"], W);
-
-julia> is_free(G)
-true
-
-julia> is_zm_graded(R)
-false
source
is_positively_gradedMethod
is_positively_graded(R::MPolyDecRing)

Return true if R is positively graded, false otherwise.

Note

We say that R is positively graded by a finitely generated abelian group $G$ if the coefficient ring of R is a field, $G$ is free, and each graded part $R_g$, $g\in G$, has finite dimension.

Examples

julia> R, (t, x, y) = polynomial_ring(QQ, ["t", "x", "y"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[t, x, y])
-
-julia> G = abelian_group([0])
-GrpAb: Z
-
-julia> S, (t, x, y) = grade(R, [-1, 1, 1])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[t, x, y])
-
-julia> is_positively_graded(S)
-false
-
-julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> G = abelian_group([0, 2])
-(General) abelian group with relation matrix
-[0 0; 0 2]
-
-julia> W = [gen(G, 1)+gen(G, 2), gen(G, 1)]
-2-element Vector{GrpAbFinGenElem}:
- Element of G with components [1 1]
- Element of G with components [1 0]
-
-julia> S, (x, y) = grade(R, W)
-(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])
-
-julia> is_positively_graded(S)
-false
source

Data Associated to Multivariate Rings

Given a multivariate polynomial ring R with coefficient ring C,

  • coefficient_ring(R) refers to C,
  • gens(R) to the generators (variables) of R,
  • ngens(R) to the number of these generators, and
  • gen(R, i) as well as R[i] to the i-th such generator.
Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> coefficient_ring(R)
-Rational field
-
-julia> gens(R)
-3-element Vector{QQMPolyRingElem}:
- x
- y
- z
-
-julia> gen(R, 2)
-y
-
-julia> R[3]
-z 
-
-julia> ngens(R)
-3
-

In the graded case, we additionally have:

grading_groupMethod
grading_group(R::MPolyDecRing)

If R is, say, G-graded, then return G.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> grading_group(R)
-GrpAb: Z
source
monomial_basisMethod
monomial_basis(R::MPolyDecRing, g::GrpAbFinGenElem)

Given a polynomial ring R over a field which is graded by a free group of type GrpAbFinGen, and given an element g of that group, return the monomials of degree g in R.

monomial_basis(R::MPolyDecRing, W::Vector{<:IntegerUnion})

Given a $\mathbb Z^m$-graded polynomial ring R over a field and a vector W of $m$ integers, convert W into an element g of the grading group of R and proceed as above.

monomial_basis(R::MPolyDecRing, d::IntegerUnion)

Given a $\mathbb Z$-graded polynomial ring R over a field and an integer d, convert d into an element g of the grading group of R and proceed as above.

Note

If the component of the given degree is not finite dimensional, an error message will be thrown.

Examples

julia> T, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> G = grading_group(T)
-GrpAb: Z
-
-julia> L = monomial_basis(T, 2)
-6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- z^2
- y*z
- y^2
- x*z
- x*y
- x^2
source
homogeneous_componentMethod
homogeneous_component(R::MPolyDecRing, g::GrpAbFinGenElem)

Given a polynomial ring R over a field which is graded by a free group of type GrpAbFinGen, and given an element g of that group, return the homogeneous component of R of degree g as a standard vector space. Additionally, return the map which sends an element of that vector space to the corresponding monomial in R.

homogeneous_component(R::MPolyDecRing, W::Vector{<:IntegerUnion})

Given a $\mathbb Z^m$-graded polynomial ring R over a field, and given a vector W of $m$ integers, convert W into an element g of the grading group of R and proceed as above.

homogeneous_component(R::MPolyDecRing, d::IntegerUnion)

Given a $\mathbb Z$-graded polynomial ring R over a field, and given an integer d, convert d into an element g of the grading group of R proceed as above.

Note

If the component is not finite dimensional, an error message will be thrown.

Examples

julia> R, x, y = polynomial_ring(QQ, "x" => 1:2, "y" => 1:3);
-
-julia> W = [1 1 0 0 0; 0 0 1 1 1]
-2×5 Matrix{Int64}:
- 1  1  0  0  0
- 0  0  1  1  1
-
-julia> S, _ = grade(R, W);
-
-julia> G = grading_group(S)
-GrpAb: Z^2
-
-julia> L = homogeneous_component(S, [1, 1]);
-
-julia> L[1]
-homogeneous component of Graded multivariate polynomial ring in 5 variables over QQ of degree [1 1]
-
-julia> FG = gens(L[1]);
-
-julia> EMB = L[2]
-Map from
-S_[1 1] of dim 6 to S defined by a julia-function with inverse
-
-julia> for i in 1:length(FG) println(EMB(FG[i])) end
-x[2]*y[3]
-x[2]*y[2]
-x[2]*y[1]
-x[1]*y[3]
-x[1]*y[2]
-x[1]*y[1]
source

Elements of Multivariate Rings

Constructors

One way to create elements of a multivariate polynomial ring is to build up polynomials from the generators (variables) of the ring using basic arithmetic as shown below:

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> f = 3*x^2+y*z
-3*x^2 + y*z
-
-julia> typeof(f)
-QQMPolyRingElem
-
-julia> S, (x, y, z) = grade(R)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> g = 3*x^2+y*z
-3*x^2 + y*z
-
-julia> typeof(g)
-MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}
-
-julia> g == S(f)
-true
-

Alternatively, there is the following constructor:

(R::MPolyRing{T})(c::Vector{T}, e::Vector{Vector{Int}}) where T <: RingElem

Its return value is the element of R whose nonzero coefficients are specified by the elements of c, with exponent vectors given by the elements of e.

Examples
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> f = 3*x^2+y*z
-3*x^2 + y*z
-
-julia> g = R(QQ.([3, 1]), [[2, 0, 0], [0, 1, 1]])
-3*x^2 + y*z
-
-julia> f == g
-true
-

An often more effective way to create polynomials is to use the MPoly build context as indicated below:

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> B = MPolyBuildCtx(R)
-Builder for an element of Multivariate polynomial ring in 2 variables over QQ
-
-julia> for i = 1:5 push_term!(B, QQ(i), [i, i-1]) end
-
-julia> finish(B)
-5*x^5*y^4 + 4*x^4*y^3 + 3*x^3*y^2 + 2*x^2*y + x
-

Special Elements

Given a multivariate polynomial ring R, zero(R) and one(R) refer to the additive and multiplicative identity of R, respectively. Relevant test calls on an element f of R are iszero(f) and isone(f).

Data Associated to Elements of Multivariate Rings

Given an element f of a multivariate polynomial ring R or a graded version of such a ring,

  • parent(f) refers to R, and
  • total_degree(f) to the total degree of f.
Note

Given a set of variables $x = \{x_1, \ldots, x_n\}$, the total degree of a monomial $x^\alpha=x_1^{\alpha_1}\cdots x_n^{\alpha_n}\in\text{Mon}_n(x)$ is the sum of the $\alpha_i$. The total degree of a polynomial f is the maximum of the total degrees of its monomials. In particular, the notion of total degree ignores the weights given to the variables in the graded case.

For iterators which allow one to recover the monomials (terms, $\dots$) of f we refer to the subsection Monomials, Terms, and More of the section on Gröbner/Standard Bases.

Examples
julia> R, (x, y) = polynomial_ring(GF(5), ["x", "y"])
-(Multivariate polynomial ring in 2 variables over GF(5), fpMPolyRingElem[x, y])
-
-julia> c = map(GF(5), [1, 2, 3])
-3-element Vector{fpFieldElem}:
- 1
- 2
- 3
-
-julia> e = [[3, 2], [1, 0], [0, 1]]
-3-element Vector{Vector{Int64}}:
- [3, 2]
- [1, 0]
- [0, 1]
-
-julia> f = R(c, e)
-x^3*y^2 + 2*x + 3*y
-
-julia> parent(f)
-Multivariate polynomial ring in 2 variables x, y
-  over finite field of characteristic 5
-
-julia> total_degree(f)
-5

Further functionality is available in the graded case:

homogeneous_componentsMethod
homogeneous_components(f::MPolyDecRingElem{T, S}) where {T, S}

Given an element f of a graded multivariate ring, return the homogeneous components of f.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> f = x^2+y+z
-x^2 + y + z
-
-julia> homogeneous_components(f)
-Dict{GrpAbFinGenElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:
-  [2] => x^2 + y
-  [3] => z
-
-julia> R, x = polynomial_ring(QQ, "x" => 1:5)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])
-
-julia> G = abelian_group([0, 0, 2, 2])
-(General) abelian group with relation matrix
-[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
-
-julia> g = gens(G);
-
-julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
-
-julia> S, x = grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])
-
-julia> f = x[1]^2+x[3]^2+x[5]^2
-x[1]^2 + x[3]^2 + x[5]^2
-
-julia> homogeneous_components(f)
-Dict{GrpAbFinGenElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:
-  [2 2 0 0] => x[5]^2
-  [2 0 0 0] => x[1]^2 + x[3]^2
source
homogeneous_componentMethod
homogeneous_component(f::MPolyDecRingElem, g::GrpAbFinGenElem)

Given an element f of a graded multivariate ring, and given an element g of the grading group of that ring, return the homogeneous component of f of degree g.

homogeneous_component(f::MPolyDecRingElem, g::Vector{<:IntegerUnion})

Given an element f of a $\mathbb Z^m$-graded multivariate ring R, say, and given a vector g of $m$ integers, convert g into an element of the grading group of R, and return the homogeneous component of f whose degree is that element.

homogeneous_component(f::MPolyDecRingElem, g::IntegerUnion)

Given an element f of a $\mathbb Z$-graded multivariate ring R, say, and given an integer g, convert g into an element of the grading group of R, and return the homogeneous component of f whose degree is that element.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:5)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])
-
-julia> G = abelian_group([0, 0, 2, 2])
-(General) abelian group with relation matrix
-[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
-
-julia> g = gens(G);
-
-julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
-
-julia> S, x = grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])
-
-julia> f = x[1]^2+x[3]^2+x[5]^2
-x[1]^2 + x[3]^2 + x[5]^2
-
-julia> homogeneous_component(f, 2*g[1])
-x[1]^2 + x[3]^2
-
-julia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]
-4-element Vector{Vector{Int64}}:
- [1, 0]
- [0, 1]
- [1, 0]
- [4, 1]
-
-julia> R, x = graded_polynomial_ring(QQ, ["x[1]", "x[2]", "x[3]", "x[4]"], W)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4]])
-
-julia> f = x[1]^2*x[2]+x[4]
-x[1]^2*x[2] + x[4]
-
-julia> homogeneous_component(f, [2, 1])
-x[1]^2*x[2]
-
-julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> f = x^2+y+z
-x^2 + y + z
-
-julia> homogeneous_component(f, 1)
-0
-
-julia> homogeneous_component(f, 2)
-x^2 + y
-
-julia> homogeneous_component(f, 3)
-z
source
is_homogeneousMethod
is_homogeneous(f::MPolyDecRingElem)

Given an element f of a graded multivariate ring, return true if f is homogeneous, false otherwise.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> f = x^2+y*z
-x^2 + y*z
-
-julia> is_homogeneous(f)
-false
-
-julia> W = [1 2 1 0; 3 4 0 1]
-2×4 Matrix{Int64}:
- 1  2  1  0
- 3  4  0  1
-
-julia> S, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"], W)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[w, x, y, z])
-
-julia> F = w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3
-w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3
-
-julia> is_homogeneous(F)
-true
source
degreeMethod
degree(f::MPolyDecRingElem)

Given a homogeneous element f of a graded multivariate ring, return the degree of f.

degree(::Type{Vector{Int}}, f::MPolyDecRingElem)

Given a homogeneous element f of a $\mathbb Z^m$-graded multivariate ring, return the degree of f, converted to a vector of integer numbers.

degree(::Type{Int}, f::MPolyDecRingElem)

Given a homogeneous element f of a $\mathbb Z$-graded multivariate ring, return the degree of f, converted to an integer number.

Examples

julia> R, x = polynomial_ring(QQ, "x" => 1:5)
-(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])
-
-julia> G = abelian_group([0, 0, 2, 2])
-(General) abelian group with relation matrix
-[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
-
-julia> g = gens(G);
-
-julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
-
-julia> S, x = grade(R, W)
-(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])
-
-julia> f = x[2]^2+2*x[4]^2
-x[2]^2 + 2*x[4]^2
-
-julia> degree(f)
-Element of G with components [0 2 0 0]
-
-julia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]
-4-element Vector{Vector{Int64}}:
- [1, 0]
- [0, 1]
- [1, 0]
- [4, 1]
-
-julia> R, x = graded_polynomial_ring(QQ, ["x[1]", "x[2]", "x[3]", "x[4]"], W)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4]])
-
-julia> f = x[1]^4*x[2]+x[4]
-x[1]^4*x[2] + x[4]
-
-julia> degree(f)
-[4 1]
-
-julia> degree(Vector{Int}, f)
-2-element Vector{Int64}:
- 4
- 1
-
-julia>  R, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"], [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> f = x^6+y^3+z^2
-x^6 + y^3 + z^2
-
-julia> degree(f)
-[6]
-
-julia> typeof(degree(f))
-GrpAbFinGenElem
-
-julia> degree(Int, f)
-6
-
-julia> typeof(degree(Int, f))
-Int64
source
forget_gradingMethod
forget_grading(f::MPolyDecRingElem)

Return the element in the underlying ungraded ring.

source

Homomorphisms From Multivariate Rings

If $R$ is a multivariate polynomial ring, and $S$ is any ring, then a ring homomorphism $R \to S$ is determined by specifying its restriction to the coefficient ring of $R$, and by assigning an image to each variable of $R$. In OSCAR, such homomorphisms are created by using the following constructor:

homMethod
hom(R::MPolyRing, S::NCRing, coeff_map, images::Vector; check::Bool = true)
-
-hom(R::MPolyRing, S::NCRing, images::Vector; check::Bool = true)

Given a homomorphism coeff_map from C to S, where C is the coefficient ring of R, and given a vector images of nvars(R) elements of S, return the homomorphism R $\to$ S whose restriction to C is coeff_map, and which sends the i-th variable of R to the i-th entry of images.

If no coefficient map is entered, invoke a canonical homomorphism of C to S, if such a homomorphism exists, and throw an error, otherwise.

Note

In case check = true (default), the function checks the conditions below:

  • If S is graded, the assigned images must be homogeneous with respect to the given grading.
  • If S is noncommutative, the assigned images must pairwise commute.

Examples

julia> K, a = FiniteField(2, 2, "a");
-
-julia> R, (x, y) = polynomial_ring(K, ["x", "y"]);
-
-julia> F = hom(R, R, z -> z^2, [y, x])
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 2 variables over GF(2^2)
-Codomain:
-=========
-Multivariate polynomial ring in 2 variables over GF(2^2)
-
-julia> F(a * y)
-(a + 1)*x
-
-julia> Qi, i = quadratic_field(-1)
-(Imaginary quadratic field defined by x^2 + 1, sqrt(-1))
-
-julia> S, (x, y) = polynomial_ring(Qi, ["x", "y"]);
-
-julia> G = hom(S, S, hom(Qi, Qi, -i), [x^2, y^2])
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 2 variables over imaginary quadratic field defined by x^2 + 1
-Codomain:
-=========
-Multivariate polynomial ring in 2 variables over imaginary quadratic field defined by x^2 + 1
-
-julia> G(x+i*y)
-x^2 - sqrt(-1)*y^2
-
-julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]);
-
-julia> f = 3*x^2+2*x+1;
-
-julia> S, (x, y) = polynomial_ring(GF(2), ["x", "y"]);
-
-julia> H = hom(R, S, gens(S))
-Map with following data
-Domain:
-=======
-Multivariate polynomial ring in 2 variables over ZZ
-Codomain:
-=========
-Multivariate polynomial ring in 2 variables over GF(2)
-
-julia> H(f)
-x^2 + 1
source

Given a ring homomorphism F from R to S as above, domain(F) and codomain(F) refer to R and S, respectively.

Note

The OSCAR homomorphism type AffAlgHom models ring homomorphisms R $\to$ S such that the type of both R and S is a subtype of Union{MPolyRing{T}, MPolyQuoRing{U}}, where T <: FieldElem and U <: MPolyRingElem{T}. Functionality for these homomorphism is discussed in the section on affine algebras.

diff --git a/previews/PR2578/DeveloperDocumentation/AbstractCollection/index.html b/previews/PR2578/DeveloperDocumentation/AbstractCollection/index.html deleted file mode 100644 index bbeb84250c11..000000000000 --- a/previews/PR2578/DeveloperDocumentation/AbstractCollection/index.html +++ /dev/null @@ -1,9 +0,0 @@ - -AbstractCollection · Oscar.jl

AbstractCollection

Allowing the user to pass input using several formats usually is handled within julia by defining specialized methods for each function and argument type(s). This can prove to be inefficient when the amount possible combinations of these increases. AbstractCollection is a Dict meant to enable the user to profit from a fixed interpretation describing different collections of mathematical objects, while also simplifying the life of the developer, also resulting in less code duplication.

Idea

Commonly the same kind of information, e.g. an amount of PointVectors, is accepted as argument for many different functions. The user can chose from different types (coming with an interpretation of their content) to use when calling one of these functions to describe the data. This data is then converted to a type and format Polymake.jl (and thus indirectly the polymake kernel) supports.

Example

Usually in polymake, a collection of points is displayed as a matrix of row-vectors. Such a matrix is always created from the input information. When writing a new function accepting an object x of type AbstractCollection[PointVector] (note that, with AbstractCollection being a Dict, its entries are accessed using square brackets; the keys are the Oscar types of the elements of the collection), the necessary conversion can (and should) be called at the beginning. These conversion functions already exist and support all of the types stated in Type compatibility. In this case the function is homogenized_matrix(x, 1).

RayVectors and their collections work about the same; the main difference for the programmer is that homogenized_matrix(x, 0) is called.

When looking at the beginning of the convex_hull method, the corresponding conversions of the three arguments V, R and L can be seen:

function convex_hull(::Type{T}, V::AbstractCollection[PointVector], R::Union{AbstractCollection[RayVector], Nothing} = nothing, L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) where T<:scalar_types
-    # Rays and Points are homogenized and combined and
-    # Lineality is homogenized
-    points = stack(homogenized_matrix(V, 1), homogenized_matrix(R, 0))
-    lineality = isnothing(L) || isempty(L) ? zero_matrix(QQ, 0, size(points,2)) : homogenized_matrix(L, 0)
-
-    ...
-end

Conversion functions

So effectively supporting AbstractCollections only requires to know when to apply which conversion function. The following table explains this for AbstractCollection[T]:

TTarget formatConversion function
PointVectormatrix of row-vectorshomogenized_matrix(*, 1)
RayVectormatrix of row-vectors (linear setting)unhomogenized_matrix(*)
RayVectormatrix of row-vectors (affine setting)homogenized_matrix(*, 0)
LinearHalfspace/LinearHyperplaneinequality/equation matrix (linear setting)linear_matrix_for_polymake(*)
AffineHalfspace/AffineHyperplaneinequality/equation matrix (affine setting)affine_matrix_for_polymake(*)
diff --git a/previews/PR2578/DeveloperDocumentation/SubObjectIterator/index.html b/previews/PR2578/DeveloperDocumentation/SubObjectIterator/index.html deleted file mode 100644 index 10f310355860..000000000000 --- a/previews/PR2578/DeveloperDocumentation/SubObjectIterator/index.html +++ /dev/null @@ -1,49 +0,0 @@ - -SubObjectIterator · Oscar.jl

SubObjectIterator

Many of the objects in the field of Polyhedral Geometry mask a BigObject from Polymake.jl. These big objects have properties which can easily be accessed via julia's dot syntax. The return commonly does not adhere to the mathematical or the typing conventions of Oscar; many properties encode information about a collection of mathematical objects within a single data object.

The SubObjectIterator is a precise and flexible tool to directly access and/or process the desired properties of any Polymake.BigObject, but it requires specific interface definitions to work properly for each context. The user can thus profit from an easily understandable and usable iterator.

This guide is meant to communicate the application of the SubObjectIterator for developers, utilizing existing code as reference and examples.

Creating a working SubObjectIterator

The formal definition of the SubObjectIterator in src/PolyhedralGeometry/iterators is:

struct SubObjectIterator{T} <: AbstractVector{T}
-    Obj::Polymake.BigObject
-    Acc::Function
-    n::Int
-    options::NamedTuple
-end

An instance can be created by passing values for all fields, while options is optional.

Trivially, Obj is the Polymake.BigObject whose property is to be accessed. The other fields will each be explained in an upcoming section.

Length

As an AbstractVector, the SubObjectIterator has a length. Due to the nature of Polymake.BigObjects this length is constant for any property. Sometimes the length can easily be derived as a by-product of pre-computations when creating an instance of SubObjectIterator. To avoid performing unnecessary computations afterwards, the value is set at construction in n.

Access function

Optimally retrieving and converting the elements varies strongly between the contexts in which a SubObjectIterator is created. Thus its getindex method redirects the call to the (internal) function Acc:

function Base.getindex(iter::SubObjectIterator{T}, i::Base.Integer) where T
-    @boundscheck 1 <= i && i <= iter.n
-    return iter.Acc(T, iter.Obj, i; iter.options...)
-end

From this call we can see that the access function's signature needs to satisfy certain requirements for the SubObjectIterator to work. The arguments are:

  1. T: The return type.
  2. iter.Obj: The Polymake.BigObject whose property is to be accessed.
  3. i: The index.
  4. iter.options: Additional arguments. Will be explained later.

Let us look at an example how we can utilize this interface. The following is the implementation to access the rays of a Cone:

rays(as::Type{RayVector{T}}, C::Cone) where T = SubObjectIterator{as}(pm_object(C), _ray_cone, nrays(C))
-
-_ray_cone(::Type{T}, C::Polymake.BigObject, i::Base.Integer) where T = T(C.RAYS[i, :])

Typing r = rays(RayVector{Polymake.Rational}, C) with a Cone C returns a SubObjectIterator over RayVector{Polymake.Rational} elements of length nrays(C) with access function _ray_cone. With the given method of this function, getindex(r, i) returns a RayVector{Polymake.Rational} constructed from the i-th row of the property RAYS of the Polymake.BigObject.

The user does never directly create a SubObjectIterator, so type restrictions made where it is created can be assumed to hold. In our example _ray_cone will always be called with T<:RayVector.

One can define several methods of the access function to ideally read and process data. Consider facets(as::Type{T}, C::Cone). Depending on the return type we offer three methods:

_facet_cone(::Type{T}, C::Polymake.BigObject, i::Base.Integer) where T<:Union{Polyhedron, AffineHalfspace} = T(-C.FACETS[[i], :], 0)
-
-_facet_cone(::Type{LinearHalfspace}, C::Polymake.BigObject, i::Base.Integer) = LinearHalfspace(-C.FACETS[[i], :])
-
-_facet_cone(::Type{Cone}, C::Polymake.BigObject, i::Base.Integer) = cone_from_inequalities(-C.FACETS[[i], :])

Additional Methods

The SubObjectIterator can moreover be understood as a mathematical collection the sense that one can

  1. ask for specific information encoded in the data or
  2. use this collection as an argument for construction another mathematical object.

The first case is covered by adding methods to specific internal functions. Remember implementation of rays discussed above. It makes sense to define a vector_matrix method on its output, encoding the rays of the cone as a single matrix based on a convention applied throughout Oscar. The function's implementation a user calls in this case is evaluated to these lines:

vector_matrix(iter::SubObjectIterator{<:AbstractVector{Polymake.Rational}}) = matrix(QQ, Matrix{QQFieldElem}(_vector_matrix(Val(iter.Acc), iter.Obj; iter.options...)))
-vector_matrix(iter::SubObjectIterator{<:AbstractVector{Polymake.Integer}}) = matrix(ZZ, _vector_matrix(Val(iter.Acc), iter.Obj; iter.options...))
-_vector_matrix(::Any, ::Polymake.BigObject) = throw(ArgumentError("Vector Matrix not defined in this context."))

Two functionalities are defined this way:

  1. The call of vector_matrix(iter) is redirected to _vector_matrix(Val(iter.Acc), iter.Obj). If that method is not defined for the value type of the access function, it falls back to throwing an error.
  2. The matrix received from step 1 is converted from Polymake.jl format to Oscar format.

So by defining the following we have a fully functional vector_matrix method in the context of rays:

_vector_matrix(::Val{_ray_cone}, C::Polymake.BigObject) = C.RAYS

The second case is solved with defining a special _matrix_for_polymake method. One just hast to name the internal function that returns the desired matrix. This way one has the ability to precisely control how the iterator works internally in specific contexts, even if there happen to be multiple additional matrix functions.

Again, the call matrix_for_polymake(iter) will either redirect to the defined method or fall back to throwing an error if there is none:

function matrix_for_polymake(iter::SubObjectIterator)
-    if hasmethod(_matrix_for_polymake, Tuple{Val{iter.Acc}})
-        return _matrix_for_polymake(Val(iter.Acc))(Val(iter.Acc), iter.Obj; iter.options...)
-    else
-        throw(ArgumentError("Matrix for Polymake not defined in this context."))
-    end
-end

For rays(C::Cone) this reduces the implementation to the following line:

_matrix_for_polymake(::Val{_ray_cone}) = _vector_matrix

With matrix_for_polymake the output of rays can be handled as a usual matrix and constructors or other functions can easily be extended by additionally allowing SubObjectIterator as an argument type. E.g. the signature of one of the Cone constructors now looks like this while the body has not changed:

Cone(R::Union{SubObjectIterator{<:RayVector}, Oscar.MatElem, AbstractMatrix}, L::Union{SubObjectIterator{<:RayVector}, Oscar.MatElem, AbstractMatrix, Nothing} = nothing; non_redundant::Bool = false)

There also are linear_matrix_for_polymake and affine_matrix_for_polymake used in the context of linear and affine halfspaces/hyperplanes. Defining this functionality in a context works the same way as for matrix_for_polymake; you can create a new method of _linear_matrix_for_polymake or _affine_matrix_for_polymake. It suffices to define the most relevant of these two; the other one will be derived, if possible. Also, halfspace_matrix_pair is defined in terms of affine_matrix_for_polymake, so this does not need another implementation.

The example code for rays(C::Cone) has covered every line of the implementation by now, but we had different code in between, so let us summarize and take a look at what the whole implementation actually looks like:

rays(as::Type{RayVector{T}}, C::Cone) where T = SubObjectIterator{as}(pm_object(C), _ray_cone, nrays(C))
-
-_ray_cone(::Type{T}, C::Polymake.BigObject, i::Base.Integer) where T = T(C.RAYS[i, :])
-
-_vector_matrix(::Val{_ray_cone}, C::Polymake.BigObject) = C.RAYS
-
-_matrix_for_polymake(::Val{_ray_cone}) = _vector_matrix

options

Sometimes you need further arguments to specify the returned data. These arguments are set at construction of the SubObjectIterator and later passed to the corresponding functions as keyword arguments.

A good example how to use this is faces(C::Cone, face_dim::Int). It is not enough to know that our SubObjectIterator is set in the context of faces of cones; face_dim will be relevant for any type of access occurring in the future.

function faces(C::Cone, face_dim::Int)
-   n = face_dim - length(lineality_space(C))
-   n < 1 && return nothing
-   return SubObjectIterator{Cone}(C.pm_cone, _face_cone, size(Polymake.polytope.faces_of_dim(pm_object(C), n), 1), (f_dim = n,))
-end

When this method is called with meaningful input, it creates a SubObjectIterator where the last argument is a NamedTuple specifying that f_dim = n. The information encoded in this NamedTuple will be passed as keyword arguments when calling the access function or any additional method (reconsider their definitions). This allows us to directly ask for that data when implementing these methods:

function _face_cone(::Type{Cone}, C::Polymake.BigObject, i::Base.Integer; f_dim::Int = 0)
-   return Cone(Polymake.polytope.Cone(RAYS = C.RAYS[collect(Polymake.to_one_based_indexing(Polymake.polytope.faces_of_dim(C, f_dim)[i])), :], LINEALITY_SPACE = C.LINEALITY_SPACE))
-end
-
-function _ray_indices(::Val{_face_cone}, C::Polymake.BigObject; f_dim::Int = 0)
-   f = Polymake.to_one_based_indexing(Polymake.polytope.faces_of_dim(C, f_dim))
-   return IncidenceMatrix([collect(f[i]) for i in 1:length(f)])
-end

Extending the interface

The additional methods offer an intuitive way of interaction for the user, but their current selection is not carved in stone. You can easily add more similar methods by extending the list that is iterated over to generate the code. Which list that is usually depends on the output format. vector_matrix returns matrices with either integer or rational elements. The same capabilities hold for point_matrix and generator_matrix:

for (sym, name) in (("point_matrix", "Point Matrix"), ("vector_matrix", "Vector Matrix"), ("generator_matrix", "Generator Matrix"))
-    M = Symbol(sym)
-    _M = Symbol(string("_", sym))
-    @eval begin
-        $M(iter::SubObjectIterator{<:AbstractVector{Polymake.Rational}}) = matrix(QQ, Matrix{QQFieldElem}($_M(Val(iter.Acc), iter.Obj; iter.options...)))
-        $M(iter::SubObjectIterator{<:AbstractVector{Polymake.Integer}}) = matrix(ZZ, $_M(Val(iter.Acc), iter.Obj; iter.options...))
-        $_M(::Any, ::Polymake.BigObject) = throw(ArgumentError(string($name, " not defined in this context.")))
-    end
-end

The second string (name) of each pair determines the name that is printed in error messages.

If required, one can of course write completely new functions to extend the interface.

diff --git a/previews/PR2578/DeveloperDocumentation/debugging/index.html b/previews/PR2578/DeveloperDocumentation/debugging/index.html deleted file mode 100644 index 41aa06d3fd6e..000000000000 --- a/previews/PR2578/DeveloperDocumentation/debugging/index.html +++ /dev/null @@ -1,60 +0,0 @@ - -Debugging OSCAR Code · Oscar.jl

Debugging OSCAR Code

Pitfalls: Mutable objects in OSCAR code

Suppose you are having the following difficulties. Your code is exhibiting inexplicable behaviour and values that should not be changing are changing in seemingly random locations. To get to the bottom of these kind of issues it is necessary to be familiar with mutable objects in Julia and some of the relevant conventions in place in OSCAR. This section discusses these informal rules as well as some of the exceptions to these rules.

In Julia, objects that can change after construction are declared with the mutable struct keywords and satisfy the ismutable predicate. These objects can be linked together into an arbitrary dependency graph, and a change to one object may therefore have unintended consequences on another object in the system.

The simplest example is the creation of a polynomial ring. If we mutate the array of symbols used for printing, we have effectively changed the ring.

julia> v = [:x, :y, :z]; R = polynomial_ring(QQ, v)[1]
-Multivariate Polynomial Ring in x, y, z over Rational Field
-
-julia> v[3] = :w; R
-Multivariate Polynomial Ring in x, y, w over Rational Field

In this example, the modification of v is unexpected and may in fact corrupt the internal data structures used by the polynomial ring. As such, this modification of v has to be considered illegal. Upon creation of the array called v, we have full rights over the object and can mutate at will. However, after passing it to the function polynomial_ring, we have given up ownership of the array and are no longer free to modify it.

General OSCAR Principle (GOP):

Code should be expected to behave as if all objects are immutable.

Ramifications:

  1. This means that the polynomial ring constructor is allowed to expect that v is never mutated for the remaining duration of its life. In return, the constructor is guaranteed not to modify the array, so that v is still [:x, :y, :z] after polynomial_ring returns.
  2. In general this means that all functions should be expected to take ownership of their arguments: the user is safest never modifying an existing object that has been passed to an unknown Julia function. Note that assignments such as a[i] = b or a.foo = b usually mutate the object a. See Ownership of function arguments
  3. For reasons of efficiency, it is sometimes desirable to defy this principle and modify an existing object. The fact that a given function may modify a preexisting object is usually communicated via coding conventions on the name - either a ! or a _unsafe in the name of the function. See Unsafe arithmetic with OSCAR objects

Ownership of function arguments

In this example we construct the factored element x = 2^3 and then change the 2 to a 1. The GOP says this modification of a on line 3 is illegal.

julia> a = ZZRingElem(2)
-2
-
-julia> x = FacElem([a], [ZZRingElem(3)]); evaluate(x)
-8
-
-julia> a = one!(a)  # illegal in-place assignment of a to 1
-1
-
-julia> evaluate(x)  # x has been changed and possibly corrupted
-1

In the previous example, the link between the object x and the object a can be broken by passing a deepcopy of a to the FacElem function.

julia> a = ZZRingElem(2)
-2
-
-julia> x = FacElem([deepcopy(a)], [ZZRingElem(3)]); evaluate(x)
-8
-
-julia> a = one!(a)  # we still own a, so modification is legal
-1
-
-julia> evaluate(x)  # x is now unchanged
-8

It is of course not true that all Julia functions take ownership of their arguments, but the GOP derives from the fact that this decision is an implementation detail with performance consequences. The behaviour of a function may be inconsistent across different types and versions of OSCAR. In the following two snippets, the GOP says both modifications of a are illegal since they have since been passed to a function. If K = QQ, the two mutations turn out to be legal currently, while they are illegal if K = quadratic_field(-1)[1]. Only with special knowledge of the types can the GOP be safely ignored.

R = polynomial_ring(K, [:x, :y])[1]
-a = one(K)
-p = R([a], [[0,0]])
-@show p
-a = add!(a, a, a)       # legal? (does a += a in-place)
-@show p
R = polynomial_ring(K, :x)[1]
-a = [one(K), one(K)]
-p = R(a)
-@show (p, degree(p))
-a[2] = zero(K)          # legal?
-@show (p, degree(p))

Ownership of function return values

The nuances of who is allowed to modify an object returned by a function is best left to the next section Unsafe arithmetic with OSCAR objects. The GOP says of course you should not do it, but there are cases where it can be more efficient. However, there is another completely different issue of return values that can arise in certain interfaces.

First, we create the Gaussian rationals and the two primes above 5.

julia> K, i = quadratic_field(-1)
-(Imaginary quadratic field defined by x^2 + 1, sqrt(-1))
-
-julia> m = Hecke.modular_init(K, 5)
-modular environment for p=5, using 2 ideals

The function modular_project returns the projection of an element of K into each of the residue fields.

julia> a = Hecke.modular_proj(1+2*i, m)
-2-element Vector{fqPolyRepFieldElem}:
- 2
- 0

While the function has produced the correct answer, if we run it again on a different input, we will find that a has changed.

julia> b = Hecke.modular_proj(2+3*i, m)
-2-element Vector{fqPolyRepFieldElem}:
- 1
- 3
-
-julia> a
-2-element Vector{fqPolyRepFieldElem}:
- 1
- 3

The preceding behaviour of the function modular_proj is an artifact of internal efficiency and may be desirable in certain circumstances. In other circumstances, the following deepcopys may be necessary for your code to function correctly.

julia> a = deepcopy(Hecke.modular_proj(1+2*i, m));
-julia> b = deepcopy(Hecke.modular_proj(2+3*i, m));
-julia> (a, b)
-(fqPolyRepFieldElem[2, 0], fqPolyRepFieldElem[1, 3])

Unsafe arithmetic with OSCAR objects

Particularly with integers (BigInt and ZZRingElem) - but also to a lesser extent with polynomials - the cost of basic arithmetic operations can easily be dominated by the cost of allocating space for the answer. For this reason, OSCAR offers an interface for in-place arithmetic operations.

Instead of writing x = a + b to compute a sum, one writes x = add!(x, a, b) with the idea that the object to which x is pointing is modified instead of having x point to a newly allocated object. In order for this to work, x must point to a fully independent object, that is, an object whose modification through the interface Unsafe operators will not change the values of other existing objects. The actual definition of "fully independent" is left to the implementation of the ring element type. For example, there is no distinction for immutables.

It is generally not safe to mutate the return of a function. However, the basic arithmetic operations +, -, *, and ^ are guaranteed to return a fully independent object regardless of the status of their inputs. As such, the following implementation of ^ is illegal by this guarantee.

function ^(a::RingElem, n::Int)
-  if n == 1
-    return a    # must be return deepcopy(a)
-  else
-    ...
-  end
-end

In general, if you are not sure if your object is fully independent, a deepcopy should always do the job.

diff --git a/previews/PR2578/DeveloperDocumentation/design_decisions/index.html b/previews/PR2578/DeveloperDocumentation/design_decisions/index.html deleted file mode 100644 index 4e3319839169..000000000000 --- a/previews/PR2578/DeveloperDocumentation/design_decisions/index.html +++ /dev/null @@ -1,5 +0,0 @@ - -Design Decisions · Oscar.jl

Design Decisions

This document covers the ideas and design decisions behind OSCAR, as well as some pitfalls to avoid.

OSCAR - what is the idea

OSCAR is the innovative, next generation Computer Algebra System. The ultimate goal for OSCAR is to compete with (and ideally beat) Magma and Sage in our areas of expertise. OSCAR should be accessible, even for the youngest student who is familiar with these objects. OSCAR should follow general mathematical conventions to support the widest possible range of applications.

The key idea for development of OSCAR is to pick a single textbook for every area and follow the conventions in there. This way we get a consistent interface.

OSCAR and Julia

OSCAR is written in Julia, but is not Julia, nor can it be. Some examples to illustrate what that means: Julia's matrices are arrays (of arbitrary dimension), parameterized by the type of the entries (apart from banded, sparse, ... special matrices). In the numerical world, the type mostly defines the representation of an object

  • double and variations
  • complex
  • BigFloat
  • Int
  • BigInt

In algebra, this is either not true or terribly inefficient (or impossible) Take $\mathbb{Z}/n\mathbb{Z}$ integers modulo $n$, and matrices over it

Then either:

  • $n$ is part of the type -> every function is recompiled for every $n$ - which kills all modular (Chinese remainder theorem (CRT) based) algorithms
  • $n$ is not part of the type, then it needs to be elsewhere, e.g. in the parent, or in every element, or by passing additional arguments, or ...

Furthermore, if $n$ is BigInt (ZZRingElem), so no bittype, then it cannot be part of the type.

For non-empty matrices, this can be compensated if the entries store enough information, but for empty matrices this information needs to be collected elsewhere.

To summarize, normal Julia infrastructure does not suffice for our purposes in many places. Hence we provide our own, which any code contributions should use. If functions are missing in it, then please

  • add them
  • or tell us

Mathematical Context in OSCAR

When studying mathematics, the exact meaning of a term or object is determined by context. In OSCAR, this does not work. The meaning has to be part of either

  • the object
  • or the question posed about the object

As an example: in classical number theory there is the convention that many definitions that are trivial for fields are silently applied to the ring of integers. One speaks of the unit group of the number field, meaning the unit group of the ring of integers. Let alpha be an element explicitly constructed as an element of the number field, not of the ring of integers, then

  • is_unit will just test if it is non-zero (unit in a field as a special type of ring)
  • is_unit_in_ring_of_integers would supply the context for the other interpretation.

In OSCAR, this context is mostly supplied by the type of the object and possibly the parent, e.g. the containing ring/ field/ group.

What Do We Have:

We have a large codebase for infrastructure in place, comprising at least

  • matrices
  • polynomials (univariate and multivariate)
  • power series
  • number fields
  • (abelian) groups
  • polytopes, cones, linear programs
  • polyhedral fans
  • ... and MUCH more

For specialized functionality we can access the entirety of the following software frameworks on a lower level:

  • polymake
  • Singular
  • Gap

So: Please use it. It is safe to assume all can be improved, however, if we try to perfect every single line of code again and again, we we won't get anywhere; there is a balance to be found. For preference:

Correctness > Interoperability, Readability
-Interoperability > Speed
-Readability > Speed

Having said that: of course, sometimes pure speed matters, but not nearly as often as people think.

What Is Missing?

The infrastructure is incomplete, e.g. we do not have

  • combinatorial manifolds
  • surfaces
  • tropical polytopes
  • ....

Since we are a relatively small team and OSCAR is still very new, the usual

I work for 6 month in a separate repo on a branch and then will dazzle you
-with perfect code and cool examples

approach is not going to work for now. It will result in everyone fixing the same infrastructure problems over and over again. Please consider to work, e.g. in a file/directory in Oscar/examples and push on a regular basis, even, or in particular, incomplete code. Break it down into small pull requests. Please also see the Introduction for new developers.

Practical Development

Creating New Basic Types

If you encounter the need for a new basic type, say a new multivariate ring, please consider the ramifications:

  • can you do matrices?
  • modules?
  • ideals?
  • graded stuff?
  • "complete" arithmetic?
  • interaction with other types? (map to residue rings, apply automorphisms, ...)
  • in fact, everything the other MPoly type can?

If no: at least use "our" types to interface your function, better still, use our type and complain about lack of functionality/ speed/ interface (or provide patches).

This applies to all foundations! They are all incomplete, and they can all be improved BUT if everyone does their own foundations, we cannot work together.

Expert definitions

As a reminder, please stick to "global definitions" and not "experts" versions of definitions. Reasoning such as: "but all experts know and expect this - it is always done this way" will make your function impossible to be used by outsiders. Feel free to add the other "expert" definition layer if you need.

diff --git a/previews/PR2578/DeveloperDocumentation/documentation/index.html b/previews/PR2578/DeveloperDocumentation/documentation/index.html deleted file mode 100644 index f7cb24bba2e9..000000000000 --- a/previews/PR2578/DeveloperDocumentation/documentation/index.html +++ /dev/null @@ -1,25 +0,0 @@ - -Documenting OSCAR code · Oscar.jl

Documenting OSCAR code

The general philosophy of the OSCAR documentation is to put as much of the information as possible into the docstrings and only use the doc pages for collecting this information and provide some additional general context. Exceptions to this philosophy are the developer and general pages.

Docstrings of exported functions

Exported function should have docstrings, which look like

@doc raw"""
-    functionname(x::ArgumentType, b::OtherArgument; c::Keyword = default) -> Int, Int
-
-A short description of the function. It is allowed to use $\LaTeX$.
-"""
-functionname(x...,b...; c = ...)

If the signature is too long, use linebreaks to fit 80 characters.

Please also do provide an example within the docstring if possible, preferably as a jldoctest, i.e.

@doc raw"""
-    functionname(x::ArgumentType, b::OtherArgument; c::Keyword = default) -> Int, Int
-
-A short description of the function. It is allowed to use $\LaTeX$.
-
-# Examples
-This shows that `functionname` does the right thing for input `input`
-```jldoctest
-julia> input = ...
-
-julia> functionname(input)
-output
-```
-"""
-functionname(x...,b...; c = ...)

This allows the user to immediately see how the function can be used, gives them some code that they can copy-paste and manipulate, and, as a bonus, provides a testcase as well.

The folder docs

The folder docs/src contains the OSCAR documentation website. Most of the pages are relatively sparse and consist of

```@docs
-some_function
-some_other_function
-[...]
-```

blocks that simply pull in the docstring from the corresponding source file. If you add a new page in docs/src, you will have to modify docs/doc.main to include your new page in the appropriate place.

Building the OSCAR documentation with Oscar.build_doc

Previewing the documentation

Once you have created a pull request it is possible to preview the documentation on github using the link https://docs.oscar-system.org/previews/PR<prnumber>/ where you insert the number of your PR for prnumber. Alternatively you can look at the github actions tab of your PR and click the details link next to the documenter/deploy action. There are a few conditions for this to work:

  • No conflicts with the master branch.
  • Documentation action is successful, i.e. no doctest errors.
  • The branch for the PR is in the main oscar-system/Oscar.jl repository.

You can still build the documentation locally with the commands described below.

build_docFunction
build_doc(; doctest=false, strict=false, open_browser=true)

Build the manual of Oscar.jl locally and open the front page in a browser.

The optional parameter doctest can take three values:

  • false: Do not run the doctests (default).
  • true: Run the doctests and report errors.
  • :fix: Run the doctests and replace the output in the manual with the output produced by Oscar. Please use this option carefully.

In GitHub Actions the Julia version used for building the manual is 1.9 and doctests are run with >= 1.7. Using a different Julia version may produce errors in some parts of Oscar, so please be careful, especially when setting doctest=:fix.

The optional parameter strict is passed on to makedocs of Documenter.jl and if set to true then according to the manual of Documenter.jl "a doctesting error will always make makedocs throw an error in this mode".

To prevent the opening of the browser at the end, set the optional parameter open_browser to false.

When working on the manual the Revise package can significantly sped up running build_doc. First, install Revise in the following way:

using Pkg ; Pkg.add("Revise")

Second, restart Julia and load Revise before Oscar:

using Revise, Oscar;

The first run of build_doc will take the usual few minutes, subsequently runs will be significantly faster.

source

Please also read the section below on repairing the jldoctests using build_doc.

Automatically repairing jldoctests

It is possible to have julia fix the output of all jldoctests when your changes to the code entail changes to the output. Just run the following command:

build_doc(doctest = :fix)
Danger

Please use this command carefully:

  • Make sure to only commit the changes to the doctests originating from your changes to the code.
  • The doctests also serve as actual tests, so make absolutely sure that the output is still mathematically correct.
Tip

If this command fails with an error message indicating lacking permissions to change AbstractAlgebra.jl related docs, it may help to run the following command:

]dev AbstractAlgebra

Updating the bibliography

When editing docs/oscar_references.bib please follow the style of the existing entries. An easy way to do that is to add your new BibTeX entry, then run bibtool by invoking it as follows from the root directory of the Oscar.jl repository:

bibtool docs/oscar_references.bib -o docs/oscar_references.bib

For every pull request on github, the CI checks if running bibtool leads to changes in the bibliography. If so, this test fails and indicates that the (recently) added bibliography entries are not standardized. For a merge, it is not required that this test is passed. Still, please feel encouraged to fix this failure by running bibtool locally as explained above.

diff --git a/previews/PR2578/DeveloperDocumentation/gap_integration/index.html b/previews/PR2578/DeveloperDocumentation/gap_integration/index.html deleted file mode 100644 index b739451029e3..000000000000 --- a/previews/PR2578/DeveloperDocumentation/gap_integration/index.html +++ /dev/null @@ -1,56 +0,0 @@ - -GAP Integration · Oscar.jl

GAP Integration

This section explains how Oscar interacts with GAP.

The Julia package GAP.jl

This package provides a bidirectional interface between GAP and Julia. Its documentation describes how to call GAP functions in Julia code and vice versa, and how low level Julia objects can be converted to GAP objects and vice versa.

When one works interactively in an Oscar session, calling GAP.prompt() opens a GAP session which has access to the variables in the Julia session, in particular to all Oscar functions and objects; one can return to the Julia prompt by entering quit; in the GAP session.

Interface functionalities beyond GAP.jl

For code involving Julia types that are defined in Oscar, GAP.jl cannot provide utility functions such as conversions to and from GAP.

  • The GAP package OscarInterface (at gap/OscarInterface) is intended to contain the GAP code in question, for example the declarations of new filters and the installation of new methods.

    Note that such code must be loaded at runtime into the GAP session that is started by Julia, and the OscarInterface package gets loaded in Oscar's __init__ function.

  • The files in the directory src/GAP are intended to contain the Julia code in question, for example conversions from GAP to ZZRingElem, QQFieldElem, FinFieldElem, etc., and the construction of isomorphisms between algebraic structures such as rings and fields in GAP and Oscar, via Oscar.iso_oscar_gap and Oscar.iso_gap_oscar.

  • In Oscar code, global GAP variables can be accessed as members of GAP.Globals, but for the case of GAP functions, it is more efficient to use Oscar.GAPWrap instead.

    For example, if one wants to call GAP's IsFinite then it is recommended to replace the call GAP.Globals.IsFinite(x)::Bool, for some GAP object x (a group or a ring or a list, etc.), by Oscar.GAPWrap.IsFinite(x). This works only if the method in question gets defined in src/GAP/wrappers.jl, thus methods with the required signatures should be added to this file when they turn out to be needed.

    (The reason why we collect the GAP.@wrap lines in an Oscar file and not inside GAP.jl is that we can extend the list without waiting for releases of GAP.jl.)

  • In GAP code, global Julia variables can be accessed as members of Julia, relative to its Main module. For example, one can call Julia.sqrt and Julia.typeof (or Julia.Base.sqrt and Julia.Core.typeof) in GAP code.

    In order to access variables from the Oscar module, it is not safe to use Julia.Oscar because the module Oscar is not always defined in Main. Instead, there is the global GAP variable Oscar.

iso_oscar_gapFunction
Oscar.iso_oscar_gap(R) -> Map{T, GAP.GapObj}

Return an isomorphism f with domain R and codomain a GAP object S.

Elements x of R are mapped to S via f(x), and elements y of S are mapped to R via preimage(f, y).

Matrices m over R are mapped to matrices over S via map_entries(f, m), and matrices n over S are mapped to matrices over R via Oscar.preimage_matrix(f, n).

Admissible values of R and the corresponding S are currently as follows.

RS (in GAP.Globals)
ZZIntegers
QQRationals
residue_ring(ZZ, n)mod(Integers, n)
FiniteField(p, d)[1]GF(p, d)
cyclotomic_field(n)[1]CF(n)
number_field(f::QQPolyRingElem)[1]AlgebraicExtension(Rationals, g)
abelian_closure(QQ)[1]Cyclotomics
polynomial_ring(F)[1]PolynomialRing(G)
polynomial_ring(F, n)[1]PolynomialRing(G, n)

(Here g is the polynomial over GAP.Globals.Rationals that corresponds to f, and G is equal to Oscar.iso_oscar_gap(F).)

Examples

julia> f = Oscar.iso_oscar_gap(ZZ);
-
-julia> x = ZZ(2)^100;  y = f(x)
-GAP: 1267650600228229401496703205376
-
-julia> preimage(f, y) == x
-true
-
-julia> m = matrix(ZZ, 2, 3, [1, 2, 3, 4, 5, 6]);
-
-julia> n = map_entries(f, m)
-GAP: [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
-
-julia> Oscar.preimage_matrix(f, n) == m
-true
-
-julia> R, x = polynomial_ring(QQ);
-
-julia> f = Oscar.iso_oscar_gap(R);
-
-julia> pol = x^2 + x - 1;
-
-julia> y = f(pol)
-GAP: x_1^2+x_1-1
-
-julia> preimage(f, y) == pol
-true
Warning

The functions Oscar.iso_oscar_gap and Oscar.iso_gap_oscar are not injective. Due to caching, it may happen that S stores an attribute value of Oscar.iso_gap_oscar(S), but that the codomain of this map is not identical with or even not equal to the given R.

source
iso_gap_oscarFunction
Oscar.iso_gap_oscar(R) -> Map{GAP.GapObj, T}

Return an isomorphism f with domain the GAP object R and codomain an Oscar object S.

Elements x of R are mapped to S via f(x), and elements y of S are mapped to R via preimage(f, y).

Matrices m over R are mapped to matrices over S via map_entries(f, m), and matrices n over S are mapped to matrices over R via Oscar.preimage_matrix(f, n).

Admissible values of R and the corresponding S are currently as follows.

S (in GAP.Globals)R
IntegersZZ
RationalsQQ
mod(Integers, n)residue_ring(ZZ, n)
GF(p, d)FiniteField(p, d)[1]
CF(n)cyclotomic_field(n)[1]
AlgebraicExtension(Rationals, f)number_field(g)[1]
Cyclotomicsabelian_closure(QQ)[1]
PolynomialRing(F)polynomial_ring(G)[1]
PolynomialRing(F, n)polynomial_ring(G, n)[1]

(Here g is the polynomial over QQ that corresponds to the polynomial f, and G is equal to Oscar.iso_gap_oscar(F).)

Examples

julia> f = Oscar.iso_gap_oscar(GAP.Globals.Integers);
-
-julia> x = ZZ(2)^100;  y = preimage(f, x)
-GAP: 1267650600228229401496703205376
-
-julia> f(y) == x
-true
-
-julia> m = matrix(ZZ, 2, 3, [1, 2, 3, 4, 5, 6]);
-
-julia> n = Oscar.preimage_matrix(f, m)
-GAP: [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
-
-julia> map_entries(f, n) == m
-true
-
-julia> R = GAP.Globals.PolynomialRing(GAP.Globals.Rationals);
-
-julia> f = Oscar.iso_gap_oscar(R);
-
-julia> x = gen(codomain(f));
-
-julia> pol = x^2 + x + 1;
-
-julia> y = preimage(f, pol)
-GAP: x_1^2+x_1+1
-
-julia> f(y) == pol
-true
Warning

The functions Oscar.iso_gap_oscar and Oscar.iso_oscar_gap are not injective. Due to caching, it may happen that S stores an attribute value of Oscar.iso_oscar_gap(S), but that the codomain of this map is not identical with or even not equal to the given R.

source
diff --git a/previews/PR2578/DeveloperDocumentation/new_developers/index.html b/previews/PR2578/DeveloperDocumentation/new_developers/index.html deleted file mode 100644 index b500781ba5e5..000000000000 --- a/previews/PR2578/DeveloperDocumentation/new_developers/index.html +++ /dev/null @@ -1,7 +0,0 @@ - -Introduction for new developers · Oscar.jl

Introduction for new developers

This document is meant to get new developers started. It will not go into depth of programming in Julia or working with git, as there are far better resources on these things online.

Pay attention to your GitHub notifications!

Once you open a pull request on GitHub you will receive feedback, comments, and questions on GitHub. So please pay attention to your GitHub notifications.

Important notes

  1. If you encounter error messages after rebasing to the current master, chances are that some dependencies need upgrading. Please first try whether executing ]up gets rid of your errors.
  2. Please have a look at the Developer Style Guide and the Design Decisions. Adhering to the style guide makes reviewing code easier for us, and hence your new feature can be merged faster.
  3. Let us know what you are working on early:
    • You can open a draft pull request on GitHub right at the beginning of your work. We are more than happy to look at incomplete prototypes to get an idea of what you are working on. This allows us to assess what kind of problems you might encounter and whether we can mitigate these by making changes to OSCAR.
    • Feel free to contact us on Slack.
    • Have a look at our community page.
  4. Please also read our page on Documenting OSCAR code.
  5. Look at existing code that does similar things to your project to get an idea of what OSCAR code should look like. Try to look at multiple examples.
  6. If you are planning to implement a new feature from scratch, please also read Adding new projects to experimental.

Overview

In general you have to do the following six steps for submitting changes to the OSCAR source:

  1. Fork the main Oscar.jl repository. For this go to the Oscar.jl GitHub page and click on "Fork" at the upper right.
  2. Clone your forked repository to your local machine. If you have set up ssh access you can do this in the following way:
    git clone git@github.com:your_github_username/Oscar.jl
  3. Create a new branch, usually the naming convention is to use your initials ("yi") and then describe your change, for example:
    git checkout -b yi/new_feature
    -git checkout -b yi/issue1234
    -git checkout -b yi/document_feature
  4. Edit your source and try out your changes locally (see below). To use your local copy of the sources, start Julia and
    ]dev /path/to/local/clone/of/your/fork/of/Oscar.jl
    If this succeeds, you can enter using Oscar in Julia and it will use your local copy.
  5. Once you are done editing, push your branch and open a pull request. It is recommended that you open a draft pull request to the main OSCAR repository as soon as you start working. That way OSCAR developers are aware of work being done and can give feedback early in the process.
  6. Once you have finished your work, mark your pull request as ready. It will then be reviewed and, probably after feedback and requests for changes, merged.

Alternative: ]dev Oscar

Alternatively you can call

]dev Oscar

in Julia. This will create a directory ~/.julia/dev/Oscar. This directory is a git clone of the central OSCAR repository. You can develop your code here, however you will still have to fork OSCAR, as you have no rights to push to the central repository. You can then add your fork as another remote, have a look at the section on rebasing below for hints.

The edit process

Editing the source

The sources can be found in the src folder. Please pay attention to the folder structure and choose sensibly where to place your code (when fixing a bug this is probably a minor question).

Adding tests

There are two ways to add tests:

  • There are combined tests and examples in the docstrings, namely the jldoctest blocks. For these have a closer look at Documenting OSCAR code.
  • Larger tests and tests that aren't useful examples are in the test folder. The main file there is test/runtests.jl which then includes other testfiles.

Tests that rely on random values should use Oscar.get_seeded_rng, which will return a seeded random number source, and pass this to any functions that need random values. The code may also directly create and use such a random source. The current seed will be printed at the beginning of the testsuite, it is fixed to 42 in the CI. It can be changed by setting ENV["OSCAR_RANDOM_SEED"] (for the testsuite running in a separate process) or by using Oscar.set_seed! (for the current session, e.g. Oscar.test_module("something", new=false)).

test_moduleFunction
test_module(file::AbstractString; new::Bool = true)

Run the Oscar tests in the file test/<file>.jl where file may be a path.

The optional parameter new takes the values false and true (default). If true, then the tests are run in a new session, otherwise the currently active session is used.

For experimental modules, use test_experimental_module instead.

source
get_seeded_rngFunction
get_seeded_rng()

Return a new random number generator object of type MersenneTwister which is seeded with the global seed value Oscar.rng_seed. This can be used for the testsuite to get more stable output and running times. Using a separate RNG object for each testset (or file) makes sure previous uses don't affect later testcases. It could also be useful for some randomized algorithms. The seed will be initialized with a random value during OSCAR startup but can be set to a fixed value with Oscar.set_seed! as it is done in runtests.jl.

source

Adding documentation

For more information on docstrings, please read our page on Documenting OSCAR code. There are two places where documentation can be added:

  1. In the docstrings above the functions in the src folder;
  2. In the documentation files in the docs/src folder. The overall structure is fixed in the file docs/doc.main. If you create a new file in docs/src, you will have to add an entry in docs/doc.main.

In general, 1 is preferred to 2, i.e. any explanation of the functions and objects should go there and the files in docs/src should remain relatively sparse. Please also pay attention to the documentation section of the Developer Style Guide.

Further hints

Give gh a try

Especially if you will be developing a lot, this can speed up your workflow tremendously.

Use the Revise package

Using Revise you can avoid having to restart Julia and reloading OSCAR when editing the code. As a quick summary, first install Revise with:

using Pkg;
-Pkg.add("Revise");

From then on do

using Revise, Oscar

whenever you are using OSCAR in Julia.

Use ]up

Working with the development version also entails that the packages Oscar depends on need to be up to date. Julia can update these packages if you type ]up in the Julia prompt. Many error messages after updating the source can be resolved by simply updating.

Style guide

Please have a look at the Developer Style Guide to get an overview over naming conventions, code formatting, etc.

Building the documentation

To build and test the documentation, please have a look at Documenting OSCAR code.

Rebasing

One way to stay up to date with the current master is rebasing. In order to do this, add the main Oscar.jl repository as a remote, fetch, and then rebase.

git remote add oscar-system git@github.com:oscar-system/Oscar.jl
-git fetch oscar-system
-git rebase oscar-system/master

Adding the remote only has to be executed once.

Useful Julia functions

diff --git a/previews/PR2578/DeveloperDocumentation/printing_details/index.html b/previews/PR2578/DeveloperDocumentation/printing_details/index.html deleted file mode 100644 index 96f0fdf59598..000000000000 --- a/previews/PR2578/DeveloperDocumentation/printing_details/index.html +++ /dev/null @@ -1,120 +0,0 @@ - -Details on printing in Oscar · Oscar.jl

Details on printing in Oscar

The following dection contains more details and examples on how to implement Oscar's 2+1 printing modes. The specifications and a minimal example may be found in the Developer Style Guide.

Implementing show functions

Here is the translation between :detail, one line and :supercompact.

print(io, "text/plain", x)                 # detailed printing
-print(io, x)                               # one line printing
-print(IOContext(:supercompact => true), x) # supercompact printing

For reference, string interpolation "$(x)" will also use print(io, x).

Mockup

Detailed printing with a new line

struct NewRing
-  base_ring
-end
-
-base_ring(R::NewRing) = R.base_ring

The following is a template for detailed printing. Note that at least one new line is needed for technical reasons. see below why.

function Base.show(io::IO, ::MIME"text/plain", R::NewRing)
-  println(io, "I am a new ring")  # at least one new line is needed
-  println(io, "I print with newlines")
-  print(io, base_ring(R)) # the last print statement must not add a new line
-end

The following is a template for one line and :supercompact printing.

function Base.show(io::IO, R::NewRing)
-  if get(io, :supercompact, false)
-    # no nested printing
-    print(io, "supercompact printing of newring ")
-  else
-    # nested printing allowed, preferably supercompact
-    print(io, "one line printing of newring with ")
-    print(IOContext(io, :supercompact => true), "supercompact ", base_ring(R))
-  end
-end

And this is how it looks like:

julia> R = NewRing(QQ)
-I am a new ring
-I print with newlines
-QQ
-
-julia> [R,R]
-2-element Vector{NewRing}:
- one line printing of newring with supercompact QQ
- one line printing of newring with supercompact QQ
-

Detailed printing in a single line

This version needs to be used in case the detailed printing does not contain newlines. Then detailed and one line printing agree. The if clause takes care of supercompact printing as well.

struct NewRing2
-  base_ring
-end
-
-base_ring(R::NewRing2) = R.base_ring
-
-function Base.show(io::IO, R::NewRing2)
-  if get(io, :supercompact, false)
-    # no nested printing
-    print(io, "supercompact printing of newring")
-  else
-    # nested printing allowed, preferably supercompact
-    print(io, "I am a new ring and always print in one line " )
-    print(IOContext(io, :supercompact => true), base_ring(R))
-  end
-end

And this is how it looks like:

julia> R = NewRing2(QQ)
-I am a new ring and always print in one line QQ
-
-julia> [R,R]
-2-element Vector{NewRing2}:
- I am a new ring and always print in one line Rational Field
- I am a new ring and always print in one line Rational Field
-
-julia> print(IOContext(Base.stdout, :supercompact => true) ,R)
-supercompact printing of newring

The following is not working as expected and should not be used

This example does not work correctly because the detailed printing does not include a newline, which is expected by the Julia printing system. To correctly support single line detailed printing, read the preceding section.

function Base.show(io::IO, ::MIME"text/plain", R::NewRing)  # do not implement me like this
-  print(io, "I am a new ring with a detailed printing of one line")
-end

Then the following will not be used for array/tuple printing. It will be used for print(io, R::NewRing) though.

function Base.show(io::IO, R::NewRing)
-  if get(io, :supercompact, false)
-    print(io, "supercompact printing of newring")
-  else # this is what we call one line
-    print(io, "one line printing of newring with ")
-    print(IOContext(io, :supercompact => true), "supercompact ", R.base_ring)
-  end
-end

This example illustrates the unexpected behavior.

julia> R = NewRing(1)
-
-julia> R
-I am a new ring with a detailed printing of one line
-
-julia> [R,R]  # one line printing is ignored
-2-element Vector{NewRing}:
- I am a new ring with a detailed printing of one line
- I am a new ring with a detailed printing of one line
-
-julia> print(Base.stdout, R)
-one line printing of newring with supercompact QQ

Advanced printing functionality

To facilitate printing of nested mathematical structures, we provide a modified IOCustom object, that supports indentation and decapitalization.

Example

We illustrate this with an example

struct A{T}
-  x::T
-end
-
-function Base.show(io::IO, a::A)
-  io = AbstractAlgebra.pretty(io)
-  println(io, "Something of type A")
-  print(io, AbstractAlgebra.Indent(), "over ", AbstractAlgebra.Lowercase(), a.x)
-  print(io, AbstractAlgebra.Dedent()) # don't forget to undo the indentation!
-end
-
-struct B
-end
-
-function Base.show(io::IO, b::B)
-  io = AbstractAlgebra.pretty(io)
-  print(io, LowercaseOff(), "Hilbert thing")
-end

At the REPL, this will then be printed as follows:

julia> A(2)
-Something of type A
-  over 2
-
-julia> A(A(2))
-Something of type A
-  over something of type A
-    over 2
-
-julia> A(B())
-Something of type A
-  over Hilbert thing

LaTeX and Unicode printing

LaTeX output

Some types support LaTeX output.

julia> Qx, x = QQ["x"];
-
-julia> show(stdout, "text/latex", x^2 + 2x + x^10)
-x^{10} + x^{2} + 2 x
-
-julia> show(stdout, "text/latex", Qx[x x^2; 1 1])
-\begin{array}{cc}
-x & x^{2} \\
-1 & 1
-\end{array}
Base.show(io::IOContext, ::MIME"text/latex")

Unicode printing

Per default output should be ASCII only (no Unicode). Implementors of Base.show and related functions can branch on the output of Oscar.is_unicode_allowed() to display objects using non-ASCII characters. This will then be used for users which enabled Unicode using allow_unicode(true). Note that

  • there must be a default ASCII only output, since this is the default setting for new users, and
  • OSCAR library code is not allowed to call Oscar.allow_unicode.

Here is an example with and without output using Unicode:

  struct AtoB
-  end
-
-  function Base.show(io::IO, ::AtoB)
-    if Oscar.is_unicode_allowed()
-      print(io, "A→B")
-    else
-      print(io, "A->B")
-    end
-  end
diff --git a/previews/PR2578/DeveloperDocumentation/serialization/index.html b/previews/PR2578/DeveloperDocumentation/serialization/index.html deleted file mode 100644 index 0b2074693eda..000000000000 --- a/previews/PR2578/DeveloperDocumentation/serialization/index.html +++ /dev/null @@ -1,34 +0,0 @@ - -Serialization · Oscar.jl

Serialization

Warning

Never load data from an untrusted source. Loading data is inherently unsafe and at this point allows arbitrary code execution on your machine. Just as you should never run a program from someone you do not trust, you should also not load their data.

Warning

Serialization development has just started and the concrete design may still change drastically. In particular the mechanism for upgrading old data to newer versions is not in place yet, so at this point we do not yet guarantee that old data can be read.

This document summarises the serialization efforts of OSCAR, how it is supposed to work, how it works and the overall goal. Serialization broadly speaking is the process of writing data to and reading data from files. There are many reasons for needing this feature in OSCAR, but the main reason is communication on mathematics by mathematicians.

How it works

The mechanism for saving and loading is very simple. It is implemented via two methods save and load, and works in the following manner:

julia> save("/tmp/fourtitwo.json", 42);
-
-julia> load("/tmp/fourtitwo.json")
-42
-

As hinted by the filename, OSCAR writes a file in JSON format. The file looks as follow:

{
-    "_ns": {
-        "Oscar": [
-            "https://github.com/oscar-system/Oscar.jl",
-            {
-                "major": 0,
-                "minor": 8,
-                "patch": 3,
-                "prerelease": [
-                    "DEV"
-                ],
-                "build": []
-            }
-        ]
-    },
-    "id": "-1",
-    "type": "Base.Int",
-    "data": "42"
-}

It contains the version of OSCAR it was written by, its type, and the actual content, in this case as a string.

The id

If you look at the file src/Serialization/main.jl, you will see that all save methods hand down a SerializerState, and all load methods have a DeserializerState. These two objects are very simple, they just contain dictionaries connecting objects and their id. We use this to avoid saving or loading larger objects twice (or multiple times). Consider the following example code snippet:

c = cube(3);
-LP0 = linear_program(c, [2,2,-3]);
-LP1 = linear_program(c, [2,2,4]);
-v = [LP0, LP1];
-save("vector_of_lp.json", v)

This creates two linear programs on the cube, stores them in a vector and then writes this vector to a file. It would be wasteful to store the cube twice for each linear program, instead it is only stored once and the second linear program just gets the id of the cube in its serialized form. Please take some time to look at the file written in this concrete example.

The version number

We will use the version number for checking compatibility of the data with the current OSCAR version before attempting to load it. If the data version is lower than the OSCAR version we will provide appropriate upgrade scripts such that the data can be loaded. We will not provide scripts for attempting to downgrade data, but we will throw a warning or even error in this case. We may provide an option for attempting to load anyway in such a scenario.

Implementation

All files for serialization can be found in the folder src/Serialization. The naming conventions of the files there follows the overall structure of OSCAR, i.e. the file src/Serialization/PolyhedralGeometry.jl contains functions for serializing objects of the polyhedral geometry section.

The file main.jl contains the core of the serialization process, namely:

  • reading and writing files;
  • the SerializerState and DeserializerState objects;
  • writing and reading versions; and
  • generic functions for attempting to serialize objects that do not have their own dedicated serialization methods.

If you want to write a serialization routine for an object, the way to go is to implement the following two functions, here in the example for ZZRingElem:

function load_internal(s::DeserializerState, ::Type{ZZRingElem}, str::String)
-    return ZZRingElem(str)
-end
-
-function save_internal(s::SerializerState, z::ZZRingElem)
-    return string(z)
-end

Then the main serialization methods will dispatch to load_internal and save_internal for ZZRingElem instead of attempting the generic serialization.

Often the generic serialization will fail and it is necessary to provide a save_internal and load_internal function. In that case, please have a look at the existing functions to get an idea of how these work, and maybe use something of this as a blueprint.

Challenges

This section documents the various challenges we (will) encounter while implementing this feature.

  • OSCAR is based on several subsystems, some of which already have their own serialization. We want this to be compatible, if possible in both directions.
  • Many mathematical objects need context to be understood. A polynomial needs the ring it lives in, a group element needs the surrounding group, a divisor needs the underlying variety, etc. We will need a way to store this context along the objects.
  • Context should not be stored twice: A matrix of polynomials should only store the surrounding ring once.
  • Support other data formats: It has been proposed to not only support JSON, but binary formats needed for HPC communication as well. It is unclear whether this needs a separate implementation.
  • Versioning and upgrading: Work on OSCAR will change what its objects look like. Nevertheless, we still want to be able load data written by older versions of OSCAR. For this we intend to develop an upgrade mechanism.

Another important point is the wider mathematical context of the data and code. For data associated to a publication, this context is provided by the paper.

Goals

The general goal is to make mathematical data FAIR, a goal for which we cooperate with the MaRDI project.

The ramifications of making mathematical data FAIR are manifold.

  • It becomes easier to exchange data and code with fellow mathematicians, enhancing communication and boosting research.
  • Computer experiments and new implementations require a lot of work and hence deserve to be recognized in form of a publication. Standardizing data plays an important role for this process.
  • Future generations of mathematicians will be able to reuse both data and code if we establish a FAIR culture.
diff --git a/previews/PR2578/DeveloperDocumentation/styleguide/index.html b/previews/PR2578/DeveloperDocumentation/styleguide/index.html deleted file mode 100644 index 63798c9c900d..000000000000 --- a/previews/PR2578/DeveloperDocumentation/styleguide/index.html +++ /dev/null @@ -1,45 +0,0 @@ - -Developer Style Guide · Oscar.jl

Developer Style Guide

In general we aim to follow the Julia Style Guide but there are some exceptions due to our specific needs and a different background.

The content of this page are merely guidelines. There may be good reasons to deviate from them in some cases; in that case just do so.

General styleguide

  • Use Julia conventions where applicable and when they don't contradict our own rules above.
  • Unless really really necessary, don't add new dependencies. Every new dependency complicates the development workflow, in that we will need to stay compatible with this package.
  • If already existing types in OSCAR are almost what you need, consider improving them instead of writing your own. While it might be tempting to create a new polynomial ring type for the new application because some feature is missing, it causes a lot of work and compatibility issues: Will the new type support
    • normal functions (gcd, factor),
    • quotient fields,
    • modules and residue rings,
    • conversion to and from other already existing types?
  • Whenever functions return the same mathematical object, but in different mathematical categories, the first argument should be the desired return type. One example is projective_space(NormalToricVariety, *) vs projective_space(ProjectiveScheme, *). However, if the return type is different, even if the result describes the same mathematical object, it should be indicated in the function name, for example automorphism_group vs automorphism_group_generators vs automorphism_list.
  • Follow the mathematics. If your function needs a list of points, you should create a point-type (or use the one already there) and then use this. For user-facing functions, please do not use re-purposed lists, arrays, matrices...

Naming conventions

The usual Julia naming conventions apply to OSCAR, too (that said, for various reasons our code still violates quite some of them; but in general we strive to reduce these). Here is a summary of the naming convention followed in OSCAR:

  • Use CamelCase for types and snake_case for everything else. (Internal functions do not have to follow these rules.) Types (and their constructor) tend to be in CamelCase. However, please also provide the constructor (or a constructor) in snake_case. As a user one usually does not know if something is a constructor or a function.
  • For filenames we recommend using snake_case.jl.
  • Noteworthy difference to Julia base is that we do not have exceptions for is* or has* as prefix. It is is_foo instead of isfoo and has_bar instead of hasbar. The main reason is to avoid awkward constructions like isvery_ample, while also being consistent. For compatibility with standard Julia, while staying consistent internally, we also provide aliases (using AbstractAlgebra.@alias) for various standard Julia functions, e.g. is_one as alias for isone
  • For generic concepts choose generic names, based on general algebraic concepts, preferably not special names from your area of speciality.
  • Avoid direct access to members of our objects. This means, do not use something like A.foo, instead use a suitable getter get_foo(A), and if there is none, please write one or request that one be written. Internal member names are free to change at any time, but functions can be deprecated properly.
  • In Julia we have multiple dispatch, so we do not need functions like point_from_matrix as the "from" part is clear by the type of the argument. It should be called points(T::Matrix) in some variation. Similarly for matrix_to_points. Of course it is fine to use them internally, where useful.

Code formatting

Editor configuration

Please check if your editor can be configured to honor our .editorconfig file, see https://editorconfig.org for more information about this.

Unicode

As most modern programming languages, Julia allows the use of Unicode, e.g., α, in the REPL as well as in source code. As this reduces accessibility to various groups of users and developers, the use of Unicode should be kept to a minimum. Here is a general principle:

Do not use Unicode characters inside functions. See below for the exception concerning printing.

Whitespace

  • Do not use tabs.
  • Do not put spaces "inside" parenthesis.
  • Do put spaces after commas.

Good example:

f(x, y) = x + 1
-print(f(1, 2))

Bad example:

f( x,y ) = x + 1
-print( f ( 1,2 ) )

Loops and other control structures

  • for loops should use in not =
  • don't put spaces around the : in a range

Good example:

for i in 1:3
-  println(i)
-end

Bad example:

for i = 1 : 3
-  println(i)
-end

Code structure

  • do not nest loops and if clauses too deeply; if you are using 5 or more levels, then in general that's a hint that you should refactor; e.g.

    • by moving parts of the code into a separate function
    • by replacing guard constructs like
      for i in A
      -  if flag
      -    ...
      -  end
      -end
      by
      for i in A
      -  if !flag
      -    continue
      -  end
      -  ...
      -end
      or
      for i in A
      -  flag ||continue
      -  ...
      -end
    • by merging loops: you can replace
      for i in A
      -  for j in B
      -    ...
      -  end
      -end
      by
      for i in A, j in B
      -  ...
      -end
  • Functions should not have too many arguments. If you need a bunch arguments, chances are that introducing a new type makes it more readable.

  • Functions should not be too long; very long functions are in general harder to understand; it is also more difficult to see all the code at once. Consider splitting the function into multiple ones, if it is sensibly possible.

  • Every export statement must be confined to a single line; the intention is to make it easy to use tools like git grep to find exports. In general it is recommended export exactly one identifier per export statement. Exceptions may be made for certain tightly related identifiers, e.g. is_finite, set_is_finite and has_is_finite could be put on a single line. In general if multiple export statements appear in sequence, they must be sorted alphabetically.

However, as always, rules sometimes should be broken.

Documentation

  • In general we try to follow the list of recommendations in the Documentation section of the Julia manual.

  • Via the MathJax integration it is possible to use LaTeX code, and this is the preferred way to denote the mathematical symbols in the docstrings.

Printing in Oscar

The 2 + 1 print modes of Oscar

Oscar has two user print modes detailed and one line and one internal print mode :supercompact. The latter is for use during recursion, e.g. to print the base_ring(X) when in one line mode. It exists to make sure that one line stays compact and human readable.

Top-level REPL printing of an object will use detailed mode by default

julia> X
-detailed

Inside nested structures, e.g. inside a Vector, the one line mode is used.

julia> [X,X]
-3-element Vector{TypeofX{T}}
-one line
-one line
-one line
An Example for the 2 + 1 print modes
# detailed
-General linear group of degree 24
-  over Finite field of degree 7 over GF(29)
-
-# one line
-General linear group of degree 24 over GF(29^7)
-
-# supercompact
-General linear group

The print modes are specified as follows

Detailed printing

  • the output must make sense as a standalone without context to non-specialists
  • the number of output lines should fit in the terminal
  • if the object is simple enough use only one line
  • use indentation and (usually) one line to print substructures

One line printing

  • the output must print in one line
  • should make sense as a standalone without context
  • variable names/generators/relations should not be printed only their number.
  • Only the first word is capitalized e.g. Polynomial ring
  • one should use :supercompact for nested printing in compact
  • nested calls to one line (if you think them really necessary) should be at the end, so that one can read sequentially. Calls to :supercompact can be anywhere.
  • commas must be enclosed in brackets so that printing tuples stays unambiguous

Super compact printing

  • a user readable version of the main (mathematical) type.
  • a single term or a symbol/letter mimicking mathematical notation
  • should usually only depend on the type and not of the type parameters or of the concrete instance - exceptions of this rule are possible e.g. for GF(2)
  • no nested printing. In particular variable names and base_ring must not be displayed. This ensures that one line and :supercompact stay compact even for complicated things. If you want nested printing use one line or detailed.

For further information and examples we refer you to our section Details on printing in Oscar.

Deprecating functions

Sometimes it is necessary to rename a function or otherwise change it. To allow for backwards compatibility, please then introduce a new line in the file src/deprecations.jl. The syntax is as follows:

# Deprecated after CURRENT_RELEASE_VERSION
-@deprecate old_function(args) new_function(args)

It is possible to transform the args too, if the syntax has changed. If this process needs an auxiliary function, which otherwise is unnecessary, please add it above:

# Deprecated after CURRENT_RELEASE_VERSION
-function transform_args_for_new_function(args)
-    # Do something
-    return new_args
-end
-@deprecate old_function(args) new_function(transform_args_for_new_function(args))

The comment about the version number is only necessary if you are the first one adding to deprecations.jl after a release, otherwise please add to the existing block.

Note

Please make sure to change to the new function everywhere in the existing OSCAR code base. Even if you think, you were the only one using the function, run a quick grep to make sure. When you are done, deprecations.jl should be the only place mentioning old_function. To make sure, you can start Julia with --depwarn=yes or even --depwarn=error and then run the tests.

Approved abbreviations

  • Types for rings/groups/ideals/modules/... end with Ring/Group/Ideal/Module/...
  • Types for elements should have the same name as the type of the parent with Elem added;
    • Exception: MatrixSpace elements end with Matrix.
  • We abbreviate certain parts of type names, according to a fixed set of substitutions; further abbreviations should be carefully decided upon.
  • Every abbreviation must be unique; e.g. Abs stands for Absolute, and so must not be used for e.g. Abstract.
  • List of approved abbreviations
    • absolute -> Abs
      • abstract -> Abstract
    • decorated -> Dec
    • group -> Group
    • ideal -> Ideal
    • localized -> Loc
    • matrix -> Matrix
    • module -> Module
    • multivariate polynomial -> MPoly
    • polynomial -> Poly
    • quotient -> Quo
    • relative -> Rel
    • ring ->Ring
    • subquotient -> Subquo
  • If a type comes in sparse and dense variants, then call the dense type T and the sparse one SparseT.
diff --git a/previews/PR2578/Experimental/FTheoryTools/hypersurface/index.html b/previews/PR2578/Experimental/FTheoryTools/hypersurface/index.html deleted file mode 100644 index 5e36adc9ad1c..000000000000 --- a/previews/PR2578/Experimental/FTheoryTools/hypersurface/index.html +++ /dev/null @@ -1,118 +0,0 @@ - -Hypersurface models · Oscar.jl

Hypersurface models

Introduction

A hypersurface model describes a particular form of an elliptic fibration. For now, we consider such models in toric settings only, that is we restrict to a toric base space $B$ and assume that the generic fiber is a hypersurface in a 2-dimensional toric fiber ambient space $F$.

In addition, we shall assume that the first two homogeneous coordinates of $F$ transform in the divisor classes $D_1$ and $D_2$ over the base $B$ of the elliptic fibration. The remaining coordinates of $F$ are assumed to transform in the trivial bundle over $B$. See Denis Klevers, Damian Kaloni Mayorga Pena, Paul-Konstantin Oehlmann, Hernan Piragua, Jonas Reuter (2015) for more details.

Given this set of information, it is possible to compute a toric ambient space $A$ for the elliptic fibration. The elliptic fibration is then a hypersurface in this toric space $A$. Furthermore, since we assume that this fibration is Calabi-Yau, it is clear that the hypersurface equation is a (potentially very special) section of the $\overline{K}_A$. This hypersurface equation completes the information required about a hypersurface model.

Constructors

We aim to provide support for hypersurface models over the following bases:

  • a toric variety,
  • a toric scheme,
  • a (covered) scheme.

[Often, one also wishes to obtain information about a hypersurface model without explicitly specifying the base space. Also for this application, we provide support.]

Finally, we provide support for some standard constructions.

Before we detail these constructors, we must comment on the constructors over toric base spaces. Namely, in order to construct a hypersurface model, we first have to construct the ambient space in question. For a toric base, one way to achieve this is by means of triangulations. However, this is a rather time consuming and computationally challenging task, which leads to a huge number of ambient spaces. Even more, typically one wishes to only pick one of thees many ambient spaces. For instance, a common and often appropriate choice is a toric ambient space which contains the toric base space in a manifest way.

To circumvent this very demanding computation, our constructors operate in the opposite direction. That is, they begin by extracting the rays and maximal cones of the chosen toric base space. Subsequently, those rays and cones are extended to form one of the many toric ambient spaces. This proves hugely superior in performance than going through the triangulation task of enumerating all possible toric ambient spaces. One downside of this strategy is that the so-constructed ambient space need not be smooth.

A toric variety as base space

We require that the provided toric base space is complete. This is a technical limitation as of now. The functionality of OSCAR only allows us to compute a section basis (or a finite subset thereof) for complete toric varieties. In the future, this could be extended.

Completeness is an expensive check. Therefore, we provide an optional argument which one can use to disable this check if desired. To this end, one passes the optional argument completeness_check = false as last argument to the constructor. The following examples demonstrate this:

hypersurface_modelMethod
hypersurface_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)

Construct a hypersurface model. This constructor takes $\mathbb{P}^{2,3,1}$ as fiber ambient space with coordinates $[x:y:z]$ and ensures that $x$ transforms as $2 \overline{K}_{B_3}$ and $y$ as $3 \overline{K}_{B_3}$.

Examples

julia> base = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> hypersurface_model(base; completeness_check = false)
-Hypersurface model over a concrete base
source
hypersurface_modelMethod
hypersurface_model(base::AbstractNormalToricVariety, fiber_ambient_space::AbstractNormalToricVariety, D1::ToricDivisorClass, D2::ToricDivisorClass; completeness_check::Bool = true)

Construct a hypersurface model, for which the user can specify a fiber ambient space as well as divisor classes of the toric base space, in which the first two homogeneous coordinates of the fiber ambient space transform.

Examples

julia> base = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])
-Normal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor
-
-julia> set_coordinate_names(fiber_ambient_space, ["x", "y", "z"])
-
-julia> D1 = 2 * anticanonical_divisor_class(base)
-Divisor class on a normal toric variety
-
-julia> D2 = 3 * anticanonical_divisor_class(base)
-Divisor class on a normal toric variety
-
-julia> hypersurface_model(base, fiber_ambient_space, D1, D2; completeness_check = false)
-Hypersurface model over a concrete base
source

A toric scheme as base space

For the same reasons as above, the toric base must be complete. Similar to toric varieties as bases, we can use the optional argument completeness_check = false to switch off the expensive completeness check. The following examples demonstrate this:

hypersurface_modelMethod
hypersurface_model(base::ToricCoveredScheme; completeness_check::Bool = true)

Construct a hypersurface model. This constructor takes $\mathbb{P}^{2,3,1}$ as fiber ambient space with coordinates $[x:y:z]$ and ensures that $x$ transforms as $2 \overline{K}_{B_3}$ and $y$ as $3 \overline{K}_{B_3}$.

Examples

julia> base = projective_space(ToricCoveredScheme, 2)
-Scheme of a toric variety
-
-julia> hypersurface_model(base; completeness_check = false)
-Hypersurface model over a concrete base
source
hypersurface_modelMethod
hypersurface_model(base::ToricCoveredScheme, fiber_ambient_space::ToricCoveredScheme, D1::ToricDivisorClass, D2::ToricDivisorClass; completeness_check::Bool = true)

Construct a hypersurface model, for which the user can specify a fiber ambient space as well as divisor classes of the toric base space, in which the first two homogeneous coordinates of the fiber ambient space transform.

Examples

julia> base = projective_space(ToricCoveredScheme, 2)
-Scheme of a toric variety
-
-julia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])
-Normal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor
-
-julia> set_coordinate_names(fiber_ambient_space, ["x", "y", "z"])
-
-julia> fiber_ambient_space = ToricCoveredScheme(fiber_ambient_space)
-Scheme of a toric variety
-
-julia> D1 = 2 * anticanonical_divisor_class(underlying_toric_variety(base))
-Divisor class on a normal toric variety
-
-julia> D2 = 3 * anticanonical_divisor_class(underlying_toric_variety(base))
-Divisor class on a normal toric variety
-
-julia> h = hypersurface_model(base, fiber_ambient_space, D1, D2; completeness_check = false)
-Hypersurface model over a concrete base
source

A (covered) scheme as base space

This functionality does not yet exist.

Base space not specified

This method constructs a hypersurface model over a base space, where this base space is not (fully) specified. We currently provide the following constructors:

hypersurface_modelMethod
hypersurface_model(auxiliary_base_vars::Vector{String}, auxiliary_base_grading::Matrix{Int64}, d::Int, fiber_ambient_space::NormalToricVariety, D1::Vector{Int64}, D2::Vector{Int64}, p::MPolyRingElem)

This method constructs a hypersurface model over a base space that is not fully specified. In the background, we construct an auxiliary toric base space. This method requires the following information:

  1. The names of the homogeneous coordinates of the auxiliary toric base space.
  2. The grading of the Cox ring of the auxiliary toric base space.
  3. The weights corresponding to the divisor class D_1 of the auxiliary toric base space under which the first fiber coordinate transforms.
  4. The weights corresponding to the divisor class D_2 of the auxiliary toric base space under which the first fiber coordinate transforms.
  5. The dimension of the auxiliary toric base space.
  6. The fiber ambient space.
  7. The hypersurface equation.

Note that many studies in the literature use the class of the anticanonical bundle in their analysis. We anticipate this by adding this class as a variable of the auxiliary base space, unless the user already provides this grading. Our convention is that the first grading refers to Kbar and that the homogeneous variable corresponding to this class carries the name "Kbar".

The following example exemplifies this constructor.

Examples

julia> auxiliary_base_vars = ["a1", "a21", "a32", "a43", "a65", "w"]
-6-element Vector{String}:
- "a1"
- "a21"
- "a32"
- "a43"
- "a65"
- "w"
-
-julia> auxiliary_base_grading = [1 2 3 4 6 0; 0 -1 -2 -3 -5 1]
-2×6 Matrix{Int64}:
- 1   2   3   4   6  0
- 0  -1  -2  -3  -5  1
-
-julia> D1 = [4,0]
-2-element Vector{Int64}:
- 4
- 0
-
-julia> D2 = [6,0]
-2-element Vector{Int64}:
- 6
- 0
-
-julia> d = 3
-3
-
-julia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])
-Normal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor
-
-julia> set_coordinate_names(fiber_ambient_space, ["x", "y", "z"])
-
-julia> auxiliary_ambient_ring, (a1, a21, a32, a43, a65, w, x, y, z)  = QQ["a1", "a21", "a32", "a43", "a65", "w", "x", "y", "z"]
-(Multivariate polynomial ring in 9 variables over QQ, QQMPolyRingElem[a1, a21, a32, a43, a65, w, x, y, z])
-
-julia> p = x^3 - y^2 - x * y * z * a1 + x^2 * z^2 * a21 * w - y * z^3 * a32 * w^2 + x * z^4 * a43 * w^3 + z^6 * a65 * w^5
--a1*x*y*z + a21*w*x^2*z^2 - a32*w^2*y*z^3 + a43*w^3*x*z^4 + a65*w^5*z^6 + x^3 - y^2
-
-julia> h = hypersurface_model(auxiliary_base_vars, auxiliary_base_grading, d, fiber_ambient_space, D1, D2, p)
-Assuming that the first row of the given grading is the grading under Kbar
-
-Hypersurface model over a not fully specified base
source

Standard constructions

We provide convenient constructions of hypersurface models over famous base spaces. Currently, we support the following:

hypersurface_model_over_projective_spaceMethod
hypersurface_model_over_projective_space(d::Int)

This method constructs a hypersurface model over the projective space.

Examples

julia> hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
source
hypersurface_model_over_hirzebruch_surfaceMethod
hypersurface_model_over_hirzebruch_surface(r::Int)

This method constructs a hypersurface model over a Hirzebruch surface.

Examples

julia> hypersurface_model_over_hirzebruch_surface(1)
-Hypersurface model over a concrete base
source
hypersurface_model_over_del_pezzo_surfaceMethod
hypersurface_model_over_del_pezzo_surface(b::Int)

This method constructs a hypersurface model over a del-Pezzo surface.

Examples

julia> hypersurface_model_over_del_pezzo_surface(3)
-Hypersurface model over a concrete base
source

Attributes

Basic attributes

For all hypersurface models – irrespective over whether the base is toric or not – we support the following attributes:

hypersurface_equationMethod
hypersurface_equation(h::HypersurfaceModel)

Return the hypersurface equation.

julia> h = hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
-
-julia> hypersurface_equation(h);
source

One can also decide to specify a custom hypersurface equation:

set_hypersurface_equationMethod
set_hypersurface_equation(h::HypersurfaceModel, p::MPolyRingElem)

Set the hypersurface equation to a custom value.

julia> h = hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
-
-julia> R = parent(hypersurface_equation(h));
-
-julia> new_poly = gens(R)[4]^3
-x^3
-
-julia> set_hypersurface_equation(h, new_poly);
source

The fiber ambient space can be accessed via

fiber_ambient_spaceMethod
fiber_ambient_space(HypersurfaceModel)

Return the fiber ambient space of the hypersurface model.

julia> h = hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
-
-julia> fiber_ambient_space(h)
-Scheme of a toric variety
source

In case the hypersurface model is constructed over a not fully specified base, recall that we construct an auxiliary (toric) base space as well as an auxiliary (toric) ambient space. The (auxiliary) base and ambient space can be accessed with the following functions:

base_spaceMethod
base_space(h::HypersurfaceModel)

Return the base space of the hypersurface model.

julia> h = hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
-
-julia> base_space(h)
-Scheme of a toric variety
source
ambient_spaceMethod
ambient_space(h::HypersurfaceModel)

Return the ambient space of the hypersurface model.

julia> h = hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
-
-julia> ambient_space(h)
-Scheme of a toric variety
source

The following method allows to tell if the base/ambient space is auxiliary or not:

base_fully_specifiedMethod
base_fully_specified(h::HypersurfaceModel)

Return true is the hypersurface model has a concrete base space and false otherwise.

julia> h = hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
-
-julia> base_fully_specified(h)
-true
source

The user can decide to get an information whenever an auxiliary base space, auxiliary ambient space or auxiliary hypersurface have been computed. To this end, one invokes set_verbosity_level(:HypersurfaceModel, 1). More background information is available here.

Attributes in toric settings

If the base space of the hypersurface model is a toric space, then we also provide a special type for the Calabi-Yau hypersurface:

calabi_yau_hypersurfaceMethod
calabi_yau_hypersurface(h::HypersurfaceModel)

Return the Calabi-Yau hypersurface in the toric ambient space which defines the hypersurface model.

julia> h = hypersurface_model_over_projective_space(2)
-Hypersurface model over a concrete base
-
-julia> calabi_yau_hypersurface(h)
-Closed subvariety of a normal toric variety
source

Attributes based on the corresponding global Tate and Weierstrass models

Currently, we do not provide functionality to convert a hypersurface model into a Weierstrass or global Tate model. Still, for some constructions this might be known or detailed in the literature. If the user wishes, one can then associate a corresponding Weierstrass or global Tate model as follows:

set_weierstrass_modelMethod
set_weierstrass_model(h::HypersurfaceModel, w::WeierstrassModel)

Allows to define the Weierstrass model corresponding to the hypersurface model.

source
set_global_tate_modelMethod
set_global_tate_model(h::HypersurfaceModel, w::GlobalTateModel)

Allows to define the global Tate model corresponding to the hypersurface model.

source

These models can then be accessed with the following functions:

weierstrass_modelMethod
weierstrass_model(h::HypersurfaceModel)

Return the Weierstrass model corresponding to the hypersurface model, provided that the latter is known.

source
global_tate_modelMethod
global_tate_model(h::HypersurfaceModel)

Return the global Tate model corresponding to the hypersurface model, provided that the latter is known.

source

Provided that the corresponding Weierstrass model is known for a hypersurface model, the following functionality is available. It returns the attribute in question of the corresponding Weierstrass model.

discriminantMethod
discriminant(h::HypersurfaceModel)

Return the discriminant of the hypersurface model.

source
singular_lociMethod
singular_loci(h::HypersurfaceModel)

Return the singular loci of the hypersurface model, along with the order of vanishing of the Weierstrass sections and discriminant $(f, g, \Delta)$` at each locus. Also the refined Tate fiber type is returned.

source
diff --git a/previews/PR2578/Experimental/FTheoryTools/introduction/index.html b/previews/PR2578/Experimental/FTheoryTools/introduction/index.html deleted file mode 100644 index 458c657ae153..000000000000 --- a/previews/PR2578/Experimental/FTheoryTools/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Welcome to FTheoryTools · Oscar.jl

Welcome to FTheoryTools

Goal

We aim to automate a number of recurring and (at least in part) tedious computations in F-theory model building as described in large detail in Timo Weigand (2018). Specifically, we focus on the following setups:

  • 4d F-theory compactifications,
  • defined by a global and singular Weierstrass model as codimension 1 locus of a toric ambient space $Y$,
  • which can be crepantly resolved.

Some of the techniques/algorithms extend naturally to more general settings. For example, it is not at all necessary to restrict to 4-dimensional settings (or alternatively, base spaces of dimension 3). Indeed, the current implementation does allow for arbitrary base dimension. For more extensions that we might address in the future, please take a look at the section "possible future extensions" below.

We aim for the following workflow:

  • User input:
    • Weierstrass polynomial $P_W$,
    • Data defining the toric ambient space $Y$ (if applicable),
    • Choice of resolved phase (if applicable),
    • Generating sections (for $\operatorname{U}(1)$ symmetries).
  • Output:
    • Singular loci in codimension 1, 2, and 3,
    • Defining data of resolved geometry,
    • (Pictures of) fibre diagrams of resolved fibre over the originally singular loci, including intersections of $\operatorname{U}(1)$-sections,
    • Gauge group,
    • Topological data (e.g., Euler number).

Status

This project just began, and is therefore in its experimental stage. Upcoming tasks include, but are not limited, to the following:

  • The irrelevant ideal, SR ideal, and ideal of linear relations may need to be modified when the exceptional coordinate "e" is included in the blowup. They are currently set up to work when e is eliminated.
  • Decide whether to stick with global blowups or use charts.
  • Consolidate notation about sections and line bundles in the documentation.
  • The Kodaira type function assumes that the singular locus is given by a single coordinate.
  • The Kodaira type function only works for codimension 1.
  • Modify the ambientspacefrombase function to return ring maps from the base to the ambient space and all other constructors/types to appropriately carry that around, then fix the corresponding bit of code in analyze_fibers.

Tutorial

We provide a tutorial for FTheoryTools in OSCAR.

Possible future extensions

Future extensions include, but are not necessarily limited to, the following:

  • Specify a $G_4$-flux and work out the chiral spectra,
  • Specify a gauge potential and work out (candidates for) the line bundles whose cohomologies encode the vector-like spectra,
  • Other singularity types (non-minimal, terminal, etc.,
  • Base blowups for singularity resolution.

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

Acknowledgements

We appreciate insightful discussions with Mirjam Cvetič. The work of Andrew Turner is supported by DOE (HEP) Award DE-SC001352.

diff --git a/previews/PR2578/Experimental/FTheoryTools/literature/index.html b/previews/PR2578/Experimental/FTheoryTools/literature/index.html deleted file mode 100644 index 1c7f2e5f544d..000000000000 --- a/previews/PR2578/Experimental/FTheoryTools/literature/index.html +++ /dev/null @@ -1,308 +0,0 @@ - -Literature constructions · Oscar.jl

Literature constructions

Certain models have been studied in the physics literature over and over again. Thereby, these constructions became famous and some were given special names. We aim to provide support for such standard constructions. An example of such a model is the following:

su5_tate_model_over_arbitrary_3d_baseMethod
su5_tate_model_over_arbitrary_3d_base()

Return the SU(5) Tate model over an arbitrary 3-dimensional base space. For more details see e.g. Timo Weigand (2018) and references therein.

julia> tm = su5_tate_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base
-
-julia> v = underlying_toric_variety(ambient_space(tm))
-Normal toric variety
-
-julia> a10,a21,a32,a43,a65,w,x,y,z = gens(cox_ring(v));
-
-julia> I = ideal([x,y,w]);
-
-julia> v2 = domain(blow_up(v,I))
-Normal toric variety
-
-julia> cox_ring(v2)
-Multivariate polynomial ring in 10 variables over QQ graded by 
-  a10 -> [1 0 0 0]
-  a21 -> [0 1 0 0]
-  a32 -> [-1 2 0 0]
-  a43 -> [-2 3 0 0]
-  a65 -> [-4 5 0 0]
-  w -> [0 0 1 0]
-  x -> [0 1 1 2]
-  y -> [1 1 1 3]
-  z -> [0 0 0 1]
-  e -> [2 -1 -1 0]
source

More generally, we support literature constructions.

literature_modelMethod
literature_model(; doi::String="", arxiv_id::String="", version="", equation::String="")

Many models have been created in the F-theory literature. A significant number of them have even been given specific names, for instance the "U(1)-restricted SU(5)-GUT model". This method has access to a database, from which it can look up such literature models.

Currently, you can provide any combination of the following optional arguments to the method literature_model:

  • doi: A string representing the DOI of the publication that

introduced the model in question.

  • equation: A string representing the number of the equation that introduced

the model in question. For papers, that were posted on the arXiv, we can instead of the doi also provide the following:

  • arxiv_id: A string that represents the arXiv identifier of the paper that

introduced the model in question.

  • version: A string representing the version of the arXiv upload.

The method literature_model attempts to find a model in our database for which the provided data matches the information in our record. If no such model can be found, or multiple models exist with information matching the provided information, then an error is raised.

Some literature models require additional parameters to specified to single out a model from a family of models. Such models can be provided using the optional argument model_parameters, which should be a dictionary such as Dict("k" => 5).

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> v = ambient_space(t)
-Scheme of a toric variety
-
-julia> a1,a21,a32,a43,w,x,y,z = gens(cox_ring(v));
-
-julia> I = ideal([x,y,w]);
-
-julia> v2 = domain(blow_up(underlying_toric_variety(v),I))
-Normal toric variety
-
-julia> cox_ring(v2)
-Multivariate polynomial ring in 9 variables over QQ graded by
-  a1 -> [1 0 0 0]
-  a21 -> [0 1 0 0]
-  a32 -> [-1 2 0 0]
-  a43 -> [-2 3 0 0]
-  w -> [0 0 1 0]
-  x -> [0 1 1 2]
-  y -> [1 1 1 3]
-  z -> [0 0 0 1]
-  e -> [2 -1 -1 0]
source

Attributes

For literature models, we provide the following attributes:

arxiv_idMethod
arxiv_id(m::AbstractFTheoryModel)

Return the arxiv_id of the preprint that introduced the given model. If no arxiv_id is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> arxiv_id(m)
-"1109.3454"
source
arxiv_doiMethod
arxiv_doi(m::AbstractFTheoryModel)

Return the arxiv_doi of the preprint that introduced the given model. If no arxiv_doi is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> arxiv_doi(m)
-"10.48550/arXiv.1109.3454"
source
arxiv_linkMethod
arxiv_link(m::AbstractFTheoryModel)

Return the arxiv_link (formatted as string) to the arXiv version of the paper that introduced the given model. If no arxiv_link is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> arxiv_link(m)
-"https://arxiv.org/abs/1109.3454v2"
source
arxiv_model_equation_numberMethod
arxiv_model_equation_number(m::AbstractFTheoryModel)

Return the arxiv_model_equation_number in which the given model was introduced in the arXiv preprint in our record. If no arxiv_model_equation_number is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> arxiv_model_equation_number(m)
-"3.1"
source
arxiv_model_pageMethod
arxiv_model_page(m::AbstractFTheoryModel)

Return the arxiv_model_page on which the given model was introduced in the arXiv preprint in our record. If no arxiv_model_page is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> arxiv_model_page(m)
-"10"
source
arxiv_model_sectionMethod
arxiv_model_section(m::AbstractFTheoryModel)

Return the arxiv_model_section in which the given model was introduced in the arXiv preprint in our record. If no arxiv_model_section is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> arxiv_model_section(m)
-"3"
source
arxiv_versionMethod
arxiv_version(m::AbstractFTheoryModel)

Return the arxiv_version of the arXiv preprint that introduced the given model. If no arxiv_version is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> arxiv_version(m)
-"2"
source
associated_literature_modelsMethod
associated_literature_models(m::AbstractFTheoryModel)

Return a list of the unique identifiers any associated_literature_models of the given model. These are either other presentations (Weierstrass, Tate, ...) of the given model, or other version of the same model from a different paper in the literature. If no associated_literature_models are known, an error is raised.

julia> m = literature_model(arxiv_id = "1507.05954", equation = "A.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base -- U(1)xU(1) Weierstrass model based on arXiv paper 1507.05954 Eq. (A.1)
-
-julia> associated_literature_models(m)
-1-element Vector{String}:
- "1507_05954-1"
source
generating_sectionsMethod
generating_sections(m::AbstractFTheoryModel)

Return a list of the known Mordell–Weil generating sections of the given model. If no generating sections are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> generating_sections(m)
-1-element Vector{Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- [0, 0, 1]
source
journal_doiMethod
journal_doi(m::AbstractFTheoryModel)

Return the journal_doi of the publication that introduced the given model. If no journal_doi is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_doi(m)
-"10.1016/j.nuclphysb.2011.12.013"
source
journal_linkMethod
journal_link(m::AbstractFTheoryModel)

Return the journal_link (formatted as string) to the published version of the paper that introduced the given model. If no journal_link is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_link(m)
-"https://www.sciencedirect.com/science/article/pii/S0550321311007115"
source
journal_model_equation_numberMethod
journal_model_equation_number(m::AbstractFTheoryModel)

Return the journal_model_equation_number in which the given model was introduced in the published paper in our record. If no journal_model_equation_number is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_model_equation_number(m)
-"3.1"
source
journal_model_pageMethod
journal_model_page(m::AbstractFTheoryModel)

Return the journal_model_page on which the given model was introduced in the published paper in our record. If no journal_model_page is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_model_page(m)
-"9"
source
journal_model_sectionMethod
journal_model_section(m::AbstractFTheoryModel)

Return the journal_model_section in which the given model was introduced in the published paper in our record. If no journal_model_section is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_model_section(m)
-"3"
source
journal_pagesMethod
journal_pages(m::AbstractFTheoryModel)

Return the journal_pages of the published paper in which the given model was introduced. If no journal_pages are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_pages(m)
-"1–47"
source
journal_report_numbersMethod
journal_report_numbers(m::AbstractFTheoryModel)

Return the journal_report_numbers of the published paper in which the given model was introduced. If no journal_report_numbers is known, an error is raised.

julia> m = literature_model(arxiv_id = "1507.05954", equation = "A.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base -- U(1)xU(1) Weierstrass model based on arXiv paper 1507.05954 Eq. (A.1)
-
-julia> journal_report_numbers(m)
-3-element Vector{String}:
- "UPR-1274-T"
- "CERN-PH-TH-2015-157"
- "MIT-CTP-4678"
source
journal_volumeMethod
journal_volume(m::AbstractFTheoryModel)

Return the journal_volume of the published paper in which the given model was introduced. If no journal_volume are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_volume(m)
-"858"
source
journal_yearMethod
journal_year(m::AbstractFTheoryModel)

Return the journal_year of the published paper in which the given model was introduced. If no journal_year is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> journal_year(m)
-"2012"
source
literature_identifierMethod
literature_identifier(m::AbstractFTheoryModel)

Return the literature_identifier of the given mode, which is a unique string that distinguishes the model from all others in the literature model database. If no literature_identifier is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> literature_identifier(m)
-"1109_3454"
source
model_descriptionMethod
model_description(m::AbstractFTheoryModel)

Return the model_description of the given model. If no model_description is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> model_description(m)
-"SU(5)xU(1) restricted Tate model"
source
model_parametersMethod
model_parameters(m::AbstractFTheoryModel)

Return the model_parameters of the given model. If no model_parameters are known, an error is raised.

julia> m = literature_model(arxiv_id = "1212.2949", equation = "3.2", model_parameters = Dict("k" => 5))
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(2k+1) Tate model with parameter values (k = 5) based on arXiv paper 1212.2949 Eq. (3.2)
-
-julia> model_parameters(m)
-Dict{String, Int64} with 1 entry:
-  "k" => 5
source
paper_authorsMethod
paper_authors(m::AbstractFTheoryModel)

Return the paper_authors of the paper that introduced the given model. If no paper_authors are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> paper_authors(m)
-3-element Vector{String}:
- "Sven Krause"
- "Christoph Mayrhofer"
- "Timo Weigand"
source
paper_buzzwordsMethod
paper_buzzwords(m::AbstractFTheoryModel)

Return the paper_buzzwords of the paper that introduced the given model. If no paper_buzzwords are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> paper_buzzwords(m)
-4-element Vector{String}:
- "GUT model"
- "Tate"
- "U(1)"
- "SU(5)"
source
paper_descriptionMethod
paper_description(m::AbstractFTheoryModel)

Return the paper_description of the paper that introduced the given model. If no paper_description is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> paper_description(m)
-"SU(5)xU(1) restricted Tate model"
source
paper_titleMethod
paper_title(m::AbstractFTheoryModel)

Return the paper_title of the arXiv preprint that introduced the given model. If no paper_title is known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> paper_title(m)
-"\$G_4\$ flux, chiral matter and singularity resolution in F-theory compactifications"
source
related_literature_modelsMethod
related_literature_models(m::AbstractFTheoryModel)

Return a list of the unique identifiers of any related_literature_models of the given model. These are models that are introduced in the same paper as the given model, but that are distinct from the given model. If no related_literature_models are known, an error is raised.

julia> m = literature_model(arxiv_id = "1212.2949", equation = "3.2", model_parameters = Dict("k" => 5))
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(2k+1) Tate model with parameter values (k = 5) based on arXiv paper 1212.2949 Eq. (3.2)
-
-julia> related_literature_models(m)
-6-element Vector{String}:
- "1212_2949-2"
- "1212_2949-3"
- "1212_2949-4"
- "1212_2949-5"
- "1212_2949-6"
- "1212_2949-7"
source
resolutionsMethod
resolutions(m::AbstractFTheoryModel)

Return the list of all known resolutions for the given model. If no resolutions are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> resolutions(m)
-1-element Vector{Vector{Vector}}:
- [[["x", "y", "w"], ["y", "e1"], ["x", "e4"], ["y", "e2"], ["x", "y"]], ["e1", "e4", "e2", "e3", "s"]]
source
resolution_generating_sectionsMethod
resolution_generating_sections(m::AbstractFTheoryModel)

Return a list of lists of known Mordell–Weil generating sections for the given model after each known resolution. Each element of the outer list corresponds to a known resolution (in the same order), and each element of the list associated to a given resolution corresponds to a known generating section (in the same order). If no resolution generating sections are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> resolution_generating_sections(m)
-1-element Vector{Vector{Vector{Vector{String}}}}:
- [[["0", "0", "1"], ["0", "0", "1"], ["0", "1"], ["0", "1"], ["0", "1"], ["a32", "-a43"]]]
source
resolution_zero_sectionsMethod
resolution_zero_sections(m::AbstractFTheoryModel)

Return a list of known Mordell–Weil zero sections for the given model after each known resolution. Each element of the list corresponds to a known resolution (in the same order). If no resolution zero sections are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> resolution_zero_sections(m)
-1-element Vector{Vector{Vector{String}}}:
- [["1", "1", "0"], ["1", "1", "w"], ["1", "1"], ["1", "1"], ["1", "1"], ["1", "1"]]
source
weighted_resolutionsMethod
weighted_resolutions(m::AbstractFTheoryModel)

Return the list of all known weighted resolutions for the given model. If no weighted resolutions are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> weighted_resolutions(m)
-1-element Vector{Vector{Vector}}:
- [Vector{Vector{Any}}[[["x", "y", "w"], [1, 1, 1]], [["x", "y", "w"], [1, 2, 1]], [["x", "y", "w"], [2, 2, 1]], [["x", "y", "w"], [2, 3, 1]], [["x", "y"], [1, 1]]], ["e1", "e4", "e2", "e3", "s"]]
source
weighted_resolution_generating_sectionsMethod
weighted_resolution_generating_sections(m::AbstractFTheoryModel)

Return a list of lists of known Mordell–Weil generating sections for the given model after each known weighted resolution. Each element of the outer list corresponds to a known weighted resolution (in the same order), and each element of the list associated to a given weighted resolution corresponds to a known generating section (in the same order). If no weighted resolution generating sections are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> weighted_resolution_generating_sections(m)
-1-element Vector{Vector{Vector{Vector{String}}}}:
- [[["0", "0", "1"], ["0", "0", "1"], ["0", "0", "1"], ["0", "0", "1"], ["0", "0", "1"], ["a32", "-a43"]]]
source
weighted_resolution_zero_sectionsMethod
weighted_resolution_zero_sections(m::AbstractFTheoryModel)

Return a list of known Mordell–Weil zero sections for the given model after each known weighted resolution. Each element of the list corresponds to a known weighted resolution (in the same order). If no weighted resolution zero sections are known, an error is raised.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> weighted_resolution_zero_sections(m)
-1-element Vector{Vector{Vector{String}}}:
- [["1", "1", "0"], ["1", "1", "w"], ["1", "1", "w"], ["1", "1", "w"], ["1", "1", "w"], ["1", "1"]]
source

One can add this information for a model that does not have it:

set_descriptionMethod
set_description(m::AbstractFTheoryModel, description::String)

Set a description for a model.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> set_description(m, "An SU(5)xU(1) GUT-model")
-
-julia> m
-Global Tate model over a not fully specified base -- An SU(5)xU(1) GUT-model based on arXiv paper 1109.3454 Eq. (3.1)
source

Note however, that these changes will (currently) not be stored in our data base. One can also check if a model has a particular set of information. This is achieved with the following methods:

  • has_arxiv_id(m::AbstractFTheoryModel),
  • has_arxiv_doi(m::AbstractFTheoryModel),
  • has_arxiv_link(m::AbstractFTheoryModel),
  • has_arxiv_model_equation_number(m::AbstractFTheoryModel),
  • has_arxiv_model_page(m::AbstractFTheoryModel),
  • has_arxiv_model_section(m::AbstractFTheoryModel),
  • has_arxiv_version(m::AbstractFTheoryModel),
  • has_associated_literature_models(m::AbstractFTheoryModel),
  • has_generating_sections(m::AbstractFTheoryModel),
  • has_journal_doi(m::AbstractFTheoryModel),
  • has_journal_link(m::AbstractFTheoryModel),
  • has_journal_model_equation_number(m::AbstractFTheoryModel),
  • has_journal_model_page(m::AbstractFTheoryModel),
  • has_journal_model_section(m::AbstractFTheoryModel),
  • has_journal_pages(m::AbstractFTheoryModel),
  • has_journal_report_numbers(m::AbstractFTheoryModel),
  • has_journal_volume(m::AbstractFTheoryModel),
  • has_journal_year(m::AbstractFTheoryModel),
  • has_literature_identifier(m::AbstractFTheoryModel),
  • has_model_description(m::AbstractFTheoryModel),
  • has_model_parameters(m::AbstractFTheoryModel),
  • has_paper_authors(m::AbstractFTheoryModel),
  • has_paper_buzzwords(m::AbstractFTheoryModel),
  • has_paper_description(m::AbstractFTheoryModel),
  • has_paper_title(m::AbstractFTheoryModel),
  • has_related_literature_models(m::AbstractFTheoryModel),
  • has_resolutions(m::AbstractFTheoryModel),
  • has_resolution_generating_sections(m::AbstractFTheoryModel),
  • has_resolution_zero_sections(m::AbstractFTheoryModel),
  • has_weighted_resolutions(m::AbstractFTheoryModel),
  • has_weighted_resolution_generating_sections(m::AbstractFTheoryModel),
  • has_weighted_resolution_zero_sections(m::AbstractFTheoryModel),
  • has_zero_section(m::AbstractFTheoryModel).

Methods

Resolution(s) of a singular model

A central task in F-theory is to resolve a singular model. For literature models, we have stored resolutions in our data base. Upon construction of a literature model, we load these known resolutions.

In addition to listing the known resolutions with resolutions(m::AbstractFTheoryModel), the user might want to add a resolution. This can be achieved with the following method:

add_resolutionMethod
add_resolution(m::AbstractFTheoryModel, centers::Vector{Vector{String}}, exceptionals::Vector{String})

Add a known resolution for a model.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> add_resolution(m, [["x", "y"], ["y", "s", "w"], ["s", "e4"], ["s", "e3"], ["s", "e1"]], ["s", "w", "e3", "e1", "e2"])
-
-julia> length(resolutions(m))
-2
source

Provided that a resolution for a model is known, we can (attempt to) resolve the model.

resolveMethod
resolve(m::AbstractFTheoryModel, index::Int)

Resolve a model with the index-th resolution that is known.

Careful: Currently, this assumes that all blowups are toric blowups. We hope to remove this requirement in the near future.

julia> m = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> v = resolve(m, 1)
-Scheme of a toric variety
-
-julia> cox_ring(v)
-Multivariate polynomial ring in 13 variables over QQ graded by 
-  a1 -> [1 0 0 0 0 0 0 0]
-  a21 -> [0 1 0 0 0 0 0 0]
-  a32 -> [-1 2 0 0 0 0 0 0]
-  a43 -> [-2 3 0 0 0 0 0 0]
-  w -> [0 0 1 0 0 0 0 0]
-  x -> [0 0 0 1 0 0 0 0]
-  y -> [0 0 0 0 1 0 0 0]
-  z -> [0 0 0 0 0 1 0 0]
-  e1 -> [0 0 0 0 0 0 1 0]
-  e4 -> [0 0 0 0 0 0 0 1]
-  e2 -> [1 -1 -1 -1 1 -1 -1 0]
-  e3 -> [1 0 0 1 -1 1 0 -1]
-  s -> [-2 2 2 -1 0 2 1 1]
source
diff --git a/previews/PR2578/Experimental/FTheoryTools/tate/index.html b/previews/PR2578/Experimental/FTheoryTools/tate/index.html deleted file mode 100644 index 05af720dbbda..000000000000 --- a/previews/PR2578/Experimental/FTheoryTools/tate/index.html +++ /dev/null @@ -1,159 +0,0 @@ - -Global Tate models · Oscar.jl

Global Tate models

Introduction

A global Tate model describes a particular form of an elliptic fibration. We focus on an elliptic fibration over a base $B$. Consider the weighted projective space $\mathbb{P}^{2,3,1}$ with coordinates $x, y, z$. In addition, consider

  • $a_1 \in H^0( B_3, \overline{K}_{B} )$,
  • $a_2 \in H^0( B_3, \overline{K}_{B}^{\otimes 2} )$,
  • $a_3 \in H^0( B_3, \overline{K}_{B}^{\otimes 3} )$,
  • $a_4 \in H^0( B_3, \overline{K}_{B}^{\otimes 4} )$,
  • $a_6 \in H^0( B_3, \overline{K}_{B}^{\otimes 6} )$.

Then form a $\mathbb{P}^{2,3,1}$-bundle over $B$ such that

  • $x$ transforms as a section of $2 \overline{K}_{B}$,
  • $y$ transforms as a section of $3 \overline{K}_{B}$,
  • $z$ transforms as a section of $0 \overline{K}_{B} = \mathcal{O}_{B}$.

In this 5-fold ambient space, a global Tate model is the hypersurface defined by the vanishing of the Tate polynomial $P_T = x^3 - y^2 - x y z a_1 + x^2 z^2 a_2 - y z^3 a_3 + x z^4 a_4 + z^6 a_6$.

Crucially, for non-trivial F-theory settings, the elliptic fibration in question must be singular. In fact, by construction, one usually engineers certain singularities. For this, vanishing orders of the sections $a_i$ above need to specified. The following table–-often referred to as the Tate table and taken from Timo Weigand (2010)–-summarizes the singularities introduced by certain vanishing orders:

sing. type$\mathrm{ord}(\Delta)$singularitygroup $G$$a_1$$a_2$$a_3$$a_4$$a_6$
$I_0$$0$$0$$0$$0$$0$$0$
$I_1$$1$$0$$0$$1$$1$$1$
$I_2$$2$$A_1$$SU(2)$$0$$0$$1$$1$$2$
$I_{2k}^{ns}$$2k$$C_k$$Sp(k)$$0$$0$$k$$k$$2k$
$I_{2k}^s$$2k$$A_{2k-1}$$SU(2k)$$0$$1$$k$$k$$2k$
$I_{2k+1}^{ns}$$2k+1$$Sp(k)$$0$$0$$k+1$$k+1$$2k+1$
$I_{2k+1}^{s}$$2k+1$$A_{2k}$$SU(2k+1)$$0$$1$$k$$k+1$$2k+1$
$II$$2$$1$$1$$1$$1$$1$
$III$$3$$A_1$$SU(2)$$1$$1$$1$$1$$2$
$IV^{ns}$$4$$Sp(1)$$1$$1$$1$$2$$2$
$IV^s$$4$$A_2$$SU(3)$$1$$1$$1$$2$$3$
$I_0^{*ns}$$6$$G_2$$G_2$$1$$1$$2$$2$$3$
$I_0^{*ss}$$6$$B_3$$SO(7)$$1$$1$$2$$2$$4$
$I_0^{*s}$$6$$D_4$$SO(8)$$1$$1$$2$$2$$4$
$I_1^{*ns}$$7$$B_4$$SO(9)$$1$$1$$2$$3$$4$
$I_1^{*s}$$7$$D_5$$SO(10)$$1$$1$$2$$3$$5$
$I_2^{*ns}$$8$$B_5$$SO(11)$$1$$1$$3$$3$$5$
$I_2^{*s}$$8$$D_6$$SO(12)$$1$$1$$3$$3$$5$
$I_{2k-3}^{*ns}$$2k+3$$B_{2k}$$SO(4k+1)$$1$$1$$k$$k+1$$2k$
$I_{2k-3}^{*s}$$2k+3$$D_{2k+1}$$SO(4k+2)$$1$$1$$k$$k+1$$2k+1$
$I_{2k-2}^{*ns}$$2k+4$$B_{2k+1}$$SO(4k+3)$$1$$1$$k+1$$k+1$$2k+1$
$I_{2k-2}^{*s}$$2k+4$$D_{2k+2}$$SO(4k+4)$$1$$1$$k+1$$k+1$$2k+1$
$IV^{*ns}$$8$$F_4$$F_4$$1$$2$$2$$3$$4$
$IV^{*s}$$8$$E_6$$E_6$$1$$2$$2$$3$$5$
$III^*$$9$$E_7$$E_7$$1$$2$$3$$3$$5$
$II^*$$10$$E_8$$E_8$$1$$2$$3$$4$$5$
non-min.$12$$1$$2$$3$$4$$6$

Constructors

We aim to provide support for global Tate models over the following bases:

  • a toric variety,
  • a toric scheme,
  • a (covered) scheme.

Often, one also wishes to obtain information about a global Tate model without explicitly specifying the base space. Also for this application, we provide support. Finally, we provide support for some standard constructions.

Before we detail these constructors, we must comment on the constructors over toric base spaces. Namely, in order to construct a global Tate model as a hypersurface in an ambient space, we first wish to construct the ambient space in question. For a toric base, one way to achieve this is to first focus on the Cox ring of the toric ambient space. This ring must be graded such that the Tate polynomial is homogeneous and cuts out a Calabi-Yau hypersurface. Given this grading, one can perform a triangulation task. Typically, this combinatorial task is very demanding, consumes a lot of computational power and takes a long time to complete. Even more, it will yield a large, often huge, number of candidate ambient spaces of which the typical user will only pick one. For instance, a common and often appropriate choice is a toric ambient space which contains the toric base space in a manifest way.

To circumvent this very demanding computation, our toric constructors operate in the opposite direction. That is, they begin by extracting the rays and maximal cones of the chosen toric base space. Subsequently, those rays and cones are extended to form one of the many toric ambient spaces. This proves hugely superior in performance than going through the triangulation task of enumerating all possible toric ambient spaces. One downside of this strategy is that the so-constructed ambient space need not be smooth.

A toric variety as base space

We require that the provided toric base space is complete. This is a technical limitation as of now. The functionality of OSCAR only allows us to compute a section basis (or a finite subset thereof) for complete toric varieties. In the future, this could be extended.

However, completeness is an expensive check. Therefore, we provide an optional argument which one can use to disable this check if desired. To this end, one passes the optional argument completeness_check = false as last argument to the constructor. The following examples demonstrate this:

global_tate_modelMethod
global_tate_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)

This method constructs a global Tate model over a given toric base 3-fold. The Tate sections $a_i$ are taken with (pseudo) random coefficients.

Examples

julia> t = global_tate_model(sample_toric_variety(); completeness_check = false)
-Global Tate model over a concrete base
source
global_tate_modelMethod
global_tate_model(base::AbstractNormalToricVariety, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}

This method operates analogously to global_tate_model(base::AbstractNormalToricVariety). The only difference is that the Tate sections $a_i$ can be specified with non-generic values.

Examples

julia> base = sample_toric_variety()
-Normal toric variety
-
-julia> a1 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base))]);
-
-julia> a2 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^2)]);
-
-julia> a3 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^3)]);
-
-julia> a4 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^4)]);
-
-julia> a6 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^6)]);
-
-julia> t = global_tate_model(base, [a1, a2, a3, a4, a6]; completeness_check = false)
-Global Tate model over a concrete base
source

A toric scheme as base space

For the same reasons as above, the toric base must be complete. Similar to toric varieties as bases, we can use the optional argument completeness_check = false to switch off the expensive completeness check. The following examples demonstrate this:

global_tate_modelMethod
global_tate_model(base::ToricCoveredScheme; completeness_check::Bool = true)

This method constructs a global Tate model over a given toric scheme base 3-fold. The Tate sections $a_i$ are taken with (pseudo) random coefficients.

Examples

julia> t = global_tate_model(sample_toric_scheme(); completeness_check = false)
-Global Tate model over a concrete base
source
global_tate_modelMethod
global_tate_model(base::ToricCoveredScheme, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}

This method operates analogously to global_tate_model(base::ToricCoveredScheme). The only difference is that the Tate sections $a_i$ can be specified with non-generic values.

Examples

julia> base = sample_toric_scheme()
-Scheme of a toric variety
-
-julia> a1 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base)))]);
-
-julia> a2 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^2)]);
-
-julia> a3 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^3)]);
-
-julia> a4 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^4)]);
-
-julia> a6 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^6)]);
-
-julia> t = global_tate_model(base, [a1, a2, a3, a4, a6]; completeness_check = false)
-Global Tate model over a concrete base
source

A (covered) scheme as base space

This functionality does not yet exist.

Base space not specified

This method constructs a global Tate model over a base space, where this base space is not (fully) specified. Consequently, we simply assume that a base space exists such that the Tate sections $a_i$ as introduced above do exist.

For many practical applications, one wishes to assume a further factorization of the Tate sections $a_i$. This has the advantage that one can engineer singularity loci or even the singularity type over a specific locus. This is the backbone of many F-theory constructions. For example, we could consider the factorization:

  • $a_1 = a_{10} w^0$,
  • $a_2 = a_{21} w^1$,
  • $a_3 = a_{32} w^2$,
  • $a_4 = a_{43} w^3$,
  • $a_6 = a_{65} w^5$,

In this case, it is useful to consider the polynomial ring with indeterminates $a_{10}$, $a_{21}$, $a_{32}$, $a_{43}$, $a_{65}$ and $w$. In theory, one can consider these indeterminates as local coordinate of an auxiliary base space. Indeed, for our computer implementation the polynomial ring with these indeterminates serve as the coordinate ring of an auxiliary toric base space. Despite this auxiliary base space being toric, the predictions from such an analysis are not limited to the world of toric varieties.

For constructions along these lines, we support the following constructor:

global_tate_modelMethod
global_tate_model(auxiliary_base_ring::MPolyRing, auxiliary_base_grading::Matrix{Int64}, d::Int, ais::Vector{T}) where {T<:MPolyRingElem}

This method constructs a global Tate model over a base space that is not fully specified.

Note that many studies in the literature use the class of the anticanonical bundle in their analysis. We anticipate this by adding this class as a variable of the auxiliary base space, unless the user already provides this grading. Our convention is that the first grading refers to Kbar and that the homogeneous variable corresponding to this class carries the name "Kbar".

The following example exemplifies this approach.

Examples

julia> auxiliary_base_ring, (a10, a21, a32, a43, a65, w) = QQ["a10", "a21", "a32", "a43", "a65", "w"];
-
-julia> auxiliary_base_grading = [1 2 3 4 6 0; 0 -1 -2 -3 -5 1]
-2×6 Matrix{Int64}:
- 1   2   3   4   6  0
- 0  -1  -2  -3  -5  1
-
-julia> a1 = a10;
-
-julia> a2 = a21 * w;
-
-julia> a3 = a32 * w^2;
-
-julia> a4 = a43 * w^3;
-
-julia> a6 = a65 * w^5;
-
-julia> ais = [a1, a2, a3, a4, a6];
-
-julia> t = global_tate_model(auxiliary_base_ring, auxiliary_base_grading, 3, ais)
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base
source

Standard constructions

We provide convenient constructions of global Tate models over standard base spaces. Currently, we support the following:

global_tate_model_over_projective_spaceMethod
global_tate_model_over_projective_space(d::Int)

This method constructs a global Tate model over the projective space.

Examples

julia> global_tate_model_over_projective_space(3)
-Global Tate model over a concrete base
source
global_tate_model_over_hirzebruch_surfaceMethod
global_tate_model_over_hirzebruch_surface(r::Int)

This method constructs a global Tate model over a Hirzebruch surface.

Examples

julia> global_tate_model_over_hirzebruch_surface(1)
-Global Tate model over a concrete base
source
global_tate_model_over_del_pezzo_surfaceMethod
global_tate_model_over_del_pezzo_surface(b::Int)

This method constructs a global Tate model over a del-Pezzo surface.

Examples

julia> global_tate_model_over_del_pezzo_surface(3)
-Global Tate model over a concrete base
source

Attributes

Basic attributes

For all global Tate models – irrespective over whether the base is toric or not – we support the following attributes:

tate_section_a1Method
tate_section_a1(t::GlobalTateModel)

Return the Tate section $a_1$.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> tate_section_a1(t)
-a1
source
tate_section_a2Method
tate_section_a2(t::GlobalTateModel)

Return the Tate section $a_2$.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> tate_section_a2(t)
-a21*w
source
tate_section_a3Method
tate_section_a3(t::GlobalTateModel)

Return the Tate section $a_3$.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> tate_section_a3(t)
-a32*w^2
source
tate_section_a4Method
tate_section_a4(t::GlobalTateModel)

Return the Tate section $a_4$.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> tate_section_a4(t)
-a43*w^3
source
tate_section_a6Method
tate_section_a6(t::GlobalTateModel)

Return the Tate section $a_6$.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> tate_section_a6(t)
-0
source
tate_polynomialMethod
tate_polynomial(t::GlobalTateModel)

Return the Tate polynomial of the global Tate model.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> tate_polynomial(t)
--a1*x*y*z + a21*w*x^2*z^2 - a32*w^2*y*z^3 + a43*w^3*x*z^4 + x^3 - y^2
source

In case the global Tate model is constructed over a not fully specified base, recall that we construct an auxiliary (toric) base space as well as an auxiliary (toric) ambient space. The (auxiliary) base and ambient space can be accessed with the following functions:

base_spaceMethod
base_space(t::GlobalTateModel)

Return the base space of the global Tate model.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> base_space(t)
-Scheme of a toric variety
source
ambient_spaceMethod
ambient_space(t::GlobalTateModel)

Return the ambient space of the global Tate model.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> ambient_space(t)
-Scheme of a toric variety
source
fiber_ambient_spaceMethod
fiber_ambient_space(t::GlobalTateModel)

Return the fiber ambient space of the global Tate model.

julia> t = su5_tate_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base
-
-julia> fiber_ambient_space(t)
-Scheme of a toric variety
source

The following method allows to tell if the base/ambient space is auxiliary or not:

base_fully_specifiedMethod
base_fully_specified(t::GlobalTateModel)

Return true if the Tate model has a concrete base space and false otherwise.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> base_fully_specified(t)
-false
source

The user can decide to get an information whenever an auxiliary base space, auxiliary ambient space or auxiliary hypersurface have been computed. To this end, one invokes set_verbosity_level(:GlobalTateModel, 1). More background information is available here.

Advanced attributes

The following attributes are currently only supported in a toric setting:

calabi_yau_hypersurfaceMethod
calabi_yau_hypersurface(t::GlobalTateModel)

Return the Calabi-Yau hypersurface in the toric ambient space which defines the global Tate model.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> calabi_yau_hypersurface(t)
-Closed subvariety of a normal toric variety
source
weierstrass_modelMethod
weierstrass_model(t::GlobalTateModel)

Return the Weierstrass model which is equivalent to the given Tate model.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> weierstrass_model(t)
-Weierstrass model over a not fully specified base
source

Note that for applications in F-theory, singular elliptic fibrations are key (cf. Timo Weigand (2018) and references therein). Consequently the discriminant locus as well as the singular loci of the fibration in question are of ample importance:

discriminantMethod
discriminant(t::GlobalTateModel)

Return the discriminant of the global Tate model.

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> discriminant(t);
source
singular_lociMethod
singular_loci(t::GlobalTateModel)

Return the singular loci of the global Tate model, along with the order of vanishing of $(f, g, \Delta)$` at each locus and the refined Tate fiber type.

For the time being, we either explicitly or implicitly focus on toric varieties as base spaces. Explicitly, in case the user provides such a variety as base space, and implicitly, in case we work over a non-fully specified base. This has the advantage that we can "filter out" trivial singular loci.

Specifically, recall that every closed subvariety of a simplicial toric variety is of the form $V(I)$, where $I$ is a homogeneous ideal of the Cox ring. Let $B$ be the irrelevant ideal of this toric variety. Then, by proposition 5.2.6. of David A. Cox, John B. Little, Henry K. Schenck (2011), $V(I)$ is trivial/empty iff $B^l \subseteq I$ for a suitable $l \geq 0$. This can be checked by checking if the saturation $I:B^\infty$ is the ideal generated by $1$.

By treating a non-fully specified base space implicitly as a toric space, we can extend this result straightforwardly to this situation also. This is the reason for constructing this auxiliary base space.

Let us demonstrate the functionality by computing the singular loci of a Type $III$ Tate model Sheldon Katz, David R. Morrison, Sakura Schafer-Nameki, James Sully (2011). In this case, we will consider Global Tate model over a non-fully specified base. The Tate sections are factored as follows:

  • $a_1 = a_{11} w^1$,
  • $a_2 = a_{21} w^1$,
  • $a_3 = a_{31} w^1$,
  • $a_4 = a_{41} w^1$,
  • $a_6 = a_{62} w^2$.

For this factorization, we expect a singularity of Kodaira type $III$ over the divisor $W = {w = 0}$, as desired. So this should be one irreducible component of the discriminant. Moreover, we should find that the discriminant vanishes to order 3 on $W = {w = 0}$, while the Weierstrass sections $f$ and $g$ vanish to orders 1 and 2, respectively. Let us verify this.

julia> auxiliary_base_ring, (a11, a21, a31, a41, a62, w) = QQ["a10", "a21", "a32", "a43", "a65", "w"];
-
-julia> auxiliary_base_grading = [1 2 3 4 6 0; -1 -1 -1 -1 -2 1];
-
-julia> a1 = a11 * w;
-
-julia> a2 = a21 * w;
-
-julia> a3 = a31 * w;
-
-julia> a4 = a41 * w;
-
-julia> a6 = a62 * w^2;
-
-julia> ais = [a1, a2, a3, a4, a6];
-
-julia> t = global_tate_model(auxiliary_base_ring, auxiliary_base_grading, 3, ais)
-Assuming that the first row of the given grading is the grading under Kbar
-
-Global Tate model over a not fully specified base
-
-julia> length(singular_loci(t))
-2
-
-julia> singular_loci(t)[2]
-(ideal(w), (1, 2, 3), "III")
source

Methods

Fiber study

In F-theory, it is standard to not work with the singular space directly. Rather, one resolves its singularities in order to obtain a smooth space instead. Subsequently, one performs computations on this smooth space.

In order to perform such a resolution, one wishes to analyze the fibration in detail. The following method aims at giving a first window into this analysis by working out the fiber components and their intersection pattern over a particular locus of the base.

analyze_fibersMethod
analyze_fibers(model::GlobalTateModel, centers::Vector{<:Vector{<:Integer}})

Determine the fiber of a (singular) global Tate model over a particular base locus. ```

source
diff --git a/previews/PR2578/Experimental/FTheoryTools/weierstrass/index.html b/previews/PR2578/Experimental/FTheoryTools/weierstrass/index.html deleted file mode 100644 index 7d75569e1681..000000000000 --- a/previews/PR2578/Experimental/FTheoryTools/weierstrass/index.html +++ /dev/null @@ -1,86 +0,0 @@ - -Weierstrass models · Oscar.jl

Weierstrass models

A Weierstrass model describes a particular form of an elliptic fibration. We focus on an elliptic fibration over a complete base $B$. Consider the weighted projective space $\mathbb{P}^{2,3,1}$ with coordinates $x, y, z$. In addition, consider

  • $f \in H^0( B, \overline{K}_{B}^{\otimes 4} )$,
  • $g \in H^0( B, \overline{K}_{B}^{\otimes 6} )$,

Then form a $\mathbb{P}^{2,3,1}$-bundle over $B$ such that

  • $x$ transforms as a section of $2 \overline{K}_{B}$,
  • $y$ transforms as a section of $3 \overline{K}_{B}$,
  • $z$ transforms as a section of $0 \overline{K}_{B} = \mathcal{O}_{B}$.

In this 5-fold ambient space, a Weierstrass model is the hypersurface defined by the vanishing of the Weierstrass polynomial $P_W = x^3 - y^2 + f x z^4 + g z^6$.

Crucially, for non-trivial F-theory settings, the elliptic fibration in question must be singular. In fact, by construction, one usually engineers certain singularities. This can be read-off from the Weierstrass table, which we have reproduced from Timo Weigand (2018) with small corrections:

type$\mathrm{ord}(f)$$\mathrm{ord}(g)$$\mathrm{ord}(\Delta)$sing.monodromy coveralgebra $\mathfrak{g}$comp.
$I_0$$\geq 0$$\geq 0$0
$I_1$$0$$0$$1$
$II$$\geq 1$$1$$2$
$III$$1$$\geq 2$$3$$A_1$$\mathfrak{su}(2)$
$IV^{ns}$$\geq 2$$2$$4$$A_2$$\left. \psi^2 - \frac{g}{w^2} \right|_{w = 0}$$\mathfrak{sp}(1)$$1$
$IV^{s}$$\geq 2$$2$$4$$A_2$$\left. \psi^2 - \frac{g}{w^2} \right|_{w = 0}$$\mathfrak{su}(3)$$2$
$I_m^{ns}$$0$$0$$m$$A_{m - 1}$$\left. \psi^2 + \frac{9g}{2f} \right|_{w = 0}$$\mathfrak{sp}(\lfloor \frac{m}{2} \rfloor])$$1$
$I_m^{s}$$0$$0$$m$$A_{m - 1}$$\left. \psi^2 + \frac{9g}{2f} \right|_{w = 0}$$\mathfrak{su}(m)$$2$
$I_0^{*ns}$$\geq 2$$\geq 3$$6$$D_4$$\left. \psi^3 + \psi \cdot \frac{f}{w^2} + \frac{g}{w^3} \right|_{w = 0}$$\mathfrak{g}_2$$1$
$I_0^{*ss}$$\geq 2$$\geq 3$$6$$D_4$$\left. \psi^3 + \psi \cdot \frac{f}{w^2} + \frac{g}{w^3} \right|_{w = 0}$$\mathfrak{so}(7)$$2$
$I_0^{*s}$$\geq 2$$\geq 3$$6$$D_4$$\left. \psi^3 + \psi \cdot \frac{f}{w^2} + \frac{g}{w^3} \right|_{w = 0}$$\mathfrak{so}(8)$$3$
$I_{2n-5}^{*ns}$ ($n \geq 3$)$2$$3$$2n+1$$D_{2n-1}$$\left. \psi^2 + \frac{1}{4} \left( \frac{\Delta}{w^{2n+1}} \right) \left( \frac{2wf}{9g} \right)^3 \right|_{w = 0}$$\mathfrak{so}(4n-3)$$1$
$I_{2n-5}^{*s}$ ($n \geq 3$)$2$$3$$2n+1$$D_{2n-1}$$\left. \psi^2 + \frac{1}{4} \left( \frac{\Delta}{w^{2n+1}} \right) \left( \frac{2wf}{9g} \right)^3 \right|_{w = 0}$$\mathfrak{so}(4n-2)$$2$
$I_{2n-4}^{*ns}$ ($n \geq 3$)$2$$3$$2n+2$$D_{2n}$$\left. \psi^2 + \left( \frac{\Delta}{w^{2n+2}} \right) \left( \frac{2wf}{9g} \right)^2 \right|_{w = 0}$$\mathfrak{so}(4n-1)$$1$
$I_{2n-4}^{*s}$ ($n \geq 3$)$2$$3$$2n+2$$D_{2n}$$\left. \psi^2 + \left( \frac{\Delta}{w^{2n+2}} \right) \left( \frac{2wf}{9g} \right)^2 \right|_{w = 0}$$\mathfrak{so}(4n)$$2$
$IV^{*ns}$$\geq 3$$4$$8$$E_6$$\left. \psi^2 - \frac{g}{w^4} \right|_{w = 0}$$\mathfrak{f}_4$$1$
$IV^{*s}$$\geq 3$$4$$8$$E_6$$\left. \psi^2 - \frac{g}{w^4} \right|_{w = 0}$$\mathfrak{e}_6$$2$
$III^*$$3$$\geq 5$$9$$E_7$$\mathfrak{e}_7$
$II^*$$\geq 4$$5$$10$$E_8$$\mathfrak{e}_8$
non-min.$\geq 4$$\geq 6$$\geq 12$non-can.

Constructors

We aim to provide support for Weierstrass models over the following bases:

  • a toric variety,
  • a toric scheme,
  • a (covered) scheme.

Often, one also wishes to obtain information about a Weierstrass model without explicitly specifying the base space. Also for this application, we provide support. Finally, we provide support for some standard constructions.

Before we detail these constructors, we must comment on the constructors over toric base spaces. Namely, in order to construct a Weierstrass model as a hypersurface in an ambient space, we first wish to construct the ambient space in question. For a toric base, one way to achieve this is to first focus on the Cox ring of the toric ambient space. This ring must be graded such that the Weierstrass polynomial is homogeneous and cuts out a Calabi-Yau hypersurface. Given this grading, one can perform a triangulation task. Typically, this combinatorial task is very demanding, consumes a lot of computational power and takes a long time to complete. Even more, it will yield a large, often huge, number of candidate ambient spaces of which the typical user will only pick one. For instance, a common and often appropriate choice is a toric ambient space which contains the toric base space in a manifest way.

To circumvent this very demanding computation, our toric constructors operate in the opposite direction. That is, they begin by extracting the rays and maximal cones of the chosen toric base space. Subsequently, those rays and cones are extended to form one of the many toric ambient spaces. This proves hugely superior in performance than going through the triangulation task of enumerating all possible toric ambient spaces. One downside of this strategy is that the so-constructed ambient space need not be smooth.

A toric variety as base space

We require that the provided toric base space is complete. This is a technical limitation as of now. The functionality of OSCAR only allows us to compute a section basis (or a finite subset thereof) for complete toric varieties. In the future, this could be extended.

However, completeness is an expensive check. Therefore, we provide an optional argument which one can use to disable this check if desired. To this end, one passes the optional argument completeness_check = false as last argument to the constructor. The following examples demonstrate this:

weierstrass_modelMethod
weierstrass_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)

This method constructs a Weierstrass model over a given toric base 3-fold. The Weierstrass sections $f$ and $g$ are taken with (pseudo)random coefficients.

Examples

julia> w = weierstrass_model(sample_toric_variety(); completeness_check = false)
-Weierstrass model over a concrete base
source
weierstrass_modelMethod
weierstrass_model(base::AbstractNormalToricVariety, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)

This method operates analogously to weierstrass_model(base::AbstractNormalToricVariety). The only difference is that the Weierstrass sections $f$ and $g$ can be specified with non-generic values.

Examples

julia> base = sample_toric_variety()
-Normal toric variety
-
-julia> f = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^4)]);
-
-julia> g = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^6)]);
-
-julia> w = weierstrass_model(base, f, g; completeness_check = false)
-Weierstrass model over a concrete base
source

A toric scheme as base space

For the same reasons as above, the toric base must be complete. Similar to toric varieties as bases, we can use the optional argument completeness_check = false to switch off the expensive completeness check. The following examples demonstrate this:

weierstrass_modelMethod
weierstrass_model(base::ToricCoveredScheme; completeness_check::Bool = true)

This method constructs a Weierstrass model over a given toric base 3-fold. The Weierstrass sections $f$ and $g$ are taken with (pseudo)random coefficients.

Examples

julia> w = weierstrass_model(sample_toric_scheme(); completeness_check = false)
-Weierstrass model over a concrete base
source
weierstrass_modelMethod
weierstrass_model(base::ToricCoveredScheme, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)

This method operates analogously to weierstrass_model(base::ToricCoveredScheme). The only difference is that the Weierstrass sections $f$ and $g$ can be specified with non-generic values.

Examples

julia> base = sample_toric_scheme()
-Scheme of a toric variety
-
-julia> f = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^4)]);
-
-julia> g = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^6)]);
-
-julia> w = weierstrass_model(base, f, g; completeness_check = false)
-Weierstrass model over a concrete base
source

A (covered) scheme as base space

This functionality does not yet exist.

Base space not specified

A Weierstrass model can also be constructed over a base space that is not fully specified. Rather, it assumes that a base space exists such that the Weierstrass sections $f$ and $g$ are well-defined, so that the Weierstrass model in question is well-defined.

For many practical applications, one wishes to assume a further specialize the Weierstrass sections $f$ and $g$. This has the advantage that one can engineer singularity loci or even the singularity type over a specific locus. To some extend, this is the backbone of many F-theory constructions. It is useful to consider a polynomial ring whose variables are the sections used in the desired factorization of the Weierstrass sections $f$ and $g$. In theory, one can consider the indeterminates of this polynomial ring as local coordinate of an auxiliary base space. Indeed, for our computer implementation the polynomial ring with these indeterminates serve as the coordinate ring of an auxiliary toric base space. Despite this auxiliary base space being toric, the predictions from such an analysis are not limited to the world of toric varieties.

For constructions along these lines, we support the following constructor:

weierstrass_modelMethod
weierstrass_model(auxiliary_base_ring::MPolyRing, auxiliary_base_grading::Matrix{Int64}, d::Int, weierstrass_f::MPolyRingElem, weierstrass_g::MPolyRingElem)

This method constructs a Weierstrass model over a base space that is not fully specified.

Note that many studies in the literature use the class of the anticanonical bundle in their analysis. We anticipate this by adding this class as a variable of the auxiliary base space, unless the user already provides this grading. Our convention is that the first grading refers to Kbar and that the homogeneous variable corresponding to this class carries the name "Kbar".

The following example illustrates this approach.

Examples

julia> auxiliary_base_ring, (f, g, Kbar, v) = QQ["f", "g", "Kbar", "u"]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])
-
-julia> auxiliary_base_grading = [4 6 1 0]
-1×4 Matrix{Int64}:
- 4  6  1  0
-
-julia> w = weierstrass_model(auxiliary_base_ring, auxiliary_base_grading, 3, f, g)
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
source

Standard constructions

We provide convenient constructions of Weierstrass models over famous base spaces. Currently, we support the following:

weierstrass_model_over_projective_spaceMethod
weierstrass_model_over_projective_space(d::Int)

This method constructs a Weierstrass model over the projective space.

Examples

julia> weierstrass_model_over_projective_space(3)
-Weierstrass model over a concrete base
source
weierstrass_model_over_hirzebruch_surfaceMethod
weierstrass_model_over_hirzebruch_surface(r::Int)

This method constructs a Weierstrass model over a Hirzebruch surface.

Examples

julia> weierstrass_model_over_hirzebruch_surface(1)
-Weierstrass model over a concrete base
source
weierstrass_model_over_del_pezzo_surfaceMethod
weierstrass_model_over_del_pezzo_surface(b::Int)

This method constructs a Weierstrass model over a del-Pezzo surface.

Examples

julia> weierstrass_model_over_del_pezzo_surface(3)
-Weierstrass model over a concrete base
source

Literature models

Certain Weierstrass models have been studied in the physics literature over and over again. Thereby, these constructions became famous and some were given special names. We aim to provide support for such standard constructions. Currently, we provide support for the following:

su5_weierstrass_model_over_arbitrary_3d_baseMethod
su5_weierstrass_model_over_arbitrary_3d_base()

Return the SU(5) Weierstrass model over an arbitrary 3-dimensional base space. For more details see e.g. Timo Weigand (2018) and references therein.

julia> tm = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
source

Attributes

Basic attributes

For all Weierstrass models – irrespective over whether the base is toric or not – we support the following attributes:

weierstrass_section_fMethod
weierstrass_section_f(w::WeierstrassModel)

Return the polynomial $f$ used for the construction of the Weierstrass model.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> weierstrass_section_f(w);
source
weierstrass_section_gMethod
weierstrass_section_g(w::WeierstrassModel)

Return the polynomial $g$ used for the construction of the Weierstrass model.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> weierstrass_section_g(w);
source
weierstrass_polynomialMethod
weierstrass_polynomial(w::WeierstrassModel)

Return the Weierstrass polynomial of the Weierstrass model.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> weierstrass_polynomial(w);
source

In case the Weierstrass model is constructed over a not fully specified base, recall that we construct an auxiliary (toric) base space as well as an auxiliary (toric) ambient space. The (auxiliary) base and ambient space can be accessed with the following functions:

base_spaceMethod
base_space(w::WeierstrassModel)

Return the base space of the Weierstrass model.

```jldoctest julia> w = su5weierstrassmodeloverarbitrary3dbase() Weierstrass model over a not fully specified base

julia> base_space(w) Scheme of a toric variety with fan spanned by RayVector{QQFieldElem}[[1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0]]

source
ambient_spaceMethod
ambient_space(w::WeierstrassModel)

Return the base space of the Weierstrass model.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> ambient_space(w)
-Scheme of a toric variety
source
fiber_ambient_spaceMethod
fiber_ambient_space(w::WeierstrassModel)

Return the fiber ambient space of the Weierstrass model.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> fiber_ambient_space(w)
-Scheme of a toric variety
source

The following method allows to tell if the base/ambient space is auxiliary or not:

base_fully_specifiedMethod
base_fully_specified(w::WeierstrassModel)

Return true is the Weierstrass model has a concrete base space and false otherwise.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> base_fully_specified(w)
-false
source

The user can decide to get an information whenever an auxiliary base space, auxiliary ambient space or auxiliary hypersurface have been computed. To this end, one invokes set_verbosity_level(:WeierstrassModel, 1). More background information is available here.

Advanced attributes

The following attributes are currently only supported in a toric setting:

calabi_yau_hypersurfaceMethod
calabi_yau_hypersurface(w::WeierstrassModel)

Return the Calabi-Yau hypersurface in the toric ambient space which defines the Weierstrass model.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> calabi_yau_hypersurface(w)
-Closed subvariety of a normal toric variety
source

Note that for applications in F-theory, singular elliptic fibrations are key (cf. Timo Weigand (2018) and references therein). Consequently the discriminant locus as well as the singular loci of the fibration in question are of ample importance:

discriminantMethod
discriminant(w::WeierstrassModel)

Return the discriminant $\Delta = 4 f^3 + 27 g^2$.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> discriminant(w);
source
singular_lociMethod
singular_loci(w::WeierstrassModel)

Return the singular loci of the Weierstrass model, along with the order of vanishing of $(f, g, \Delta)$ at each locus and the refined Tate fiber type.

For the time being, we either explicitly or implicitly focus on toric varieties as base spaces. Explicitly, in case the user provides such a variety as base space, and implicitly, in case we work over a non-fully specified base. This has the advantage that we can "filter out" trivial singular loci.

Specifically, recall that every closed subvariety of a simplicial toric variety is of the form $V(I)$, where $I$ is a homogeneous ideal of the Cox ring. Let $B$ be the irrelevant ideal of this toric variety. Then, by proposition 5.2.6. of David A. Cox, John B. Little, Henry K. Schenck (2011), $V(I)$ is trivial/empty iff $B^l \subseteq I$ for a suitable $l \geq 0$. This can be checked by checking if the saturation $I:B^\infty$ is the ideal generated by $1$.

By treating a not-fully specified base space implicitly as toric space, we can extend this result straightforwardly to this situation also. This is the reason for constructing this auxiliary base space.

julia> w = su5_weierstrass_model_over_arbitrary_3d_base()
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base
-
-julia> length(singular_loci(w))
-2
source

Methods

Towards resolution of singularities

To come.

diff --git a/previews/PR2578/Experimental/LieAlgebras/ideals_and_subalgebras/index.html b/previews/PR2578/Experimental/LieAlgebras/ideals_and_subalgebras/index.html deleted file mode 100644 index 72247c3aaf96..000000000000 --- a/previews/PR2578/Experimental/LieAlgebras/ideals_and_subalgebras/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Ideals and Lie subalgebras · Oscar.jl

Ideals and Lie subalgebras

Ideals and Lie subalgebras are represented by the types LieAlgebraIdeal and LieSubalgebra respectively. They are used similarly in most cases.

Functions

Ideals

dimMethod
dim(I::LieAlgebraIdeal) -> Int

Return the dimension of the ideal I.

source
basisMethod
basis(I::LieAlgebraIdeal) -> Vector{LieAlgebraElem}

Return the basis of the ideal I.

source
basisMethod
basis(I::LieAlgebraIdeal, i::Int) -> LieAlgebraElem

Return the i-th basis element of the ideal I.

source
inMethod
in(x::LieAlgebraElem, I::LieAlgebraIdeal) -> Bool

Return true if x is in the ideal I, false otherwise.

source
bracketMethod
bracket(I1::LieAlgebraIdeal, I2::LieAlgebraIdeal) -> LieAlgebraIdeal

Return $[I_1,I_2]$.

source
normalizerMethod
normalizer(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra

Return the normalizer of I in L, i.e. $\{x \in L \mid [x, I] \subseteq I\} = L$. As I is an ideal in L, this is just L.

source
centralizerMethod
centralizer(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra

Return the centralizer of I in L, i.e. $\{x \in L \mid [x, I] = 0\}$.

source

Lie subalgebras

dimMethod

dim(S::LieSubalgebra) -> Int

Return the dimension of the Lie subalgebra S.

source
basisMethod
basis(S::LieSubalgebra{C}) -> Vector{LieAlgebraElem{C}}

Return a basis of the Lie subalgebra S.

source
basisMethod
basis(S::LieSubalgebra{C}, i::Int) -> LieAlgebraElem{C}

Return the i-th basis element of the Lie subalgebra S.

source
inMethod
in(x::LieAlgebraElem, S::LieSubalgebra) -> Bool

Return true if x is in the Lie subalgebra S, false otherwise.

source
bracketMethod
bracket(S1::LieSubalgebra, S2::LieSubalgebra) -> LieAlgebraIdeal

Return $[S_1, S_2]$.

source
normalizerMethod
normalizer(L::LieAlgebra, S::LieSubalgebra) -> LieSubalgebra

Return the normalizer of S in L, i.e. $\{x \in L \mid [x, S] \subseteq S\}$.

source
centralizerMethod
centralizer(L::LieAlgebra, S::LieSubalgebra) -> LieSubalgebra

Return the centralizer of S in L, i.e. $\{x \in L \mid [x, S] = 0\}$.

source
is_self_normalizingMethod
is_self_normalizing(S::LieSubalgebra) -> Bool

Return true if S is self-normalizing, i.e. if its normalizer is S.

source

Constructors

Ideals

idealMethod
ideal(L::LieAlgebra, gens::Vector{LieAlgebraElem}; is_basis::Bool=false) -> LieAlgebraIdeal

Return the smallest ideal of L containing gens. If is_basis is true, then gens is assumed to be a basis of the ideal.

source
idealMethod
ideal(L::LieAlgebra, gen::LieAlgebraElem) -> LieAlgebraIdeal

Return the smallest ideal of L containing gen.

source
idealMethod
ideal(L::LieAlgebra) -> LieAlgebraIdeal

Return L as an ideal of itself.

source

Lie subalgebras

subMethod
sub(L::LieAlgebra, gens::Vector{LieAlgebraElem}; is_basis::Bool=false) -> LieSubalgebra

Return the smallest Lie subalgebra of L containing gens. If is_basis is true, then gens is assumed to be a basis of the subalgebra.

source
subMethod
sub(L::LieAlgebra, gen::LieAlgebraElem) -> LieSubalgebra

Return the smallest Lie subalgebra of L containing gen.

source
subMethod
sub(L::LieAlgebra) -> LieSubalgebra

Return L as a Lie subalgebra of itself.

source

Conversions

lie_algebraMethod
lie_algebra(S::LieSubalgebra) -> LieAlgebra

Return S as a Lie algebra.

source
lie_algebraMethod
lie_algebra(I::LieAlgebraIdeal) -> LieAlgebra

Return I as a Lie algebra.

source
subMethod
sub(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra

Return I as a subalgebra of L.

source
diff --git a/previews/PR2578/Experimental/LieAlgebras/introduction/index.html b/previews/PR2578/Experimental/LieAlgebras/introduction/index.html deleted file mode 100644 index eb5337a491b4..000000000000 --- a/previews/PR2578/Experimental/LieAlgebras/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This project aims to provide functionality for Lie algebras and their representations. It aims to provide the computational tools to work with the concepts defined in James E. Humphreys (1972).

Status

This part of OSCAR is in an experimental state; please see Adding new projects to experimental for what this means.

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/Experimental/LieAlgebras/lie_algebras/index.html b/previews/PR2578/Experimental/LieAlgebras/lie_algebras/index.html deleted file mode 100644 index 2521087a3f6f..000000000000 --- a/previews/PR2578/Experimental/LieAlgebras/lie_algebras/index.html +++ /dev/null @@ -1,101 +0,0 @@ - -Lie algebras · Oscar.jl

Lie algebras

Lie algebras in OSCAR are currently always finite dimensional, and represented by two different types, namely LinearLieAlgebra{C} and AbstractLieAlgebra{C}, depending on whether a matrix representation is available or not. Both types are subtypes of LieAlgebra{C}. Similar to other types in OSCAR, each Lie algebra type has a corresponding element type. The type parameter C is the element type of the coefficient ring.

zeroMethod
zero(L::LieAlgebra{C}) -> LieAlgebraElem{C}

Return the zero element of the Lie algebra L.

source
iszeroMethod
iszero(x::LieAlgebraElem{C}) -> Bool

Check whether the Lie algebra element x is zero.

source
dimMethod
dim(L::LieAlgebra) -> Int

Return the dimension of the Lie algebra L.

source
basisMethod
basis(L::LieAlgebra{C}) -> Vector{LieAlgebraElem{C}}

Return a basis of the Lie algebra L.

source
basisMethod
basis(L::LieAlgebra{C}, i::Int) -> LieAlgebraElem{C}

Return the i-th basis element of the Lie algebra L.

source
symbolsMethod
symbols(L::LieAlgebra{C}) -> Vector{Symbol}

Return the symbols used for printing basis elements of the Lie algebra L.

source

Special functions for LinearLieAlgebras

matrix_repr_basisMethod
matrix_repr_basis(L::LinearLieAlgebra{C}) -> Vector{MatElem{C}}

Return the basis basis(L) of the Lie algebra L in the underlying matrix representation.

source
matrix_repr_basisMethod
matrix_repr_basis(L::LinearLieAlgebra{C}, i::Int) -> MatElem{C}

Return the i-th element of the basis basis(L) of the Lie algebra L in the underlying matrix representation.

source
matrix_reprMethod
matrix_repr(a::Perm)

Return the permutation matrix as a sparse matrix representing a via natural embedding of the permutation group into the general linear group over $\mathbb{Z}$.

Examples

julia> p = Perm([2,3,1])
-(1,2,3)
-
-julia> matrix_repr(p)
-3×3 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
- ⋅  1  ⋅
- ⋅  ⋅  1
- 1  ⋅  ⋅
-
-julia> Array(ans)
-3×3 Matrix{Int64}:
- 0  1  0
- 0  0  1
- 1  0  0
matrix_repr(Y::YoungTableau)

Construct sparse integer matrix representing the tableau.

Examples

julia> y = YoungTableau([4,3,1]);
-
-
-julia> matrix_repr(y)
-3×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 8 stored entries:
- 1  2  3  4
- 5  6  7  ⋅
- 8  ⋅  ⋅  ⋅

Element constructors

(L::LieAlgebra{C})() returns the zero element of the Lie algebra L.

(L::LieAlgebra{C})(x::LieAlgebraElem{C}) returns x if x is an element of L, and fails otherwise.

(L::LieAlgebra{C})(v) constructs the element of L with coefficient vector v. v can be of type Vector{C}, Vector{Int}, SRow{C}, or MatElem{C} (of size $1 \times \dim(L)$).

If L is a LinearLieAlgebra of dim(L) > 1, the call (L::LinearLieAlgebra{C})(m::MatElem{C}) returns the Lie algebra element whose matrix representation corresponds to m. This requires m to be a square matrix of size n > 1 (the dimension of L), and to lie in the Lie algebra L (i.e. to be in the span of basis(L)). The case of m being a $1 \times \dim(L)$ matrix still works as explained above.

Arithmetics

The usual arithmetics, e.g. +, -, and *, are defined for LieAlgebraElems.

Warning

Please note that * refers to the Lie bracket and is thus not associative.

Properties

is_abelianMethod
is_abelian(L::LieAlgebra) -> Bool

Return true if L is abelian, i.e. $[L, L] = 0$.

source
is_simpleMethod
is_simple(L::LieAlgebra) -> Bool

Return true if L is simple, i.e. L is not abelian and has no non-trivial ideals.

Warning

This function is not implemented yet.

source

More functions

derived_algebraMethod
derived_algebra(L::LieAlgebra) -> LieAlgebraIdeal

Return the derived algebra of L, i.e. $[L, L]$.

source
centerMethod
center(L::LieAlgebra) -> LieAlgebraIdeal

Return the center of L, i.e. $\{x \in L \mid [x, L] = 0\}$

source
centralizerMethod
centralizer(L::LieAlgebra, xs::AbstractVector{<:LieAlgebraElem}) -> LieSubalgebra

Return the centralizer of xs in L, i.e. $\{y \in L \mid [x, y] = 0 \forall x \in xs\}$.

source
centralizerMethod
centralizer(L::LieAlgebra, x::LieAlgebraElem) -> LieSubalgebra

Return the centralizer of x in L, i.e. $\{y \in L \mid [x, y] = 0\}$.

source

Lie algebra constructors

lie_algebraFunction
lie_algebra(gapL::GAP.GapObj, s::Vector{<:VarName}; cached::Bool) -> LieAlgebra{elem_type(R)}

Construct a Lie algebra isomorphic to the GAP Lie algebra gapL. Its basis element are named by s, or by x_i by default. We require gapL to be a finite-dimensional GAP Lie algebra. The return type is dependent on properties of gapL, in particular, whether GAP knows about a matrix representation.

If cached is true, the constructed Lie algebra is cached.

source
lie_algebra(R::Ring, struct_consts::Matrix{SRow{elem_type(R)}}, s::Vector{<:VarName}; cached::Bool, check::Bool) -> AbstractLieAlgebra{elem_type(R)}

Construct the Lie algebra over the ring R with structure constants struct_consts and with basis element names s.

The Lie bracket on the newly constructed Lie algebra L is determined by the structure constants in struct_consts as follows: let $x_i$ denote the $i$-th standard basis vector of L. Then the entry struct_consts[i,j][k] is a scalar $a_{i,j,k}$ such that $[x_i, x_j] = \sum_k a_{i,j,k} x_k$.

  • s: A vector of basis element names. This is [Symbol("x_$i") for i in 1:size(struct_consts, 1)] by default.
  • cached: If true, cache the result. This is true by default.
  • check: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.
source
lie_algebra(R::Ring, struct_consts::Array{elem_type(R),3}, s::Vector{<:VarName}; cached::Bool, check::Bool) -> AbstractLieAlgebra{elem_type(R)}

Construct the Lie algebra over the ring R with structure constants struct_consts and with basis element names s.

The Lie bracket on the newly constructed Lie algebra L is determined by the structure constants in struct_consts as follows: let $x_i$ denote the $i$-th standard basis vector of L. Then the entry struct_consts[i,j,k] is a scalar $a_{i,j,k}$ such that $[x_i, x_j] = \sum_k a_{i,j,k} x_k$.

  • s: A vector of basis element names. This is [Symbol("x_$i") for i in 1:size(struct_consts, 1)] by default.
  • cached: If true, cache the result. This is true by default.
  • check: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.

Examples

julia> struct_consts = zeros(QQ, 3, 3, 3);
-
-julia> struct_consts[1, 2, 3] = QQ(1);
-
-julia> struct_consts[2, 1, 3] = QQ(-1);
-
-julia> struct_consts[3, 1, 1] = QQ(2);
-
-julia> struct_consts[1, 3, 1] = QQ(-2);
-
-julia> struct_consts[3, 2, 2] = QQ(-2);
-
-julia> struct_consts[2, 3, 2] = QQ(2);
-
-julia> sl2 = lie_algebra(QQ, struct_consts, ["e", "f", "h"])
-Abstract Lie algebra
-  of dimension 3
-over rational field
-
-julia> e, f, h = basis(sl2)
-3-element Vector{AbstractLieAlgebraElem{QQFieldElem}}:
- e
- f
- h
-
-julia> e * f
-h
-
-julia> h * e
-2*e
-
-julia> h * f
--2*f
source
lie_algebra(R::Ring, dynkin::Tuple{Char,Int}; cached::Bool) -> AbstractLieAlgebra{elem_type(R)}

Construct the simple Lie algebra over the ring R with Dynkin type given by dynkin. The actual construction is done in GAP.

If cached is true, the constructed Lie algebra is cached.

source
lie_algebra(R::Ring, n::Int, basis::Vector{<:MatElem{elem_type(R)}}, s::Vector{<:VarName}; cached::Bool) -> LinearLieAlgebra{elem_type(R)}

Construct the Lie algebra over the ring R with basis basis and basis element names given by s. The basis elements must be square matrices of size n. We require basis to be linearly independent, and to contain the Lie bracket of any two basis elements in its span.

If cached is true, the constructed Lie algebra is cached.

source
lie_algebra(S::LieSubalgebra) -> LieAlgebra

Return S as a Lie algebra.

source
lie_algebra(I::LieAlgebraIdeal) -> LieAlgebra

Return I as a Lie algebra.

source

Classical Lie algebras

general_linear_lie_algebraMethod
general_linear_lie_algebra(R::Ring, n::Int) -> LinearLieAlgebra{elem_type(R)}

Return the general linear Lie algebra $\mathfrak{gl}_n(R)$.

Examples

julia> L = general_linear_lie_algebra(QQ, 2)
-General linear Lie algebra of degree 2
-  of dimension 4
-over rational field
-
-julia> basis(L)
-4-element Vector{LinearLieAlgebraElem{QQFieldElem}}:
- x_1_1
- x_1_2
- x_2_1
- x_2_2
-
-julia> matrix_repr_basis(L)
-4-element Vector{QQMatrix}:
- [1 0; 0 0]
- [0 1; 0 0]
- [0 0; 1 0]
- [0 0; 0 1]
source
special_linear_lie_algebraMethod
special_linear_lie_algebra(R::Ring, n::Int) -> LinearLieAlgebra{elem_type(R)}

Return the special linear Lie algebra $\mathfrak{sl}_n(R)$.

Examples

julia> L = special_linear_lie_algebra(QQ, 2)
-Special linear Lie algebra of degree 2
-  of dimension 3
-over rational field
-
-julia> basis(L)
-3-element Vector{LinearLieAlgebraElem{QQFieldElem}}:
- e_1_2
- f_1_2
- h_1
-
-julia> matrix_repr_basis(L)
-3-element Vector{QQMatrix}:
- [0 1; 0 0]
- [0 0; 1 0]
- [1 0; 0 -1]
source
special_orthogonal_lie_algebraMethod
special_orthogonal_lie_algebra(R::Ring, n::Int) -> LinearLieAlgebra{elem_type(R)}

Return the special orthogonal Lie algebra $\mathfrak{so}_n(R)$.

Examples

julia> L = special_orthogonal_lie_algebra(QQ, 3)
-Special orthogonal Lie algebra of degree 3
-  of dimension 3
-over rational field
-
-julia> basis(L)
-3-element Vector{LinearLieAlgebraElem{QQFieldElem}}:
- x_1_2
- x_1_3
- x_2_3
-
-julia> matrix_repr_basis(L)
-3-element Vector{QQMatrix}:
- [0 1 0; -1 0 0; 0 0 0]
- [0 0 1; 0 0 0; -1 0 0]
- [0 0 0; 0 0 1; 0 -1 0]
source

Relation to GAP Lie algebras

Using Oscar.iso_oscar_gap(L), one can get an isomorphism from the OSCAR Lie algebra L to some isomorphic GAP Lie algebra. For more details, please refer to iso_oscar_gap.

diff --git a/previews/PR2578/Experimental/LieAlgebras/modules/index.html b/previews/PR2578/Experimental/LieAlgebras/modules/index.html deleted file mode 100644 index 48651816e35f..000000000000 --- a/previews/PR2578/Experimental/LieAlgebras/modules/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Lie algebra modules · Oscar.jl

Lie algebra modules

Lie algebra modules in OSCAR are always finite dimensional and represented by the type LieAlgebraModule{C}. Similar to other types in OSCAR, there is the corresponding element type LieAlgebraModuleElem{C}. The type parameter C is the element type of the coefficient ring.

base_lie_algebraMethod
base_lie_algebra(V::LieAlgebraModule{C}) -> LieAlgebra{C}

Return the Lie algebra V is a module over.

source
zeroMethod
zero(V::LieAlgebraModule{C}) -> LieAlgebraModuleElem{C}

Return the zero element of the Lie algebra module V.

source
iszeroMethod
iszero(v::LieAlgebraModuleElem{C}) -> Bool

Check whether the Lie algebra module element v is zero.

source
dimMethod
dim(V::LieAlgebraModule{C}) -> Int

Return the dimension of the Lie algebra module V.

source
basisMethod
basis(V::LieAlgebraModule{C}) -> Vector{LieAlgebraModuleElem{C}}

Return a basis of the Lie algebra module V.

source
basisMethod
basis(V::LieAlgebraModule{C}, i::Int) -> LieAlgebraModuleElem{C}

Return the i-th basis element of the Lie algebra module V.

source
symbolsMethod
symbols(V::LieAlgebraModule{C}) -> Vector{Symbol}

Return the symbols used for printing basis elements of the Lie algebra module V.

source

Element constructors

(V::LieAlgebraModule{C})() returns the zero element of the Lie algebra module V.

(V::LieAlgebraModule{C})(v::LieAlgebraModuleElem{C}) returns v if v is an element of L. If V is the dual module of the parent of v, it returns the dual of v. In all other cases, it fails.

(V::LieAlgebraModule{C})(v) constructs the element of V with coefficient vector v. v can be of type Vector{C}, Vector{Int}, SRow{C}, or MatElem{C} (of size $1 \times \dim(L)$).

(V::LieAlgebraModule{C})(a::Vector{T}) where {T<:LieAlgebraModuleElem{C}}): If V is a direct sum, return its element, where the $i$-th component is equal to a[i]. If V is a tensor product, return the tensor product of the a[i]. If V is a exterior (symmetric, tensor) power, return the wedge product (product, tensor product) of the a[i]. Requires that a has a suitable length, and that the a[i] are elements of the correct modules, where correct depends on the case above.

Arithmetics

The usual arithmetics, e.g. +, -, and * (scalar multiplication), are defined for LieAlgebraModuleElems.

The module action is defined as *.

*Method
action(x::LieAlgebraElem{C}, v::LieAlgebraModuleElem{C}) -> LieAlgebraModuleElem{C}
-*(x::LieAlgebraElem{C}, v::LieAlgebraModuleElem{C}) -> LieAlgebraModuleElem{C}

Apply the action of x on v.

source

Module constructors

standard_moduleMethod
standard_module(L::LinearLieAlgebra{C}) -> LieAlgebraModule{C}

Construct the standard module of the linear Lie algebra L. If L is a Lie subalgebra of $\mathfrak{gl}_n(R)$, then the standard module is $R^n$ with the action of $L$ given by left multiplication.

source
dualMethod
dual(V::LieAlgebraModule{C}) -> LieAlgebraModule{C}

Construct the dual module of V.

source
direct_sumMethod
direct_sum(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}
-⊕(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}

Construct the direct sum of the modules V....

source
tensor_productMethod

tensor_product(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C} ⊗(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}

Construct the tensor product of the modules V....

source
exterior_powerMethod
exterior_power(V::LieAlgebraModule{C}, k::Int) -> LieAlgebraModule{C}

Construct the k-th exterior power $\bigwedge^k (V)$ of the module V.

source
symmetric_powerMethod
symmetric_power(V::LieAlgebraModule{C}, k::Int) -> LieAlgebraModule{C}

Construct the k-th symmetric power $S^k (V)$ of the module V.

source
tensor_powerMethod
tensor_power(V::LieAlgebraModule{C}, k::Int) -> LieAlgebraModule{C}

Construct the k-th tensor power $T^k (V)$ of the module V.

source
abstract_moduleMethod
abstract_module(L::LieAlgebra{C}, dimV::Int, transformation_matrices::Vector{<:MatElem{C}}, s::Vector{<:VarName}; check::Bool) -> LieAlgebraModule{C}

Construct the the Lie algebra module over L of dimension dimV given by transformation_matrices and with basis element names s.

  • transformation_matrices: The action of the $i$-th basis element of L on some element $v$ of the constructed module is given by left multiplication of the matrix transformation_matrices[i] to the coefficient vector of $v$.
  • s: A vector of basis element names. This is [Symbol("v_$i") for i in 1:dimV] by default.
  • check: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.
source
abstract_moduleMethod
abstract_module(L::LieAlgebra{C}, dimV::Int, struct_consts::Matrix{SRow{C}}, s::Vector{<:VarName}; check::Bool) -> LieAlgebraModule{C}

Construct the the Lie algebra module over L of dimension dimV given by structure constants struct_consts and with basis element names s.

The action on the newly constructed Lie algebra module V is determined by the structure constants in struct_consts as follows: let $x_i$ denote the $i$-th standard basis vector of L, and $v_i$ the $i$-th standard basis vector of V. Then the entry struct_consts[i,j][k] is a scalar $a_{i,j,k}$ such that $x_i * v_j = \sum_k a_{i,j,k} v_k$.

  • s: A vector of basis element names. This is [Symbol("v_$i") for i in 1:dimV] by default.
  • check: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.
source

Type-dependent getters

is_standard_moduleMethod
is_standard_module(V::LieAlgebraModule{C}) -> Bool

Check whether V has been constructed as a standard module.

source
is_dualMethod
is_dual(V::LieAlgebraModule{C}) -> Bool

Check whether V has been constructed as a dual module.

source
is_direct_sumMethod
is_direct_sum(V::LieAlgebraModule{C}) -> Bool

Check whether V has been constructed as a direct sum of modules.

source
is_tensor_productMethod
is_tensor_product(V::LieAlgebraModule{C}) -> Bool

Check whether V has been constructed as a tensor product of modules.

source
is_exterior_powerMethod
is_exterior_power(V::LieAlgebraModule{C}) -> Bool

Check whether V has been constructed as an exterior power of a module.

source
is_symmetric_powerMethod
is_symmetric_power(V::LieAlgebraModule{C}) -> Bool

Check whether V has been constructed as a symmetric power of a module.

source
is_tensor_powerMethod
is_tensor_power(V::LieAlgebraModule{C}) -> Bool

Check whether V has been constructed as a tensor power of a module.

source
base_moduleMethod
base_module(V::LieAlgebraModule{C}) -> LieAlgebraModule{C}

Returns the base module of V, if V has been constructed as a power module.

source
base_modulesMethod
base_modules(V::LieAlgebraModule{C}) -> Vector{LieAlgebraModule{C}}

Returns the summands or tensor factors of V, if V has been constructed as a direct sum or tensor product of modules.

source
diff --git a/previews/PR2578/Experimental/LinearQuotients/cox_rings/index.html b/previews/PR2578/Experimental/LinearQuotients/cox_rings/index.html deleted file mode 100644 index 3c31bfa96009..000000000000 --- a/previews/PR2578/Experimental/LinearQuotients/cox_rings/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Cox rings · Oscar.jl

Cox rings

Cox rings of linear quotients

By a theorem of Arzhantsev and Gaifullin Ivan V. Arzhantsev, Sergei A. Gaǐfullin (2010), the Cox ring of a linear quotient $V/G$ is graded isomorphic to the invariant ring $K[V]^{[G,G]}$, where $[G,G]$ is the derived subgroup of $G$. This functionality is so far only available if the group does not contain any reflections.

cox_ringMethod
cox_ring(L::LinearQuotient)

Return the Cox ring of the linear quotient L in a presentation as a graded affine algebra (MPolyQuoRing) and an injective map from this ring into a polynomial ring.

By a theorem of Arzhantsev–Gaifullin Ivan V. Arzhantsev, Sergei A. Gaǐfullin (2010) the Cox ring is graded isomorphic to the invariant ring of the derived subgroup of group(L). We use ideas from Maria Donten-Bury, Simon Keicher (2017) to find homogeneous generators of the invariant ring. To get a map from group(G) to the grading group of the returned ring, use class_group.

source

Cox rings of $\mathbb Q$-factorial terminalizations

We provide an experimental algorithm to compute the Cox ring of a $\mathbb Q$-factorial terminalization $X\to V/G$ of a linear quotient due to Ryo Yamagishi (2018).

cox_ring_of_qq_factorial_terminalizationMethod
cox_ring_of_qq_factorial_terminalization(L::LinearQuotient)

Return the Cox ring of a QQ-factorial terminalization of the linear quotient L in a presentation as a graded affine algebra (MPolyQuoRing) and an injective map from this ring into a Laurent polynomial ring using the algorithm from Ryo Yamagishi (2018).

source
diff --git a/previews/PR2578/Experimental/LinearQuotients/introduction/index.html b/previews/PR2578/Experimental/LinearQuotients/introduction/index.html deleted file mode 100644 index 203ce53580a9..000000000000 --- a/previews/PR2578/Experimental/LinearQuotients/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Linear quotients are orbit spaces of the action of a finite group $G$ on a finite-dimensional vector space $V$ over $\mathbb C$. Formally, we define $V/G := \operatorname{Spec}\mathbb C[V]^G$. Notice that the invariant ring $\mathbb C[V]^G$ is an affine algebra by a theorem of Hilbert-Noether.

Status

This part of OSCAR is in an experimental state; please see Adding new projects to experimental for what this means. See also the dedicated README.md for details.

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/Experimental/LinearQuotients/linear_quotients/index.html b/previews/PR2578/Experimental/LinearQuotients/linear_quotients/index.html deleted file mode 100644 index 8a6a29c3d571..000000000000 --- a/previews/PR2578/Experimental/LinearQuotients/linear_quotients/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Construction and basic functionality · Oscar.jl

Construction and basic functionality

Constructor

Given a finite group $G\leq \operatorname{GL}_n(K)$, one can construct the corresponding linear quotient $K^n/G$:

linear_quotientMethod
linear_quotient(G::MatrixGroup)

Return the linear quotient by G, that is, the orbit space of the action of G on the vector space of dimension degree(G).

If the given group is not finite, an error is raised.

source
Implicit choice of representation

Let $V = K^n$ be the regular representation of the matrix group $G$. In the current version, the object returned by linear_quotient(G) will work with the dual representation, that is, the linear quotient will be $V^\ast/G$. This might change in the future (notice that this code is still considered experimental)

Root of unity

For many computations, we require that the base field base_ring(G) contains a primitive root of unity of order exponent(G). If your chosen field is 'too small', you can easily change the base field with map_entries(L, G), where L is the larger field.

Class group

The divisor class group of a linear quotient $V/G$ is controlled by the reflections contained in the group $G$, see David J. Benson (1993).

class_groupMethod
class_group(L::LinearQuotient)

Return the class group of the linear quotient L and a map from group(L) to this group.

If G = group(L), then the class group is Ab(G/H), where H is the subgroup of G generated by the reflections.

source

Singularities

One can study the types of the singularities of a linear quotient as follows.

diff --git a/previews/PR2578/Experimental/OrthogonalDiscriminants/access/index.html b/previews/PR2578/Experimental/OrthogonalDiscriminants/access/index.html deleted file mode 100644 index 92b374e5067d..000000000000 --- a/previews/PR2578/Experimental/OrthogonalDiscriminants/access/index.html +++ /dev/null @@ -1,23 +0,0 @@ - -Access to precomputed OD data · Oscar.jl

Access to precomputed OD data

all_od_infosFunction
all_od_infos(L...)

Return the array of all those entries of the known OD data (see OD_data) that satisfy the conditions in L.

The following conditions are supported.

  • is_simple with value true or false, meaning entries only for simple or non-simple groups, respectively,

  • is_sporadic_simple with value true or false, meaning entries only for sporadic simple or not sporadic simple groups, respectively,

  • characteristic, with value 0 or a prime integer, meaning entries only for this characteristic,

  • character_field, with value either a map or a vector of maps, meaning entries only for characters whose character fields (finite fields if the characteristic is positive, and subfields of cyclotomic fields in characteristic zero) have the given map(s) as embeddings into the algebraic closure or abelian closure, respectively,

  • identifier, with value a string denoting the name of an Atlas group, or a vector of such strings, meaning entries only for these groups,

  • dim, with value a positive integer, or a vector of such integers, meaning entries only for characters of these degrees,

  • orthogonal_discriminant, with value a string ("O+", "O-", or a string that encodes an algebraic integer), meaning entries only with this orthogonal discriminant,

  • comment_matches, with value a string (one of "ev", "specht", ...), or a vector of such strings, meaning entries whose comment contains these values.

For all conditions except the boolean valued ones, also a function can be given as value, meaning that all those entries satisfy this condition for which the function returns true when applied to the stored value. For example, the condition characteristic => is_odd matches all entries for characteristics different from 0 and 2, and the condition character_field => (emb -> degree(domain(emb)) == 1) matches all entries for which the character field is the field of rationals.

Examples

julia> length(all_od_infos(identifier => "A6"))
-8
-
-julia> length(all_od_infos(identifier => "A6", characteristic => 0))
-3
-
-julia> length(all_od_infos(identifier => "A6", characteristic => 2:5))
-5
source
orthogonal_discriminantsFunction
orthogonal_discriminants(tbl::Oscar.GAPGroupCharacterTable)

Examples

julia> t = character_table("A6");
-
-julia> println(orthogonal_discriminants(t))
-["", "", "", "1", "1", "", "-1"]
-
-julia> println(orthogonal_discriminants(t % 3))
-["", "", "", "O-", ""]
source
orthogonal_discriminantFunction
orthogonal_discriminant(chi::Oscar.GAPGroupClassFunction)

Examples

julia> t = character_table("A6");
-
-julia> orthogonal_discriminant(t[4])
-"1"
-
-julia> t2 = t % 2;
-
-julia> orthogonal_discriminant(t2[4])
-"O+"
source
diff --git a/previews/PR2578/Experimental/OrthogonalDiscriminants/introduction/index.html b/previews/PR2578/Experimental/OrthogonalDiscriminants/introduction/index.html deleted file mode 100644 index 3632aad19594..000000000000 --- a/previews/PR2578/Experimental/OrthogonalDiscriminants/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The aim of this project is to provide methods for computing the orthogonal discriminants of the absolutely irreducible orthogonal representations of even degree that are listed in the Atlas of Finite Groups.

Status

This part of OSCAR is in an experimental state; please see Adding new projects to experimental for what this means.

Contact

Please direct questions about this part of OSCAR to the following people:

diff --git a/previews/PR2578/Experimental/OrthogonalDiscriminants/misc/index.html b/previews/PR2578/Experimental/OrthogonalDiscriminants/misc/index.html deleted file mode 100644 index 91c4331928cf..000000000000 --- a/previews/PR2578/Experimental/OrthogonalDiscriminants/misc/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Miscellaneous functions · Oscar.jl

Miscellaneous functions

dimension_specht_moduleFunction
dimension_specht_module(mu::Partition{T}) where T <: IntegerUnion -> ZZRingElem

Return the dimension of the Specht module for mu.

Examples

julia> print([dimension_specht_module(p) for p in partitions(4)])
-ZZRingElem[1, 3, 2, 3, 1]
source
gram_determinant_specht_moduleFunction
gram_determinant_specht_module(mu::Partition{T}) where T <: IntegerUnion

Return the determinant of the Gram matrix for the Specht module for mu, in factorized collected form.

Examples

julia> print(gram_determinant_specht_module(partition([4, 3, 2, 1])))
-Vector{ZZRingElem}[[3, 1152], [5, 768], [7, 384]]
source
diff --git a/previews/PR2578/Experimental/PlaneCurve/divisors/index.html b/previews/PR2578/Experimental/PlaneCurve/divisors/index.html deleted file mode 100644 index 4f3a698fe8f8..000000000000 --- a/previews/PR2578/Experimental/PlaneCurve/divisors/index.html +++ /dev/null @@ -1,189 +0,0 @@ - -Divisors · Oscar.jl

Divisors

In order to consider divisors on curves, we restrict our attention to smooth and irreducible curves.

Let $C$ be an affine or projective plane curve defined by an irreducible equation $F$. Then any polynomial function $G$ which is not divisible by $F$ will vanish on $C$ only at finitely many points. A way to encode these points together with their intersection multiplicities is to consider a divisor. A divisor on a curve is a formal finite sum of points of the curve with integer coefficients. A natural operation of addition can be defined on the set of divisors of a curve, which turns it into an Abelian group.

Constructors

Divisors on curves are here introduced as a dictionary associating a point on the curve to its multiplicity.

AffineCurveDivisorType
AffineCurveDivisor(C::AffinePlaneCurve{S}, D::Dict{Point{S}, Int}) where S <: FieldElem

Given a curve C which is assumed to be smooth and irreducible, return the divisor on the curve C defined by D.

Examples

julia> R, (x,y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^2 + y + x^2)
-Affine plane curve defined by x^2 + y^2 + y
-
-julia> P = Point([QQ(0), QQ(0)])
-Point with coordinates QQFieldElem[0, 0]
-
-julia> Q = Point([QQ(0), QQ(-1)])
-Point with coordinates QQFieldElem[0, -1]
-
-julia> Oscar.AffineCurveDivisor(C, Dict(P => 3, Q => -2))
--2*QQFieldElem[0, -1] + 3*QQFieldElem[0, 0]
source
ProjCurveDivisorType
ProjCurveDivisor(C::ProjPlaneCurve{S}, D::Dict{Oscar.Geometry.ProjSpcElem{S}, Int}) where S <: FieldElem

Given a curve C which is assumed to be smooth and irreducible, return the divisor on the curve C defined by D.

Examples

julia> S, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2 + y*z + x^2))
-Projective plane curve defined by x^2 + y^2 + y*z
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])
-(0 : 0 : 1)
-
-julia> Q = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(-1), QQ(1)])
-(0 : -1 : 1)
-
-julia> D = Oscar.ProjCurveDivisor(C, Dict(P => 3, Q => -2))
--2*(0 : 1 : -1) + 3*(0 : 0 : 1)
source

To define the divisor $0$ of the group of divisors, one uses the following method:

curve_zero_divisorMethod
curve_zero_divisor(C::ProjPlaneCurve{S}) where S <: FieldElem

Return the divisor 0 on the curve C.

source
curve_zero_divisorMethod
curve_zero_divisor(C::AffinePlaneCurve{S}) where S <: FieldElem

Return the divisor 0 on the curve C.

source

Methods

The following functions on divisors of curves are implemented.

curveMethod
curve(D::CurveDivisor)

Return the curve on which the divisor is considered.

source
degreeMethod
degree(D::CurveDivisor)

Return the degree of the divisor.

source
is_effectiveMethod
is_effective(D::CurveDivisor)

Return true if D is an effective divisor, false otherwise.

Examples

julia> R, (x,y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^2 + y + x^2)
-Affine plane curve defined by x^2 + y^2 + y
-
-julia> P = Point([QQ(0), QQ(0)])
-Point with coordinates QQFieldElem[0, 0]
-
-julia> Q = Point([QQ(0), QQ(-1)])
-Point with coordinates QQFieldElem[0, -1]
-
-julia> D = Oscar.AffineCurveDivisor(C, Dict(P => 3, Q => -2))
--2*QQFieldElem[0, -1] + 3*QQFieldElem[0, 0]
-
-julia> Oscar.is_effective(D)
-false
source
is_linearly_equivalentMethod
is_linearly_equivalent(D::ProjCurveDivisor, E::ProjCurveDivisor)

Return true if the divisors D and E are linearly equivalent, and false otherwise

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))
-Projective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])
-(0 : 1 : 0)
-
-julia> R = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])
-(0 : 0 : 1)
-
-julia> E = Oscar.ProjCurveDivisor(C, P)
-(0 : 1 : 0)
-
-julia> F = Oscar.ProjCurveDivisor(C, R)
-(0 : 0 : 1)
-
-julia> Oscar.is_linearly_equivalent(E, F)
-false
source
is_principalMethod
is_principal(D::ProjCurveDivisor{S}) where S <: FieldElem

Return true if the divisor D is principal, and false otherwise

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))
-Projective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])
-(0 : 1 : 0)
-
-julia> E = Oscar.ProjCurveDivisor(C, P)
-(0 : 1 : 0)
-
-julia> Oscar.is_principal(E)
-false
source
principal_divisorMethod
principal_divisor(D::ProjCurveDivisor{S}) where S <: FieldElem

If the divisor D is principal, return a rational function phi such that D is linearly equivalent to the divisor defined by phi.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))
-Projective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])
-(0 : 1 : 0)
-
-julia> R = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])
-(0 : 0 : 1)
-
-julia> E = Oscar.ProjCurveDivisor(C, P, 2)
-2*(0 : 1 : 0)
-
-julia> F = Oscar.ProjCurveDivisor(C, R, 2)
-2*(0 : 0 : 1)
-
-julia> G = 2*E - 2*F
-4*(0 : 1 : 0) - 4*(0 : 0 : 1)
-
-julia> Oscar.principal_divisor(G)
-x^2//z^2
source
global_sectionsMethod
global_sections(D::ProjCurveDivisor)

Return a set of generators of the global sections of the sheaf associated to the divisor D of a smooth and irreducible projective curve.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))
-Projective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])
-(0 : 1 : 0)
-
-julia> D = Oscar.ProjCurveDivisor(C, P, 4)
-4*(0 : 1 : 0)
-
-julia> Oscar.global_sections(D)
-4-element Vector{AbstractAlgebra.Generic.Frac{QQMPolyRingElem}}:
- 1
- y//z
- x//z
- x^2//z^2
source
dimension_global_sectionsMethod
dimension_global_sections(D::ProjCurveDivisor)

Return the dimension of the global sections of the sheaf associated to the divisor D of a smooth and irreducible projective curve.

source

In addition, the multiplicity of a polynomial or a fraction at a given point can be computed:

multiplicityMethod
multiplicity(C::AffinePlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}, P::Point{S}) where {S <: FieldElem, T <: MPolyRingElem{S}}
-multiplicity(C::ProjPlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}, P::Oscar.Geometry.ProjSpcElem{S})  where {S <: FieldElem, T <: Oscar.MPolyDecRingElem{S}}

Return the multiplicity of the rational function phi on the curve C at the point P.

Examples

julia> S, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2 + y*z + x^2))
-Projective plane curve defined by x^2 + y^2 + y*z
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])
-(0 : 0 : 1)
-
-julia> phi = T(x)//T(y)
-x//y
-
-julia> multiplicity(C, phi, P)
--1
source
multiplicityMethod
multiplicity(C::AffinePlaneCurve{S}, F::Oscar.MPolyRingElem{S}, P::Point{S}) where S <: FieldElem
-multiplicity(C::ProjPlaneCurve{S}, F::Oscar.MPolyDecRingElem{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem

Return the multiplicity of the polynomial F on the curve C at the point P.

source

The divisor of a polynomial or a fraction along a plane curve can be computed, but will give only the points which belong to the base field.

divisorMethod
divisor(C::AffinePlaneCurve{S}, F::Oscar.MPolyRingElem{S}) where S <: FieldElem

Return the divisor defined by the polynomial F on the curve C.

source
divisorMethod
divisor(C::AffinePlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}) where {S <: FieldElem, T <: MPolyRingElem{S}}

Return the divisor defined by the rational function phi on the curve C.

source
divisorMethod
divisor([PP::Oscar.Geometry.ProjSpc{S}], C::ProjPlaneCurve{S}, F::Oscar.MPolyDecRingElem{S}) where S <: FieldElem

Return the divisor defined by the polynomial F on the curve C. The points of the divisor are in the projective space PP if specified, or in a new projective space otherwise.

source
divisorMethod
divisor(PP::Oscar.Geometry.ProjSpc{S}, C::ProjPlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T})  where {S <: FieldElem, T <: Oscar.MPolyDecRingElem{S}}

Return the divisor defined by the rational function phi on the curve C.

Examples

julia> S, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2 + y*z + x^2))
-Projective plane curve defined by x^2 + y^2 + y*z
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> phi = T(x)//T(y)
-x//y
-
-julia> Oscar.divisor(PP[1], C, phi)
-(0 : 1 : -1) - (0 : 0 : 1)
source
diff --git a/previews/PR2578/Experimental/PlaneCurve/elliptic_curves/index.html b/previews/PR2578/Experimental/PlaneCurve/elliptic_curves/index.html deleted file mode 100644 index 5915c1dcf8d9..000000000000 --- a/previews/PR2578/Experimental/PlaneCurve/elliptic_curves/index.html +++ /dev/null @@ -1,131 +0,0 @@ - -Elliptic Curves · Oscar.jl

Elliptic Curves

An elliptic plane curve is a projective plane curve of degree 3 together with a point of the curve, called the base point. An operation of addition of points can be defined on elliptic curves.

Constructor

An elliptic curve is a subtype of the abstract type ProjectivePlaneCurve. To define an elliptic curve over a field, one can either give as input an equation and the point at infinity, or just an equation in Weierstrass form. In the latter case, the point at infinity is $(0 : 1 : 0)$.

Considering elliptic curves over a ring is helpful in some primality proving test. We introduce here a structure of elliptic curve over a ring. In that case, we always assume the equation to be in Weierstrass form, with infinity point $(0 : 1 : 0)$.

ProjEllipticCurveType
ProjEllipticCurve{S}(eq::Oscar.MPolyDecRingElem{S}) where {S <: FieldElem}
-ProjEllipticCurve(eq::Oscar.MPolyDecRingElem{S}, P::Oscar.Geometry.ProjSpcElem{S}) where {S <: FieldElem}
-ProjEllipticCurve(eq::Oscar.MPolyDecRingElem{S}) where {S <: Nemo.ZZModRingElem}

Return the Projective Elliptic Curve defined by the equation eq, with P as infinity point. If no point is specified it is expected that eq is in Weierstrass form, and the infinity point is (0:1:0).

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> F = T(-x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3)
--x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(-1), QQ(1), QQ(0)])
-(-1 : 1 : 0)
-
-julia> E1 = Oscar.ProjEllipticCurve(F, P)
-Projective elliptic curve defined by -x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3
-
-julia> E2 = Oscar.ProjEllipticCurve(T(y^2*z - x^3 - x*z^2))
-Projective elliptic curve defined by -x^3 - x*z^2 + y^2*z
source

Points on Elliptic Curves

We define a specific structure for the points on an elliptic curve, on which the operation of addition and multiplication by an integer are defined.

Point_EllCurveType
Point_EllCurve(E::ProjEllipticCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where {S <: FieldElem}
-Point_EllCurve(E::ProjEllipticCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where {S <: Nemo.ZZModRingElem}

Create the point P on the elliptic curve E.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> E = Oscar.ProjEllipticCurve(T(y^2*z - x^3 + 2*x*z^2))
-Projective elliptic curve defined by -x^3 + 2*x*z^2 + y^2*z
-
-julia> PP = Oscar.proj_space(E)
-Projective space of dim 2 over Rational field
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP, [QQ(2), QQ(2), QQ(1)])
-(2 : 2 : 1)
-
-julia> Q = Oscar.Point_EllCurve(E, P)
-(2 : 2 : 1)
source

Methods

Most of the functions described for projective plane curves are also available for elliptic curves over a field. We describe here the functions which are specific to elliptic curves.

Basic functions

proj_spaceMethod
proj_space(E::ProjEllipticCurve{S}) where S <: FieldElem

Return the projective space to which the base point of the elliptic curve E belongs.

source
proj_spaceMethod
proj_space(P::Point_EllCurve{S}) where S <: FieldElem

Return the projective space to which the point P belongs.

source
curveMethod
curve(P::Point_EllCurve{S}) where S <: FieldElem

Return the curve on which the point P is considered.

source

Addition and multiplication by an integer of a point on an elliptic curve can be performed using the usual symbols + and *.

Example

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> E = Oscar.ProjEllipticCurve(T(y^2*z - x^3 + 2*x*z^2))
-Projective elliptic curve defined by -x^3 + 2*x*z^2 + y^2*z
-
-julia> PP = Oscar.proj_space(E)
-Projective space of dim 2 over Rational field
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP, [QQ(2), QQ(2), QQ(1)])
-(2 : 2 : 1)
-
-julia> Q = Oscar.Point_EllCurve(E, P)
-(2 : 2 : 1)
-
-julia> Q+Q
-(9//4 : -21//8 : 1)
-
-julia> 3*Q
-(338 : 6214 : 1)
-

Weierstrass form

weierstrass_formMethod
weierstrass_form(E::ProjEllipticCurve{S}) where {S <: FieldElem}

Return the equation of a projective elliptic curve defined by an equation in Weierstrass form and which is linearly equivalent to E.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> F = T(-x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3)
--x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(-1), QQ(1), QQ(0)])
-(-1 : 1 : 0)
-
-julia> E = Oscar.ProjEllipticCurve(F, P)
-Projective elliptic curve defined by -x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3
-
-julia> Oscar.weierstrass_form(E)
--x^3 - x*z^2 + y^2*z - 4*z^3
source
toweierstrassMethod
toweierstrass(C::ProjPlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem

Given a smooth plane cubic projective curve C and a point P on the curve, return an elliptic curve birationally equivalent to C given by an equation in long Weierstrass form.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> Q = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(-1), QQ(1), QQ(0)])
-(-1 : 1 : 0)
-
-julia> D = ProjPlaneCurve(T(-x^3 - 3*x^2*y + 2*x^2*z - 3*x*y^2 + 3*x*y*z - 4*x*z^2 - y^3 - y*z^2 + 6*z^3))
-Projective plane curve defined by -x^3 - 3*x^2*y + 2*x^2*z - 3*x*y^2 + 3*x*y*z - 4*x*z^2 - y^3 - y*z^2 + 6*z^3
-
-julia> Oscar.toweierstrass(D, Q)
--x^3 - 2*x^2*z + x*y*z - 4*x*z^2 + y^2*z + 3*y*z^2 - 6*z^3
source

Invariant of Elliptic Curves, torsion points...

discriminantMethod
discriminant(E::ProjEllipticCurve{S}) where S <: FieldElem

Return the discriminant of the projective elliptic curve E.

source
j_invariantMethod
j_invariant(E::ProjEllipticCurve{S}) where S <: FieldElem

Return the j-invariant of the projective elliptic curve E.

source
is_torsion_pointMethod
is_torsion_point(P::Point_EllCurve{QQFieldElem})

Return whether the point P is a torsion point.

source
torsion_points_lutz_nagellMethod
torsion_points_lutz_nagell(E::ProjEllipticCurve{QQFieldElem})

Return the rational torsion points of the elliptic curve E using the Lutz-Nagell theorem.

source
torsion_points_division_polyMethod
torsion_points_division_poly(E::ProjEllipticCurve{QQFieldElem})

Return the rational torsion points of a rational elliptic curve E using division polynomials.

source
orderMethod
order(P::Point_EllCurve{QQFieldElem})

Return the order of the point P or 0 if the order is infinite.

source

The following functions are implemented for elliptic curves over finite fields:

randMethod
rand(E::ProjEllipticCurve{S}) where S <: FieldElem

Return a random point on the elliptic curve E defined over a finite field.

source
list_randMethod
list_rand(E::ProjEllipticCurve, N::Int)

Return a list of N random points on the elliptic curve E defined over a finite field.

source
orderMethod
order(E::ProjEllipticCurve{S}) where S <: FieldElem

Given an elliptic curve E over a finite field $\mathbf F$, computes $\#E(\mathbf F)$.

source

The addition of points is not well defined for projective elliptic curves over a ring, that's why this case has to be considered separately. The following methods can for example be used for teaching purposes to show the steps of the Elliptic Curve Method.

sum_Point_EllCurveZnZMethod
sum_Point_EllCurveZnZ(P::Point_EllCurve{S}, Q::Point_EllCurve{S}) where S <: Nemo.ZZModRingElem

Return, if possible, the sum of the points P and Q, and an error otherwise.

source
IntMult_Point_EllCurveZnZMethod
IntMult_Point_EllCurveZnZ(m::ZZRingElem, P::Point_EllCurve{S}) where S <: Nemo.ZZModRingElem

Return, if possible, the point mP, and an error otherwise.

source
rand_pair_EllCurve_PointMethod
rand_pair_EllCurve_Point(R::Oscar.MPolyDecRing{S}, PP::Oscar.Geometry.ProjSpc{S}) where S <: Nemo.ZZModRingElem

Return a pair composed of an elliptic plane curve E with equation in R, and a point P on E.

source

Primality proving

Elliptic Curve Method

Projective elliptic curves over a ring are for example used in the Elliptic Curve Method. We give here an example (see Example 7.1 of Lawrence C. Washington (2008)) on how to use the previous functions to apply it.

julia> n = 4453
-4453
-
-julia> A = residue_ring(ZZ, ZZ(n))
-Integers modulo 4453
-
-julia> S, (x,y,z) = polynomial_ring(A, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over ZZ/(4453), AbstractAlgebra.Generic.MPoly{ZZModRingElem}[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over ZZ/(4453), MPolyDecRingElem{ZZModRingElem, AbstractAlgebra.Generic.MPoly{ZZModRingElem}}[x, y, z])
-
-julia> E = Oscar.ProjEllipticCurve(T(y^2*z - x^3 - 10*x*z^2 + 2*z^3))
-Projective elliptic curve defined by 4452*x^3 + 4443*x*z^2 + y^2*z + 2*z^3
-
-julia> PP = proj_space(A, 2)
-(Projective space of dim 2 over Integers modulo 4453
-, MPolyDecRingElem{ZZModRingElem, AbstractAlgebra.Generic.MPoly{ZZModRingElem}}[x[0], x[1], x[2]])
-
-julia> Q = Oscar.Geometry.ProjSpcElem(PP[1], [A(1), A(3), A(1)])
-(1 : 3 : 1)
-
-julia> P = Oscar.Point_EllCurve(E, Q)
-(1 : 3 : 1)
-
-julia> P2 = Oscar.IntMult_Point_EllCurveZnZ(ZZ(2), P)
-(4332 : 3230 : 1)
-
-julia> Oscar.sum_Point_EllCurveZnZ(P, P2)
-ERROR: 61 is not invertible in the base ring, cannot perform the sum
-

The last sum is not defined, and the error which is shown when we ask for the sum gives us a factor of 4453. The Elliptic Curve Method is implemented and can be called using:

ECMMethod
ECM(n::ZZRingElem; nbcurve::Int = 25000, multfact::ZZRingElem = factorial(ZZ(10^4)))

Return a factor of n, obtained with the Elliptic Curve Method.

source

Elliptic Curve Primality Proving

Elliptic curves over finite fields or rings are used for the method called "Elliptic Curve Primality Proving". We implemented here the version relying on Atkin-Morain's test. The present implementation is not intended to be competitive.

ECPPMethod
ECPP(n::ZZRingElem)

The algorithm returns true if the number is prime, false if not, and an error if it can't decide.

source

Other algorithms

TODO: The following algorithms are not directly related to Plane Curves, they might be moved to another section of the documentation.

cornacchia_algorithmMethod
cornacchia_algorithm(d::ZZRingElem, m::ZZRingElem)

Return true and a solution of x^2 + d*y^2 = m if it exists, and false and (0, 0) otherwise.

source
Miller_Rabin_testFunction
Miller_Rabin_test(N::ZZRingElem, k::Int64 = 20)

Given an odd number N, return false if the number is composite, and true if it is probably prime.

source
Pollard_rhoFunction
Pollard_rho(N::ZZRingElem, bound::Int = 50000)

The algorithm computes a factor of N using the Pollard rho algorithm and returns it.

source
Pollard_p_1Function
Pollard_p_1(N::ZZRingElem, B::ZZRingElem = ZZ(10)^5)

The algorithm computes a factor of N and returns it.

source
diff --git a/previews/PR2578/Experimental/PlaneCurve/introduction/index.html b/previews/PR2578/Experimental/PlaneCurve/introduction/index.html deleted file mode 100644 index c41c3db66ed5..000000000000 --- a/previews/PR2578/Experimental/PlaneCurve/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl
diff --git a/previews/PR2578/Experimental/PlaneCurve/non_plane_curves/index.html b/previews/PR2578/Experimental/PlaneCurve/non_plane_curves/index.html deleted file mode 100644 index d0afdf4356e7..000000000000 --- a/previews/PR2578/Experimental/PlaneCurve/non_plane_curves/index.html +++ /dev/null @@ -1,77 +0,0 @@ - -Projective Curves · Oscar.jl

Projective Curves

We consider projective curves in projective spaces of arbitrary dimension.

Constructors

We define a projective curve by an ideal of homogeneous polynomials.

ProjCurveType
ProjCurve(I::MPolyIdeal)

Given a homogeneous ideal I of Krull dimension 2, return the projective curve defined by I.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, ["w", "x", "y", "z"]);
-
-julia> M = matrix(R, 2, 3, [w x y; x y z])
-[w   x   y]
-[x   y   z]
-
-julia> V = minors(M, 2)
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- w*y - x^2
- w*z - x*y
- x*z - y^2
-
-julia> I = ideal(R, V);
-
-julia> TC = ProjCurve(I)
-Projective curve defined by the ideal(w*y - x^2, w*z - x*y, x*z - y^2)
source

General functions for curves

defining_idealMethod
defining_ideal(C::ProjCurve)

Return the defining ideal of the projective curve C.

source
inMethod
in(P::Oscar.Geometry.ProjSpcElem, C::ProjCurve)

Return true if the point P is on the curve C, and false otherwise.

Examples

julia> S, (x, y, z, t) = polynomial_ring(QQ, ["x", "y", "z", "t"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])
-
-julia> I = ideal(T, [x^2, y^2*z, z^2])
-ideal(x^2, y^2*z, z^2)
-
-julia> C = Oscar.ProjCurve(I)
-Projective curve defined by the ideal(x^2, y^2*z, z^2)
-
-
-julia> PP = proj_space(QQ, 3)
-(Projective space of dim 3 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2], x[3]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(2), QQ(0), QQ(5)])
-(0 : 2 : 0 : 5)
-
-julia> P in C
-true
source
curve_componentsMethod
curve_components(C::ProjCurve)

Return a dictionary containing the irreducible components of C and the corresponding reduced curve.

source
is_irreducibleMethod
is_irreducible(C::ProjCurve)

Return true if C is irreducible, and false otherwise.

Examples

julia> S, (x, y, z, t) = polynomial_ring(QQ, ["x", "y", "z", "t"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])
-
-julia> I = ideal(T, [x^2, y^2*z, z^2])
-ideal(x^2, y^2*z, z^2)
-
-julia> C = Oscar.ProjCurve(I)
-Projective curve defined by the ideal(x^2, y^2*z, z^2)
-
-julia> Oscar.is_irreducible(C)
-true
source
reductionMethod
reduction(C::ProjCurve)

Return the projective curve defined by the radical of the defining ideal of C.

Examples

julia> S, (x, y, z, t) = polynomial_ring(QQ, ["x", "y", "z", "t"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])
-
-julia> I = ideal(T, [x^2, y^2*z, z^2])
-ideal(x^2, y^2*z, z^2)
-
-julia> C = Oscar.ProjCurve(I)
-Projective curve defined by the ideal(x^2, y^2*z, z^2)
-
-julia> Oscar.reduction(C)
-Projective curve defined by the ideal(z, x)
source
jacobi_idealMethod
jacobi_ideal(C::ProjCurve)

Return the Jacobian ideal of the defining ideal of C.

Examples

julia> S, (x, y, z, t) = polynomial_ring(QQ, ["x", "y", "z", "t"])
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])
-
-julia> I = ideal(T, [x^2, y^2*z, z^2])
-ideal(x^2, y^2*z, z^2)
-
-julia> C = Oscar.ProjCurve(I)
-Projective curve defined by the ideal(x^2, y^2*z, z^2)
-
-julia> Oscar.jacobi_ideal(C)
-ideal(4*x*y*z, 2*x*y^2, 4*x*z, 4*y*z^2)
source
invert_birational_mapMethod
invert_birational_map(phi::Vector{T}, C::ProjCurve) where {T <: MPolyRingElem}

Return a dictionary where image represents the image of the birational map given by phi, and inverse represents its inverse, where phi is a birational map of the projective curve C to its image in the projective space of dimension size(phi) - 1. Note that the entries of inverse should be considered as representatives of elements in R/image, where R is the basering.

source
diff --git a/previews/PR2578/Experimental/PlaneCurve/plane_curves/index.html b/previews/PR2578/Experimental/PlaneCurve/plane_curves/index.html deleted file mode 100644 index 30252d8cc64f..000000000000 --- a/previews/PR2578/Experimental/PlaneCurve/plane_curves/index.html +++ /dev/null @@ -1,293 +0,0 @@ - -Affine and Projective Plane Curves · Oscar.jl

Affine and Projective Plane Curves

We consider two kinds of plane curves: affine and projective. An affine plane curve is defined by a polynomial in two variables, whereas a projective plane curve is defined by a homogeneous polynomial belonging to a graded polynomial ring in three variables.

Affine Plane Curves

An affine plane curve is defined as the class of a two-variables polynomial $F$ over a field $K$, modulo the equivalence relation $F \sim G \iff \exists \lambda \in K\backslash \{0\}, F = \lambda \cdot G$.

Example

AffinePlaneCurveType
AffinePlaneCurve{S}(eq::Oscar.MPolyRingElem{S}) where S <: FieldElem

Return the Affine Plane Curve defined by the polynomial in two variables eq.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> F = y^3*x^6 - y^6*x^2
-x^6*y^3 - x^2*y^6
-
-julia> C = AffinePlaneCurve(F)
-Affine plane curve defined by x^6*y^3 - x^2*y^6
source

Projective Plane Curves

Similarly, a projective plane curve is defined as the class of a three-variables homogeneous polynomial $F$ over a field $K$, modulo the equivalence relation $F\sim G \iff \exists \lambda \in K\backslash \{0\}, F = \lambda \cdot G$. The defining equation is supposed to belong to a graded ring.

ProjPlaneCurveType
ProjPlaneCurve{S}(eq::Oscar.MPolyDecRingElem{S}) where {S <: FieldElem}

Return the Projective Plane Curve defined by the homogeneous polynomial in three variables eq.

Examples

julia> R, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(R)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> F = T(y^3*x^6 - y^6*x^2*z)
-x^6*y^3 - x^2*y^6*z
-
-julia> ProjPlaneCurve(F)
-Projective plane curve defined by x^6*y^3 - x^2*y^6*z
source

A particular kind of projective curves is the case of elliptic curves, see the corresponding section for more information. The types ProjPlaneCurve and ProjEllipticCurve are subtypes of the abstract type ProjectivePlaneCurve. In addition, the types AffinePlaneCurve and ProjectivePlaneCurve are subtypes of the abstract type PlaneCurve.

Points

When considering curves, it is natural to have a look at points on the curve. We describe in this section how to deal with points, both in the affine and projective settings.

Point in the affine space

A point in the affine space can be defined as follows:

PointType
Point(coordinates::Vector{S}) where {S <: FieldElem}

Return the point with the given coordinates.

Examples

julia> P = Point([QQ(1), QQ(2), QQ(2)])
-Point with coordinates QQFieldElem[1, 2, 2]
source

We consider also the following function for points.

ideal_pointMethod
ideal_point(R::MPolyRing{S}, P::Point{S}) where S <: FieldElem

Return the maximal ideal associated to the point P in the ring R.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> P = Point([QQ(2), QQ(1)])
-Point with coordinates QQFieldElem[2, 1]
-
-julia> Oscar.ideal_point(R, P)
-ideal(x - 2, y - 1)
source

The following function checks if a given point is on a curve:

inMethod
in(P::Point{S}, C::AffinePlaneCurve{S}) where S <: FieldElem

Return true if the point P is on the curve C, and false otherwise.

source

Point in the projective space

In order to define a point in the projective plane, one needs first to define the projective plane as follows, where K is the base ring:

julia> K = QQ
-Rational field
-
-julia> PP = proj_space(K, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-

Then, one can define a projective point as follows:

julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(1), QQ(2), QQ(-5)])
-(1 : 2 : -5)
-

The following function checks if a given point is on a curve:

inMethod
in(P::Oscar.Geometry.ProjSpcElem{S}, C::ProjectivePlaneCurve{S}) where S <: FieldElem

Return true if the point P is on the curve C, and false otherwise.

source

General functions for curves

degreeMethod
degree(C::PlaneCurve)

Return the degree of the defining polynomial of C.

source
ringMethod
ring(C::PlaneCurve)

Return the coordinate ring of the curve C.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^2+x-x^3)
-Affine plane curve defined by -x^3 + x + y^2
-
-julia> Oscar.ring(C)
-(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from
-Multivariate polynomial ring in 2 variables over QQ to Quotient of multivariate polynomial ring by ideal with 1 generator defined by a julia-function with inverse)
source
curve_componentsMethod
curve_components(C::PlaneCurve{S}) where S <: FieldElem

Return a dictionary containing the irreducible components of C and their multiplicity.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^3*x^6 - y^6*x^2)
-Affine plane curve defined by x^6*y^3 - x^2*y^6
-
-julia> Oscar.curve_components(C)
-Dict{AffinePlaneCurve{QQFieldElem}, Int64} with 3 entries:
-  y         => 3
-  x         => 2
-  x^4 - y^3 => 1
source
reductionMethod
reduction(C::AffinePlaneCurve{S}) where S <: FieldElem
-reduction(C::ProjPlaneCurve{S}) where S <: FieldElem

Return the plane curve defined by the squarefree part of the equation of C.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^3*x^6 - y^6*x^2)
-Affine plane curve defined by x^6*y^3 - x^2*y^6
-
-julia> Oscar.reduction(C)
-Affine plane curve defined by x^5*y - x*y^4
source
is_irreducibleMethod
is_irreducible(C::PlaneCurve{S}) where S <: FieldElem

Return true if C is irreducible, and false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^2+x-x^3)
-Affine plane curve defined by -x^3 + x + y^2
-
-julia> Oscar.is_irreducible(C)
-true
-
-julia> D = AffinePlaneCurve(y^3*x^6 - y^6*x^2)
-Affine plane curve defined by x^6*y^3 - x^2*y^6
-
-julia> Oscar.is_irreducible(D)
-false
source
is_reducedMethod
is_reduced(C::PlaneCurve{S}) where S <: FieldElem

Return true if C is reduced, and false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^2+x-x^3)
-Affine plane curve defined by -x^3 + x + y^2
-
-julia> Oscar.is_reduced(C)
-true
-
-julia> D = AffinePlaneCurve(y^3*x^6 - y^6*x^2)
-Affine plane curve defined by x^6*y^3 - x^2*y^6
-
-julia> Oscar.is_reduced(D)
-false
source
unionMethod
union(C::T, D::T) where T <: PlaneCurve

Return the union of C and D (with multiplicity).

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^2+x-x^3)
-Affine plane curve defined by -x^3 + x + y^2
-
-julia> D = AffinePlaneCurve(y^3*x^6 - y^6*x^2)
-Affine plane curve defined by x^6*y^3 - x^2*y^6
-
-julia> union(C, D)
-Affine plane curve defined by -x^9*y^3 + x^7*y^3 + x^6*y^5 + x^5*y^6 - x^3*y^6 - x^2*y^8
source
arithmetic_genusMethod
arithmetic_genus(C::ProjectivePlaneCurve)

Return the arithmetic genus of C.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(T(y^2 * z - x^3 - x * z^2))
-Projective plane curve defined by -x^3 - x*z^2 + y^2*z
-
-julia> Oscar.PlaneCurveModule.arithmetic_genus(C)
-1
source
arithmetic_genusMethod
arithmetic_genus(C::AffinePlaneCurve)

Return the arithmetic genus of the projective closure of C.

source
geometric_genusMethod
geometric_genus(C::ProjectivePlaneCurve{T}) where T <: FieldElem

Return the geometric genus of C.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> C = ProjPlaneCurve(z*x^2-y^3)
-Projective plane curve defined by x^2*z - y^3
-
-julia> geometric_genus(C)
-0
source
geometric_genusMethod
geometric_genus(C::AffinePlaneCurve)

Return the geometric genus of the projective closure of C.

Examples

julia> R, (x, y) = polynomial_ring(GF(7), ["x", "y"])
-(Multivariate polynomial ring in 2 variables over GF(7), fpMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^9 - x^2*(x-1)^9)
-Affine plane curve defined by 6*x^11 + 2*x^10 + 6*x^9 + x^4 + 5*x^3 + x^2 + y^9
-
-julia> geometric_genus(C)
-0
source
jacobi_idealMethod
jacobi_ideal(C::PlaneCurve)

Return the Jacobian ideal of the defining polynomial of C.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(y^3*x^6 - y^6*x^2)
-Affine plane curve defined by x^6*y^3 - x^2*y^6
-
-julia> Oscar.jacobi_ideal(C)
-ideal(6*x^5*y^3 - 2*x*y^6, 3*x^6*y^2 - 6*x^2*y^5)
source
is_smoothMethod
is_smooth(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem

Throw an error if P is not a point of C, return false if P is a singular point of C, and true if P is a smooth point of C.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))
-Affine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4
-
-julia> P = Point([QQ(0), QQ(0)])
-Point with coordinates QQFieldElem[0, 0]
-
-julia> is_smooth(C, P)
-false
source
is_smoothMethod
is_smooth(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem

Throw an error if P is not a point of C, return false if P is a singular point of C, and true if P is a smooth point of C.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> C = ProjPlaneCurve(x^2*(x+y)*(y^3-x^2*z))
-Projective plane curve defined by -x^5*z - x^4*y*z + x^3*y^3 + x^2*y^4
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])
-(0 : 0 : 1)
-
-julia> is_smooth(C, P)
-false
source
tangentMethod
tangent(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem

Return the tangent of C at P when P is a smooth point of C, and throw an error otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))
-Affine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4
-
-julia> P2 = Point([QQ(2), QQ(-2)])
-Point with coordinates QQFieldElem[2, -2]
-
-julia> tangent(C, P2)
-Affine plane curve defined by -48*x - 48*y
source
tangentMethod
tangent(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem

Return the tangent of C at P when P is a smooth point of C, and throw an error otherwise.

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y","z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> C = ProjPlaneCurve(x^2*(x+y)*(y^3-x^2*z))
-Projective plane curve defined by -x^5*z - x^4*y*z + x^3*y^3 + x^2*y^4
-
-julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(2), QQ(-2), QQ(1)])
-(2 : -2 : 1)
-
-julia> tangent(C, P)
-Projective plane curve defined by -48*x - 48*y
source
curve_singular_locusMethod
curve_singular_locus(C::AffinePlaneCurve)

Return the reduced singular locus of C as a list whose first element is the affine plane curve consisting of the singular components of C (if any), and the second element is the list of the isolated singular points (which may be contained in the singular component). The singular component might not contain any point over the considered field.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))
-Affine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4
-
-julia> curve_singular_locus(C)
-2-element Vector{Vector}:
- AffinePlaneCurve[Affine plane curve defined by x]
- Point[Point with coordinates QQFieldElem[-1, 1], Point with coordinates QQFieldElem[0, 0]]
source
curve_singular_locusMethod
curve_singular_locus([PP::Oscar.Geometry.ProjSpc{S}], C::ProjectivePlaneCurve{S}) where S <: FieldElem

Return the reduced singular locus of C as a list whose first element is the projective plane curve consisting of the singular components of C (if any), and the second element is the list of the singular points of the reduction of C (the points are in PP if specified, or in a new projective space otherwise). The singular component might not contain any point over the considered field.

source
multiplicityMethod
multiplicity(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem

Return the multiplicity of C at P.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))
-Affine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4
-
-julia> P = Point([QQ(2), QQ(-2)])
-Point with coordinates QQFieldElem[2, -2]
-
-julia> multiplicity(C, P)
-1
source
multiplicityMethod
 multiplicity(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem

Return the multiplicity of C at P.

source
tangent_linesMethod
tangent_lines(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem

Return the tangent lines at P to C with their multiplicity.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))
-Affine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4
-
-julia> P = Point([QQ(0), QQ(0)])
-Point with coordinates QQFieldElem[0, 0]
-
-julia> tangent_lines(C, P)
-Dict{AffinePlaneCurve{QQFieldElem}, Int64} with 2 entries:
-  x     => 4
-  x + y => 1
source
tangent_linesMethod
  tangent_lines(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem

Return the tangent lines at P to C with their multiplicity.

source
is_smooth_curveMethod
is_smooth_curve(C::AffinePlaneCurve)

Return true if C has no singular point, and false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x*(x+y))
-Affine plane curve defined by x^2 + x*y
-
-julia> is_smooth_curve(C)
-false
source
is_smooth_curveMethod
is_smooth_curve(C::ProjectivePlaneCurve)

Return true if C has no singular point, and false otherwise.

source

Intersection of curves

common_componentsMethod
common_components(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}) where S <: FieldElem

Return the affine plane curve consisting of the common component of C and D, or an empty vector if they do not have a common component.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x*(x+y)*(x^2 + x + 1))
-Affine plane curve defined by x^4 + x^3*y + x^3 + x^2*y + x^2 + x*y
-
-julia> D = AffinePlaneCurve(x*(x+y)*(x-y))
-Affine plane curve defined by x^3 - x*y^2
-
-julia> common_components(C, D)
-1-element Vector{AffinePlaneCurve{QQFieldElem}}:
- Affine plane curve defined by x^2 + x*y
source
common_componentsMethod
common_components(C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}) where S <: FieldElem

Return the projective plane curve consisting of the common component of C and D, or an empty vector if they do not have a common component.

source
curve_intersectMethod
curve_intersect(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}) where S <: FieldElem

Return a list whose first element is the affine plane curve defined by the gcd of C.eq and D.eq, the second element is the list of the remaining intersection points when the common components are removed from C and D.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x*(x+y))
-Affine plane curve defined by x^2 + x*y
-
-julia> D = AffinePlaneCurve((x-y)*(x-2))
-Affine plane curve defined by x^2 - x*y - 2*x + 2*y
-
-julia> curve_intersect(C, D)
-2-element Vector{Vector}:
- AffinePlaneCurve[]
- Point{QQFieldElem}[Point with coordinates QQFieldElem[0, 0], Point with coordinates QQFieldElem[2, -2]]
source
curve_intersectMethod
curve_intersect([PP::Oscar.Geometry.ProjSpc{S}], C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}) where S <: FieldElem

Return a list whose first element is the projective plane curve defined by the gcd of C.eq and D.eq, the second element is the list of the remaining intersection points when the common components are removed from C and D (the points are in PP if specified, or in a new projective space otherwise).

Examples

julia> S, (x, y, z) = polynomial_ring(QQ, ["x", "y","z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> T, _ = grade(S)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> PP = proj_space(QQ, 2)
-(Projective space of dim 2 over Rational field
-, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])
-
-julia> C = ProjPlaneCurve(T(x+y+z))
-Projective plane curve defined by x + y + z
-
-julia> D = ProjPlaneCurve(T(z))
-Projective plane curve defined by z
-
-julia> curve_intersect(PP[1], C, D)
-2-element Vector{Vector{Any}}:
- []
- [(-1 : 1 : 0)]
source
intersection_multiplicityMethod
intersection_multiplicity(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem

Return the intersection multiplicity of C and D at P.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve((x^2+y^2)*(x^2 + y^2 + 2*y))
-Affine plane curve defined by x^4 + 2*x^2*y^2 + 2*x^2*y + y^4 + 2*y^3
-
-julia> D = AffinePlaneCurve((x^2+y^2)*(y^3*x^6 - y^6*x^2))
-Affine plane curve defined by x^8*y^3 + x^6*y^5 - x^4*y^6 - x^2*y^8
-
-julia> Q = Point([QQ(0), QQ(-2)])
-Point with coordinates QQFieldElem[0, -2]
-
-julia> intersection_multiplicity(C, D, Q)
-2
source
intersection_multiplicityMethod
 intersection_multiplicity(C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem

Return the intersection multiplicity of C and D at P.

source
aretransverseMethod
aretransverse(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}, P::Point{S}) where S<:FieldElem

Return true if C and D intersect transversally at P and false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> C = AffinePlaneCurve(x*(x+y))
-Affine plane curve defined by x^2 + x*y
-
-julia> D = AffinePlaneCurve((x-y)*(x-2))
-Affine plane curve defined by x^2 - x*y - 2*x + 2*y
-
-julia> P = Point([QQ(0), QQ(0)])
-Point with coordinates QQFieldElem[0, 0]
-
-julia> Q = Point([QQ(2), QQ(-2)])
-Point with coordinates QQFieldElem[2, -2]
-
-julia> aretransverse(C, D, P)
-false
-
-julia> aretransverse(C, D, Q)
-true
source
aretransverseMethod
 aretransverse(C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S<:FieldElem

Return true if C and D intersect transversally at P and false otherwise.

source
diff --git a/previews/PR2578/Experimental/QuadFormAndIsom/enumeration/index.html b/previews/PR2578/Experimental/QuadFormAndIsom/enumeration/index.html deleted file mode 100644 index 1e9257a6aebb..000000000000 --- a/previews/PR2578/Experimental/QuadFormAndIsom/enumeration/index.html +++ /dev/null @@ -1,118 +0,0 @@ - -Enumeration of isometries · Oscar.jl

Enumeration of isometries

One of the main features of this project is the enumeration of lattices with isometry of finite order with at most two prime divisors. This is the content of Simon Brandhorst, Tommy Hofmann (2023) which has been implemented. We guide the user here to the global aspects of the available theory, and we refer to the paper Simon Brandhorst, Tommy Hofmann (2023) for further reference.

Admissible triples

Roughly speaking, for a prime number $p$, a $p$-admissible triple (A, B, C) is a triple of integer lattices such that, in certain cases, C can be obtained as a primitive extension $A \perp B \to C$ where one can glue along $p$-elementary subgroups of the respective discriminant groups of A and B. Note that not all admissible triples satisfy this extension property.

For instance, if $f$ is an isometry of an integer lattice C of prime order p, then for $A := \ker \Phi_1(f)$ and $B := \ker \Phi_p(f)$, one has that (A, B, C) is $p$-admissible (see Lemma 4.15. in Simon Brandhorst, Tommy Hofmann (2023)).

We say that a triple (AA, BB, CC) of genus symbols for integer lattices is $p$-admissible if there are some lattices $A \in AA$, $B \in BB$ and $C \in CC$ such that $(A, B, C)$ is $p$-admissible.

We use Definition 4.13. and Algorithm 1 of Simon Brandhorst, Tommy Hofmann (2023) to implement the necessary tools for working with admissible triples. Most of the computations consists of local genus symbol manipulations and combinatorics. The code also relies on enumeration of integer genera with given signatures, determinant and bounded scale valuations for the Jordan components at all the relevant primes (see integer_genera).

admissible_triplesMethod
admissible_triples(C::ZZGenus, p::Integer) -> Vector{Tuple{ZZGenus, ZZGenus}}

Given a $\mathbb Z$-genus C and a prime number p, return all tuples of $\mathbb Z$-genera (A, B) such that (A, B, C) is p-admissible and B is of rank divisible by $p-1$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> g = genus(L)
-Genus symbol for integer lattices
-Signatures: (5, 0, 0)
-Local symbols:
-  Local genus symbol at 2: 1^-4 2^1_7
-  Local genus symbol at 3: 1^-4 3^1
-
-julia> admissible_triples(g, 5)
-2-element Vector{Tuple{ZZGenus, ZZGenus}}:
- (Genus symbol: II_(5, 0) 2^-1_3 3^1, Genus symbol: II_(0, 0))
- (Genus symbol: II_(1, 0) 2^1_7 3^1 5^1, Genus symbol: II_(4, 0) 5^1)
-
-julia> admissible_triples(g, 2)
-8-element Vector{Tuple{ZZGenus, ZZGenus}}:
- (Genus symbol: II_(5, 0) 2^-1_3 3^1, Genus symbol: II_(0, 0))
- (Genus symbol: II_(4, 0) 2^2_6 3^1, Genus symbol: II_(1, 0) 2^1_1)
- (Genus symbol: II_(3, 0) 2^-3_1 3^1, Genus symbol: II_(2, 0) 2^2_2)
- (Genus symbol: II_(3, 0) 2^3_3, Genus symbol: II_(2, 0) 2^-2 3^1)
- (Genus symbol: II_(2, 0) 2^-2 3^1, Genus symbol: II_(3, 0) 2^3_3)
- (Genus symbol: II_(2, 0) 2^2_2, Genus symbol: II_(3, 0) 2^-3_1 3^1)
- (Genus symbol: II_(1, 0) 2^1_1, Genus symbol: II_(4, 0) 2^2_6 3^1)
- (Genus symbol: II_(0, 0), Genus symbol: II_(5, 0) 2^-1_3 3^1)
source
is_admissible_tripleMethod
is_admissible_triple(A::ZZGenus, B::ZZGenus, C::ZZGenus, p::Integer) -> Bool

Given a triple of $\mathbb Z$-genera (A,B,C) and a prime number p, such that the rank of B is divisible by $p-1$, return whether (A,B,C) is p-admissible.

Examples

A standard example is the following: let $(L, f)$ be a lattice with isometry of prime order $p$, let $F:= L^f$ and $C:= L_f$ be respectively the invariant and coinvariant sublattices of $(L, f)$. Then, the triple of genera $(g(F), g(C), g(L))$ is $p$-admissible.

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> F = invariant_lattice(Lf);
-
-julia> C = coinvariant_lattice(Lf);
-
-julia> is_admissible_triple(genus(F), genus(C), genus(Lf), 5)
-true
source

Note that admissible triples are mainly used for enumerating lattices with isometry of a given order and in a given genus.

Enumeration functions

We give an overview of the functions implemented for the enumeration of the isometries of integral integer lattices. For more details such as the proof of the algorithms and the theory behind them, we refer to the reference paper Simon Brandhorst, Tommy Hofmann (2023).

Global function

As we will see later, the algorithms from Simon Brandhorst, Tommy Hofmann (2023) are specialized on the requirement for the input and regular users might not be able to choose between the functions available. We therefore provide a general function which allows one to enumerate lattices with isometry of a given order and in a given genus. The only requirements are to provide a genus symbol, or a lattice from this genus, and the order wanted (as long as the number of distinct prime divisors is at most 2).

enumerate_classes_of_lattices_with_isometryMethod
enumerate_classes_of_lattices_with_isometry(L::ZZLat, order::IntegerUnion)
-                                                        -> Vector{ZZLatWithIsom}
-enumerate_classes_of_lattices_with_isometry(G::ZZGenus, order::IntegerUnion)
-                                                        -> Vector{ZZLocalGenus}

Given an integral integer lattice L, return representatives of isomorphism classes of lattice with isometry $(M ,g)$ where M is in the genus of L, and g has order order. Alternatively, one can input a given genus symbol G for integral integer lattices as an input - the function first computes a representative of G.

Note that currently we support only orders which admit at most 2 prime divisors.

source

As a remark: if $n = p^dq^e$ is the chosen order, with $p < q$ prime numbers, the previous function computes first iteratively representatives for all classes with isometry in the given genus of order $q^e$. Then, the function increases iteratively the order up to $p^dq^e$.

Underlying machinery

Here is a list of the algorithmic machinery provided by Simon Brandhorst, Tommy Hofmann (2023) used previously to enumerate lattices with isometry:

representatives_of_hermitian_typeMethod
representatives_of_hermitian_type(Lf::ZZLatWithIsom, m::Int = 1)
-                                        -> Vector{ZZLatWithIsom}

Given a lattice with isometry $(L, f)$ of hermitian type (i.e. the minimal polynomial of f is irreducible cyclotomic) and a positive integer m, return a set of representatives of isomorphism classes of lattices with isometry of hermitian type $(M, g)$ and such that the type of $(B, g^m)$ is equal to the type of $(L, f)$. Note that in this case, the isometries g's are of order $nm$.

Examples

julia> L = root_lattice(:A,2);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> reps = representatives_of_hermitian_type(Lf, 6)
-1-element Vector{ZZLatWithIsom}:
- Integer lattice with isometry of finite order 6
-
-julia> is_of_hermitian_type(reps[1])
-true
source
splitting_of_hermitian_prime_powerMethod
splitting_of_hermitian_prime_power(Lf::ZZLatWithIsom, p::Int) -> Vector{ZZLatWithIsom}

Given a lattice with isometry $(L, f)$ of hermitian type with f of order $q^e$ for some prime number q, and given another prime number $p \neq q$, return a set of representatives of the isomorphism classes of lattices with isometry $(M, g)$ such that the type of $(M, g^p)$ is equal to the type of $(L, f)$.

Note that e can be 0.

Examples

julia> L = root_lattice(:A,2);
-
-julia> f = matrix(QQ, 2, 2, [0 1; -1 -1]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> is_of_hermitian_type(Lf)
-true
-
-julia> reps = splitting_of_hermitian_prime_power(Lf, 2)
-2-element Vector{ZZLatWithIsom}:
- Integer lattice with isometry of finite order 6
- Integer lattice with isometry of finite order 3
-
-julia> all(is_of_hermitian_type, reps)
-true
-
-julia> is_of_same_type(Lf, reps[1]^2)
-true
-
-julia> is_of_same_type(Lf, reps[2]^2)
-true
source
splitting_of_prime_powerMethod
splitting_of_prime_power(Lf::ZZLatWithIsom, p::Int, b::Int = 0)
-                                                   -> Vector{ZZLatWithIsom}

Given a lattice with isometry $(L, f)$ with f of order $q^e$ for some prime number q, a prime number $p \neq q$ and an integer $b = 0, 1$, return a set of representatives of the isomorphism classes of lattices with isometry $(M, g)$ such that the type of $(M, g^p)$ is equal to the type of $(L, f)$.

If b == 1, return only the lattices with isometry $(M, g)$ where g is of order $pq^e$.

Note that e can be 0.

Examples

julia> L = root_lattice(:A,2);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> splitting_of_prime_power(Lf, 2)
-4-element Vector{ZZLatWithIsom}:
- Integer lattice with isometry of finite order 2
- Integer lattice with isometry of finite order 2
- Integer lattice with isometry of finite order 2
- Integer lattice with isometry of finite order 1
-
-julia> splitting_of_prime_power(Lf, 3, 1)
-1-element Vector{ZZLatWithIsom}:
- Integer lattice with isometry of finite order 3
source
splitting_of_pure_mixed_prime_powerMethod
splitting_of_pure_mixed_prime_power(Lf::ZZLatWithIsom, p::Int)
-                                             -> Vector{ZZLatWithIsom}

Given a lattice with isometry $(L, f)$ and a prime number p, such that $\prod_{i=0}^e\Phi_{p^dq^i}(f)$ is trivial for some $d > 0$ and $e \geq 0$, return a set of representatives of the isomorphism classes of lattices with isometry $(M, g)$ such that the type of $(M, g^p)$ is equal to the type of $(L, f)$.

Note that e can be 0, while d has to be positive.

source
splitting_of_mixed_prime_powerMethod
splitting_of_mixed_prime_power(Lf::ZZLatWithIsom, p::Int, b::Int = 1)
-                                      -> Vector{ZZLatWithIsom}

Given a lattice with isometry $(L, f)$ and a prime number p such that f is of order $p^dq^e$ for some prime number $q \neq p$, return a set of representatives of the isomorphism classes of lattices with isometry $(M, g)$ such that the type of $(M, g^p)$ is equal to the type of $(L, f)$.

If b == 1, return only the lattices with isometry $(M, g)$ where g is of order $p^{d+1}q^e$.

Note that d and e can be both zero.

Examples

julia> L = root_lattice(:E,7);
-
-julia> f = matrix(QQ, 7, 7, [ 1  1  2  1  0  0  1;
-                             -1 -2 -3 -2 -1 -1 -1;
-                              0  1  2  1  1  1  1;
-                              0  0 -1 -1 -1 -1 -1;
-                              1  1  2  2  2  1  1;
-                              0  0 -1 -1 -1  0  0;
-                              0  0  0  1  0  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 7 and degree 7
-  with isometry of finite order 6
-  given by
-  [ 1    1    2    1    0    0    1]
-  [-1   -2   -3   -2   -1   -1   -1]
-  [ 0    1    2    1    1    1    1]
-  [ 0    0   -1   -1   -1   -1   -1]
-  [ 1    1    2    2    2    1    1]
-  [ 0    0   -1   -1   -1    0    0]
-  [ 0    0    0    1    0    0    0]
-
-julia> reps = splitting_of_mixed_prime_power(Lf, 2)
-2-element Vector{ZZLatWithIsom}:
- Integer lattice with isometry of finite order 12
- Integer lattice with isometry of finite order 12
-
-julia> all(LL -> is_of_same_type(Lf, LL^2), reps)
-true
source

Note that an important feature from the theory in Simon Brandhorst, Tommy Hofmann (2023) is the notion of admissible gluings and equivariant primitive embeddings for admissible triples. In the next chapter, we present the methods regarding Nikulins's theory on primitive embeddings and their equivariant version. We use this basis to introduce the method admissible_equivariant_primitive_extension (Algorithm 2 in Simon Brandhorst, Tommy Hofmann (2023)) which is the major tool making the previous enumeration possible and fast, from an algorithmic point of view.

diff --git a/previews/PR2578/Experimental/QuadFormAndIsom/introduction/index.html b/previews/PR2578/Experimental/QuadFormAndIsom/introduction/index.html deleted file mode 100644 index 606dba78ee9a..000000000000 --- a/previews/PR2578/Experimental/QuadFormAndIsom/introduction/index.html +++ /dev/null @@ -1,17 +0,0 @@ - -Quadratic forms and isometries · Oscar.jl

Quadratic forms and isometries

This project is a complement to the code about hermitian lattices available in Hecke. We aim here to connect Hecke and GAP to handle some algorithmic methods regarding quadratic forms with their isometries. In particular, the integration of this code within Oscar is necessary to benefit from all the performance of GAP with respect to computations with groups and automorphisms in general.

For now, the project covers methods regarding rational and integral quadratic forms.

Content

We introduce two new structures

The former parametrizes pairs $(V, f)$ where $V$ is a rational quadratic form and $f$ is an isometry of $V$. The latter parametrizes pairs $(L, f)$ where $L$ is an integral quadratic form, also known as $\mathbb Z$-lattice and $f$ is an isometry of $L$. One of the main features of this project is the enumeration of isomorphism classes of pairs $(L, f)$, where $f$ is an isometry of finite order with at most two prime divisors. The methods we resort to for this purpose are developed in the paper [BH23].

We also provide some algorithms computing isomorphism classes of primitive embeddings of even lattices following Nikulin's theory. More precisely, the function primitive_embeddings offers, under certain conditions, the possibility to compute representatives of primitive embeddings and classify them in different ways. Note nonetheless that these functions are not efficient in the case were the discriminant groups have a large number of subgroups.

Status

This project has been slightly tested on simple and known examples. It is currently being tested on a larger scale to test its reliability. Moreover, there are still computational bottlenecks due to non-optimized algorithms.

Among the possible improvements and extensions:

  • Implement extra methods for lattices with isometries of infinite order;
  • Extend existing methods for equivariant primitive embeddings/extensions.

Currently application of this project

The project was initiated by S. Brandhorst and T. Hofmann for classifying finite subgroups of automorphisms of K3 surfaces. Our current goal is to use this code, and further extensions of it, to classify finite subgroups of bimeromorphic self-maps of hyperkaehler manifolds, which are a higher dimensional analogues of K3 surface.

Tutorials

No tutorials available at the moment.

Examples

No examples available at the moment.

Notice to the user

Disclaimer

Since this project is still under development, feel free to try any feature and report all the bugs you may have found. Any suggestions for improvements or extensions are more than welcome. Refer to the next section to know who you should contact and how. Do not hesitate either to ask for new features - we will be glad to add anything you may need for your research.

One may expect many things to vary within the next months: name of the functions, available features, performance. This is due to the fact that the current version of the code is still at an experimental stage.

Report an issue

If you are working with some objects of type QuadSpaceWithIsom or ZZLatWithIsom and you need to report an issue, you can produce directly some lines of codes helping to reconstruct your example. This can help the reviewers to understand your issue and assist you. We have implemented a method to_oscar which prints few lines of codes for reconstructing your example.


julia> V = quadratic_space(QQ, 2);
julia> Vf = quadratic_space_with_isometry(V, neg = true)Quadratic space of dimension 2 - with isometry of finite order 2 - given by - [-1 0] - [ 0 -1]
julia> Oscar.to_oscar(Vf)G = matrix(QQ, 2, 2, [1 0; 0 1]); -V = quadratic_space(QQ, G); -f = matrix(QQ, 2, 2, [-1 0; 0 -1]); -Vf = quadratic_space_with_isometry(V, f);
julia> Lf = lattice(Vf)Integer lattice of rank 2 and degree 2 - with isometry of finite order 2 - given by - [-1 0] - [ 0 -1]
julia> Oscar.to_oscar(Lf)B = matrix(QQ, 2, 2, [1 0; 0 1]); -G = matrix(QQ, 2, 2, [1 0; 0 1]); -L = integer_lattice(B, gram = G); -f = matrix(QQ, 2, 2, [-1 0; 0 -1]); -Lf = integer_lattice_with_isometry(L, f);

Make the code more talkative

Within the code, there are more hidden messages and testing which are disabled by default. If you plan to experiment with the codes with your favourite examples, you may want to be able to detect some issues to be reported, as well as knowing what the code is doing. Indeed, some functions might take time in term of compilation but also computations. For this, you can enable these extra tests and printings by setting:

Oscar.set_lwi_level(2)

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on GitHub.

diff --git a/previews/PR2578/Experimental/QuadFormAndIsom/latwithisom/index.html b/previews/PR2578/Experimental/QuadFormAndIsom/latwithisom/index.html deleted file mode 100644 index ab90e57af5a4..000000000000 --- a/previews/PR2578/Experimental/QuadFormAndIsom/latwithisom/index.html +++ /dev/null @@ -1,1057 +0,0 @@ - -Lattice with isometry · Oscar.jl

Lattice with isometry

We call lattice with isometry any pair $(L, f)$ consisting of an integer lattice $L$ together with an isometry $f \in O(L)$. We refer to the section about integer lattices of the documentation for new users.

In Oscar, such a pair is encoded in the type called ZZLatWithIsom:

ZZLatWithIsomType
ZZLatWithIsom

A container type for pairs (L, f) consisting on an integer lattice L of type ZZLat and an isometry f given as a QQMatrix representing the action on a given basis of L.

We store the ambient space V of L together with an isometry f_ambient inducing f on L seen as a pair $(V, f_ambient)$ of type QuadSpaceWithIsom. We moreover store the order n of f, which can be finite or infinite.

To construct an object of type ZZLatWithIsom, see the following examples:

Examples

One first way to construct such object, is by entering directly the lattice with an isometry. The isometry can be a honnest isometry of the lattice, or it can be an isometry of the ambient space preserving the lattice. Depending on this choice, one should enter the appropriate boolean value ambient_representation. This direct construction is done through the constructors integer_lattice_with_isometry.

julia> L = root_lattice(:E, 6);
-
-julia> f = matrix(QQ, 6, 6, [ 1  2  3  2  1  1;
-                             -1 -2 -2 -2 -1 -1;                                                
-                              0  1  0  0  0  0;      
-                              1  0  0  0  0  0;
-                             -1 -1 -1  0  0 -1;
-                              0  0  1  1  0  1]);
-
-julia> Lf = integer_lattice_with_isometry(L, f, ambient_representation = false)
-Integer lattice of rank 6 and degree 6
-  with isometry of finite order 8
-  given by
-  [ 1    2    3    2    1    1]
-  [-1   -2   -2   -2   -1   -1]
-  [ 0    1    0    0    0    0]
-  [ 1    0    0    0    0    0]
-  [-1   -1   -1    0    0   -1]
-  [ 0    0    1    1    0    1]
-
-julia> B = matrix(QQ,1,6, [1   2   3   1   -1   3]);
-
-julia> I = lattice_in_same_ambient_space(L, B); # This is the invariant sublattice L^f
-
-julia> If = integer_lattice_with_isometry(I, ambient_isometry(Lf))
-Integer lattice of rank 1 and degree 6
-  with isometry of finite order 1
-  given by
-  [1]
-
-julia> integer_lattice_with_isometry(I, neg=true)
-Integer lattice of rank 1 and degree 6
-  with isometry of finite order 2
-  given by
-  [-1]

Another way to construct such objects is to see them as sub-objects of their ambient space, of type QuadSpaceWithIsom. Through the constructors lattice and lattice_in_same_ambient_space, one can then construct lattices with isometry for free, in a given space, as long as the module they define is preserved by the fixed isometry of the ambient space.

Examples

julia> G = matrix(QQ, 6, 6 , [ 3 1 -1 1 0 0;
-                               1 3  1 1 1 1;
-                              -1 1  3 0 0 1;
-                               1 1  0 4 2 2;
-                               0 1  0 2 4 2;
-                               0 1  1 2 2 4]);
-
-julia> V = quadratic_space(QQ, G);
-
-julia> f = matrix(QQ, 6, 6, [ 1 0  0 0 0  0
-                              0 0 -1 0 0  0
-                             -1 1 -1 0 0  0
-                              0 0  0 1 0 -1
-                              0 0  0 0 0 -1
-                              0 0  0 0 1 -1]);
-
-julia> Vf = quadratic_space_with_isometry(V, f);
-
-julia> Lf = lattice(Vf)
-Integer lattice of rank 6 and degree 6
-  with isometry of finite order 3
-  given by
-  [ 1   0    0   0   0    0]
-  [ 0   0   -1   0   0    0]
-  [-1   1   -1   0   0    0]
-  [ 0   0    0   1   0   -1]
-  [ 0   0    0   0   0   -1]
-  [ 0   0    0   0   1   -1]
-
-julia> B = matrix(QQ, 4, 6, [1 0 3 0 0 0;
-                             0 1 1 0 0 0;
-                             0 0 0 0 1 0;
-                             0 0 0 0 0 1]);
-
-julia> Cf = lattice(Vf, B)  # coinvariant sublattice L_f
-Integer lattice of rank 4 and degree 6
-  with isometry of finite order 3
-  given by
-  [-2   3   0    0]
-  [-1   1   0    0]
-  [ 0   0   0   -1]
-  [ 0   0   1   -1]
-
-julia> Cf2 = lattice_in_same_ambient_space(Lf, B)
-Integer lattice of rank 4 and degree 6
-  with isometry of finite order 3
-  given by
-  [-2   3   0    0]
-  [-1   1   0    0]
-  [ 0   0   0   -1]
-  [ 0   0   1   -1]
-
-julia> Cf == Cf2
-true

The last equality of the last example shows why we care about "ambient context": the two pairs of lattice with isometry Cf and Cf2 are basically the same mathematical objects. Indeed, they lie in the same space, defines the same module and their respective isometries are induced by the same isometry of the ambient space. As for regular ZZLat, as soon as the lattices are in the same ambient space, we can compare them as $\mathbb Z$-modules, endowed with an isometry.

source

and it is seen as a quadruple $(Vf, L, f, n)$ where $Vf = (V, f_a)$ consists of the ambient rational quadratic space $V$ of $L$ and an isometry $f_a$ of $V$ preserving $L$ and inducing $f$ on $L$. The integer $n$ is the order of $f$, which is a divisor of the order of the isometry $f_a\in O(V)$.

Given a lattice with isometry $(L, f)$, we provide the following accessors to the elements of the previously described quadruple:

ambient_isometryMethod

ambient_isometry(Lf::ZZLatWithIsom) -> QQMatrix

Given a lattice with isometry $(L, f)$, return an isometry of the ambient space of L inducing f on L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> ambient_isometry(Lf)
-[-1    0    0    0    0]
-[ 0   -1    0    0    0]
-[ 0    0   -1    0    0]
-[ 0    0    0   -1    0]
-[ 0    0    0    0   -1]
source
ambient_spaceMethod
ambient_space(Lf::ZZLatWithIsom) -> QuadSpaceWithIsom

Given a lattice with isometry $(L, f)$, return the pair $(V, g)$ where V is the ambient quadratic space of L and g is an isometry of V inducing f on L.

Note that g might not be unique and we fix such a global isometry together with V into a container type QuadSpaceWithIsom.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> Vf = ambient_space(Lf)
-Quadratic space of dimension 5
-  with isometry of finite order 2
-  given by
-  [-1    0    0    0    0]
-  [ 0   -1    0    0    0]
-  [ 0    0   -1    0    0]
-  [ 0    0    0   -1    0]
-  [ 0    0    0    0   -1]
-
-julia> typeof(Vf)
-QuadSpaceWithIsom
source
isometryMethod
isometry(Lf::ZZLatWithIsom) -> QQMatrix

Given a lattice with isometry $(L, f)$, return the underlying isometry f.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> isometry(Lf)
-[-1    0    0    0    0]
-[ 0   -1    0    0    0]
-[ 0    0   -1    0    0]
-[ 0    0    0   -1    0]
-[ 0    0    0    0   -1]
source
latticeMethod
lattice(Lf::ZZLatWithIsom) -> ZZLat

Given a lattice with isometry $(L, f)$, return the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> lattice(Lf) === L
-true
source
order_of_isometryMethod
order_of_isometry(Lf::ZZLatWithIsom) -> IntExt

Given a lattice with isometry $(L, f)$, return the order of the underlying isometry f.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> order_of_isometry(Lf) == 2
-true
source

Note that for some computations, it is more convenient to work either with the isometry of the lattice itself, or with the fixed isometry of the ambient quadratic space inducing it on the lattice.

Constructor

We provide two ways to construct a pair $Lf = (L,f)$ consisting of an integer lattice endowed with an isometry. One way to construct an object of type ZZLatWithIsom is through the methods integer_lattice_with_isometry. These two methods do not require as input an ambient quadratic space with isometry.

integer_lattice_with_isometryMethod
integer_lattice_with_isometry(L::ZZLat, f::QQMatrix; check::Bool = true,
-                                            ambient_representation = true)
-			                                                             -> ZZLatWithIsom

Given a $\mathbb Z$-lattice L and a matrix f, if f defines an isometry of L of order n, return the corresponding lattice with isometry pair $(L, f)$.

If ambient_representation is set to true, f is consider as an isometry of the ambient space of L and the induced isometry on L is automatically computed. Otherwise, an isometry of the ambient space of L is constructed, setting the identity on the complement of the rational span of L if it is not of full rank.

Examples

The way we construct the lattice can have an influence on the isometry of the ambient space we store. Indeed, if one mentions an isometry of the lattice, this isometry will be extended by the identity on the orthogonal complement of the rational span of the lattice. In the following example, Lf and Lf2 are the same object, but the isometry of their ambient space stored are different (one has order 2, the other one is the identity).

julia> B = matrix(QQ, 3, 5, [1 0 0 0 0;
-                             0 0 1 0 1;
-                             0 0 0 1 0]);
-
-julia> G = matrix(QQ, 5, 5, [ 2 -1  0  0  0;
-                             -1  2 -1  0  0;
-                              0 -1  2 -1  0;
-                              0  0 -1  2 -1;
-                              0  0  0 -1  2]);
-
-julia> L = integer_lattice(B; gram = G);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 3 and degree 5
-  with isometry of finite order 1
-  given by
-  [1   0   0]
-  [0   1   0]
-  [0   0   1]
-
-julia> ambient_isometry(Lf)
-[ 1    0    0    0    0]
-[-1   -1   -1   -1   -1]
-[ 0    0    0    0    1]
-[ 0    0    0    1    0]
-[ 0    0    1    0    0]
-
-julia> Lf2 = integer_lattice_with_isometry(L, isometry(Lf); ambient_representation=false)
-Integer lattice of rank 3 and degree 5
-  with isometry of finite order 1
-  given by
-  [1   0   0]
-  [0   1   0]
-  [0   0   1]
-
-julia> ambient_isometry(Lf2)
-[1   0   0   0   0]
-[0   1   0   0   0]
-[0   0   1   0   0]
-[0   0   0   1   0]
-[0   0   0   0   1]
source
integer_lattice_with_isometryMethod
integer_lattice_with_isometry(L::ZZLat; neg::Bool = false) -> ZZLatWithIsom

Given a $\mathbb Z$-lattice L return the lattice with isometry pair $(L, f)$, where f corresponds to the identity mapping of L.

If neg is set to true, then the isometry f is negative the identity of L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [-1    0    0    0    0]
-  [ 0   -1    0    0    0]
-  [ 0    0   -1    0    0]
-  [ 0    0    0   -1    0]
-  [ 0    0    0    0   -1]
source

By default, the first constructor will always check whether the matrix defines an isometry of the lattice, or its ambient space. We recommend not to disable this parameter to avoid any further issues. Note that as in the case of quadratic spaces with isometry, both isometries of integer lattices of finite order and infinite order are supported.

Another way of constructing such lattices with isometry is by fixing an ambient quadratic space with isometry, of type QuadSpaceWithIsom, and specifying a basis for an integral lattice in that space. If this lattice is preserved by the fixed isometry of the quadratic space considered, then we endow it with the induced action.

latticeMethod
lattice(Vf::QuadSpaceWithIsom) -> ZZLatWithIsom

Given a quadratic space with isometry $(V, f)$, return the full rank lattice L in V with basis the standard basis, together with the induced action of f on L.

Examples

julia> V = quadratic_space(QQ, QQ[2 -1; -1 2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> f = matrix(QQ, 2, 2, [1 1; 0 -1])
-[1    1]
-[0   -1]
-
-julia> Vf = quadratic_space_with_isometry(V, f)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
-
-julia> Lf = lattice(Vf)
-Integer lattice of rank 2 and degree 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
source
latticeMethod
lattice(Vf::QuadSpaceWithIsom, B::MatElem{<:RationalUnion};
-                               isbasis::Bool = true, check::Bool = true)
-                                                          -> ZZLatWithIsom

Given a quadratic space with isometry $(V, f)$ and a matrix B generating a lattice L in V, if L is preserved under the action of f, return the lattice with isometry $(L, f_L)$ where $f_L$ is induced by the action of f on L.

Examples

julia> V = quadratic_space(QQ, QQ[ 2 -1  0  0  0;
-                                  -1  2 -1  0  0;
-                                   0 -1  2 -1  0;
-                                   0  0 -1  2 -1;
-                                   0  0  0 -1  2]);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Vf = quadratic_space_with_isometry(V, f);
-
-julia> B = matrix(QQ,3,5,[1 0 0 0 0;
-                          0 0 1 0 1;
-                          0 0 0 1 0])
-[1   0   0   0   0]
-[0   0   1   0   1]
-[0   0   0   1   0]
-
-julia> lattice(Vf, B)
-Integer lattice of rank 3 and degree 5
-  with isometry of finite order 1
-  given by
-  [1   0   0]
-  [0   1   0]
-  [0   0   1]
source
lattice_in_same_ambient_spaceMethod
lattice_in_same_ambient_space(L::ZZLatWithIsom, B::MatElem;
-                                                check::Bool = true)
-                                                        -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$ and a matrix B whose rows define a free system of vectors in the ambient space V of L, if the lattice M in V defined by B is preserved under the fixed isometry g of V inducing f on L, return the lattice with isometry pair $(M, f_M)$ where $f_M$ is induced by the action of g on M.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> B = matrix(QQ,3,5,[1 0 0 0 0;
-                          0 0 1 0 1;
-                          0 0 0 1 0])
-[1   0   0   0   0]
-[0   0   1   0   1]
-[0   0   0   1   0]
-
-julia> I = lattice_in_same_ambient_space(Lf, B)
-Integer lattice of rank 3 and degree 5
-  with isometry of finite order 1
-  given by
-  [1   0   0]
-  [0   1   0]
-  [0   0   1]
-
-julia> ambient_space(I) === ambient_space(Lf)
-true
source

Attributes and first operations

Given a lattice with isometry $Lf := (L, f)$, one can have access most of the attributes of $L$ and $f$ by calling the similar function for the pair. For instance, in order to know the genus of $L$, one can simply call genus(Lf). Here is a list of what are the current accessible attributes:

basis_matrixMethod
basis_matrix(Lf::ZZLatWithIsom) -> QQMatrix

Given a lattice with isometry $(L, f)$, return the basis matrix of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ,5,5,[ 1  0  0  0  0;
-                          -1 -1 -1 -1 -1;
-                           0  0  0  0  1;
-                           0  0  0  1  0;
-                           0  0  1  0  0])
-[ 1    0    0    0    0]
-[-1   -1   -1   -1   -1]
-[ 0    0    0    0    1]
-[ 0    0    0    1    0]
-[ 0    0    1    0    0]
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> invariant_lattice(Lf);
-
-julia> I = invariant_lattice(Lf);
-
-julia> basis_matrix(I)
-[1   0   0   0   0]
-[0   0   1   0   1]
-[0   0   0   1   0]
source
characteristic_polynomialMethod
characteristic_polynomial(Lf::ZZLatWithIsom) -> QQPolyRingElem

Given a lattice with isometry $(L, f)$, return the characteristic polynomial of the underlying isometry f.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> factor(characteristic_polynomial(Lf))
-1 * (x + 1)^5
source
degreeMethod
degree(Lf::ZZLatWithIsom) -> Int

Given a lattice with isometry $(L, f)$, return the degree of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> degree(Lf)
-5
source
detMethod
det(Lf::ZZLatWithIsom) -> QQFieldElem

Given a lattice with isometry $(L, f)$, return the determinant of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> det(Lf)
-6
source
discriminantMethod
discriminant(Lf::ZZLatWithIsom) -> QQFieldElem

Given a lattice with isometry $(L, f)$, return the discriminant of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> discriminant(Lf) == det(Lf) == 6
-true
source
genusMethod
genus(Lf::ZZLatWithIsom) -> ZZGenus

Given a lattice with isometry $(L, f)$, return the genus of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> genus(Lf)
-Genus symbol for integer lattices
-Signatures: (5, 0, 0)
-Local symbols:
-  Local genus symbol at 2: 1^-4 2^1_7
-  Local genus symbol at 3: 1^-4 3^1
source
gram_matrixMethod
gram_matrix(Lf::ZZLatWithIsom) -> QQMatrix

Given a lattice with isometry $(L, f)$, return the gram matrix of the underlying lattice L with respect to its basis matrix.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> gram_matrix(Lf)
-[ 2   -1    0    0    0]
-[-1    2   -1    0    0]
-[ 0   -1    2   -1    0]
-[ 0    0   -1    2   -1]
-[ 0    0    0   -1    2]
source
is_definiteMethod
is_definite(Lf::ZZLatWithIsom) -> Bool

Given a lattice with isometry $(L, f)$, return whether the underlying lattice L is definite.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_definite(Lf)
-true
source
is_evenMethod
is_even(Lf::ZZLatWithIsom) -> Bool

Given a lattice with isometry $(L, f)$, return whether the underlying lattice L is even.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_even(Lf)
-true
source
is_integralMethod
is_integral(Lf::ZZLatWithIsom) -> Bool

Given a lattice with isometry $(L, f)$, return whether the underlying lattice L is integral.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_integral(Lf)
-true
source
is_positive_definiteMethod
is_positive_definite(Lf::ZZLatWithIsom) -> Bool

Given a lattice with isometry $(L, f)$, return whether the underlying lattice L is positive definite.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_positive_definite(Lf)
-true
source
is_negative_definiteMethod
is_negative_definite(Lf::ZZLatWithIsom) -> Bool

Given a lattice with isometry $(L, f)$, return whether the underlying lattice L is negative definite.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_negative_definite(Lf)
-false
source
minimumMethod
minimum(Lf::ZZLatWithIsom) -> QQFieldElem

Given a positive definite lattice with isometry $(L, f)$, return the minimum of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> minimum(Lf)
-2
source
minimal_polynomialMethod
minimal_polynomial(Lf::ZZLatWithIsom) -> QQPolyRingElem

Given a lattice with isometry $(L, f)$, return the minimal polynomial of the underlying isometry f.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> minimal_polynomial(Lf)
-x + 1
source
normMethod
norm(Lf::ZZLatWithIsom) -> QQFieldElem

Given a lattice with isometry $(L, f)$, return the norm of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> norm(Lf)
-2
source
rankMethod
rank(Lf::ZZLatWithIsom) -> Integer

Given a lattice with isometry $(L, f)$, return the rank of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L; neg=true);
-
-julia> rank(Lf)
-5
source
rational_spanMethod
rational_span(Lf::ZZLatWithIsom) -> QuadSpaceWithIsom

Given a lattice with isometry $(L, f)$, return the rational span $L \otimes \mathbb{Q}$ of the underlying lattice L together with the underlying isometry of L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> Vf = rational_span(Lf)
-Quadratic space of dimension 5
-  with isometry of finite order 1
-  given by
-  [1   0   0   0   0]
-  [0   1   0   0   0]
-  [0   0   1   0   0]
-  [0   0   0   1   0]
-  [0   0   0   0   1]
-
-julia> typeof(Vf)
-QuadSpaceWithIsom
source
scaleMethod
scale(Lf::ZZLatWithIsom) -> QQFieldElem

Given a lattice with isometry $(L, f)$, return the scale of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> scale(Lf)
-1
source
signature_tupleMethod
signature_tuple(Lf::ZZLatWithIsom) -> Tuple{Int, Int, Int}

Given a lattice with isometry $(L, f)$, return the signature tuple of the underlying lattice L.

Examples

julia> L = root_lattice(:A,5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> signature_tuple(Lf)
-(5, 0, 0)
source

Similarly, some basic operations on $\mathbb Z$-lattices are available for lattices with isometry.

^Method
^(Lf::ZZLatWithIsom, n::Int) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$ and an integer $n$, return the pair $(L, f^n)$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lf^0
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 1
-  given by
-  [1   0   0   0   0]
-  [0   1   0   0   0]
-  [0   0   1   0   0]
-  [0   0   0   1   0]
-  [0   0   0   0   1]
source
biproductMethod
biproduct(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                  Vector{AbstractSpaceMor},
-                                                  Vector{AbstractSpaceMor}
-biproduct(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                  Vector{AbstractSpaceMor},
-                                                  Vector{AbstractSpaceMor}

Given a collection of lattices with isometries $(L_1, f_1), \ldots, (L_n, f_n)$, return the lattice with isometry $(L, f)$ together with the injections $L_i \to L$ and the projections $L \to L_i$, where L is the biproduct $L := L_1 \oplus \ldots \oplus L_n$ and f is the isometry of L induced by the diagonal actions of the $f_i$'s.

For objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(L, f)$ as a direct sum with the injections $L_i \to L$, one should call direct_sum(x). If one wants to obtain $(L, f)$ as a direct product with the projections $L \to L_i$, one should call direct_product(x).

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> g = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lg = integer_lattice_with_isometry(L, g)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 5
-  given by
-  [1    1    1    1    1]
-  [0   -1   -1   -1   -1]
-  [0    1    0    0    0]
-  [0    0    1    0    0]
-  [0    0    0    1    0]
-
-julia> Lh, inj, proj = biproduct(Lf, Lg)
-(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 5
-Codomain:
-=========
-Quadratic space of dimension 10, Map with following data
-Domain:
-=======
-Quadratic space of dimension 5
-Codomain:
-=========
-Quadratic space of dimension 10], AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 10
-Codomain:
-=========
-Quadratic space of dimension 5, Map with following data
-Domain:
-=======
-Quadratic space of dimension 10
-Codomain:
-=========
-Quadratic space of dimension 5])
-
-julia> Lh
-Integer lattice of rank 10 and degree 10
-  with isometry of finite order 10
-  given by
-  [ 1    0    0    0    0   0    0    0    0    0]
-  [-1   -1   -1   -1   -1   0    0    0    0    0]
-  [ 0    0    0    0    1   0    0    0    0    0]
-  [ 0    0    0    1    0   0    0    0    0    0]
-  [ 0    0    1    0    0   0    0    0    0    0]
-  [ 0    0    0    0    0   1    1    1    1    1]
-  [ 0    0    0    0    0   0   -1   -1   -1   -1]
-  [ 0    0    0    0    0   0    1    0    0    0]
-  [ 0    0    0    0    0   0    0    1    0    0]
-  [ 0    0    0    0    0   0    0    0    1    0]
-
-julia> matrix(compose(inj[1], proj[1]))
-[1   0   0   0   0]
-[0   1   0   0   0]
-[0   0   1   0   0]
-[0   0   0   1   0]
-[0   0   0   0   1]
-
-julia> matrix(compose(inj[1], proj[2]))
-[0   0   0   0   0]
-[0   0   0   0   0]
-[0   0   0   0   0]
-[0   0   0   0   0]
-[0   0   0   0   0]
source
direct_productMethod
direct_product(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                   Vector{AbstractSpaceMor}
-direct_product(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                   Vector{AbstractSpaceMor}

Given a collection of lattices with isometries $(L_1, f_1), \ldots, (L_n, f_n)$, return the lattice with isometry $(L, f)$ together with the projections $L \to L_i$, where L is the direct product $L := L_1 \times \ldots \times L_n$ and f is the isometry of L induced by the diagonal actions of the $f_i$'s.

For objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(L, f)$ as a direct sum with the injections $L_i \to L$, one should call direct_sum(x). If one wants to obtain $(L, f)$ as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> g = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lg = integer_lattice_with_isometry(L, g)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 5
-  given by
-  [1    1    1    1    1]
-  [0   -1   -1   -1   -1]
-  [0    1    0    0    0]
-  [0    0    1    0    0]
-  [0    0    0    1    0]
-
-julia> Lh, proj = direct_product(Lf, Lg)
-(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 10
-Codomain:
-=========
-Quadratic space of dimension 5, Map with following data
-Domain:
-=======
-Quadratic space of dimension 10
-Codomain:
-=========
-Quadratic space of dimension 5])
-
-julia> Lh
-Integer lattice of rank 10 and degree 10
-  with isometry of finite order 10
-  given by
-  [ 1    0    0    0    0   0    0    0    0    0]
-  [-1   -1   -1   -1   -1   0    0    0    0    0]
-  [ 0    0    0    0    1   0    0    0    0    0]
-  [ 0    0    0    1    0   0    0    0    0    0]
-  [ 0    0    1    0    0   0    0    0    0    0]
-  [ 0    0    0    0    0   1    1    1    1    1]
-  [ 0    0    0    0    0   0   -1   -1   -1   -1]
-  [ 0    0    0    0    0   0    1    0    0    0]
-  [ 0    0    0    0    0   0    0    1    0    0]
-  [ 0    0    0    0    0   0    0    0    1    0]
source
direct_sumMethod
direct_sum(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                   Vector{AbstractSpaceMor}
-direct_sum(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,
-                                                   Vector{AbstractSpaceMor}

Given a collection of lattices with isometries $(L_1, f_1), \ldots, (L_n, f_n)$, return the lattice with isometry $(L, f)$ together with the injections $L_i \to L$, where L is the direct sum $L := L_1 \oplus \ldots \oplus L_n$ and f is the isometry of L induced by the diagonal actions of the $f_i$'s.

For objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(L, f)$ as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain $(L, f)$ as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> g = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lg = integer_lattice_with_isometry(L, g)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 5
-  given by
-  [1    1    1    1    1]
-  [0   -1   -1   -1   -1]
-  [0    1    0    0    0]
-  [0    0    1    0    0]
-  [0    0    0    1    0]
-
-julia> Lh, inj = direct_sum(Lf, Lg)
-(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 5
-Codomain:
-=========
-Quadratic space of dimension 10, Map with following data
-Domain:
-=======
-Quadratic space of dimension 5
-Codomain:
-=========
-Quadratic space of dimension 10])
-
-julia> Lh
-Integer lattice of rank 10 and degree 10
-  with isometry of finite order 10
-  given by
-  [ 1    0    0    0    0   0    0    0    0    0]
-  [-1   -1   -1   -1   -1   0    0    0    0    0]
-  [ 0    0    0    0    1   0    0    0    0    0]
-  [ 0    0    0    1    0   0    0    0    0    0]
-  [ 0    0    1    0    0   0    0    0    0    0]
-  [ 0    0    0    0    0   1    1    1    1    1]
-  [ 0    0    0    0    0   0   -1   -1   -1   -1]
-  [ 0    0    0    0    0   0    1    0    0    0]
-  [ 0    0    0    0    0   0    0    1    0    0]
-  [ 0    0    0    0    0   0    0    0    1    0]
source
dualMethod
dual(Lf::ZZLatWithIsom) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$ inside the space $(V, \Phi)$, such that f is induced by an isometry g of $(V, \Phi)$, return the lattice with isometry $(L^{\vee}, h)$ where $L^{\vee}$ is the dual of L in $(V, \Phi)$ and h is induced by g.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lfv = dual(Lf)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [1   -1   0   0   0]
-  [0   -1   0   0   0]
-  [0   -1   0   0   1]
-  [0   -1   0   1   0]
-  [0   -1   1   0   0]
-
-julia> ambient_space(Lfv) == ambient_space(Lf)
-true
source
lllMethod
lll(Lf::ZZLatWithIsom) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$, return the same lattice with isometry with a different basis matrix for L obtained by performing an LLL-reduction on the associated gram matrix of L.

Note that matrix representing the action of f on L changes but the global action on the ambient space of L stays the same.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lf2 = lll(Lf)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1    0    0    0   -1]
-  [-1    0    0   -1    0]
-  [-1    0   -1    0    0]
-  [-1   -1    0    0    0]
-
-julia> ambient_space(Lf2) == ambient_space(Lf)
-true
source
rescaleMethod
rescale(Lf::ZZLatWithIsom, a::RationalUnion) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$ and a rational number a, return the lattice with isometry $(L(a), f)$.

Examples

julia> L = root_lattice(:A,5)
-Integer lattice of rank 5 and degree 5
-with gram matrix
-[ 2   -1    0    0    0]
-[-1    2   -1    0    0]
-[ 0   -1    2   -1    0]
-[ 0    0   -1    2   -1]
-[ 0    0    0   -1    2]
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> Lf2 = rescale(Lf, 1//2)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 2
-  given by
-  [ 1    0    0    0    0]
-  [-1   -1   -1   -1   -1]
-  [ 0    0    0    0    1]
-  [ 0    0    0    1    0]
-  [ 0    0    1    0    0]
-
-julia> lattice(Lf2)
-Integer lattice of rank 5 and degree 5
-with gram matrix
-[    1   -1//2       0       0       0]
-[-1//2       1   -1//2       0       0]
-[    0   -1//2       1   -1//2       0]
-[    0       0   -1//2       1   -1//2]
-[    0       0       0   -1//2       1]
source

Type for finite order isometries

Given a lattice with isometry $Lf := (L, f)$ where $f$ is of finite order $n$, one can compute the type of $Lf$, which can be seen as an equivalent of the genus used to classified single lattices.

typeMethod
type(Lf::ZZLatWithIsom)
-                  -> Dict{Int, Tuple{ <: Union{ZZGenus, HermGenus}, ZZGenus}}

Given a lattice with isometry $(L, f)$ with f of finite order n, return the type of $(L, f)$.

In this context, the type is defined as follows: for each divisor k of n, the k-type of $(L, f)$ is the tuple $(H_k, A_K)$ consisting of the genus $H_k$ of the lattice $\ker(\Phi_k(f))$ viewed as a hermitian $\mathbb{Z}[\zeta_k]$- lattice (so a $\mathbb{Z}$-lattice for k= 1, 2) and of the genus $A_k$ of the $\mathbb{Z}$-lattice $\ker(f^k-1)$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> t = type(Lf);
-
-julia> genus(invariant_lattice(Lf)) == t[1][1]
-true
source

Since determining whether two pairs of lattices with isometry are isomorphic is a challenging task, one can perform a coarser comparison by looking at the type. This set of data keeps track of some local and global invariants of the pair $(L, f)$ with respect to the action of $f$ on $L$.

is_of_typeMethod
is_of_type(Lf::ZZLatWithIsom, t::Dict) -> Bool

Given a lattice with isometry $(L, f)$, return whether $(L, f)$ is of type t.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> t = type(Lf);
-
-julia> is_of_type(Lf, t)
-true
source
is_of_same_typeMethod
is_of_same_type(Lf::ZZLatWithIsom, Mg::ZZLatWithIsom) -> Bool

Given two lattices with isometry $(L, f)$ and $(M, g)$, return whether they are of the same type.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> M = coinvariant_lattice(Lf);
-
-julia> is_of_same_type(Lf, M)
-false
source

Finally, if the minimal polynomial of $f$ is irreducible, then we say that the pair $(L, f)$ is of hermitian type. The type of a lattice with isometry of hermitian type is called hermitian (note that the type is only defined for finite order isometries).

These namings follow from the fact that, by the trace equivalence, one can associate to the pair $(L, f)$ a hermitian lattice over the equation order of $f$, if it is maximal in the associated number field $\mathbb{Q}[f]$.

is_of_hermitian_typeMethod
is_of_hermitian_type(Lf::ZZLatWithIsom) -> Bool

Given a lattice with isometry $(L, f)$, return whether the minimal polynomial of the underlying isometry f is irreducible.

Note that if $(L, f)$ is of hermitian type with f of minimal polynomial $\chi$, then L can be seen as a hermitian lattice over the order $\mathbb{Z}[\chi]$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f)
-Integer lattice of rank 5 and degree 5
-  with isometry of finite order 5
-  given by
-  [1    1    1    1    1]
-  [0   -1   -1   -1   -1]
-  [0    1    0    0    0]
-  [0    0    1    0    0]
-  [0    0    0    1    0]
-
-julia> is_of_hermitian_type(Lf)
-false
-
-julia> is_of_hermitian_type(coinvariant_lattice(Lf))
-true
source
is_hermitianMethod
is_hermitian(t::Dict) -> Bool

Given a type t of lattices with isometry, return whether t is hermitian, i.e. whether it defines the type of a hermitian lattice with isometry.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> M = coinvariant_lattice(Lf);
-
-julia> is_hermitian(type(Lf))
-false
-
-julia> is_hermitian(type(M))
-true
source

Hermitian structure and trace equivalence

As mentioned in the previous section, to a lattice with isometry $Lf := (L, f)$ such that the minimal polynomial of $f$ is irreducible, one can associate a hermitian lattice $\mathfrak{L}$ over the equation order of $f$, if it is maximal, for which $Lf$ is the associated trace lattice. Hecke provides the tools to perform the trace equivalence for lattices with isometry of hermitian type.

hermitian_structureMethod
hermitian_structure(Lf::ZZLatWithIsom) -> HermLat

Given a lattice with isometry $(L, f)$ such that the minimal polynomial of the underlying isometry f is irreducible, return the hermitian structure of the underlying lattice L over the equation order of the minimal polynomial of f.

If it exists, the hermitian structure is stored. For now, we only cover the case where the equation order is maximal (which is always the case when the order is finite, for instance, since the minimal polynomial is cyclotomic).

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> M = coinvariant_lattice(Lf)
-Integer lattice of rank 4 and degree 5
-  with isometry of finite order 5
-  given by
-  [-1   -1   -1   -1]
-  [ 1    0    0    0]
-  [ 0    1    0    0]
-  [ 0    0    1    0]
-
-julia> H = hermitian_structure(M)
-Hermitian lattice of rank 1 and degree 1
-  over relative maximal order of Relative number field of degree 2 over maximal real subfield of cyclotomic field of order 5
-  with pseudo-basis 
-  (1, 1//1 * <1, 1>)
-  (z_5, 1//1 * <1, 1>)
-
-julia> res = get_attribute(M, :transfer_data)
-Map of change of scalars
-  from quadratic space of dimension 4
-  to hermitian space of dimension 1
-
-julia> M2, f2 = trace_lattice_with_isometry(H, res)
-(Integer lattice of rank 4 and degree 4, [-1 -1 -1 -1; 1 0 0 0; 0 1 0 0; 0 0 1 0])
-
-julia> genus(M) == genus(M2) # One class in this genus, so they are isometric
-true
-
-julia> f2 == isometry(M)
-true
source

Discriminant group

Given an integral lattice with isometry $Lf := (L, f)$, if one denotes by $D_L$ the discriminant group of $L$, there exists a natural map $\pi\colon O(L) \to O(D_L)$ sending any isometry to its induced action on the discriminant group of $L$. In general, this map is neither injective nor surjective. If we denote by $D_f := \pi(f)$ then $\pi$ induces a map between centralizers $O(L, f)\to O(D_L, D_f)$. Again, this induced map is in general neither injective nor surjective, and we denote its image by $G_{L,f}$.

discriminant_groupMethod
discriminant_group(Lf::ZZLatWithIsom) -> TorQuadModule, AutomorphismGroupElem

Given an integral lattice with isometry $(L, f)$, return the discriminant group q of the underlying lattice L as well as this image of the underlying isometry f inside $O(q)$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> qL, qf = discriminant_group(Lf)
-(Finite quadratic module: Z/6 -> Q/2Z, [1])
-
-julia> qL
-Finite quadratic module
-  over integer ring
-Abelian group: Z/6
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form: 
-[5//6]
-
-julia> qf
-Isometry of Finite quadratic module: Z/6 -> Q/2Z defined by 
-[1]
-
-julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-                             -1 -1 -1 -1 -1;
-                              0  0  0  0  1;
-                              0  0  0  1  0;
-                              0  0  1  0  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> discriminant_group(Lf)[2]
-Isometry of Finite quadratic module: Z/6 -> Q/2Z defined by 
-[5]
source

For simple cases as for definite lattices, $f$ being plus-or-minus the identity or if the rank of $L$ is equal to the totient of the order of $f$ (in the finite case), $G_{L,f}$ can be easily computed. The only other case which can be currently handled is for lattices with isometry of hermitian type following the hermitian Miranda-Morisson theory from Simon Brandhorst, Tommy Hofmann (2023). This has been implemented in this project and it can be indirectly used through the general following method:

image_centralizer_in_OqMethod
image_centralizer_in_Oq(Lf::ZZLatWithIsom) -> AutomorphismGroup{TorQuadModule},
-                                              GAPGroupHomomorphism

Given an integral lattice with isometry $(L, f)$, return the image $G_L$ in $O(q_L, \bar{f})$ of the centralizer $O(L, f)$ of f in $O(L)$. Here $q_L$ denotes the discriminant group of L and $\bar{f}$ is the isometry of $q_L$ induced by f.

Examples

julia> L = root_lattice(:A,2);
-
-julia> f = matrix(QQ, 2, 2, [1 1; 0 -1]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> G, _ = image_centralizer_in_Oq(Lf)
-(Group of isometries of Finite quadratic module: Z/3 -> Q/2Z generated by 2 elements, Group homomorphism from
-Group of isometries of Finite quadratic module: Z/3 -> Q/2Z generated by 2 elements
-to
-Group of isometries of Finite quadratic module: Z/3 -> Q/2Z generated by 1 elements)
-
-julia> order(G)
-2
source

For an implementation of the regular Miranda-Morisson theory, we refer to the function image_in_Oq which actually computes the image of $\pi$ in both the definite and the indefinite case.

We will see later in the section about enumeration of lattices with isometry that one can compute $G_{L,f}$ in some particular cases arising from equivariant primitive embeddings of lattices with isometries.

Kernel sublattices

As for single integer lattices, it is possible to compute kernel sublattices of some $\mathbb{Z}$-module homomorphisms. We provide here the possibility to compute $\ker(p(f))$ as a sublattice of $L$ equipped with the induced action of $f$, where $p$ is a polynomial with rational coefficients.

kernel_latticeMethod
kernel_lattice(Lf::ZZLatWithIsom, p::Union{fmpz_poly, QQPolyRingElem})
-                                                     -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$ and a polynomial p with rational coefficients, return the sublattice $M := \ker(p(f))$ of the underlying lattice L with isometry f, together with the restriction $f_{\mid M}$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> Zx,x = ZZ["x"]
-(Univariate polynomial ring in x over ZZ, x)
-
-julia> mf = minimal_polynomial(Lf)
-x^5 - 1
-
-julia> factor(mf)
-1 * (x - 1) * (x^4 + x^3 + x^2 + x + 1)
-
-julia> kernel_lattice(Lf, x-1)
-Integer lattice of rank 1 and degree 5
-  with isometry of finite order 1
-  given by
-  [1]
-
-julia> kernel_lattice(Lf, cyclotomic_polynomial(5))
-Integer lattice of rank 4 and degree 5
-  with isometry of finite order 5
-  given by
-  [-1   -1   -1   -1]
-  [ 1    0    0    0]
-  [ 0    1    0    0]
-  [ 0    0    1    0]
source
kernel_latticeMethod
kernel_lattice(Lf::ZZLatWithIsom, l::Integer) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$ and an integer l, return the kernel lattice of $(L, f)$ associated to the l-th cyclotomic polynomial.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> kernel_lattice(Lf, 5)
-Integer lattice of rank 4 and degree 5
-  with isometry of finite order 5
-  given by
-  [-1   -1   -1   -1]
-  [ 1    0    0    0]
-  [ 0    1    0    0]
-  [ 0    0    1    0]
-
-julia> kernel_lattice(Lf, 1)
-Integer lattice of rank 1 and degree 5
-  with isometry of finite order 1
-  given by
-  [1]
source

Note that such sublattices are by definition primitive in $L$ since $L$ is non-degenerate. As particular kernel sublattices of $L$, one can also compute the so-called invariant and coinvariant lattices of $(L, f)$:

coinvariant_latticeMethod
coinvariant_lattice(Lf::ZZLatWithIsom) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$, return the coinvariant lattice $L_f$ of $(L, f)$ together with the restriction of f to $L_f$.

The coinvariant lattice $L_f$ of $(L, f)$ is the orthogonal complement in L of the invariant lattice $L_f$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> coinvariant_lattice(Lf)
-Integer lattice of rank 4 and degree 5
-  with isometry of finite order 5
-  given by
-  [-1   -1   -1   -1]
-  [ 1    0    0    0]
-  [ 0    1    0    0]
-  [ 0    0    1    0]
source
invariant_latticeMethod
invariant_lattice(Lf::ZZLatWithIsom) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$, return the invariant lattice $L^f$ of $(L, f)$ together with the restriction of f to $L^f$ (which is the identity in this case).

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> invariant_lattice(Lf)
-Integer lattice of rank 1 and degree 5
-  with isometry of finite order 1
-  given by
-  [1]
source

Similarly, we provide the possibility to compute invariant and coinvariant sublattices given an orthogonal representation G in matrix form of a finite group on a given lattice L:

coinvariant_latticeMethod
coinvariant_lattice(L::ZZLat, G::MatrixGroup;
-                              ambient_representation::Bool = true)
-                                                    -> ZZLat, MatrixGroup

Given an integer lattice L and a group G of isometries of L in matrix, return the coinvariant sublattice $L_G$ of L, together with the subgroup H of isometries of $L_G$ induced by the action of $G$.

If ambient_representation is set to true, the isometries in G and H are seen as isometries of the ambient quadratic space of L preserving L. Otherwise, they are considered as honnest isometries of L.

Examples

julia> L = root_lattice(:A,2);
-
-julia> G = isometry_group(L);
-
-julia> L2, G2 = coinvariant_lattice(L, G)
-(Integer lattice of rank 2 and degree 2, Matrix group of degree 2 over Rational field)
-
-julia> L == L2
-true
-
-julia> G == G2
-true
source
invariant_latticeMethod
invariant_lattice(L::ZZLat, G::MatrixGroup;
-                            ambient_representation::Bool = true) -> ZZLat

Given an integer lattice L and a group G of isometries of L in matrix, return the invariant sublattice $L^G$ of L.

If ambient_representation is set to true, the isometries in G are seen as isometries of the ambient quadratic space of L preserving L. Otherwise, they are considered as honnest isometries of L.

Examples

julia> L = root_lattice(:A,2);
-
-julia> G = isometry_group(L);
-
-julia> invariant_lattice(L, G)
-Integer lattice of rank 0 and degree 2
-with gram matrix
-0 by 0 empty matrix
source
invariant_coinvariant_pairMethod
invariant_coinvariant_pair(L::ZZLat, G::MatrixGroup;
-                                     ambient_representation::Bool = true)
-                                               -> ZZLat, ZZLat, MatrixGroup

Given an integer lattice L and a group G of isometries of L in matrix, return the invariant sublattice $L^G$ of L and its coinvariant sublattice $L_G$ together with the subgroup H of isometries of $L_G$ induced by the action of $G$.

If ambient_representation is set to true, the isometries in G and H are seen as isometries of the ambient quadratic space of L preserving L. Otherwise, they are considered as honnest isometries of L.

Examples

julia> L = root_lattice(:A,2);
-
-julia> G = isometry_group(L);
-
-julia> Gsub, _ = sub(G, [gens(G)[end]]);
-
-julia> F, C, G2 = invariant_coinvariant_pair(L, Gsub)
-(Integer lattice of rank 1 and degree 2, Integer lattice of rank 1 and degree 2, Matrix group of degree 2 over Rational field)
-
-julia> F
-Integer lattice of rank 1 and degree 2
-with gram matrix
-[2]
-
-julia> C
-Integer lattice of rank 1 and degree 2
-with gram matrix
-[6]
source

Signatures

We conclude this introduction about standard functionalities for lattices with isometry by introducing a last invariant for lattices with finite isometry of hermitian type $(L, f)$, called the signatures. These signatures are are intrinsequely connected to the local archimedean invariants of the hermitian structure associated to $(L, f)$ via the trace equivalence.

signaturesMethod
signatures(Lf::ZZLatWithIsom) -> Dict{Int, Tuple{Int, Int}}

Given a lattice with isometry $(L, f)$ where the minimal polynomial of f is irreducible cyclotomic, return the signatures of $(L, f)$.

In this context, if we denote $z$ a primitive n-th root of unity, where n is the order of f, then for each $1 \leq i \leq n/2$ such that $(i, n) = 1$, the $i$-th signature of $(L, f)$ is given by the signatures of the real quadratic form $\ker(f + f^{-1} - z^i - z^{-i})$.

Examples

julia> L = root_lattice(:A,5);
-
-julia> f = matrix(QQ, 5, 5, [1  1  1  1  1;
-                             0 -1 -1 -1 -1;
-                             0  1  0  0  0;
-                             0  0  1  0  0;
-                             0  0  0  1  0]);
-
-julia> Lf = integer_lattice_with_isometry(L, f);
-
-julia> M = coinvariant_lattice(Lf);
-
-julia> signatures(M)
-Dict{Integer, Tuple{Int64, Int64}} with 2 entries:
-  2 => (2, 0)
-  1 => (2, 0)
source

Equality

We choose as a convention that two pairs $(L, f)$ and $(L', f')$ of integer lattices with isometries are equal if their ambient quadratic space with isometry of type QuadSpaceWithIsom are equal, and if the underlying lattices $L$ and $L'$ are equal as $\mathbb Z$-modules in the common ambient quadratic space.

diff --git a/previews/PR2578/Experimental/QuadFormAndIsom/primembed/index.html b/previews/PR2578/Experimental/QuadFormAndIsom/primembed/index.html deleted file mode 100644 index 217d5b9403be..000000000000 --- a/previews/PR2578/Experimental/QuadFormAndIsom/primembed/index.html +++ /dev/null @@ -1,24 +0,0 @@ - -Primitive embeddings in even lattices · Oscar.jl

We introduce here the necessary definitions and results which lie behind the methods presented. Most of the content is taken from V. V. Nikulin (1979).

Primitive embeddings in even lattices

Nikulin's theory

Given an embedding $i\colon S\hookrightarrow T$ of non-degenerate integral integer lattices, we call $i$ primitive if its cokernel $T/i(S)$ is torsion free. Two primitive embeddings $i_1\colon S\hookrightarrow M_1$ and $i_2\colon S \hookrightarrow M_2$ of $S$ into two lattices $M_1$ and $M_2$ are called isomorphic if there exists an isometry $M_1 \to M_2$ which restricts to the identity of $S$. Moreover, if there exists an isometry between $M_1$ and $M_2$ which maps $S$ to itself (not necessarily identically), we say that $i_1$ and $i_2$ defines isomorphic primitive sublattices V. V. Nikulin (1979).

In his paper, V. V. Nikulin gives necessary and sufficient condition for an even integral lattice $M$ to embed primitively into an even unimodular lattice with given invariants (see Theorem 1.12.2 in V. V. Nikulin (1979)). More generally, the author also provides methods to compute primitive embeddings of any even lattice into an even lattice in a given genus (see Proposition 1.15.1 in V. V. Nikulin (1979)). In the latter proposition, it is explained how to classify such embeddings as isomorphic embeddings or as isomorphic sublattices.

Such a method can be algorithmically implemented, however it tends to be slow and inefficient in general for large rank or determinant. But, in the case where the discriminant groups are (elementary) $p$-groups, the method can be more efficient.

We provide 4 kinds of output:

  • A boolean, which only returns whether there exists a primitive embedding;
  • A single primitive embedding as soon as the algorithm computes one;
  • A list of representatives of isomorphism classes of primitive embeddings;
  • A list of representatives of isomorphism classes of primitive sublattices.
primitive_embeddingsMethod
primitive_embeddings(L::ZZLat, M::ZZLat; classification::Symbol = :sublat,
-                                         check::Bool = true)
-                                -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}

Given an even integer lattice L, which is unique in its genus, and an even integer lattice M, return whether M embeds primitively in L.

The first input of the function is a boolean T stating whether or not M embeds primitively in L. The second output V consists on triples (L', M', N') where L' is isometric to L, M' is a primitive sublattice of L' isometric to M, and N' is the orthogonal complement of M' in L'.

If T == false, then V will always be the empty list. If T == true, then the content of V actually depends on the value of the symbol classification. There are 4 possibilities:

  • classification = :none: V is the empty list;
  • classification = :first: V consists on the first primitive embedding found;
  • classification = :sublat: V consists on representatives for all isomorphism classes of primitive embeddings of M in L, up to the actions of $\bar{O}(M)$ and $O(q)$ where q is the discriminant group of L;
  • classification = :emb: V consists on representatives for all isomorphism classes of primitive sublattices of L isometric to M up to the action of $O(q)$ where q is the discriminant group of L.

If check is set to true, the function determines whether L is in fact unique in its genus.

Examples

We can use such primitive embeddings algorithm to classify embedding in unimodular lattices

julia> E8 = root_lattice(:E,8);
-
-julia> A4 = root_lattice(:A,4);
-
-julia> bool, pe = primitive_embeddings(E8, A4)
-(true, Tuple{ZZLat, ZZLat, ZZLat}[(Integer lattice of rank 8 and degree 8, Integer lattice of rank 4 and degree 8, Integer lattice of rank 4 and degree 8)])
-
-julia> pe
-1-element Vector{Tuple{ZZLat, ZZLat, ZZLat}}:
- (Integer lattice of rank 8 and degree 8, Integer lattice of rank 4 and degree 8, Integer lattice of rank 4 and degree 8)
-
-julia> genus(pe[1][2]) == genus(pe[1][3])
-true

To be understood here that there exists a unique class of embedding of the root lattice $A_4$ in the root lattice $E_8$, and the orthogonal primitive sublattice is isometric to $A_4$.

source

Note that the previous two functions require the first lattice of the input to be unique in its genus. Otherwise, one can specify a genus, or its invariants, as a first input:

primitive_embeddingsMethod
primitive_embeddings(G::ZZGenus, M::ZZLat; classification::Symbol = :sublat)
-                                  -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}

Given a genus symbol G for even integer lattices and an even integer lattice M, return whether M embeds primitively in a lattice in G.

The first input of the function is a boolean T stating whether or not M embeds primitively in a lattice in G. The second output V consists on triples (L', M', N') where L' is a lattice in G, M' is a sublattice of L' isometric to M, and N' is the orthogonal complement of M' in L'.

If T == false, then V will always be the empty list. If T == true, then the content of V actually depends on the value of the symbol classification. There are 4 possibilities:

  • classification = :none: V is the empty list;
  • classification = :first: V consists on the first primitive embedding found;
  • classification = :sublat: V consists on representatives for all isomorphism classes of primitive embeddings of M in lattices in G, up to the actions of $\bar{O}(M)$ and $O(q)$ where q is the discriminant of a lattice in G;
  • classification = :emb: V consists on representatives for all isomorphism classes of primitive sublattices of lattices in G isometric to M, up to the action of $O(q)$ where q is the discriminant group of a lattice in G.
source
primitive_embeddingsMethod
primitive_embeddings(q::TorQuadModule, sign::Tuple{Int, Int}, M::ZZLat;
-                                        classification::Symbol = :sublat)
-                                    -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}

Given a tuple sign of non-negative integers and a torsion quadratic module q which define a genus symbol G for even integer lattices, return whether the even integer lattice M embeds primitively in a lattice in G.

The first input of the function is a boolean T stating whether or not M embeds primitively in a lattice in G. The second output V consists on triples (L', M', N') where L' is a lattice in G, M' is a sublattice of L' isometric to M, and N' is the orthogonal complement of M' in L'.

If T == false, then V will always be the empty list. If T == true, then the content of V actually depends on the value of the symbol classification. There are 4 possibilities:

  • classification = :none: V is the empty list;
  • classification = :first: V consists on the first primitive embedding found;
  • classification = :sublat: V consists on representatives for all isomorphism classes of primitive embeddings of M in lattices in G, up to the actions of $\bar{O}(M)$ and $O(q)$ where q is the discriminant group of a lattice in G;
  • classification = :emb: V consists on representatives for all isomorphism classes of primitive sublattices of lattices in G isometric to M, up to the action of $O(q)$ where q is the discriminant group of a lattice in G.

If the pair (q, sign) does not define a non-empty genus for integer lattices, an error is thrown.

source

In order to compute such primitive embeddings of a lattice M into a lattice L, one first computes the possible genera for the orthogonal of M in L (after embedding), and for each lattice N in such a genus, one computes isomorphism classes of primitive extensions of $M \perp N$ modulo $\bar{O}(N)$ (and $\bar{O}(M)$ in the case of classification of primitive sublattices of L isometric to M).

We recall that a primitive extension of the orthogonal direct sum of two integral integer lattices M and N is an overlattice L of $M\perp N$ such that both M and N embed primitively in L (via the natural embeddings $M,N \to M\perp N\subseteq L$). Such primitive extensions are obtained, and classified, by looking for gluings between anti-isometric subgroups of the respective discriminant groups of M and N. The construction of an overlattice is determined by the graph of such glue map.

Admissible equivariant primitive extensions

The following function is an interesting tool provided by Simon Brandhorst, Tommy Hofmann (2023). Given a triple of integer lattices with isometry ((A, a), (B, b), (C, c)) and two prime numbers p and q (possibly equal), if (A, B, C) is p-admissible, this function returns representatives of isomorphism classes of equivariant primitive extensions $(A, a)\perp (B, b)\to (D, d)$ such that the type of $(D, d^p)$ is equal to the type of $(C, c)$ (see type(::ZZLatWithIsom)).

admissible_equivariant_primitive_extensionsMethod
admissible_equivariant_primitive_extensions(Afa::ZZLatWithIsom,
-                                            Bfb::ZZLatWithIsom,
-                                            Cfc::ZZLatWithIsom,
-                                            p::Integer,
-                                            q::Integer = p; check::Bool = true)
-                                                 -> Vector{ZZLatWithIsom}

Given a triple of lattices with isometry (A, fa), (B, fb) and (C, fc) and a prime number p, such that (A, B, C) is p-admissible, return a set of representatives of the double coset $G_B\backslash S/G_A$ where:

  • $G_A$ and $G_B$ are the respective images of the morphisms $O(A, fa) \to O(q_A, \bar{fa})$ and $O(B, fb) \to O(q_B, \bar{fb})$;
  • $S$ is the set of all primitive extensions $A \perp B \subseteq C'$ with isometry $fc'$ where $p\cdot C' \subseteq A\perp B$ and such that the type of $(C', fc'^q)$ is equal to the type of (C, fc).

If check == true the input triple is checked to a p-admissible triple of integral lattices (with isometry) with fA and fB having relatively coprime irreducible minimal polynomials and imposing that A and B are orthogonal if A, B and C lie in the same ambient quadratic space.

source

An equivariant primitive extension of a pair of integer lattices with isometries $(M, f_M)$ and $(N, f_N)$ is a primitive extension of M and N obtained by gluing two subgroups which are respectively $\bar{f_M}$ and $\bar{f_N}$ stable along a glue map which commutes with these two actions. If such a gluing exists, then the overlattice L of $M\perp N$ is equipped with an isometry $f_L$ which preserves both M and N, and restricts to $f_M$ and $f_N$ respectively.

diff --git a/previews/PR2578/Experimental/QuadFormAndIsom/spacewithisom/index.html b/previews/PR2578/Experimental/QuadFormAndIsom/spacewithisom/index.html deleted file mode 100644 index b37b76a2350f..000000000000 --- a/previews/PR2578/Experimental/QuadFormAndIsom/spacewithisom/index.html +++ /dev/null @@ -1,419 +0,0 @@ - -Quadratic space with isometry · Oscar.jl

Quadratic space with isometry

We call quadratic space with isometry any pair $(V, f)$ consisting of a non-degenerate quadratic space $V$ together with an isometry $f\in O(V)$. We refer to the section about quadratic spaces of the documentation for new users.

Note that currently, we support only rational quadratic forms, i.e. quadratic spaces defined over the rational.

In Oscar, such a pair is encoded by the type called QuadSpaceWithIsom:

QuadSpaceWithIsomType
QuadSpaceWithIsom

A container type for pairs (V, f) consisting on an rational quadratic space V of type QuadSpace and an isometry f given as a QQMatrix representing the action on the standard basis of V.

We store the order of f too, which can finite or of infinite order.

To construct an object of type QuadSpaceWithIsom, see the set of functions called quadratic_space_with_isometry

Examples

julia> V = quadratic_space(QQ, 4);
-
-julia> quadratic_space_with_isometry(V, neg=true)
-Quadratic space of dimension 4
-  with isometry of finite order 2
-  given by
-  [-1    0    0    0]
-  [ 0   -1    0    0]
-  [ 0    0   -1    0]
-  [ 0    0    0   -1]
-
-julia> L = root_lattice(:E, 6);
-
-julia> V = ambient_space(L);
-
-julia> f = matrix(QQ, 6, 6, [ 1  2  3  2  1  1;
-                             -1 -2 -2 -2 -1 -1;
-                              0  1  0  0  0  0;
-                              1  0  0  0  0  0;
-                             -1 -1 -1  0  0 -1;
-                              0  0  1  1  0  1]);
-
-julia> Vf = quadratic_space_with_isometry(V, f)
-Quadratic space of dimension 6
-  with isometry of finite order 8
-  given by
-  [ 1    2    3    2    1    1]
-  [-1   -2   -2   -2   -1   -1]
-  [ 0    1    0    0    0    0]
-  [ 1    0    0    0    0    0]
-  [-1   -1   -1    0    0   -1]
-  [ 0    0    1    1    0    1]
source

and it is seen as a triple $(V, f, n)$ where $n$ is the order of $f$. We actually support isometries of finite and infinite order. In the case where $f$ is of infinite order, then n = PosInf. If $V$ has rank 0, then any isometry $f$ of $V$ is trivial and we set by default n = -1.

Given a quadratic space with isometry $(V, f)$, we provide the following accessors to the elements of the previously described triple:

isometryMethod
isometry(Vf::QuadSpaceWithIsom) -> QQMatrix

Given a quadratic space with isometry $(V, f)$, return the underlying isometry f.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> isometry(Vf)
-[-1    0]
-[ 0   -1]
source
order_of_isometryMethod
order_of_isometry(Vf::QuadSpaceWithIsom) -> IntExt

Given a quadratic space with isometry $(V, f)$, return the order of the underlying isometry f.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> order_of_isometry(Vf) == 2
-true
source
spaceMethod
space(Vf::QuadSpaceWithIsom) -> QuadSpace

Given a quadratic space with isometry $(V, f)$, return the underlying space V.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> space(Vf) === V
-true
source

The main purpose of the definition of such objects is to define a contextual ambient space for quadratic lattices endowed with an isometry. Indeed, as we will see in the next section, lattices with isometry are attached to an ambient quadratic space with an isometry inducing the one on the lattice.

Constructors

For simplicity, we have gathered the main constructors for objects of type QuadSpaceWithIsom under the same name quadratic_space_with_isometry. The user has then the choice on the parameters depending on what they intend to do:

quadratic_space_with_isometryMethod
quadratic_space_with_isometry(V:QuadSpace, f::QQMatrix; check::Bool = false)
-                                                        -> QuadSpaceWithIsom

Given a quadratic space V and a matrix f, if f defines an isometry of V of order n (possibly infinite), return the corresponding quadratic space with isometry pair $(V, f)$.

Examples

julia> V = quadratic_space(QQ, QQ[ 2 -1;
-                                  -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> f = matrix(QQ, 2, 2, [1  1;
-                             0 -1])
-[1    1]
-[0   -1]
-
-julia> Vf = quadratic_space_with_isometry(V, f)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
source
quadratic_space_with_isometryMethod
quadratic_space_with_isometry(V::QuadSpace; neg::Bool = false) -> QuadSpaceWithIsom

Given a quadratic space V, return the quadratic space with isometry pair $(V, f)$ where f is represented by the identity matrix.

If neg is set to true, then the isometry f is negative the identity on V.

Examples

julia> V = quadratic_space(QQ, QQ[ 2 -1;
-                                  -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> Vf = quadratic_space_with_isometry(V)
-Quadratic space of dimension 2
-  with isometry of finite order 1
-  given by
-  [1   0]
-  [0   1]
source

By default, the first constructor always checks whether the matrix defines an isometry of the quadratic space. We recommend not to disable this parameter to avoid any complications. Note however that in the rank 0 case, the checks are avoided since all isometries are necessarily trivial.

Attributes and first operations

Given a quadratic space with isometry $Vf := (V, f)$, one has access to most of the attributes of $V$ and $f$ by calling the similar functions on the pair $(V, f)$ itself. For instance, in order to know the rank of $V$, one can simply call rank(Vf). Here is a list of what are the current accessible attributes:

characteristic_polynomialMethod
characteristic_polynomial(Vf::QuadSpaceWithIsom) -> QQPolyRingElem

Given a quadratic space with isometry $(V, f)$, return the characteristic polynomial of the underlying isometry f.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> characteristic_polynomial(Vf)
-x^2 + 2*x + 1
source
detMethod
det(Vf::QuadSpaceWithIsom) -> QQFieldElem

Given a quadratic space with isometry $(V, f)$, return the determinant of the underlying space V.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> is_one(det(Vf))
-true
source
diagonalMethod
diagonal(Vf::QuadSpaceWithIsom) -> Vector{QQFieldElem}

Given a quadratic space with isometry $(V, f)$, return the diagonal of the underlying space V.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> diagonal(Vf)
-2-element Vector{QQFieldElem}:
- 1
- 1
source
dimMethod
dim(Vf::QuadSpaceWithIsom) -> Integer

Given a quadratic space with isometry $(V, f)$, return the dimension of the underlying space of V.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> dim(Vf) == 2
-true
source
discriminantMethod
discriminant(Vf::QuadSpaceWithIsom) -> QQFieldElem

Given a quadratic space with isometry $(V, f)$, return the discriminant of the underlying space V.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> discriminant(Vf)
--1
source
gram_matrixMethod
gram_matrix(Vf::QuadSpaceWithIsom) -> QQMatrix

Given a quadratic space with isometry $(V, f)$, return the Gram matrix of the underlying space V with respect to its standard basis.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> is_one(gram_matrix(Vf))
-true
source
is_definiteMethod
is_definite(Vf::QuadSpaceWithIsom) -> Bool

Given a quadratic space with isometry $(V, f)$, return whether the underlying space V is definite.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> is_definite(Vf)
-true
source
is_positive_definiteMethod
is_positive_definite(Vf::QuadSpaceWithIsom) -> Bool

Given a quadratic space with isometry $(V, f)$, return whether the underlying space V is positive definite.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> is_positive_definite(Vf)
-true
source
is_negative_definiteMethod
is_negative_definite(Vf::QuadSpaceWithIsom) -> Bool

Given a quadratic space with isometry $(V, f)$, return whether the underlying space V is negative definite.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> is_negative_definite(Vf)
-false
source
minimal_polynomialMethod
minimal_polynomial(Vf::QuadSpaceWithIsom) -> QQPolyRingElem

Given a quadratic space with isometry $(V, f)$, return the minimal polynomial of the underlying isometry f.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> minimal_polynomial(Vf)
-x + 1
source
rankMethod
rank(Vf::QuadSpaceWithIsom) -> Integer

Given a quadratic space with isometry $(V, f)$, return the rank of the underlying space V.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> rank(Vf) == 2
-true
source
signature_tupleMethod
signature_tuple(Vf::QuadSpaceWithIsom) -> Tuple{Int, Int, Int}

Given a quadratic space with isometry $(V, f)$, return the signature tuple of the underlying space V.

Examples

julia> V = quadratic_space(QQ, 2);
-
-julia> Vf = quadratic_space_with_isometry(V; neg = true);
-
-julia> signature_tuple(Vf)
-(2, 0, 0)
source

Similarly, some basic operations on quadratic spaces are available for quadratic spaces with isometry.

^Method
^(Vf::QuadSpaceWithIsom, n::Int) -> QuadSpaceWithIsom

Given a quadratic space with isometry $(V, f)$ and an integer $n$, return the pair $(V, f^n)$.

Examples

julia> V = quadratic_space(QQ, QQ[ 2 -1;
-                                  -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> f = matrix(QQ, 2, 2, [1  1;
-                             0 -1])
-[1    1]
-[0   -1]
-
-julia> Vf = quadratic_space_with_isometry(V, f)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
-
-julia> Vf^2
-Quadratic space of dimension 2
-  with isometry of finite order 1
-  given by
-  [1   0]
-  [0   1]
source
biproductMethod
biproduct(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
-biproduct(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}

Given a collection of quadratic spaces with isometries $(V_1, f_1), \ldots, (V_n, f_n)$, return the quadratic space with isometry $(V, f)$ together with the injections $V_i \to V$ and the projections $V \to V_i$, where V is the biproduct $V := V_1 \oplus \ldots \oplus V_n$ and f is the isometry of V induced by the diagonal actions of the $f_i$'s.

For objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(V, f)$ as a direct sum with the injections $V_i \to V$, one should call direct_sum(x). If one wants to obtain $(V, f)$ as a direct product with the projections $V \to V_i$, one should call direct_product(x).

Examples

julia> V1 = quadratic_space(QQ, QQ[2 5;
-                                   5 6])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[2   5]
-[5   6]
-
-julia> Vf1 = quadratic_space_with_isometry(V1, neg=true)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [-1    0]
-  [ 0   -1]
-
-julia> V2 = quadratic_space(QQ, QQ[ 2 -1;
-                                   -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> f = matrix(QQ, 2, 2, [1  1;
-                             0 -1])
-[1    1]
-[0   -1]
-
-julia> Vf2 = quadratic_space_with_isometry(V2, f)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
-
-julia> Vf3, inj, proj = biproduct(Vf1, Vf2)
-(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 2
-Codomain:
-=========
-Quadratic space of dimension 4, Map with following data
-Domain:
-=======
-Quadratic space of dimension 2
-Codomain:
-=========
-Quadratic space of dimension 4], AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 4
-Codomain:
-=========
-Quadratic space of dimension 2, Map with following data
-Domain:
-=======
-Quadratic space of dimension 4
-Codomain:
-=========
-Quadratic space of dimension 2])
-
-julia> Vf3
-Quadratic space of dimension 4
-  with isometry of finite order 2
-  given by
-  [-1    0   0    0]
-  [ 0   -1   0    0]
-  [ 0    0   1    1]
-  [ 0    0   0   -1]
-
-julia> space(Vf3)
-Quadratic space of dimension 4
-  over rational field
-with gram matrix
-[2   5    0    0]
-[5   6    0    0]
-[0   0    2   -1]
-[0   0   -1    2]
-
-julia> matrix(compose(inj[1], proj[1]))
-[1   0]
-[0   1]
-
-julia> matrix(compose(inj[1], proj[2]))
-[0   0]
-[0   0]
source
direct_productMethod
direct_product(F::FreeMod{T}...; task::Symbol = :prod) where T

Given free modules $F_1\dots F_n$, say, return the direct product $\prod_{i=1}^n F_i$.

Additionally, return

  • a vector containing the canonical projections $\prod_{i=1}^n F_i\to F_i$ if task = :prod (default),
  • a vector containing the canonical injections $F_i\to\prod_{i=1}^n F_i$ if task = :sum,
  • two vectors containing the canonical projections and injections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T

Given modules $M_1\dots M_n$, say, return the direct product $\prod_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical projections $\prod_{i=1}^n M_i\to M_i$ if task = :prod (default),
  • a vector containing the canonical injections $M_i\to\prod_{i=1}^n M_i$ if task = :sum,
  • two vectors containing the canonical projections and injections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_product(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}
-direct_product(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}

Given a collection of quadratic spaces with isometries $(V_1, f_1), \ldots, (V_n, f_n)$, return the quadratic space with isometry $(V, f)$ together with the projections $V \to V_i$, where V is the direct product $V := V_1 \times \ldots \times V_n$ and f is the isometry of V induced by the diagonal actions of the $f_i$'s.

For objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(V, f)$ as a direct sum with the injections $V_i \to V$, one should call direct_sum(x). If one wants to obtain $(V, f)$ as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

Examples

julia> V1 = quadratic_space(QQ, QQ[2 5;
-                                   5 6])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[2   5]
-[5   6]
-
-julia> Vf1 = quadratic_space_with_isometry(V1, neg=true)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [-1    0]
-  [ 0   -1]
-
-julia> V2 = quadratic_space(QQ, QQ[ 2 -1;
-                                   -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> f = matrix(QQ, 2, 2, [1  1;
-                             0 -1])
-[1    1]
-[0   -1]
-
-julia> Vf2 = quadratic_space_with_isometry(V2, f)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
-
-julia> Vf3, proj = direct_product(Vf1, Vf2)
-(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 4
-Codomain:
-=========
-Quadratic space of dimension 2, Map with following data
-Domain:
-=======
-Quadratic space of dimension 4
-Codomain:
-=========
-Quadratic space of dimension 2])
-
-julia> Vf3
-Quadratic space of dimension 4
-  with isometry of finite order 2
-  given by
-  [-1    0   0    0]
-  [ 0   -1   0    0]
-  [ 0    0   1    1]
-  [ 0    0   0   -1]
-
-julia> space(Vf3)
-Quadratic space of dimension 4
-  over rational field
-with gram matrix
-[2   5    0    0]
-[5   6    0    0]
-[0   0    2   -1]
-[0   0   -1    2]
source
direct_product(algebras::AlgAss...; task::Symbol = :sum)
-  -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
-direct_product(algebras::Vector{AlgAss}; task::Symbol = :sum)
-  -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}

Returns the algebra $A = A_1 \times \cdots \times A_k$. task can be ":sum", ":prod", ":both" or ":none" and determines which canonical maps are computed as well: ":sum" for the injections, ":prod" for the projections.

direct_sumMethod
direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T

Given modules $M_1\dots M_n$, say, return the direct sum $\bigoplus_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical injections $M_i\to\bigoplus_{i=1}^n M_i$ if task = :sum (default),
  • a vector containing the canonical projections $\bigoplus_{i=1}^n M_i\to M_i$ if task = :prod,
  • two vectors containing the canonical injections and projections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_sum(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}
-direct_sum(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}

Given a collection of quadratic spaces with isometries $(V_1, f_1), \ldots, (V_n, f_n)$, return the quadratic space with isometry $(V, f)$ together with the injections $V_i \to V$, where V is the direct sum $V := V_1 \oplus \ldots \oplus V_n$ and f is the isometry of V induced by the diagonal actions of the $f_i$'s.

For objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(V, f)$ as a direct product with the projections $V \to V_i$, one should call direct_product(x). If one wants to obtain $(V, f)$ as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

Examples

julia> V1 = quadratic_space(QQ, QQ[2 5;
-                                   5 6])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[2   5]
-[5   6]
-
-julia> Vf1 = quadratic_space_with_isometry(V1, neg=true)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [-1    0]
-  [ 0   -1]
-
-julia> V2 = quadratic_space(QQ, QQ[ 2 -1;
-                                   -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> f = matrix(QQ, 2, 2, [1  1;
-                             0 -1])
-[1    1]
-[0   -1]
-
-julia> Vf2 = quadratic_space_with_isometry(V2, f)
-Quadratic space of dimension 2
-  with isometry of finite order 2
-  given by
-  [1    1]
-  [0   -1]
-
-julia> Vf3, inj = direct_sum(Vf1, Vf2)
-(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data
-Domain:
-=======
-Quadratic space of dimension 2
-Codomain:
-=========
-Quadratic space of dimension 4, Map with following data
-Domain:
-=======
-Quadratic space of dimension 2
-Codomain:
-=========
-Quadratic space of dimension 4])
-
-julia> Vf3
-Quadratic space of dimension 4
-  with isometry of finite order 2
-  given by
-  [-1    0   0    0]
-  [ 0   -1   0    0]
-  [ 0    0   1    1]
-  [ 0    0   0   -1]
-
-julia> space(Vf3)
-Quadratic space of dimension 4
-  over rational field
-with gram matrix
-[2   5    0    0]
-[5   6    0    0]
-[0   0    2   -1]
-[0   0   -1    2]
source
direct_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls

Return the isometry class of the direct sum of two representatives.

rescaleMethod
rescale(Vf::QuadSpaceWithIsom, a::RationalUnion)

Given a quadratic space with isometry $(V, f)$, return the pair $(V^a, f$) where $V^a$ is the same space as V with the associated quadratic form rescaled by a.

Examples

julia> V = quadratic_space(QQ, QQ[ 2 -1;
-                                  -1  2])
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 2   -1]
-[-1    2]
-
-julia> Vf = quadratic_space_with_isometry(V)
-Quadratic space of dimension 2
-  with isometry of finite order 1
-  given by
-  [1   0]
-  [0   1]
-
-julia> Vf2 = rescale(Vf, 1//2)
-Quadratic space of dimension 2
-  with isometry of finite order 1
-  given by
-  [1   0]
-  [0   1]
-
-julia> space(Vf2)
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[    1   -1//2]
-[-1//2       1]
source

Equality

We choose as a convention that two pairs $(V, f)$ and $(V', f')$ of quadratic spaces with isometries are equal if and only if $V$ and $V'$ are the same space, and $f$ and $f'$ are represented by the same matrix with respect to the standard basis of $V = V'$.

diff --git a/previews/PR2578/Experimental/Singularities/intro/index.html b/previews/PR2578/Experimental/Singularities/intro/index.html deleted file mode 100644 index e3b3194b6844..000000000000 --- a/previews/PR2578/Experimental/Singularities/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The singularities part of OSCAR provides functionality for handling

  • space germs
  • map germs

For readers' convenience, the documentation is organised by typical settings, This, on the other hand, implies that certain keywords may appear in several settings. In particular, there are overlaps between hypersurface singularities and curve singularities and between hypersurface singularities and isolated complete intersection singularities

Note

Most of the functions discussed here rely on standard bases. These are implemented in OSCAR for localizations of multivariate polynomial rings over fields (exact fields supported by OSCAR) at points with coordinates in said field. This explained in more detail in Generalities on Space Germs.

Textbooks offering details on theory (and some algorithms) include:

diff --git a/previews/PR2578/Experimental/Singularities/space_germs/index.html b/previews/PR2578/Experimental/Singularities/space_germs/index.html deleted file mode 100644 index 741081a53a05..000000000000 --- a/previews/PR2578/Experimental/Singularities/space_germs/index.html +++ /dev/null @@ -1,7 +0,0 @@ - -Space Germs · Oscar.jl

Space Germs

Generalities on Space germs

The geometric notion of a space germ is a local concept. A space germ $(X,x)$ at a point $x$ is an equivalence class of ringed spaces, each of which contains $x$ in its underlying topological space, and the equivalence relation is precisely the existence of an open neighbourhood of $x$ on which the spaces coincide.

Depending on the kind of ringed space in question, space germs arise in different forms:

  • a space germ in the context of affine schemes is the geometric object arising from a given scheme by localization at a point, leading to the stalk of the structure sheaf at the respective prime ideal.

  • in the context of singularity theory, the (anti-)equivalence of categories between complex space germs and analytic ${\mathbb CC}$-algebras allows the direct definition of a space germ from algebraic data

Note that analytic algebras as mentioned above, have two computational problems. On one hand, exact computations can only be performed over fields in OSCAR permitting exact computations, in particular not over ${\mathbb R}$ or ${\mathbb C}$. This usually does not pose a problem, if the input data is in an exact smaller field. But unfortunately, also analytic algebras themselves do not allow exact computations so that applications have to be considered in a localization of an affine algebra. With due care, output may again be interpreted in terms of a multivariate formal power series using the following inclusions:

\[{\mathbb Q}[\underline{x}]_{\langle x \rangle} \hookrightarrow - {\mathbb Q}\{\underline{x}\}\hookrightarrow - {\mathbb Q}[[\underline{x}]]\]

At particular points, where this difficulty of interpretation manifests itself prominently, a suitable warning, note or example has been placed (but certainly not everywhere).

Textbooks covering space germs in the sense of analytic algebras and singularity theory are:

For the point of view of schemes, we refer to the page on schemes and the references given there; an example of a standard textbook is

Creating Space Germs in OSCAR

In general, space germs in OSCAR are created in the following ways:

  • localization of an affine scheme at a point

    SpaceGerm(X::AbsSpec, I::Ideal)

    where I is a (maximal) ideal describing the chosen ${\mathbb k}$-point on the affine ${\mathbb k}$-scheme X. Provides: SpaceGerm.

    germ_at_point(X::AbsSpec, I::Ideal)

    where I is a (maximal) ideal describing the chosen ${\mathbb k}$-point on the affine ${\mathbb k}$-scheme.

    Provides: SpaceGerm, restriction map.

  • localization of a polynomial ring at a point

    germ_at_point(R::MPolyRing, I::MPolyIdeal)
    -germ_at_point(R::MPolyQuoRing, I::MPolyIdeal)

    where I is a maximal ideal describing the chosen base_ring(R)-point.

    Provides: space germ and restriction map.

  • localized ring with respect to complement of prime ideal or complement of maximal ideal)

    SpaceGerm(R::MPolyLocRing)
    -SpaceGerm(R::MPolyQuoLocRing)

    Provides: Space germ

    germ_at_point(R::MPolyLocRing)
    -germ_at_point(R::MPolyQuoLocRing)

    Provides: Space germ, restriction map

    (point inherited from underlying local ring)

As for all affine schemes, morphisms of space germs are in $1:1$ correspondence with morphisms of the underlying local rings. Hence also handled in this way in OSCAR.

Basic functionality for space germs

Most of the basic functionality immediately falls back to the underlying affine algebra or affine scheme and is just provided on the geometric side for convenience and consistence of functionality:

internal data of a space germ

  • Pass from the germ $(X,x)$ back to some affine scheme $X=Spec R$, where with the appropriate localization at $x$, where $R$ is a quotient of a multivariate polynomial ring, by

    representative(X::SpaceGerm)

    Provides: AffineScheme

  • Given the space germ $(X,x)$, the point $x$ is returned by:

    point(X:SpaceGerm)

    Provides: Vector describing of point coordinates

Note

The returned ideal is a prime ideal in the ring of a representative of the germ. At first use of it or at the latest upon the first call of representative, the respective affine scheme is cached and subsequently used for all further purposes requiring a representative

  • Given a space germ $(X,x)$, the corresponding local ring ${\mathcal O}_{(X,x)}$ is returned by:

    ring(X::SpaceGerm)

    Provides: MPolyQuoLocRing or MPolyLocRing

  • Analogously, the modulus of the ring of a given germ $(X,x)$ can be obtained by:

    ideal(X::SpaceGerm)

    Provides: Ideal

  • For technical reasons all germs $(X,x)$ in OSCAR are embedded and the smooth ambient germ can be accessed by:

    ambient_germ(X::SpaceGerm)

    Provides: SpaceGerm

containment/equality of space germs

  • containment

    issubset(X::SpaceGerm, Y::SpaceGerm)

    Test whether X is a subgerm of Y.

    Provides: Boolean Value

Note

The name 'issubset' has been chosen for consistency with other types, but is slightly misleading, as the function does not only test containment of the underlying sets, but in the scheme-theoretic sense.

  • equality

    X ==Y

    Provides: Boolean Value

Note

Equality of the germs X and Y is tested in the sense of equality of subgerms of the same ambient space germ.

  • emptyness

    For the test of equality to the empty germ, a separate function is available:

    is_empty(X::SpaceGerm)

    Provides: Boolean Value

    • intersection

      intersect(X::SpaceGerm,Y::SpaceGerm)

      Computes the intersection of two subgerms of a common larger germ.

      Provides: SpaceGerm

singular locus

singular_locus(X::SpaceGerm)

Computes the germ of the singular locus of the given germ.

Provides: SpaceGerm

If a test for smoothness is the goal, the following functions can be used

is_smooth(X::SpaceGerm)

Provides: Boolean Value

<!– julia is_regular(X::SpaceGerm) still needs to be implemented –>

<!– ...to be continued –>

diff --git a/previews/PR2578/Experimental/ToricSchemes/affine_toric_schemes/index.html b/previews/PR2578/Experimental/ToricSchemes/affine_toric_schemes/index.html deleted file mode 100644 index e77fa60006aa..000000000000 --- a/previews/PR2578/Experimental/ToricSchemes/affine_toric_schemes/index.html +++ /dev/null @@ -1,9 +0,0 @@ - -Affine Toric Schemes · Oscar.jl

Affine Toric Schemes

Constructors

We provide the following constructors for affine toric schemes:

toric_specMethod
toric_spec(antv::AffineNormalToricVariety)

Constructs the affine toric scheme (i.e. Spec of a ring) associated to an affine toric variety.

Examples

julia> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> antv = affine_normal_toric_variety(C)
-Normal, affine toric variety
-
-julia> toric_spec(antv)
-Spec of an affine toric variety
source

Attributes

An affine toric scheme has all attributes of a normal toric scheme. In addition, there are the following special attributes, that we overload from the corresponding affine toric variety:

  • $cone(X::ToricSpec)$,
  • $dual_cone(X::ToricSpec)$,
  • $hilbert_basis(X::ToricSpec)$,
  • $toric_ideal(R::MPolyRing, X::ToricSpec)$,
  • $toric_ideal(X::ToricSpec)$.

Properties

For an affine toric scheme, all properties of normal toric schemes are supported.

A note on the torus inclusion and the torus action

Note that the torus_inclusions(X::ToricSpec) is not yet supported. For an affine toric scheme $X$, we envision that this function should return a list l containing the inclusions $Tʳ⁽ⁱ⁾ ↪ X$ of the different tori.

Similarly, torus_action(X::ToricSpec) is not yet supported. For an affine toric scheme $X$ with a dense open torus $T$ this method should returns a quintuple of morphisms (pT, pX, incX, mult) consisting of the following:

  • the projection $T × X → T$ of the product with the torus $T$ to $T$,
  • the projection $T × X → X$,
  • the inclusion $X ↪ T × X$ taking $x$ to $(1, x)$,
  • the group action $T × X → X$.
diff --git a/previews/PR2578/Experimental/ToricSchemes/introduction/index.html b/previews/PR2578/Experimental/ToricSchemes/introduction/index.html deleted file mode 100644 index 1a635e10eb80..000000000000 --- a/previews/PR2578/Experimental/ToricSchemes/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

One can associate to a toric variety a scheme. The resulting class of schemes then benefits from the functionality that is available both for toric varieties and for schemes.

Content

We currently provide the following basic conversions:

  • Turn an affine toric variety into an affine scheme.
  • Turn a normal toric variety into a covered scheme.

Some (but not yet all) of the toric functionality is available for the resulting toric schemes.

Status

This project is experimental. This means that names of functions may change without being announced. In addition, the existing functionality has not yet been tested for a long time, and so may break unexpectedly.

Long term goals

We aim for a robust interface between toric varieties and schemes.

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/Experimental/ToricSchemes/normal_toric_schemes/index.html b/previews/PR2578/Experimental/ToricSchemes/normal_toric_schemes/index.html deleted file mode 100644 index a6076748b6cf..000000000000 --- a/previews/PR2578/Experimental/ToricSchemes/normal_toric_schemes/index.html +++ /dev/null @@ -1,35 +0,0 @@ - -Normal Toric Schemes · Oscar.jl

Normal Toric Schemes

Constructors

We provide the following constructors for toric covered schemes:

toric_covered_schemeMethod
toric_covered_scheme(antv::AffineNormalToricVariety)

Constructs the toric covered scheme associated to an affine toric variety.

Examples

julia> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> antv = affine_normal_toric_variety(C)
-Normal, affine toric variety
-
-julia> toric_covered_scheme(antv)
-Scheme of a toric variety
source
toric_covered_schemeMethod
toric_covered_scheme(ntv::NormalToricVariety)

Constructs the toric covered scheme associated to a normal toric variety.

Examples

julia> ntv = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> toric_covered_scheme(ntv)
-Scheme of a toric variety
source

Special constructors

We support constructors for a couple of famous geometries:

affine_spaceMethod
affine_space(::Type{ToricCoveredScheme}, d::Int; set_attributes::Bool = true)

Constructs the affine space of dimension d as toric (covered) scheme.

Examples

julia> affine_space(ToricCoveredScheme, 2)
-Scheme of a toric variety
source
projective_spaceMethod
projective_space(::Type{ToricCoveredScheme}, d::Int; set_attributes::Bool = true)

Construct the projective space of dimension d as toric (covered) scheme.

Examples

julia> projective_space(ToricCoveredScheme, 2)
-Scheme of a toric variety
source
weighted_projective_spaceMethod
weighted_projective_space(::Type{ToricCoveredScheme}, w::Vector{T}; set_attributes::Bool = true) where {T <: IntegerUnion}

Construct the weighted projective space corresponding to the weights w as toric (covered) scheme.

Examples

julia> weighted_projective_space(ToricCoveredScheme, [2,3,1])
-Scheme of a toric variety
source
hirzebruch_surfaceMethod
hirzebruch_surface(::Type{ToricCoveredScheme}, r::Int; set_attributes::Bool = true)

Constructs the r-th Hirzebruch surface as toric (covered) scheme.

Examples

julia> hirzebruch_surface(ToricCoveredScheme, 5)
-Scheme of a toric variety
source
del_pezzo_surfaceMethod
del_pezzo_surface(::Type{ToricCoveredScheme}, b::Int; set_attributes::Bool = true)

Constructs the del Pezzo surface with b blowups for b at most 3 as toric (covered) scheme.

Examples

julia> del_pezzo_surface(ToricCoveredScheme, 3)
-Scheme of a toric variety
source

Attributes

We overload the following attributes from the underlying toric variety:

  • $affine_open_covering(X::ToricCoveredScheme)$,
  • $character_lattice(X::ToricCoveredScheme)$,
  • $character_to_rational_function(R::MPolyRing, X::ToricCoveredScheme, character::Vector{ZZRingElem})$,
  • $character_to_rational_function(X::ToricCoveredScheme, character::Vector{ZZRingElem})$,
  • $class_group(X::ToricCoveredScheme)$,
  • $coefficient_ring(X::ToricCoveredScheme)$,
  • $coordinate_names(X::ToricCoveredScheme)$,
  • $coordinate_names_of_torus(X::ToricCoveredScheme)$,
  • $coordinate_ring_of_torus(R::MPolyRing, X::ToricCoveredScheme)$,
  • $coordinate_ring_of_torus(X::ToricCoveredScheme)$,
  • $cox_ring(R::MPolyRing, X::ToricCoveredScheme)$,
  • $cox_ring(X::ToricCoveredScheme)$,
  • $dim(X::ToricCoveredScheme)$,
  • $dim_of_torusfactor(X::ToricCoveredScheme)$,
  • $euler_characteristic(X::ToricCoveredScheme)$,
  • $polyhedral_fan(X::ToricCoveredScheme)$,
  • $ideal_of_linear_relations(R::MPolyRing, X::ToricCoveredScheme)$,
  • $ideal_of_linear_relations(X::ToricCoveredScheme)$,
  • $irrelevant_ideal(R::MPolyRing, X::ToricCoveredScheme)$,
  • $irrelevant_ideal(X::ToricCoveredScheme)$,
  • $map_from_character_lattice_to_torusinvariant_weil_divisor_group(X::ToricCoveredScheme)$,
  • $map_from_torusinvariant_cartier_divisor_group_to_picard_group(X::ToricCoveredScheme)$,
  • $map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(X::ToricCoveredScheme)$,
  • $map_from_torusinvariant_weil_divisor_group_to_class_group(X::ToricCoveredScheme)$,
  • $mori_cone(X::ToricCoveredScheme)$,
  • $nef_cone(X::ToricCoveredScheme)$,
  • $picard_group(X::ToricCoveredScheme)$,
  • $set_coordinate_names(X::ToricCoveredScheme)$,
  • $set_coordinate_names_of_torus(X::ToricCoveredScheme)$,
  • $stanley_reisner_ideal(R::MPolyRing, X::ToricCoveredScheme)$,
  • $stanley_reisner_ideal(X::ToricCoveredScheme)$,
  • $torusinvariant_cartier_divisor_group(X::ToricCoveredScheme)$,
  • $torusinvariant_prime_divisors(X::ToricCoveredScheme)$,
  • $torusinvariant_weil_divisor_group(X::ToricCoveredScheme)$,
  • $underlying_toric_variety(X::ToricCoveredScheme)$.

It is possible to forget the toric origin, i.e. one can turn a toric scheme into a scheme. This is achieved with the following method:

underlying_schemeMethod
underlying_scheme(X::ToricCoveredScheme)

For a toric covered scheme $X$, this returns the underlying scheme. In other words, by applying this method, you obtain a scheme that has forgotten its toric origin.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> toric_scheme = ToricCoveredScheme(P2)
-Scheme of a toric variety
-
-julia> underlying_scheme(toric_scheme)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: spec of an affine toric variety
-    2: spec of an affine toric variety
-    3: spec of an affine toric variety
-  in the coordinate(s)
-    1: [x1, x2]
-    2: [x1, x2]
-    3: [x1, x2]
source

Properties

The following properties are overloaded from the underlying toric variety:

  • $is_finalized(X::ToricCoveredScheme)$,
  • $is_normal(X::ToricCoveredScheme)$,
  • $is_affine(X::ToricCoveredScheme)$,
  • $is_projective(X::ToricCoveredScheme)$,
  • $is_projective_space(X::ToricCoveredScheme)$,
  • $is_smooth(X::ToricCoveredScheme)$,
  • $is_complete(X::ToricCoveredScheme)$,
  • $has_torusfactor(X::ToricCoveredScheme)$,
  • $is_orbifold(X::ToricCoveredScheme)$,
  • $is_simplicial(X::ToricCoveredScheme)$,
  • $is_gorenstein(X::ToricCoveredScheme)$,
  • $is_q_gorenstein(X::ToricCoveredScheme)$,
  • $is_fano(X::ToricCoveredScheme)$.
diff --git a/previews/PR2578/Experimental/intro/index.html b/previews/PR2578/Experimental/intro/index.html deleted file mode 100644 index c30e314a96c2..000000000000 --- a/previews/PR2578/Experimental/intro/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Adding new projects to experimental · Oscar.jl

Adding new projects to experimental

Purpose

The folder experimental is for code that is candidate for being added to Oscar. In particular, this includes the following cases:

  • Code from an external package that should be moved to Oscar
  • Implementing a new feature from scratch
  • In general: code whose API has not stabilized yet

The code in experimental is supposed to be mathematically correct, experimental is a staging area for new features whose interface is still to be stabilized. Also code is allowed to reside in experimental while it is brought up to Oscar standard.

Dependencies
  • Code from src must never use code from experimental
  • Say there are two packages A and B in experimental, and B depends on A. That means that B cannot be moved to src before A. Worse: If A gets abandoned, B might share that fate. So please consider carefully in such situations.

Structure

For an example of the structure for a new project in experimental have a look at project folders, i.e. experimental/PACKAGE_NAME, that have subfolders docs, src, and test (The first two examples are experimental/{FTheoryTools, PlaneCurve}). The general structure is

experimental/PACKAGE_NAME/
-├── README.md
-├── docs
-│   ├── doc.main
-│   └── src
-│       └── DOCUMENTATION.md
-├── src
-│   └── PACKAGE_NAME.jl
-└── test
-    └── runtests.jl

The files src/PACKAGE_NAME.jl and test/runtests.jl are mandatory as they are used by Oscar.jl to find your code and tests. The file docs/doc.main is used for integrating your documentation in the Oscar manual under the Experimental section. Optionally please provide a README.md describing your project and its goals, especially if you are starting from scratch and don't have any documentation yet.

Note

There are still older projects in experimental from before the introduction of this structure. Thus we mentioned FTheoryTools and PlaneCurve as projects having adopted to the new standard.

Useful functions for development

Apart from the hints in the Introduction for new developers, there are some more specialized functions for the structure of the experimental folder.

test_experimental_moduleFunction
test_experimental_module(project::AbstractString; file::AbstractString="runtests", new::Bool = true)

Run the Oscar tests in the file experimental/<project>/test/<file>.jl where file may be a path. The default is to run the entire test suite of the module project.

The optional parameter new takes the values false and true (default). If true, then the tests are run in a new session, otherwise the currently active session is used.

source

Procedure for adding a new feature

Ideally we envision the procedure to follow along the following lines.

  1. The new feature is implemented in the experimental folder.
  2. For external authors, a maintainer is assigned to guide the authors such that the implementation adheres to the Developer Style Guide and the Design Decisions. Please get in touch with us as soon as possible, preferably on the OSCAR Slack.
  3. The new feature is tested thoroughly, other people are invited to test the new feature.
  4. In the end there are three possibilities:
    1. The feature is considered done and moved into src as is.
    2. The feature is discarded, e.g., because it cannot be maintained.
    3. Parts of the feature are moved into src, others are discarded.

Criteria for acceptance

The main criteria for acceptance are:

  1. The code adheres to the Developer Style Guide and the Design Decisions.
  2. The new code is well tested.
  3. It is clear who maintains the new code, i.e. the original authors commit to maintaining the code in the future.
diff --git a/previews/PR2578/Fields/algebraic_closure_fp/index.html b/previews/PR2578/Fields/algebraic_closure_fp/index.html deleted file mode 100644 index 4d13be1f0816..000000000000 --- a/previews/PR2578/Fields/algebraic_closure_fp/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Algebraic closure of finite prime fields · Oscar.jl

Algebraic closure of finite prime fields

It is sometimes useful to consider various finite fields in a fixed characteristic at the same time, together with natural embeddings between these fields. The fields returned by abelian_closure are intended for that purpose.

algebraic_closureFunction
algebraic_closure(F::FinField)

Let F be a prime field of order p. Return a field K that is the union of finite fields of oder p^d, for all positive integers d. The degree d extension of F can be obtained as ext_of_degree(K, d).

K is cached in F, and the fields returned by ext_of_degree are cached in K.

Examples

julia> K = algebraic_closure(GF(3, 1));
-
-julia> F2 = ext_of_degree(K, 2);
-
-julia> F3 = ext_of_degree(K, 3);
-
-julia> x = K(gen(F2)) + K(gen(F3));
-
-julia> degree(x)
-6
source
ext_of_degreeFunction
ext_of_degree(A::AlgClosure, d::Int)

Return a finite field F of order p^d where p is the characteristic of K. This field is compatible with A in the sense that A(x) returns the element of A that corresponds to the element x of F.

source
diff --git a/previews/PR2578/Fields/intro/index.html b/previews/PR2578/Fields/intro/index.html deleted file mode 100644 index f935ff666016..000000000000 --- a/previews/PR2578/Fields/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The fields part of OSCAR provides functionality for handling various kinds of fields:

General textbooks offering details on theory and algorithms include:

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/General/architecture/index.html b/previews/PR2578/General/architecture/index.html deleted file mode 100644 index 9924edb9a9e1..000000000000 --- a/previews/PR2578/General/architecture/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Architecture · Oscar.jl

Architecture

This page aims to give a short technical overview of the architecture of OSCAR. A more in-depth overview of the various components of OSCAR is given on the OSCAR homepage.

Julia packages

OSCAR is developed as a pure julia package Oscar.jl and builds on the features and interfaces provided by the julia packages for the cornerstones:

The packages are integrated into the julia package manager and will be installed automatically as dependencies of OSCAR. They can be accessed directly by their names once OSCAR is loaded.

The current versions of these packages can be inspected with the Oscar.versioninfo command:

julia> Oscar.versioninfo()ERROR: UndefVarError: `Oscar` not defined

Binary packages for non-julia libraries

In addition to the pure julia packages, OSCAR builds on many non-julia libraries for the cornerstones (FLINT, GAP, polymake, Singular) and their dependencies.

Both Polymake.jl and Singular.jl use CxxWrap.jl together with the corresponding libcxxwrap-julia library as an intermediate layer between the julia packages and the C / C++ libraries.

All dependencies have been integrated into the BinaryBuilder ecosystem which provides precompiled binaries for all supported architectures. The build-recipes are maintained in julia's Yggdrasil repository. These are used to automatically build binary artifacts together with the corresponding jll packages which allow automatic installation of all required binaries as dependencies for OSCAR.

The binary packages can be found under the JuliaBinaryWrappers organization. Each repository has an autogenerated Readme file which gives some details on the original sources, supported platforms, and dependencies.

The Oscar.versioninfo function can also include the versions of all binary packages that are maintained by the OSCAR developers:

julia> Oscar.versioninfo(jll=true)ERROR: UndefVarError: `Oscar` not defined

For a full list of all dependencies of the current project please use using Pkg; Pkg.status(mode=PKGMODE_MANIFEST) or the Pkg REPL command ]st -m.

versioninfoFunction
Oscar.versioninfo(io::IO=stdout; branch=false, jll=false, julia=false, commit=false, full=false)

Print the versions of all Oscar-related dependencies.

Arguments

  • branch::Bool=false: include git branch name in the output
  • commit::Bool=false: include git commit hash and date where applicable
  • jll::Bool=false : include binary packages (jll) in the output
  • julia::Bool=false : include julia versioninfo output
  • full::Bool=false : include all of the above
source
diff --git a/previews/PR2578/General/complex/index.html b/previews/PR2578/General/complex/index.html deleted file mode 100644 index 1114828f6716..000000000000 --- a/previews/PR2578/General/complex/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Complex Algorithms in OSCAR · Oscar.jl

Complex Algorithms in OSCAR

On this page we will list some of the more involved algorithmic problems of OSCAR which you may encounter in the background. For larger examples these may not terminate, due to lack of memory or time. We will not go into the details of the respective complexity, as there is sufficient literature.

Often there are several algorithms in OSCAR solving a particular problem, and trying different alternatives may be worthwhile, as some algorithms may not terminate, while others finish in an instant.

Groebner and Standard Bases

A standard basis of an ideal is a generating with special properties. A standard basis is necessary for many (mathematical) low level operations from commutative algebra.

  • Ideal membership
  • Radical of an ideal
  • Kernel of a ring homomorphism
  • Krull dimension of an ideal

Double Description

A polyhedron may be described as the convex hull of a finite set of points or as the intersection of finitely many halfspaces. We omit the more complex cases of unbounded or non-fulldimensional polyhedra here. Computing one description from the other is done via double description algorithms. Many simple algorithms on polyhedra need a double description.

  • Equality of polyhedra
  • Face lattice
  • Lattice points
  • Hilbert basis
diff --git a/previews/PR2578/General/faq/index.html b/previews/PR2578/General/faq/index.html deleted file mode 100644 index 47060de2bc38..000000000000 --- a/previews/PR2578/General/faq/index.html +++ /dev/null @@ -1,18 +0,0 @@ - -Frequently Asked Questions · Oscar.jl

Frequently Asked Questions

General questions

Q: How do I install OSCAR?

You can find our installation instructions here.


Q: Can I find all methods that apply to a given object?

Yes, Julia provides the function methodswith for this very purpose.

For your convenience, let us give an example here. To this end, we first create a projective space in OSCAR:

julia> v = projective_space(NormalToricVariety,2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> typeof(v)
-NormalToricVariety

Suppose that we now want to find all methods that accept a NormalToricVariety as one of their arguments. This can be achieved as follows:

julia> methodswith(typeof(v))
-[1] intersection_form(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/CohomologyClasses/special_attributes.jl:101
-[2] mori_cone(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/attributes.jl:976
-[3] nef_cone(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/attributes.jl:953
-[4] toric_ideal(ntv::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/attributes.jl:510
-[5] volume_form(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/CohomologyClasses/special_attributes.jl:50

Often it can be beneficial to also include supertypes in the search:

julia> methodswith(typeof(v), supertypes = true)

As of December 2022, this results in a list of 101 functions.

Note that we can also find the constructors, i.e. functions that return an object of type NormalToricVariety. This is possible with the Julia function methods:

julia> methods(typeof(v))
-# 5 methods for type constructor:
-[1] NormalToricVariety(P::Polyhedron) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:183
-[2] NormalToricVariety(PF::PolyhedralFan) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:155
-[3] NormalToricVariety(rays::Vector{Vector{Int64}}, max_cones::Vector{Vector{Int64}}; non_redundant) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:131
-[4] NormalToricVariety(C::Cone) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:79
-[5] NormalToricVariety(polymakeNTV::Polymake.BigObject) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:8

Q: Why do you have your own matrix types, and why do they not support the exact same commands as Julia matrices?

Unfortunately, Julia's matrices and linear algebra cannot be made to work in our context due to two independent problems:

  • In empty matrices (0 rows or columns) all that is known is the type of the matrix entries, however for the complex types used in OSCAR, this information is not sufficient to create elements, hence zero(T) or friends cannot work.
  • Many functions (e.g. det) assume that all types used embed into the real or complex numbers, in Julia det(ones(Int, (1,1))) == 1.0, so the fact that this is exactly the integer 1 is lost. Furthermore, more general rings cannot be embedded into the reals at all.

Q: Why can zero(T) for a type T not work?

At least two reasons:

  • The type depends on data that is not a bit-type.

  • Even if it could, it is not desirable. Typical example: computations in $Z/nZ$, so modular arithmetic. If $n$ is small, then it is tempting to define a type T depending on $n$. We actually did this, and tried to use this. It did not work well, for various reasons. E.g.:

    A generic algorithmic pattern for problems over the integers is to solve them by solving them modulo $n$ for many $n$, e.g. chosen as prime numbers, and then to combine them. If the type depends on $n$, then for every prime the code gets compiled, thus negating any advantages from the use of modular techniqes.

Of course, one could make the $n$ an additional parameter to all functions needing it, but then e.g. addition of matrices would have to be implemented specifically for this case, negating the advantages of generic implementations.

In OSCAR, the role of the type is split between the actual Julia type and the parent.


Q: What is a parent?

Almost all element-like objects in OSCAR have a parent, i.e., they belong to some larger structure. For example algebraic numbers belong to a number field, modular integers belong to a ring $Z/nZ$, permutations are elements of permutation groups and so on. The data common to all such elements is out-sourced to the parent. For a number field for example, the parent contains the polynomial used to define the field (plus other information).

Given that a type alone is not large enough to contain the data, the parent is used. Roughly, outside a function signature, a parent replaces the role of the type. For example, for a ring element elm in OSCAR zero(parent(elm)) works, even if zero(typeof(elm)) may not.


Q: How can I install or access custom GAP packages (e.g. unpublished ones)?

TODO


Q: Why does my program not terminate?

Many of the algorithms implemented in OSCAR have a very high complexity. Even if not calling one of these algorithms directly, you may be using it in the background. Please read our page on [Complex Algorithms in OSCAR].


Windows specific

Q: How can I install OSCAR on Windows?

Please follow the install instructions on our website.


Q: Why does OSCAR require WSL on Windows?

Several of the OSCAR corner stones originate from Unix-like operating systems and have no or only limited native support for Windows.


Q: How can I access Linux files from the Explorer?

Type \\wsl$ into the Explorer address bar, then press the Enter key.


Linux specific

Q: Why can't I install OSCAR using the Julia version installed by my package manager?

Some Linux distributions unfortunately ship crippled versions of Julia by default, which prevent OSCAR from working. For example the Debian and Ubuntu Julia packages are missing some files required by OSCAR. In this case, this can be resolved by also installing the libjulia-dev package.

For this reason, we recommend always using the official Julia binaries available form the Julia website.


Q: What to do if I get an error similar to libstdc++.so.6: version `GLIBCXX_3.4.26'?

Sometimes installing or updating OSCAR gives the error libstdc++.so.6: version `GLIBCXX_3.4.26' or a similar one.

This typically happens when manually installing Julia using the official Julia binaries from their website. These bundle their own copy of the C++ standard library, which can lead to trouble if its version differs from the system's C++ library.

As a workaround, you can rename the copy of the C++ library bundled with Julia, so that the system copy is used. This can be achieved by executing the following Julia code:

  path = Libdl.dlpath("libstdc++")
-  mv(path,"$path.bak")

If for some reason you need to restore the C++ library bundled with Julia, you can simply rename it back.

Q: Why does OSCAR fail to precompile when using it with GNU parallel?

You get errors like the following when trying to run some script using OSCAR with GNU parallel:

  ERROR: LoadError: InitError: ArgumentError: '.../deps/<something>_jll' exists. `force=true` is required to remove '...' before copying.

There was a bug in julia versions before 1.8 that ignored the parent argument for the tempname function when the TMPDIR environment variable is set and GNU parallel by default sets TMPDIR to /tmp.

Either upgrade to Julia 1.8 or later, or add delete!(ENV, "TMPDIR"); to the beginning of your julia code (before importing / using Oscar).

diff --git a/previews/PR2578/General/other/index.html b/previews/PR2578/General/other/index.html deleted file mode 100644 index 09ec03f48371..000000000000 --- a/previews/PR2578/General/other/index.html +++ /dev/null @@ -1,20 +0,0 @@ - -Notes for users of other computer algebra systems · Oscar.jl

Notes for users of other computer algebra systems

General differences

  • Julia evaluates 2^100 to 0 because 2 is regarded as a 64 bit integer. Write ZZRingElem(2)^100 to get a long.

  • TODO: add more hints of this kind

Notes for GAP users

This section describes differences between GAP and Oscar. (Hints about using GAP in Oscar can be found in the section about GAP Integration.)

  • The syntax of the languages is slightly different.

    • In GAP, equality of two objects is checked with =, and one assigns a value to a variable with :=. In Julia, equality is checked with ==, and = denotes assignment. Similarly, inequality of objects is checked with <> in GAP and with != in Julia.

    • In GAP, the operator not is used to negate boolean expressions, whereas ! is used in Julia.

    • In GAP, object identity is checked with the function IsIdenticalObj, whereas the infix operator === (with negation !==) is used in Julia.

    • In GAP, if statements have the form

      if condition1 then
      -  statements1
      -elif condition2 then
      -  statements2
      -else
      -  statements3
      -fi;

      whereas the Julia syntax is

      if condition1
      -  statements1
      -elseif condition2
      -  statements2
      -else
      -  statements3
      -end

      Similarly, GAP's for loops have the form

      for var in list do
      -  statements
      -od;

      whereas the Julia syntax is

      for var in list
      -  statements
      -end

      (The situation with while loops is analogous.)

  • Variable names in GAP and Julia are recommended to be written in camel case and snake case, respectively, see Naming conventions. For example, the GAP function SylowSubgroup corresponds to Oscar's sylow_subgroup.

    Thus the GAP rule that the names of user variables should start with a lowercase letter, in order to avoid clashes with system variables, does not make sense in Julia.

    Moreover, global Oscar variables are not write protected, contrary to most global GAP variables. Thus there is always the danger that assignments overwrite Julia functions. For example, it is tempting to use gens, hom, and map as names for variables, but Julia or Oscar define them already.

    (Also copying some lines of code from an Oscar function into a Julia session can be dangerous in this sense, because some names of local variables of the function may coincide with the names of global variables.)

  • GAP provides natural embeddings of many algebraic structures. For example, two finite fields of the same characteristic are embedded into each other whenever this makes sense, and the elements of the smaller field are regarded also as elements of the larger field. Analogously, subfields of cyclotomic fields are naturally embedded into each other, and in fact their elements are internally represented w.r.t. the smallest possible cyclotomic field.

    In Oscar, this is not the case. Each element of an algebraic structure has a parent, and operations involving several elements (such as arithmetic operations) are usually restricted to the situation that their parents coincide. One has to explicitly coerce a given element into a different parent if necessary.

    The consequences can be quite subtle. Each permutation group in Oscar has a fixed degree, and the function is_transitive checks whether its argument is transitive on the points from 1 to the degree. In GAP, however, the function IsTransitive, called with a permutation group, checks whether this group is transitive on the points which are moved by it. Thus the group generated by the permutation (1, 2, 4) is regarded as transitive in GAP but as intransitive in Oscar.

Notes for Singular users

  • TODO
  • TODO: also talk about how to use it from OSCAR?

Notes for Polymake users

  • OSCAR (and Julia) is 1-based, meaning that it counts from 1, rather than from 0 like polymake. For most properties we have taken care of the translation but be aware that it might pop up at some point and generate confusion.

    For convenience, Polymake.jl provides Polymake.to_one_based_indexing and Polymake.to_zero_based_indexing.

  • Polyhedra and polyhedral complexes in OSCAR are represented inhomogeneously, i.e. without the leading 1 for vertices or 0 for rays. Hence constructors take points, rays, and lineality generators separately.

  • user_methods cannot be accessed via Julia's dot syntax, i.e. something like

    c = Polymake.polytope.cube(3)
    -c.AMBIENT_DIM

    will not work. Instead user_methods are attached as Julia functions in their respective application. They are always written in lowercase. In the example the following works:

    c = Polymake.polytope.cube(3)
    -Polymake.polytope.ambient_dim(c)

Notes for Magma users

  • TODO

Notes for SageMath users

  • TODO
diff --git a/previews/PR2578/General/serialization/index.html b/previews/PR2578/General/serialization/index.html deleted file mode 100644 index 41e43dc43288..000000000000 --- a/previews/PR2578/General/serialization/index.html +++ /dev/null @@ -1,51 +0,0 @@ - -Serialization · Oscar.jl

Serialization

Introduction

For some of our datatypes we provide a way to save them in and load them from JSON format. This is still experimental and it will take some time until all corners of OSCAR are covered by this effort. The goal of this effort is threefold:

  • Avoid recomputation by providing an easy way to store data.
  • Increase portability by giving a convenient possibility to transport data.
  • Increase overall software quality by testing against existing data and tracking errors through data computed by different versions.
saveFunction
save(io::IO, obj::Any; metadata::MetaData=nothing)
-save(filename::String, obj::Any, metadata::MetaData=nothing)

Save an object T to the given io stream respectively to the file filename.

See load.

Examples

julia> meta = metadata(author_orcid="0000-0000-0000-0042", name="the meaning of life the universe and everything")
-Oscar.MetaData("0000-0000-0000-0042", "the meaning of life the universe and everything")
-
-julia> save("/tmp/fourtitwo.json", 42; metadata=meta);
-
-julia> load("/tmp/fourtitwo.json")
-42
source
loadFunction
load(io::IO; parent::Any = nothing, type::Any = nothing)
-load(filename::String; parent::Any = nothing, type::Any = nothing)

Load the object stored in the given io stream respectively in the file filename.

If parent is specified, then the root object of the loaded data either will have this as its parent, or it is a container such as Vector and Tuple, then the parent of the entries will be set to parent.

If a type T is given then attempt to load the root object of the data being loaded with this type; if this fails, an error is thrown.

See save.

Examples

julia> save("/tmp/fourtitwo.json", 42);
-
-julia> load("/tmp/fourtitwo.json")
-42
-
-julia> load("/tmp/fourtitwo.json"; type=Int64)
-42
-
-julia> R, x = QQ["x"]
-(Univariate polynomial ring in x over QQ, x)
-
-julia> p = x^2 - x + 1
-x^2 - x + 1
-
-julia> save("/tmp/p.json", p)
-
-julia> p_loaded = load("/tmp/p.json", parent=R)
-x^2 - x + 1
-
-julia> parent(p_loaded) === R
-true
-
-julia> save("/tmp/p_v.json", [p, p])
-
-julia> loaded_p_v = load("/tmp/p_v.json", parent=R)
-2-element Vector{QQPolyRingElem}:
- x^2 - x + 1
- x^2 - x + 1
-
-julia> parent(loaded_p_v[1]) === parent(loaded_p_v[2]) === R
-true
source
is_basic_serialization_typeFunction
is_basic_serialization_type(::Type)

During the serialization of types of the form Vector{T}, entries of type T will either be serialized as strings if is_basic_serialization_type returns true, or serialized as a dict provided the serialization for such a T exists. If Vector{T} is serialized with is_basic_serialization_type(T) = true then the entry_type keyword is used to store the type T as a property of the vector.

Examples

julia> is_basic_serialization_type(ZZRingElem)
-true
source

Objects that can be serialized

In this section we will list objects that may be (de-)serialized. This list may be incomplete.

Many low level objects may be stored and these in turn allow serializing higher level objects. Such low level objects are various types of matrices, vectors and sets.

Combinatorics

Graph
-SimplicialComplex

Commutative Algebra

Ideal
-Polynomial
-polynomial_ring

Polyhedral Geometry

Cone
-LinearProgram
-PolyhedralFan
-PolyhedralComplex
-Polyhedron
-SubdivisionOfPoints

Toric Geometry

NormalToricVariety
-ToricDivisor

Tropical Geometry

TropicalCurve
-TropicalHypersurface
diff --git a/previews/PR2578/Groups/action/index.html b/previews/PR2578/Groups/action/index.html deleted file mode 100644 index 7aee20f2efb9..000000000000 --- a/previews/PR2578/Groups/action/index.html +++ /dev/null @@ -1,189 +0,0 @@ - -Group Actions · Oscar.jl

Group Actions

A group action of a group G on a set Ω (from the right) is defined by a map μ: Ω × G → Ω that satisfies the compatibility conditions μ(μ(x, g), h) = μ(x, g*h) and μ(x, one(G)) == x for all x ∈ Ω.

The maps μ are implemented as functions that take two arguments, an element x of Ω and a group element g, and return the image of x under g.

In many cases, a natural action is given by the types of the elements in Ω and in G. For example permutation groups act on positive integers by just applying the permutations. In such situations, the function ^ can be used as action function, and ^ is taken as the default whenever no other function is prescribed.

However, the action is not always determined by the types of the involved objects. For example, permutations can act on vectors of positive integers by applying the permutations pointwise, or by permuting the entries; matrices can act on vectors by multiplying the vector with the matrix, or by multiplying the inverse of the matrix with the vector; and of course one can construct new custom actions in situations where default actions are already available.

Thus it is in general necessary to specify the action function explicitly, see the following sections.

Common actions of group elements

on_tuplesFunction
on_tuples(tuple::GAP.GapObj, x::GAPGroupElem)
-on_tuples(tuple::Vector, x::GAPGroupElem)
-on_tuples(tuple::T, x::GAPGroupElem) where T <: Tuple

Return the image of tuple under x, where the action is given by applying ^ to the entries of tuple.

For Vector and Tuple objects, one can also call ^ instead of on_tuples.

Examples

julia> g = symmetric_group(3);  g[1]
-(1,2,3)
-
-julia> l = GAP.GapObj([1, 2, 4])
-GAP: [ 1, 2, 4 ]
-
-julia> on_tuples(l, g[1])
-GAP: [ 2, 3, 4 ]
-
-julia> on_tuples([1, 2, 4], g[1])
-3-element Vector{Int64}:
- 2
- 3
- 4
-
-julia> on_tuples((1, 2, 4), g[1])
-(2, 3, 4)
-
-julia> (1, 2, 4)^g[1]
-(2, 3, 4)
source
on_setsFunction
on_sets(set::GAP.GapObj, x::GAPGroupElem)
-on_sets(set::Vector, x::GAPGroupElem)
-on_sets(set::Tuple, x::GAPGroupElem)
-on_sets(set::AbstractSet, x::GAPGroupElem)

Return the image of set under x, where the action is given by applying ^ to the entries of set, and then turning the result into a sorted vector/tuple or a set, respectively.

For Set objects, one can also call ^ instead of on_sets.

Examples

julia> g = symmetric_group(3);  g[1]
-(1,2,3)
-
-julia> l = GAP.GapObj([1, 3])
-GAP: [ 1, 3 ]
-
-julia> on_sets(l, g[1])
-GAP: [ 1, 2 ]
-
-julia> on_sets([1, 3], g[1])
-2-element Vector{Int64}:
- 1
- 2
-
-julia> on_sets((1, 3), g[1])
-(1, 2)
-
-julia> on_sets(Set([1, 3]), g[1])
-Set{Int64} with 2 elements:
-  2
-  1
-
-julia> BitSet([1, 3])^g[1]
-BitSet with 2 elements:
-  1
-  2
source
permutedFunction
permuted(pnt::GAP.GapObj, x::PermGroupElem)
-permuted(pnt::Vector, x::PermGroupElem)
-permuted(pnt::Tuple, x::PermGroupElem)

Return the image of pnt under x, where the action is given by permuting the entries of pnt with x.

Examples

julia> g = symmetric_group(3);  g[1]
-(1,2,3)
-
-julia> a = ["a", "b", "c"]
-3-element Vector{String}:
- "a"
- "b"
- "c"
-
-julia> permuted(a, g[1])
-3-element Vector{String}:
- "c"
- "a"
- "b"
-
-julia> permuted(("a", "b", "c"), g[1])
-("c", "a", "b")
-
-julia> l = GAP.GapObj(a, recursive = true)
-GAP: [ "a", "b", "c" ]
-
-julia> permuted(l, g[1])
-GAP: [ "c", "a", "b" ]
source
on_indeterminatesFunction
on_indeterminates(f::GAP.GapObj, p::PermGroupElem)
-on_indeterminates(f::MPolyRingElem, p::PermGroupElem)
-on_indeterminates(f::MPolyIdeal, p::PermGroupElem)
-on_indeterminates(f::GAP.GapObj, p::MatrixGroupElem)
-on_indeterminates(f::MPolyRingElem{T}, p::MatrixGroupElem{T, S}) where T where S
-on_indeterminates(f::MPolyIdeal, p::MatrixGroupElem)

Return the image of f under p. If p is a PermGroupElem then it acts via permuting the indeterminates, if p is a MatrixGroupElem then it acts via evaluating f at the vector obtained by multiplying p with the (column) vector of indeterminates.

For MPolyRingElem and MPolyIdeal objects, one can also call ^ instead of on_indeterminates.

Examples

julia> g = symmetric_group(3);  p = g[1]
-(1,2,3)
-
-julia> R, x = polynomial_ring(QQ, ["x1", "x2", "x3"]);
-
-julia> f = x[1]*x[2] + x[2]*x[3]
-x1*x2 + x2*x3
-
-julia> f^p
-x1*x3 + x2*x3
-
-julia> x = [GAP.Globals.X(GAP.Globals.Rationals, i) for i in 1:3];
-
-julia> f = x[1]*x[2] + x[2]*x[3]
-GAP: x_1*x_2+x_2*x_3
-
-julia> on_indeterminates(f, p)
-GAP: x_1*x_3+x_2*x_3
-
-julia> g = general_linear_group(2, 5);  m = g[2]
-[4   1]
-[4   0]
-
-julia> R, x = polynomial_ring(base_ring(g), degree(g));
-
-julia> f = x[1]*x[2] + x[1]
-x1*x2 + x1
-
-julia> f^m
-x1^2 + 4*x1*x2 + 4*x1 + x2
source

G-Sets

The idea behind G-sets is to have objects that encode the permutation action induced by a group (that need not be a permutation group) on a given set. A G-set provides an explicit bijection between the elements of the set and the corresponding set of positive integers on which the induced permutation group acts, see action_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup.

gsetMethod
gset(G::GAPGroup[, fun::Function], seeds, closed::Bool = false)

Return the G-set Omega that consists of the closure of the seeds seeds under the action of G defined by fun.

This means that Omega contains all elements fun(omega, g) for omega in seeds and g in G.

fun can be omitted if the element type of seeds implies a reasonable default, for example, if G is a PermGroup and seeds is a Vector{T} where T is one of Int, Set{Int}, Vector{Int}.

If closed is set to true then seeds is assumed to be closed under the action of G. In this case, collect(Omega) is guaranteed to be equal to collect(seeds); in particular, the ordering of points in seeds (if applicable) is kept. Note that the indexing of points in Omega is used by action_homomorphism.

Examples

julia> G = symmetric_group(4);
-
-julia> length(gset(G, [[1]]))  # natural action
-4
-
-julia> length(gset(G, [[1, 2]]))  # action on ordered pairs
-12
-
-julia> length(gset(G, on_sets, [[1, 2]]))  # action on unordered pairs
-6
-
source
permutationFunction
permutation(Omega::GSetByElements{T}, g::BasicGAPGroupElem{T}) where T<:GAPGroup

Return the element of the permutation group that describes the action of g on Omega, where g is an element of acting_group(Omega).

Examples

julia> G = symmetric_group(4);
-
-julia> Omega = gset(G, [[1, 2]]);
-
-julia> x = gen(G, 1)
-(1,2,3,4)
-
-julia> permutation(Omega, x)
-(1,2,4,7)(3,6,9,12)(5,8,10,11)
-
source
action_homomorphismMethod
action_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup

Return the group homomorphism act with domain G = acting_group(Omega) and codomain symmetric_group(n) that describes the permutation action of G on Omega, where Omega has n elements.

This means that if an element g in G maps collect(Omega)[i] to collect(Omega)[j] then act(g) maps i to j.

Examples

julia> G = symmetric_group(6);
-
-julia> Omega = gset(G, [Set([1, 2])]);  # action on unordered pairs
-
-julia> acthom = action_homomorphism(Omega)
-Group homomorphism from 
-Sym( [ 1 .. 6 ] )
-to
-Sym( [ 1 .. 15 ] )
-
-julia> g = gen(G, 1)
-(1,2,3,4,5,6)
-
-julia> elms = collect(Omega);
-
-julia> actg = acthom(g)
-(1,2,3,5,7,10)(4,6,8,11,14,13)(9,12,15)
-
-julia> elms[1]^g == elms[2]
-true
-
-julia> 1^actg == 2
-true
-
source
orbitMethod
orbit(Omega::GSet, omega::T) where T

Return the G-set that consists of the elements fun(omega, g) where g is in the group of Omega and fun is the underlying action of Omega.

Examples

julia> G = sylow_subgroup(symmetric_group(6), 2)[1]
-Group([ (1,2), (3,4), (1,3)(2,4), (5,6) ])
-
-julia> Omega = gset(G, [1, 5]);
-
-julia> length(orbit(Omega, 1))
-4
-
source
orbitMethod
orbit(G::GAPGroup[, fun::Function], omega)

Return the G-set that consists of the images of omega under the action of G defined by fun.

This means that the result contains all elements fun(omega, g) for g in G.

fun can be omitted if the type of Omega implies a reasonable default, for example, if G is a PermGroup and omega is one of Int, Set{Int}, Vector{Int}.

Examples

julia> G = symmetric_group(4);
-
-julia> length(orbit(G, 1))
-4
-
-julia> length(orbit(G, [1, 2]))
-12
-
-julia> length(orbit(G, on_sets, [1, 2]))
-6
-
source
orbitsMethod
orbits(Omega::GSet)

Return the vector of transitive G-sets in Omega.

Examples

julia> G = sylow_subgroup(symmetric_group(6), 2)[1]
-Group([ (1,2), (3,4), (1,3)(2,4), (5,6) ])
-
-julia> orbs = orbits(gset(G));
-
-julia> map(collect, orbs)
-2-element Vector{Vector{Int64}}:
- [1, 2, 3, 4]
- [5, 6]
-
source

Stabilizers

stabilizerMethod
stabilizer(G::Oscar.GAPGroup, pnt::Any[, actfun::Function])

Return the subgroup of G that consists of all those elements g that fix pnt under the action given by actfun, that is, actfun(pnt, g) == pnt holds.

The default for actfun depends on the types of G and pnt: If G is a PermGroup then the default actions on integers, Vectors of integers, and Sets of integers are given by ^, on_tuples, and on_sets, respectively. If G is a MatrixGroup then the default actions on FreeModuleElems, Vectors of them, and Sets of them are given by *, on_tuples, and on_sets, respectively.

Examples

julia> G = symmetric_group(5);
-
-julia> S = stabilizer(G, 1);  order(S[1])
-24
-
-julia> S = stabilizer(G, [1, 2]);  order(S[1])
-6
-
-julia> S = stabilizer(G, Set([1, 2]));  order(S[1])
-12
-
-julia> S = stabilizer(G, [1, 1, 2, 2, 3], permuted);  order(S[1])
-4
source
diff --git a/previews/PR2578/Groups/autgroup/index.html b/previews/PR2578/Groups/autgroup/index.html deleted file mode 100644 index 1eb089d92cd6..000000000000 --- a/previews/PR2578/Groups/autgroup/index.html +++ /dev/null @@ -1,98 +0,0 @@ - -Groups of automorphisms · Oscar.jl

Groups of automorphisms

automorphism_groupMethod
automorphism_group(G::Group) -> A::AutomorphismGroup{T}

Return the full automorphism group of G. If f is an object of type GAPGroupHomomorphism and it is bijective from G to itself, then A(f) return the embedding of f in A.

Groups of automorphisms over a group G have parametric type AutomorphismGroup{T}, where T is the type of G.

Examples

julia> S = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> typeof(S)
-PermGroup
-
-julia> A = automorphism_group(S)
-Aut( Sym( [ 1 .. 3 ] ) )
-
-julia> typeof(A)
-AutomorphismGroup{PermGroup}

The evaluation of the automorphism f in the element x is analogous to the homomorphism evaluation: it can be obtained by typing either f(x) or x^f.

julia> S = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> A = automorphism_group(S)
-Aut( Sym( [ 1 .. 4 ] ) )
-
-julia> x = perm(S,[2,1,4,3])
-(1,2)(3,4)
-
-julia> f = A[2]
-Pcgs([ (3,4), (2,4,3), (1,4)(2,3), (1,3)(2,4) ]) -> [ (2,3), (2,4,3), (1,3)(2,4), (1,2)(3,4) ]
-
-julia> f(x)
-(1,4)(2,3)
-
-julia> x^f
-(1,4)(2,3)

It is possible to turn an automorphism f into a homomorphism by typing hom(f).

julia> S = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> A = automorphism_group(S)
-Aut( Sym( [ 1 .. 4 ] ) )
-
-julia> f = A[2]
-Pcgs([ (3,4), (2,4,3), (1,4)(2,3), (1,3)(2,4) ]) -> [ (2,3), (2,4,3), (1,3)(2,4), (1,2)(3,4) ]
-
-julia> typeof(f)
-AutomorphismGroupElem{PermGroup} (alias for Oscar.BasicGAPGroupElem{AutomorphismGroup{PermGroup}})
-
-julia> typeof(hom(f))
-GAPGroupHomomorphism{PermGroup, PermGroup}

The converse is also possible: if g is a bijective homomorphism from the group G to itself and A is the automorphism group of G, then the instruction A(g) returns g as automorphism of G. This is the standard way to explicitly build an automorphism (another way, available for inner automorphisms, is shown in Section Inner_automorphisms).

Examples

julia> S = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> a = perm(S,[2,1,4,3])
-(1,2)(3,4)
-
-julia> f = hom(S,S,x ->x^a)
-Group homomorphism from 
-Sym( [ 1 .. 4 ] )
-to
-Sym( [ 1 .. 4 ] )
-
-julia> A = automorphism_group(S)
-Aut( Sym( [ 1 .. 4 ] ) )
-
-julia> A(f)
-MappingByFunction( Sym( [ 1 .. 4 ] ), Sym( [ 1 .. 4 ] ), <Julia: gap_fun> )

Elements of A can be multiplied with other elements of A or by elements of type GAPGroupHomomorphism; in this last case, the result has type GAPGroupHomomorphism.

Examples

julia> S = symmetric_group(4);
-
-julia> A = automorphism_group(S);
-
-julia> g = hom(S,S,x->x^S[1]);
-
-julia> g in A
-false
-
-julia> au = A(g);
-
-julia> au in A
-true
-
-julia> g == hom(au)
-true
-
-julia> x = cperm(S,[1,2,3]);
-
-julia> au(x)
-(2,3,4)
-
-julia> g(x) == au(x)
-true

In Oscar it is possible to multiply homomorphisms and automorphisms (whenever it makes sense); in such cases, the output is always a variable of type GAPGroupHomomorphism{S,T}.

julia> S = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> A = automorphism_group(S)
-Aut( Sym( [ 1 .. 4 ] ) )
-
-julia> g = hom(S,S,x->x^S[1])
-Group homomorphism from 
-Sym( [ 1 .. 4 ] )
-to
-Sym( [ 1 .. 4 ] )
-
-julia> f = A(g)
-MappingByFunction( Sym( [ 1 .. 4 ] ), Sym( [ 1 .. 4 ] ), <Julia: gap_fun> )
-
-julia> typeof(g*f)
-GAPGroupHomomorphism{PermGroup, PermGroup}
source

The following functions are available for automorphisms, some of them similar to the corresponding functions for homomorphisms of groups.

is_invariantMethod
is_invariant(f::GAPGroupElem{AutomorphismGroup{T}}, H::T)

Return whether f(H) == H.

source
restrict_automorphismMethod
restrict_automorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::T)

Return the restriction of f to H as an automorphism of H. An exception is thrown if H is not invariant under f.

source
induced_automorphismMethod
induced_automorphism(f::GAPGroupHomomorphism, g::GAPGroupHomomorphism)
-induced_automorphism(f::GAPGroupHomomorphism, g::GAPGroupElem{AutomorphismGroup{T}})

Return the automorphism h of the image of f such that h(f) == f(g), where g is an automorphism of a group G and f is a group homomorphism defined over G such that the kernel of f is invariant under g

source
homMethod
hom(f::GAPGroupElem{AutomorphismGroup{T}}) where T

Return the element f of type GAPGroupHomomorphism{T,T}.

source

Inner automorphisms

OSCAR provides the following functions to handle inner automorphisms of a group.

inner_automorphismMethod
inner_automorphism(g::GAPGroupElem)

Return the inner automorphism in automorphism_group(parent(g)) defined by x -> x^g.

source
is_inner_automorphismMethod
is_inner_automorphism(f::GAPGroupHomomorphism)
-is_inner_automorphism(f::GAPGroupElem{AutomorphismGroup{T}})

Return whether f is an inner automorphism.

source
diff --git a/previews/PR2578/Groups/basics/index.html b/previews/PR2578/Groups/basics/index.html deleted file mode 100644 index e852860d05ce..000000000000 --- a/previews/PR2578/Groups/basics/index.html +++ /dev/null @@ -1,144 +0,0 @@ - -Basics · Oscar.jl

Basics

Elements of groups

Given a group G, it is always possible to have access to some particular elements.

GAPGroupType
GAPGroup <: AbstractAlgebra.Group

Each object of the abstract type GAPGroup stores a group object from the GAP system, and thus can delegate questions about this object to GAP.

For expert usage, you can extract the underlying GAP object via GapObj, i.e., if G is a GAPGroup, then GapObj(G) is the GapObj underlying G.

Concrete subtypes of GAPGroup are PermGroup, FPGroup, PcGroup, and MatrixGroup.

source
BasicGAPGroupElemType
BasicGAPGroupElem{T<:GAPGroup} <: GAPGroupElem{T}

The type BasicGAPGroupElem gathers all types of group elements described only by an underlying GAP object.

If $x$ is an element of the group G of type T, then the type of $x$ is BasicGAPGroupElem{T}.

source
elem_typeMethod
elem_type(::Type{T}) where T <: GAPGroup
-elem_type(::T) where T <: GAPGroup

elem_type maps (the type of) a group to the type of its elements. For now, a group of type T has elements of type BasicGAPGroupElem{T}. So we provide it mostly for consistency with other parts of OSCAR. In the future, a more elaborate setup for group element types might also be needed.

source
oneMethod
one(G::GAPGroup) -> elem_type(G)

Return the identity of the group G.

source
oneMethod
one(x::GAPGroupElem{T}) -> GAPGroupElem{T}

Return the identity of the parent group of x.

source
is_finiteorderMethod
is_finiteorder(g::GAPGroupElem) -> Bool

Return true if g has finite order, and false otherwise.

Examples

julia> is_finiteorder(gen(symmetric_group(5), 1))
-true
-
-julia> is_finiteorder(gen(free_group(2), 1))
-false
-
source
gensMethod
gens(G::Group)

Return a vector of generators of G. To get the i-th generator, use G[i] or gen(G,i) (see gen) instead of gens(G)[i], as that is more efficient.

Examples

julia> g = symmetric_group(5);  gens(g)
-2-element Vector{PermGroupElem}:
- (1,2,3,4,5)
- (1,2)
-
-julia> g[2]
-(1,2)
-
Note

The output of gens(G) is not, in general, the minimal list of generators for G.

source
has_gensMethod
has_gens(G::Group)

Return whether generators for the group G are known.

Examples

julia> F = free_group(2)
-<free group on the generators [ f1, f2 ]>
-
-julia> has_gens(F)
-true
-
-julia> H = derived_subgroup(F)[1]
-Group(<free, no generators known>)
-
-julia> has_gens(H)
-false
source
ngensMethod
ngens(G::GAPGroup) -> Int

Return the length of the vector gens(G).

WARNING:

this is NOT, in general, the minimum number of generators for G.

source
genMethod
gen(G::GAPGroup, i::Int)

Return the i-th element of the vector gens(G). This is equivalent to G[i], and returns gens(G)[i] but may be more efficient than the latter.

An exception is thrown if i is larger than the length of gens(G).

source
small_generating_setMethod
small_generating_set(G::GAPGroup)

Return a reasonably short vector of elements in G that generate G; in general the length of this vector is not minimal.

Examples

julia> length(small_generating_set(abelian_group(PcGroup, [2,3,4])))
-2
-
-julia> length(small_generating_set(abelian_group(PermGroup, [2,3,4])))
-3
source
randMethod
rand(rng::Random.AbstractRNG = Random.GLOBAL_RNG, G::Group)

Return a random element of G, using the random number generator rng.

source
rand_pseudoMethod
rand_pseudo(G::GAPGroup)

Return a pseudo random element of G. This works faster than rand, but the returned elements are not necessarily uniformly distributed.

It is sometimes necessary to work with finite groups that we cannot effectively enumerate, e.g. matrix groups over finite fields. We may not even know the size of these groups. Yet many algorithms need to sample elements from the group "as randomly as possible", whatever that means; but also they need this fast.

The function rand_pseudo returns elements that are cheap to compute and somehow random, but makes no guarantees about their distribution.

For finitely presented groups, it returns random words of bounded length.

For finite permutation and matrix groups, it uses a variant of the product replacement algorithm. For most inputs, the resulting stream of elements relatively quickly converges to a uniform distribution.

source

It is also possible to obtain the generators of G by typing

f1,f2,f3 = gens(G)

This is equivalent to

f1=G[1]; f2=G[2]; f3=G[3];

For a group G that has been created as a subgroup of another group, generated by a list L of elements, gens(G) is equal to L.

Operations on group elements

OSCAR supports the following operations and functions on group elements.

  • *, multiplication between two elements in a group.
  • inv(x) and x^-1, the inverse of x.
  • x/y, the element x y^-1.
  • x^n, the n-th power of x; if n == 0, the identity of the group is returned; if n < 0, the -n-th power of the inverse of x is returned.
  • isone(x) returns whether x is the identity of the group.
  • conj(x,y) and x^y, the conjugate of x by y, i.e., the element y^-1 x y.
  • comm(x,y), the commutator of x and y, i.e., the element x^-1 y^-1 x y.
Note

In OSCAR, the expression x^y^z is equivalent to x^(y^z). In other words, conjugations are evaluated from the right to the left.

commMethod
comm(x::GAPGroupElem, y::GAPGroupElem)

Return the commutator of x and y, which is defined as x^-1*y^-1*x*y, and usually denoted as [x,y] in the literature.

source

Properties of groups

is_finiteMethod
is_finite(G::GAPGroup) -> Bool

Return true if G is finite, and false otherwise.

Examples

julia> is_finite(symmetric_group(5))
-true
-
-julia> is_finite(free_group(2))
-false
-
source
is_trivialMethod
is_trivial(G::GAPGroup)

Return true if G has order 1, and false otherwise.

Examples

julia> is_trivial(symmetric_group(1))
-true
-
-julia> is_trivial(symmetric_group(2))
-false
source
is_cyclicMethod
is_cyclic(G::GAPGroup)

Return true if G is cyclic, i.e., if G can be generated by one element.

source
is_abelianMethod
is_abelian(G::Group)

Return true if G is abelian (commutative), that is, $x*y = y*x$ holds for all elements $x, y$ in G.

source
is_elementary_abelianFunction
is_elementary_abelian(G::Group)

Return true if G is a abelian (see is_abelian) and if there is a prime p such that the order of each element in G divides p.

Examples

julia> g = alternating_group(5);
-
-julia> is_elementary_abelian(sylow_subgroup(g, 2)[1])
-true
-
-julia> g = alternating_group(6);
-
-julia> is_elementary_abelian(sylow_subgroup(g, 2)[1])
-false
source
is_pgroupFunction
is_pgroup(G)

Return true if G is a $p$-group for some prime $p$, that is, if the order of every element in G is a power of $p$.

Note that a finite group is a $p$-group if and only if its order is a prime power. In particular, the trivial group is a $p$-group for every prime.

Examples

julia> is_pgroup(symmetric_group(1))
-true
-
-julia> is_pgroup(symmetric_group(2))
-true
-
-julia> is_pgroup(symmetric_group(3))
-false
-
source
is_pgroup_with_primeFunction
is_pgroup_with_prime(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion

Return (true, nothing) if G is the trivial group, (true, p) if the order of every element in G is a power of a prime p, and (false, nothing) otherwise.

For finite groups G, the first return value is true if and only if the order of G is a prime power.

Examples

julia> is_pgroup_with_prime(symmetric_group(1))
-(true, nothing)
-
-julia> is_pgroup_with_prime(symmetric_group(2))
-(true, 2)
-
-julia> is_pgroup_with_prime(symmetric_group(3))
-(false, nothing)
-
source
is_nilpotentFunction
is_nilpotent(a::ResElem{ZZRingElem}) -> Bool
-is_nilpotent(a::ResElem{Integer}) -> Bool

Tests if $a$ is nilpotent.

is_nilpotent(G::GAPGroup)

Return whether G is nilpotent, i.e., whether the lower central series of G reaches the trivial subgroup in a finite number of steps.

source
is_supersolvableFunction
is_supersolvable(G::GAPGroup)

Return whether G is supersolvable, i.e., G is finite and has a normal series with cyclic factors.

source
is_solvableFunction
is_solvable(G::GAPGroup)

Return whether G is solvable, i.e., whether derived_series(G) reaches the trivial subgroup in a finite number of steps.

source
is_perfectFunction
is_perfect(G::GAPGroup)

Return whether G is a perfect group, i.e., equal to its derived subgroup.

Examples

julia> is_perfect(special_linear_group(2, 5))
-true
-
-julia> is_perfect(symmetric_group(5))
-false
-
source
is_simpleMethod
is_simple(G::GAPGroup)

Return whether G is a simple group, i.e., G is not trivial and has no non-trivial normal subgroups.

Examples

julia> is_simple(alternating_group(5))
-true
-
-julia> is_simple(symmetric_group(5))
-false
-
source
is_almostsimpleFunction
is_almostsimple(G::GAPGroup)

Return whether G is an almost simple group, i.e., G is isomorphic to a group $H$ with the property $S \leq H \leq Aut(S)$, for some non-abelian simple group $S$.

Examples

julia> is_almostsimple(symmetric_group(5))
-true
-
-julia> is_almostsimple(special_linear_group(2, 5))
-false
-
source
is_quasisimpleFunction
is_quasisimple(G::GAPGroup)

Return whether G is a quasisimple group, i.e., G is perfect such that the factor group modulo its centre is a non-abelian simple group.

Examples

julia> is_quasisimple(special_linear_group(2, 5))
-true
-
-julia> is_quasisimple(symmetric_group(5))
-false
-
source
is_sporadic_simpleFunction
is_sporadic_simple(G::GAPGroup)

Return whether G is a sporadic simple group.

Examples

julia> is_sporadic_simple(mathieu_group(11))
-true
-
-julia> is_sporadic_simple(mathieu_group(10))
-false
-
source
is_finitelygeneratedFunction
is_finitelygenerated(G)

Return whether G is a finitely generated group.

Examples

julia> F = free_group(2)
-<free group on the generators [ f1, f2 ]>
-
-julia> is_finitelygenerated(F)
-true
-
-julia> H = derived_subgroup(F)[1]
-Group(<free, no generators known>)
-
-julia> is_finitelygenerated(H)
-false
source

Attributes of groups

orderMethod
order(::Type{T} = ZZRingElem, x::Union{GAPGroupElem, GAPGroup}) where T <: IntegerUnion

Return the order of x, as an instance of T.

For a group element x in the group G, the order of x is the smallest positive integer n such that x^n is the identity of G. For a group x, the order of x is the number of elements in x.

An exception is thrown if the order of x is infinite, use is_finite for checking the finiteness of a group, and is_finiteorder for checking whether a group element has finite order.

Examples

julia> g = symmetric_group(3);
-
-julia> order(g)
-6
-
-julia> order(gen(g, 1))
-3
-
-julia> g = free_group(1);
-
-julia> is_finite(g)
-false
-
-julia> is_finiteorder(gen(g, 1))
-false
source
cyclic_generatorMethod
cyclic_generator(G::GAPGroup)

Return an element of G that generates G if G is cyclic, and throw an error otherwise.

Examples

julia> g = permutation_group(5, [cperm(1:3), cperm(4:5)])
-Group([ (1,2,3), (4,5) ])
-
-julia> cyclic_generator(g)
-(1,2,3)(4,5)
source
exponentMethod
exponent(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion

Return the exponent of G, as an instance of T, i.e., the smallest positive integer $e$ such that $g^e$ is the identity of G for every $g$ in G.

Examples

julia> exponent(symmetric_group(3))
-6
-
-julia> exponent(symmetric_group(13))
-360360
source
describeMethod
describe(G::GAPGroup)

Return a string that describes some aspects of the structure of G.

For finite groups, the function works well if G is an abelian group or a finite simple group or a group in one of the following series: symmetric, dihedral, quasidihedral, generalized quaternion, general linear, special linear.

For other finite groups, the function tries to decompose G as a direct product or a semidirect product, and if this is not possible as a non-splitting extension of a normal subgroup $N$ with the factor group G$/N$, where $N$ is the center or the derived subgroup or the Frattini subgroup of G.

For infinite groups, if the group is known to be finitely generated and abelian or free, a reasonable description is printed.

For general infinite groups, or groups for which finiteness is not (yet) known, not much if anything can be done. In particular we avoid potentially expensive checks such as computing the size of the group or whether it is abelian. While we do attempt a few limited fast checks for finiteness and commutativity, these will not detect all finite or commutative groups.

Thus calling describe again on the same group after additional information about it becomes known to Oscar may yield different outputs.

Note
  • for finitely presented groups, even deciding if the group is trivial is impossible in general; the same holds for most other properties, like whether the group is finite, abelian, etc.,
  • there is in general no "nice" decomposition of G,
  • there may be several decompositions of G,
  • nonisomorphic groups may yield the same describe result,
  • isomorphic groups may yield different describe results,
  • the computations can take a long time (for example in the case of large $p$-groups), and the results are still often not very helpful.

The following notation is used in the returned string.

DescriptionSyntax
trivial group1
finite cyclic groupC<size>
infinite cyclic groupZ
alternating groupA<degree>
symmetric groupS<degree>
dihedral groupD<size>
quaternion groupQ<size>
quasidihedral groupQD<size>
projective special linear groupPSL(<n>,<q>)
special linear groupSL(<n>,<q>)
general linear groupGL(<n>,<q>)
proj. special unitary groupPSU(<n>,<q>)
orthogonal group, type BO(2<n>+1,<q>)
orthogonal group, type DO+(2<n>,<q>)
orthogonal group, type 2DO-(2<n>,<q>)
proj. special symplectic groupPSp(2<n>,<q>)
Suzuki group (type 2B)Sz(<q>)
Ree group (type 2F or 2G)Ree(<q>)
Lie group of exceptional typeE(6,<q>), E(7,<q>), E(8,<q>), 2E(6,<q>), F(4,<q>), G(2,<q>)
Steinberg triality group3D(4,<q>)
sporadic simple groupM11, M12, M22, M23, M24, J1, J2, J3, J4, Co1, Co2, Co3, Fi22, Fi23, Fi24', Suz, HS, McL, He, HN, Th, B, M, ON, Ly, Ru
Tits group2F(4,2)'
the indicated group from the library of perfect groupsPerfectGroup(<size>,<id>)
direct productA x B
semidirect productN : H
non-split extensionZ(G) . G/Z(G) = G' . G/G', Phi(G) . G/Phi(G)

Examples

julia> g = symmetric_group(6);
-
-julia> describe(g)
-"S6"
-
-julia> describe(sylow_subgroup(g,2)[1])
-"C2 x D8"
-
-julia> describe(sylow_subgroup(g, 3)[1])
-"C3 x C3"
-
-julia> describe(free_group(3))
-"a free group of rank 3"
-
source
nilpotency_classMethod
nilpotency_class(G::GAPGroup) -> Int

Return the nilpotency class of G, i.e., the smallest integer $n$ such that G has a central series of length $n$.

An exception is thrown if G is not nilpotent.

source
prime_of_pgroupFunction
prime_of_pgroup(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion

Return the prime $p$ if G is a non-trivial $p$-group.

An exception is thrown if G is not a $p$-group or is a trivial group.

Examples

julia> prime_of_pgroup(quaternion_group(8))
-2
-
-julia> prime_of_pgroup(UInt16, quaternion_group(8))
-0x0002
-
-julia> prime_of_pgroup(symmetric_group(1))
-ERROR: ArgumentError: only supported for non-trivial p-groups
-
-julia> prime_of_pgroup(symmetric_group(3))
-ERROR: ArgumentError: only supported for non-trivial p-groups
-
source
diff --git a/previews/PR2578/Groups/fpgroup/index.html b/previews/PR2578/Groups/fpgroup/index.html deleted file mode 100644 index 6e28f624c040..000000000000 --- a/previews/PR2578/Groups/fpgroup/index.html +++ /dev/null @@ -1,55 +0,0 @@ - -Finitely presented groups · Oscar.jl

Finitely presented groups

FPGroupType
FPGroup

Finitely presented group. Such groups can be constructed a factors of free groups, see free_group.

source
free_groupMethod
free_group(n::Int, s::VarName = :f; eltype::Symbol = :letter) -> FPGroup
-free_group(L::Vector{<:VarName}) -> FPGroup
-free_group(L::VarName...) -> FPGroup

The first form returns the free group of rank n, where the generators are printed as s1, s2, ..., the default being f1, f2, ... If eltype has the value :syllable then each element in the free group is internally represented by a vector of syllables, whereas a representation by a vector of integers is chosen in the default case of eltype == :letter.

The second form, if L has length n, returns the free group of rank n, where the i-th generator is printed as L[i].

The third form, if there are n arguments L..., returns the free group of rank n, where the i-th generator is printed as L[i].

Note

Variables named like the group generators are not created by this function.

source
is_full_fp_groupMethod
is_full_fp_group(G::FPGroup)

Return true if G has been constructed as a free group or a quotient of a free group, and false otherwise.

Note that also subgroups of groups of type FPGroup have the type FPGroup, and functions such as relators do not make sense for proper subgroups.

Examples

julia> f = free_group(2);  is_full_fp_group(f)
-true
-
-julia> s = sub(f, gens(f))[1];  is_full_fp_group(s)
-false
-
-julia> q = quo(f, [gen(f,1)^2])[1];  is_full_fp_group(q)
-true
-
-julia> u = sub(q, gens(q))[1];  is_full_fp_group(u)
-false
source
relatorsMethod
relators(G::FPGroup)

Return a vector of relators for the full finitely presented group G, i.e., elements $[x_1, x_2, \ldots, x_n]$ in $F =$ free_group(ngens(G)) such that G is isomorphic with $F/[x_1, x_2, \ldots, x_n]$.

An exception is thrown if G has been constructed only as a subgroup of a full finitely presented group, see is_full_fp_group.

Examples

julia> f = free_group(2);  (x, y) = gens(f);
-
-julia> q = quo(f, [x^2, y^2, comm(x, y)])[1];  relators(q)
-3-element Vector{FPGroupElem}:
- f1^2
- f2^2
- f1^-1*f2^-1*f1*f2
source
lengthMethod
length(g::FPGroupElem)

Return the length of g as a word in terms of the generators of its group if g is an element of a free group, otherwise a exception is thrown.

Examples

julia> F = free_group(2);  F1 = gen(F, 1);  F2 = gen(F, 2);
-
-julia> length(F1*F2^-2)
-3
-
-julia> length(one(F))
-0
-
-julia> length(one(quo(F, [F1])[1]))
-ERROR: ArgumentError: the element does not lie in a free group
source
map_wordFunction
map_word(g::FPGroupElem, genimgs::Vector; genimgs_inv::Vector = Vector(undef, length(genimgs)), init = nothing)
-map_word(v::Vector{Union{Int, Pair{Int, Int}}}, genimgs::Vector; genimgs_inv::Vector = Vector(undef, length(genimgs)), init = nothing)

Return the product $R_1 R_2 \cdots R_n$ that is described by g or v, respectively.

If g is an element of a free group $G$, say, then the rank of $G$ must be equal to the length of genimgs, g is a product of the form $g_{i_1}^{e_i} g_{i_2}^{e_2} \cdots g_{i_n}^{e_n}$ where $g_i$ is the $i$-th generator of $G$ and the $e_i$ are nonzero integers, and $R_j = $`imgs[`$ij$`]`$^{ej}$.

If g is an element of a finitely presented group then the result is defined as map_word applied to a representing element of the underlying free group.

If the first argument is a vector v of integers $k_i$ or pairs k_i => e_i, respectively, then the absolute values of the $k_i$ must be at most the length of genimgs, and $R_j = $`imgs[`$|ki|$`]`$^{\epsiloni}$ where $\epsilon_i$ is the sign of $k_i$ (times $e_i$).

If a vector genimgs_inv is given then its assigned entries are expected to be the inverses of the corresponding entries in genimgs, and the function will use (and set) these entries in order to avoid calling inv (more than once) for entries of genimgs.

If v has length zero then init is returned if also genimgs has length zero, otherwise one(genimgs[1]) is returned. In all other cases, init is ignored.

Examples

julia> F = free_group(2);  F1 = gen(F, 1);  F2 = gen(F, 2);
-
-julia> imgs = gens(symmetric_group(4))
-2-element Vector{PermGroupElem}:
- (1,2,3,4)
- (1,2)
-
-julia> map_word(F1^2, imgs)
-(1,3)(2,4)
-
-julia> map_word(F2, imgs)
-(1,2)
-
-julia> map_word(one(F), imgs)
-()
-
-julia> invs = Vector(undef, 2);
-
-julia> map_word(F1^-2*F2, imgs, genimgs_inv = invs)
-(1,3,2,4)
-
-julia> invs
-2-element Vector{Any}:
-    (1,4,3,2)
- #undef
-
source
diff --git a/previews/PR2578/Groups/group_characters/index.html b/previews/PR2578/Groups/group_characters/index.html deleted file mode 100644 index 56c5c044ad08..000000000000 --- a/previews/PR2578/Groups/group_characters/index.html +++ /dev/null @@ -1,337 +0,0 @@ - -Group characters · Oscar.jl

Group characters

Let $G$ be a finite group, and let $\rho: G \to GL(n, R)$ be a group homomorphism, for some ring $R$. We call $\chi: G \to R$, defined by $\chi(g) = Trace(\rho(g))$, the character afforded by $\rho$.

Since $\chi$ is constant on conjugacy classes of $G$, it can be represented by an array $l$ of values such that the value on the $i$-th conjugacy class of $G$ (see conjugacy_classes) is stored at $l[i]$. Note that this makes sense only if we assume that the ordering of conjugacy classes of $G$ is fixed once the classes have been computed.

We deal only with the cases that either $R$ can be embedded into some number field, or that $R$ is a finite field.

In the former case, the eigenvalues of the matrix $\rho(g)$, for $g \in G$, are $k$-th roots of unity, where $k$ is the order of $g$, thus all values of $\chi$ can be represented by elements in the abelian closure of the field of rational numbers, see abelian_closure. The characters obtained this way are called ordinary characters.

In the latter case, the list of traces of $\rho(g)$ (the so-called Frobenius character of $\rho$) is often not so interesting; instead, one considers the Brauer character of $\rho$, which is defined on (conjugacy classes of) elements $g$ whose order is coprime to the characteristic of $R$ (the so-called $p$-regular elements resp. classes), by first lifting the eigenvalues of $\rho(g)$ to complex roots of unity and then summing up these roots; this way, one gets again a list of values in the abelian closure of the field of rationals.

The pointwise sum and product of two characters are again characters, they are afforded by the direct sum and the tensor product of the underlying representations. A character that is not the sum of two characters is called absolutely irreducible.

Character tables

Putting the values of the absolutely irreducible ordinary characters of a group $G$ into an array such that the rows correspond to the characters and the columns correspond to the conjugacy classes yields the ordinary character table of $G$, which is in fact a square matrix. Analogously, the absolutely irreducible Brauer characters of $G$, for a given characteristic $p$, yield a square matrix, the $p$-modular Brauer character table.

Ordinary character tables can be computed with character_table from a given group. The computation of $p$-modular Brauer tables is currently restricted to the case of $p$-solvable groups.

Character tables contain a lot of information about their groups, many questions about a finite group can be answered by computations only with its characters. Thus it makes sense to deal also with character tables without an explicit labeling of the columns of the table by conjugacy classes of a group. For example, the character tables shown in Atlas of Finite Groups J. H. Conway, R. T. Curtis, S. P. Norton, R. A. Parker, R. A. Wilson (1985) and from the Atlas of Brauer Characters C. Jansen, K. Lux, R. Parker, R. Wilson (1995) are available in OSCAR. Such character tables can be fetched with character_table from the database, via their names.

In OSCAR, a character table t is identified with the array of absolutely irreducible characters of $G$, in the sense that t[i] yields the i-th irreducible character of $G$, and t[i, j] is the value of this character on the j-th conjugacy class of $G$ (or the j-th conjugacy class of $p$-regular elements in the case of Brauer tables).

Ordinary and $p$-modular Brauer tables in OSCAR are distinguished by their characteristic(tbl::GAPGroupCharacterTable); its value is 0 for ordinary tables and $p$ otherwise.

GAPGroupCharacterTableType
GAPGroupCharacterTable <: GroupCharacterTable

This is the type of (ordinary or Brauer) character tables that can delegate tasks to an underlying character table object in the GAP system (field GAPTable).

The value of the field characteristic determines whether the table is an ordinary one (value 0) or a p-modular one (value p).

A group can (but need not) be stored in the field group. If it is available then also the field isomorphism is available, its value is a bijective map from the group value to a group in GAP.

Objects of type GAPGroupCharacterTable support get_attribute, for example in order to store the already computed p-modular tables in an ordinary table, and to store the corresponding ordinary table in a p-modular table.

source
character_tableFunction
character_table(G::GAPGroup, p::T = 0) where T <: IntegerUnion

Return the ordinary (if p == 0) or p-modular character table of the finite group G. If the p-modular character table of G cannot be computed by GAP then nothing is returned.

Examples

julia> Oscar.with_unicode() do
-         show(stdout, MIME("text/plain"), character_table(symmetric_group(3)))
-       end;
-Sym( [ 1 .. 3 ] )
-
- 2  1  1  .
- 3  1  .  1
-           
-   1a 2a 3a
-2P 1a 1a 3a
-3P 1a 2a 1a
-           
-χ₁  1 -1  1
-χ₂  2  . -1
-χ₃  1  1  1
-
-julia> Oscar.with_unicode() do
-         show(stdout, MIME("text/plain"), character_table(symmetric_group(3), 2))
-       end;
-Sym( [ 1 .. 3 ] ) mod 2
-
- 2  1  .
- 3  1  1
-        
-   1a 3a
-2P 1a 3a
-3P 1a 1a
-        
-χ₁  1  1
-χ₂  2 -1
source
character_table(id::String, p::Int = 0)

Return the ordinary (if p == 0) or p-modular character table for which id is an admissible name in GAP's library of character tables. If no such table is available then nothing is returned.

Examples

julia> println(character_table("A5"))
-character table of A5
-
-julia> println(character_table("A5", 2))
-2-modular Brauer table of A5
-
-julia> println(character_table("J5"))
-nothing
source
character_table(series::Symbol, parameter::Any)

Return the ordinary character table of the group described by the series series and the parameter parameter.

Examples

julia> println(character_table(:Symmetric, 5))
-character table of Sym(5)
-
-julia> println(character_table(:WeylB, 3))
-character table of W(B3)

Currently the following series are supported.

SeriesParameter
:Cyclicpos. integer
:Dihedraleven pos. integer
:Symmetricpos. integer
:Alternatinginteger > 1
:WeylBpos. integer
:WeylDinteger > 1
:DoubleCoverSymmetricpos. integer
:DoubleCoverAlternatingpos. integer
:GL2prime power
:SL2oddodd prime power
:SL2eveneven prime power
:PSL2oddodd prime power q s. t. (q-1)/2 is odd
:PSL2evenodd prime power q s. t. (q-1)/2 is even
:Suzukiodd power of 2
:GU3prime power
:SU3prime power
Symbol("P:Q")array [p, q] with prime p and q dividing p-1
:ExtraspecialPlusOddodd power of odd prime
source
showMethod
Base.show(io::IO, ::MIME"text/plain", tbl::GAPGroupCharacterTable)

Display the irreducible characters of tbl and context information as a two-dimensional array.

  • First a header is shown. If tbl stores a group then the header describes this group, otherwise it is equal to the identifier(tbl::GAPGroupCharacterTable) value of tbl.

  • Then the irreducible characters of tbl are shown in column portions that fit on the screen, together with column labels above each portion and row labels on the left of each portion.

    The column labels consist of the factored centralizer orders (see orders_centralizers, one row for each prime divisor of the group order), followed by one row showing the class names (see class_names), followed by the power maps (one row for each stored power map).

    The row labels are X_1, X_2, ... (or χ with subscripts 1, 2, ... if unicode output is allowed). If io is an IOContext with key :indicator set to true then a second column of row labels shows the 2nd Frobenius-Schur indicator of the irreducibles (see indicator); analogously, setting the key :character_field to true yields a column showing the degrees of the character fields (see character_field), and setting the key :OD to true yields a column showing the known orthogonal discriminants of those irreducibles that have indicator + and even degree.

  • Depending on the way how irrational character values are shown, a footer may be shown in the end. By default, irrationalities are shown as sums of roots of unity, where z_n (or ζ with subscript n if unicode output is allowed) denotes the primitive n-th root $\exp(2 \pi i/n)$. If io is an IOContext with key :with_legend set to true then irrationalities are abbreviated as A, B, ..., and these names together with the corresponding expression as sums of roots of unity appear in the footer.

Output in $\LaTeX$ syntax can be created by calling show with second argument MIME("text/latex").

Examples

julia> tbl = character_table(:Cyclic, 3);
-
-julia> Oscar.with_unicode() do
-         show(stdout, MIME("text/plain"), tbl)
-       end;
-C3
-
- 3  1       1       1
-                     
-   1a      3a      3b
-3P 1a      1a      1a
-                     
-χ₁  1       1       1
-χ₂  1      ζ₃ -ζ₃ - 1
-χ₃  1 -ζ₃ - 1      ζ₃
-
-julia> Oscar.with_unicode() do
-         show(IOContext(stdout, :with_legend => true), MIME("text/plain"), tbl)
-       end;
-C3
-
- 3  1  1  1
-           
-   1a 3a 3b
-3P 1a 1a 1a
-           
-χ₁  1  1  1
-χ₂  1  A  A̅
-χ₃  1  A̅  A
-
-A = ζ₃
-A̅ = -ζ₃ - 1
-
-julia> Oscar.with_unicode() do
-         show(IOContext(stdout, :indicator => true), MIME("text/plain"), tbl)
-       end;
-C3
-
-    3  1       1       1
-                        
-      1a      3a      3b
-   3P 1a      1a      1a
-    2                   
-χ₁  +  1       1       1
-χ₂  o  1      ζ₃ -ζ₃ - 1
-χ₃  o  1 -ζ₃ - 1      ζ₃
-
-julia> Oscar.with_unicode() do
-         show(IOContext(stdout, :character_field => true), MIME("text/plain"), tbl)
-       end;
-C3
-
-    3  1       1       1
-                        
-      1a      3a      3b
-   2P 1a      3b      3a
-   3P 1a      1a      1a
-    d                   
-χ₁  1  1       1       1
-χ₂  2  1      ζ₃ -ζ₃ - 1
-χ₃  2  1 -ζ₃ - 1      ζ₃
-
-julia> Oscar.with_unicode() do
-         show(IOContext(stdout, :with_legend => true), MIME("text/latex"), tbl)
-       end;
-$C3
-
-\begin{array}{rrrr}
-3 & 1 & 1 & 1 \\
- &  &  &  \\
- & 1a & 3a & 3b \\
-2P & 1a & 3b & 3a \\
-3P & 1a & 1a & 1a \\
- &  &  &  \\
-\chi_{1} & 1 & 1 & 1 \\
-\chi_{2} & 1 & A & \overline{A} \\
-\chi_{3} & 1 & \overline{A} & A \\
-\end{array}
-
-\begin{array}{l}
-A = \zeta_{3} \\
-\overline{A} = -\zeta_{3} - 1 \\
-\end{array}
-$
source
characteristicMethod
characteristic(::Type{T} = Int, tbl::GAPGroupCharacterTable) where T <: IntegerUnion

Return T(0) if tbl is an ordinary character table, and T(p) if tbl is a p-modular character table.

Examples

julia> tbl = character_table("A5");
-
-julia> characteristic(tbl)
-0
-
-julia> characteristic(tbl % 2)
-2
source
modMethod
mod(tbl::GAPGroupCharacterTable, p::T) where T <: IntegerUnion
-rem(tbl::GAPGroupCharacterTable, p::T) where T <: IntegerUnion

Return the p-modular character table of tbl, or nothing if this table cannot be computed.

The syntax tbl % p is also supported.

An exception is thrown if tbl is not an ordinary character table.

Examples

julia> show(character_table("A5") % 2)
-2-modular Brauer table of A5
source
all_character_table_namesFunction
all_character_table_names(L...; ordered_by = nothing)

Return an array of strings that contains all those names of character tables in the character table library that satisfy the conditions in the array L.

Examples

julia> spor_names = all_character_table_names(is_sporadic_simple => true,
-         is_duplicate_table => false);
-
-julia> println(spor_names[1:5])
-["B", "Co1", "Co2", "Co3", "F3+"]
-
-julia> spor_names = all_character_table_names(is_sporadic_simple,
-         !is_duplicate_table; ordered_by = order);
-
-julia> println(spor_names[1:5])
-["M11", "M12", "J1", "M22", "J2"]
-
-julia> length(all_character_table_names(number_conjugacy_classes => 1))
-1
source

Attributes of group characters

character_fieldFunction
character_field(chi::GAPGroupClassFunction)

If chi is an ordinary character then return the pair (F, phi) where F is a number field that is generated by the character values of chi, and phi is the embedding of F into abelian_closure(QQ).

If chi is a Brauer character in characteristic p then return the pair (F, phi) where F is the finite field that is generated by the p-modular reductions of the values of chi, and phi is the identity map on F.

Examples

julia> t = character_table("A5");
-
-julia> character_field(t[2])[1]
-Number field with defining polynomial x^2 + x - 1
-  over rational field
-
-julia> flds_2 = map(character_field, mod(t, 2));
-
-julia> println([degree(x[1]) for x in flds_2])
-[1, 2, 2, 1]
source
conjMethod
conj(chi::GAPGroupClassFunction)

Return the class function whose values are the complex conjugates of the values of chi.

Examples

julia> tbl = character_table(alternating_group(4));
-
-julia> println([findfirst(y -> y == conj(x), tbl) for x in tbl])
-[1, 3, 2, 4]
source
degreeMethod
degree(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)
-       where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}

Return chi[1], as an instance of T.

source
indicatorFunction
indicator(chi::GAPGroupClassFunction, n::Int = 2)

Return the n-th Frobenius-Schur indicator of chi, that is, the value $(∑_{g ∈ G} chi(g^n))/|G|$, where $G$ is the group of chi.

If chi is irreducible then indicator(chi) is 0 if chi is not real-valued, 1 if chi is afforded by a real representation of $G$, and -1 if chi is real-valued but not afforded by a real representation of $G$.

Examples

julia> tbl = character_table("U3(3)");
-
-julia> println([indicator(chi) for chi in tbl])
-[1, -1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0]
source
is_faithfulMethod
is_faithful(chi::GAPGroupClassFunction)

Return true if the value of chi at the identity element does not occur as value of chi at any other element, and false otherwise.

If chi is an ordinary character then true is returned if and only if the representations affording chi have trivial kernel.

Examples

julia> println(map(is_faithful, character_table(symmetric_group(3))))
-Bool[0, 1, 0]
source
is_rationalMethod
is_rational(chi::GAPGroupClassFunction)

Return true if all values of chi are rational, i.e., in QQ, and false otherwise.

Examples

julia> all(is_rational, character_table(symmetric_group(4)))
-true
-
-julia> all(is_rational, character_table(alternating_group(4)))
-false
source
is_irreducibleMethod
is_irreducible(chi::GAPGroupClassFunction)

Return true if chi is an irreducible character, and false otherwise.

A character is irreducible if it cannot be written as the sum of two characters. For ordinary characters this can be checked using the scalar product of class functions (see scalar_product. For Brauer characters there is no generic method for checking irreducibility.

Examples

julia> g = symmetric_group(4);
-
-julia> all(is_irreducible, character_table(g))
-true
-
-julia> is_irreducible(natural_character(g))
-false
source
schur_indexFunction
schur_index(chi::GAPGroupClassFunction) -> Int

For an ordinary irreducible character chi, return the minimal integer m such that the character m * chi is afforded by a representation over the character field of chi, or throw an exception if the currently used character theoretic criteria do not suffice for computing m.

Examples

julia> t = character_table(quaternion_group(8));
-
-julia> println(map(schur_index, t))
-[1, 1, 1, 1, 2]
source
detMethod
det(chi::GAPGroupClassFunction)

Return the determinant character of the character chi. This is defined to be the character obtained by taking the determinant of representing matrices of any representation affording chi.

Examples

julia> t = character_table(symmetric_group(4));
-
-julia> all(chi -> det(chi) == exterior_power(chi, Int(degree(chi))), t)
-true
source
orderMethod
order(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction)
-      where T <: IntegerUnion

Return the determinantal order of the character chi. This is defined to be the multiplicative order of det(chi).

Examples

julia> println([order(chi) for chi in character_table(symmetric_group(4))])
-ZZRingElem[2, 1, 2, 2, 1]
source
order_field_of_definitionMethod
order_field_of_definition(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction) where T <: IntegerUnion

Return $p^n$, as an instance of T, if chi is a $p$-modular Brauer character such that the $p$-modular reductions of the values of chi span the field with $p^n$ elements.

Note that one need not compute the character_field value of chi in order to compute order_field_of_definition(chi).

Examples

julia> tbl = character_table("A5", 2);
-
-julia> println([order_field_of_definition(chi) for chi in tbl])
-ZZRingElem[2, 4, 4, 2]
source

Attributes of character tables

character_parametersFunction
character_parameters(tbl::GAPGroupCharacterTable)

Return a vector of character parameters for the rows of tbl if such parameters are stored, and nothing otherwise.

Examples

julia> character_parameters(character_table("S5"))
-7-element Vector{Vector{Int64}}:
- [5]
- [1, 1, 1, 1, 1]
- [3, 1, 1]
- [4, 1]
- [2, 1, 1, 1]
- [3, 2]
- [2, 2, 1]
-
-julia> character_parameters(character_table("M11"))
source
class_namesMethod
class_names(tbl::GAPGroupCharacterTable)

Return a vector of strings corresponding to the columns of tbl. The $i$-th entry consists of the element order for the $i$-th column, followed by at least one distinguishing letter. For example, the classes of elements of order two have class names `"2a", "2b", and so on.

Examples

julia> println(class_names(character_table("S5")))
-["1a", "2a", "3a", "5a", "2b", "4a", "6a"]
source
class_parametersFunction
class_parameters(tbl::GAPGroupCharacterTable)

Return a vector of class parameters for the columns of tbl if such parameters are stored, and nothing otherwise.

Examples

julia> class_parameters(character_table("S5"))
-7-element Vector{Vector{Int64}}:
- [1, 1, 1, 1, 1]
- [2, 2, 1]
- [3, 1, 1]
- [5]
- [2, 1, 1, 1]
- [4, 1]
- [3, 2]
-
-julia> class_parameters(character_table("M11"))
source
conjugacy_classesMethod
conjugacy_classes(tbl::GAPGroupCharacterTable)

Return the vector of conjugacy classes of group(tbl), ordered such that they correspond to the columns of tbl and to the GAPWrap.ConjugacyClasses value of the underlying GAP character table. Note that the vector conjugacy_classes(group(tbl)) can be independent of the vector of conjugacy classes stored in the group of the underlying GAP character table.

An error is thrown if tbl does not store a group.

Examples

julia> g = symmetric_group(4);  tbl = character_table(g);
-
-julia> [length(c) for c in conjugacy_classes(tbl)] == class_lengths(tbl)
-true
source
decomposition_matrixFunction
decomposition_matrix(modtbl::GAPGroupCharacterTable)

Return the decomposition matrix (of type ZZMatrix) of the Brauer character table modtbl. The rows and columns are indexed by the irreducible characters of the ordinary character table of modtbl and the irreducible characters of modtbl, respectively,

Examples

julia> t = character_table("A5"); t2 = mod(t, 2);
-
-julia> decomposition_matrix(t2)
-[1   0   0   0]
-[1   0   1   0]
-[1   1   0   0]
-[0   0   0   1]
-[1   1   1   0]
source
identifierFunction
identifier(tbl::GAPGroupCharacterTable)

Return a string that identifies tbl. It is used mainly for library tables.

Examples

julia> identifier(character_table("A5"))
-"A5"
source
induced_cyclicMethod
induced_cyclic(tbl::GAPGroupCharacterTable)

Return the array of permutation characters of tbl that are induced from cyclic subgroups.

source
is_duplicate_tableFunction
is_duplicate_table(tbl::GAPGroupCharacterTable)

Return whether tbl is an ordinary table from the character table library that was constructed from another library character table by permuting rows and columns.

One application of this function is to restrict the search with all_character_table_names to only one library character table for each class of permutation equivalent tables.

Examples

julia> is_duplicate_table(character_table("A5"))
-false
-
-julia> is_duplicate_table(character_table("A6M2"))
-true
source
maxesFunction
maxes(tbl::GAPGroupCharacterTable)

Return either nothing (if the value is not known) or an array of identifiers of the ordinary character tables of all maximal subgroups of tbl. There is no default method to compute this value from tbl.

If the maxes value of tbl is stored then it lists exactly one representative for each conjugacy class of maximal subgroups of the group of tbl, and the character tables of these maximal subgroups are available in the character table library, and compatible class fusions to tbl are stored on these tables.

Examples

julia> println(maxes(character_table("M11")))
-["A6.2_3", "L2(11)", "3^2:Q8.2", "A5.2", "2.S4"]
-
-julia> maxes(character_table("M")) === nothing  # not (yet) known
-true
source
names_of_fusion_sourcesFunction
names_of_fusion_sources(tbl::GAPGroupCharacterTable)

Return the array of strings that are identifiers of those character tables which store a class fusion to tbl, which must be an ordinary character table.

Examples

julia> tbl = character_table("A5");
-
-julia> println(maxes(tbl))
-["a4", "D10", "S3"]
-
-julia> all(x -> x in names_of_fusion_sources(tbl), maxes(tbl))
-true
source
class_lengthsFunction
class_lengths(tbl::GAPGroupCharacterTable)

Examples

julia> println(class_lengths(character_table("A5")))
-ZZRingElem[1, 15, 20, 12, 12]
source
orders_centralizersFunction
orders_centralizers(tbl::GAPGroupCharacterTable)

Return the array of the orders of centralizers of conjugacy class representatives for tbl in the group of tbl, ordered according to the columns of tbl.

Examples

julia> println(orders_centralizers(character_table("A5")))
-ZZRingElem[60, 4, 3, 5, 5]
source
orders_class_representativesFunction
orders_class_representatives(tbl::GAPGroupCharacterTable)

Return the array of the orders of conjugacy class representatives for tbl, ordered according to the columns of tbl.

Examples

julia> println(orders_class_representatives(character_table("A5")))
-[1, 2, 3, 5, 5]
source
ordinary_tableMethod
ordinary_table(tbl::GAPGroupCharacterTable)

Return the ordinary character table of tbl, provided that tbl is a Brauer character table.

Examples

julia> tbl = character_table("A5");
-
-julia> ordinary_table(tbl % 2) === tbl
-true
source
trivial_characterMethod
trivial_character(tbl::GAPGroupCharacterTable)

Return the character of tbl that has the value QQAbElem(1) in each position.

Examples

julia> t = character_table(symmetric_group(4));
-
-julia> all(x -> x == 1, trivial_character(t))
-true
source

Construct group characters from groups

natural_characterMethod
natural_character(G::PermGroup)

Return the permutation character of degree degree(G) that maps each element of G to the number of its fixed points.

Examples

julia> g = symmetric_group(4);
-
-julia> degree(natural_character(g))
-4
-
-julia> degree(natural_character(stabilizer(g, 4)[1]))
-4
source
natural_characterMethod
natural_character(G::Union{MatrixGroup{QQFieldElem}, MatrixGroup{nf_elem}})

Return the character that maps each element of G to its trace. We assume that the entries of the elements of G are either of type QQFieldElem or contained in a cyclotomic field.

Examples

julia> g = matrix_group(matrix(ZZ, [0 1; 1 0]));
-
-julia> println(values(natural_character(g)))
-QQAbElem{nf_elem}[2, 0]
source
natural_character(G::MatrixGroup{FinFieldElem})

Return the character that maps each $p$-regular element of G, where $p$ is the characteristic of the base field of G, to its Brauer character value.

Examples

julia> g = general_linear_group(2, 2);
-
-julia> println(values(natural_character(g)))
-QQAbElem{nf_elem}[2, -1]
source
natural_characterMethod
natural_character(G::MatrixGroup{FinFieldElem})

Return the character that maps each $p$-regular element of G, where $p$ is the characteristic of the base field of G, to its Brauer character value.

Examples

julia> g = general_linear_group(2, 2);
-
-julia> println(values(natural_character(g)))
-QQAbElem{nf_elem}[2, -1]
source
natural_characterMethod
natural_character(rho::GAPGroupHomomorphism)

Return the character of domain(rho) that is afforded by the representation rho, where codomain(rho) must be a permutation group or a matrix group. In the latter case, an ordinary character is returned if the characteristic of the base field is zero, and a $p$-modular Brauer character is returned if the characteristic is $p > 0$.

Examples

julia> g = symmetric_group(3);  h = general_linear_group(2, 2);
-
-julia> mp = hom(g, h, [g([2,1]), g([1, 3, 2])], gens(h));
-
-julia> println(values(natural_character(mp)))
-QQAbElem{nf_elem}[2, -1]
source
trivial_characterMethod
trivial_character(G::GAPGroup)

Return the character of (the ordinary character table of) G that has the value QQAbElem(1) in each position.

Examples

julia> g = symmetric_group(4);
-
-julia> all(x -> x == 1, trivial_character(g))
-true
source

Operations for group characters

length and iteration:

The length of a class function is the number of conjugacy classes of its group, iteration is defined w.r.t. the ordering of conjugacy classes.

arithmetic operations:

  • chi == psi: two class functions are equal if and only if they belong to the same character table and have the same values,
  • chi + psi and chi - psi are the pointwise sum and difference, respectively, of the two class functions chi, psi,
  • n*chi is the pointwise n-fold sum of chi, for an integer n,
  • chi*psi is the pointwise (tensor) product of chi and psi,
  • zero(chi) is the class function that is zero on all classes,
  • one(chi) is the trivial character of the character table of chi,
  • chi^n is the n-th tensor power of chi, for positive integers n,
  • chi(g) is the value of chi at the element g of the group of chi,
  • chi^g is the conjugate character of chi under the action of a group element g that normalizes the group $G$ of chi; we have chi^g(x) == chi(g*x*g^-1) for all x in $G$,
  • chi^galaut is the Galois conjugate character of chi under the pointwise action of the field automorphism galaut (If galaut was created as QQAbAutomorphism(k) then the action raises each root of unity to its k-th power; this action defines a field automorphism of the n-th cyclotomic field whenever n and k are coprime.)
  • chi^tbl is the character of the character table tbl that is induced from chi, where the group of chi is a subgroup of the group of tbl.
scalar_productFunction
scalar_product(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)
-               where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}

Return $\sum_{g \in G}$ chi($g$) conj(psi)($g$) / $|G|$, where $G$ is the group of both chi and psi. The result is an instance of T.

Note that we do not support dot(chi, psi) and its infix notation because the documentation of dot states that the result is equal to the sum of dot results of corresponding entries, which does not hold for the scalar product of characters.

source
coordinatesMethod
coordinates(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)
-               where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}

Return the vector $[a_1, a_2, \ldots, a_n]$ of scalar products (see scalar_product) of chi with the irreducible characters $[t[1], t[2], \ldots, t[n]]$ of the character table $t$ of chi, that is, chi is equal to $\sum_{i==1}^n a_i t[i]$. The result is an instance of Vector{T}.

Examples

julia> g = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> chi = natural_character(g);
-
-julia> coordinates(Int, chi)
-5-element Vector{Int64}:
- 0
- 0
- 0
- 1
- 1
-
-julia> t = chi.table;  t3 = mod(t, 3);  chi3 = restrict(chi, t3);
-
-julia> coordinates(Int, chi3)
-4-element Vector{Int64}:
- 0
- 1
- 0
- 1
source
multiplicities_eigenvaluesFunction
multiplicities_eigenvalues(::Type{T} = Int, chi::GAPGroupClassFunction, i::Int) where T <: IntegerUnion

Let $M$ be a representing matrix of an element in the i-th conjugacy class of the character table of chi, in a representation affording the character chi, and let $n$ be the order of the elements in this conjugacy class.

Return the vector $(m_1, m_2, \ldots, m_n)$ of integers of type T such that $m_j$ is the multiplicity of $\zeta_n^j$ as an eigenvalue of $M$.

Examples

julia> t = character_table("A5");  chi = t[4];
-
-julia> println(values(chi))
-QQAbElem{nf_elem}[4, 0, 1, -1, -1]
-
-julia> println(multiplicities_eigenvalues(chi, 5))
-[1, 1, 1, 1, 0]
source
induceMethod
induce(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable[, fusion::Vector{Int}])

Return the class function of tbl that is induced from chi, which is a class function of a subgroup of the group of tbl. The default for the class fusion fus is given either by the fusion of the conjugacy classes of the two character tables (if groups are stored in the tables) or by the class fusion given by known_class_fusion for the two tables.

Examples

julia> s = character_table("A5");  t = character_table("A6");
-
-julia> maps = possible_class_fusions(s, t);  length(maps)
-4
-
-julia> chi = trivial_character(s);
-
-julia> ind = [induce(chi, t, x) for x in maps];
-
-julia> length(Set(ind))
-2
source
restrictMethod
restrict(chi::GAPGroupClassFunction, subtbl::GAPGroupCharacterTable[, fusion::Vector{Int}])

Return the class function of subtbl that is the restriction of chi, which is a class function of a supergroup of the group of subtbl. The default for the class fusion fus is given either by the fusion of the conjugacy classes of the two character tables (if groups are stored in the tables) or by the class fusion given by known_class_fusion for the two tables.

Examples

julia> s = character_table("A5");  t = character_table("A6");
-
-julia> maps = possible_class_fusions(s, t);  length(maps)
-4
-
-julia> chi = t[2];  rest = [restrict(chi, s, x) for x in maps];
-
-julia> length(Set(rest))
-2
source

Symmetrizations of group characters

symmetrizationsMethod
symmetrizations(characters::Vector{GAPGroupClassFunction}, n::Int)

Return the vector of symmetrizations of characters with the ordinary irreducible characters of the symmetric group of degree n.

The symmetrization $\chi^{[\lambda]}$ of the character $\chi$ with the character $\lambda$ of the symmetric group $S_n$ of degree n is defined by

\[\chi^{[\lambda]}(g) = -(\sum_{\rho\in S_n} \lambda(\rho) \prod_{k=1}^n \chi(g^k)^{a_k(\rho)} ) / n!,\]

where $a_k(\rho)$ is the number of cycles of length $k$ in $\rho$.

Note that the returned list may contain zero class functions, and duplicates are not deleted.

For special kinds of symmetrizations, see symmetric_parts, anti_symmetric_parts, orthogonal_components, symplectic_components, exterior_power, symmetric_power.

source
symmetric_partsMethod
symmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)

Return the vector of symmetrizations of characters with the trivial character of the symmetric group of degree n, see symmetrizations.

source
anti_symmetric_partsMethod
anti_symmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)

Return the vector of symmetrizations of characters with the sign character of the symmetric group of degree n, see symmetrizations.

source
exterior_powerMethod
exterior_power(chi::GAPGroupClassFunction, n::Int)

Return the class function of the n-th exterior power of the module that is afforded by chi.

This exterior power is the symmetrization of chi with the sign character of the symmetric group of degree n, see also symmetrizations and anti_symmetric_parts.

source
symmetric_powerMethod
symmetric_power(chi::GAPGroupClassFunction, n::Int)

Return the class function of the n-th symmetric power of the module that is afforded by chi.

This symmetric power is the symmetrization of chi with the trivial character of the symmetric group of degree n, see also symmetrizations and symmetric_parts.

source
orthogonal_componentsMethod
orthogonal_components(characters::Vector{GAPGroupClassFunction}, n::Int)

Return the vector of the so-called Murnaghan components of the $m$-th tensor powers of the entries of characters, for $m$ up to n, where n must be at least 2 and at most 6 and where we assume that the entries of characters are irreducible characters with Frobenius-Schur indicator +1, see indicator.

source
symplectic_componentsMethod
symplectic_components(characters::Vector{GAPGroupClassFunction}, n::Int)

Return the vector of the Murnaghan components of the $m$-th tensor powers of the entries of characters, for $m$ up to n, where n must be at least 2 and at most 6 and where we assume that the entries of characters are irreducible characters with Frobenius-Schur indicator -1, see indicator.

source

Operations for character tables

class_multiplication_coefficientFunction
class_multiplication_coefficient(::Type{T} = ZZRingElem, tbl::GAPGroupCharacterTable, i::Int, j::Int, k::Int) where T <: IntegerUnion

Return the class multiplication coefficient of the classes i, j, and k of the group $G$ with ordinary character table tbl, as an instance of T.

The class multiplication coefficient $c_{i,j,k}$ of the classes $i, j, k$ equals the number of pairs $(x, y)$ of elements $x, y \in G$ such that $x$ lies in class $i$, $y$ lies in class $j$, and their product $xy$ is a fixed element of class $k$.

In the center of the group algebra of $G$, these numbers are found as coefficients of the decomposition of the product of two class sums $K_i$ and $K_j$ into class sums:

\[K_i K_j = \sum_k c_{ijk} K_k.\]

Given the character table of a finite group $G$, whose classes are $C_1, \ldots, C_r$ with representatives $g_i \in C_i$, the class multiplication coefficient $c_{ijk}$ can be computed with the following formula:

\[ c_{ijk} = |C_i| |C_j| / |G| - \sum_{\chi \in Irr(G)} \chi(g_i) \chi(g_j) \chi(g_k^{-1}) - / \chi(1).\]

On the other hand the knowledge of the class multiplication coefficients admits the computation of the irreducible characters of $G$.

Examples

julia> class_multiplication_coefficient(character_table("A5"), 2, 3, 4)
-5
-
-julia> class_multiplication_coefficient(character_table("A5"), 2, 4, 4)
-0
source
known_class_fusionFunction
known_class_fusion(tbl1::GAPGroupCharacterTable, tbl2::GAPGroupCharacterTable)

Return (flag, fus) where flag == true if a class fusion to tbl2 is stored on tbl1, and flag == false otherwise.

In the former case, fus is the vector of integers, of length ncols(tbl1), such that the $i$-th conjugacy class of tbl1 corresponds to the fus[$i$]-th conjugacy class of tbl2, in the following sense.

If the group of tbl1 is a subgroup of the group of tbl2 then the $i$-th conjugacy class of tbl1 is contained in the fus[$i$]-th conjugacy class of tbl2. If the group of tbl2 is a factor group of the group of tbl1 then the image of the $i$-th conjugacy class tbl1 under the relevant epimorphism is the fus[$i$]-th conjugacy class of tbl2.

source
orderMethod
order(::Type{T} = ZZRingElem, tbl::GAPGroupCharacterTable) where T <: IntegerUnion

Return the order of the group for which tbl is the character table, as an instance of T.

Examples

julia> order(character_table(symmetric_group(4)))
-24
source
possible_class_fusionsFunction
possible_class_fusions(subtbl::GAPGroupCharacterTable, tbl::GAPGroupCharacterTable)

Return the array of possible class fusions from subtbl to tbl. Each entry is an array of positive integers, where the value at position i is the position of the conjugacy class in tbl that contains the i-th class of subtbl.

Examples

julia> possible_class_fusions(character_table("A5"), character_table("A6"))
-4-element Vector{Vector{Int64}}:
- [1, 2, 3, 6, 7]
- [1, 2, 3, 7, 6]
- [1, 2, 4, 6, 7]
- [1, 2, 4, 7, 6]
source

Character tables and normal subgroups

Normal subgroups of a group $G$ are unions of conjugacy classes of elements of $G$. Thus one can often turn questions about a normal subgroup $N$ of $G$ into questions about the array of those positions in the list of conjugacy classes of $G$ that contain the elements of $N$.

centerMethod
center(chi::GAPGroupClassFunction)

Return C, f where C is the center of chi (i.e. the largest normal subgroup of the underlying group G of chi such that chi maps each element of C to chi[1] times a root of unity) and f is the embedding morphism of C into G.

Examples

julia> t = character_table(symmetric_group(4));
-
-julia> chi = t[3];  chi[1]
-2
-
-julia> C, f = center(chi);  order(C)
-4
source
class_positions_of_centerFunction
class_positions_of_center(chi::GAPGroupClassFunction)

Return the array of those integers i such that chi[i] is chi[1] times a root of unity.

Examples

julia> println(class_positions_of_center(character_table("2.A5")[2]))
-[1, 2]
source
kernelMethod
kernel(chi::GAPGroupClassFunction)

Return C, f where C is the kernel of chi (i.e. the largest normal subgroup of the underlying group G of chi such that chi maps each element of C to chi[1]) and f is the embedding morphism of C into G.

Examples

julia> t = character_table(symmetric_group(4));
-
-julia> chi = t[3];  chi[1]
-2
-
-julia> C, f = kernel(chi);  order(C)
-4
source
class_positions_of_kernelFunction
class_positions_of_kernel(chi::GAPGroupClassFunction)

Return the array of those integers i such that chi[i] == chi[1] holds.

Examples

julia> println(class_positions_of_kernel(character_table("2.A5")[2]))
-[1, 2]
source
class_positions_of_pcoreFunction
class_positions_of_pcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)

Return the array of integers $i$ such that the $i$-th conjugacy class of tbl is contained in the p-core of the group of tbl, see pcore(G::GAPGroup, p::IntegerUnion).

Examples

julia> println(class_positions_of_pcore(character_table("2.A5"), 2))
-[1, 2]
source
diff --git a/previews/PR2578/Groups/grouphom/index.html b/previews/PR2578/Groups/grouphom/index.html deleted file mode 100644 index 9750ff0de4f2..000000000000 --- a/previews/PR2578/Groups/grouphom/index.html +++ /dev/null @@ -1,88 +0,0 @@ - -Group homomorphisms · Oscar.jl

Group homomorphisms

In OSCAR, a group homomorphism from G to H is an object of parametric type GAPGroupHomomorphism{S,T}, where S and T are the types of G and H respectively.

A homomorphism from G to H can be defined in two ways.

  • Writing explicitly the images of the generators of G:
f = hom(G,H,[x1,x2,...],[y1,y2,...])

Here, [x1,x2,...] must be a generating set for G (not necessarily minimal) and [y1,y2,...] is a vector of elements of H of the same length of [x1,x2,...]. This assigns to f the value of the group homomorphism sending x_i into y_i.

An exception is thrown if such a homomorphism does not exist.

  • Taking an existing function g satisfying the group homomorphism properties:
f = hom(G,H,g)

An exception is thrown if the function g does not define a group homomorphism.

Example: The following procedures define the same homomorphism (conjugation by x) in the two ways explained above.

julia> S=symmetric_group(4);
-
-julia> x=S[1];
-
-julia> f=hom(S,S,gens(S),[S[1]^x,S[2]^x]);
-
-julia> g=hom(S,S,y->y^x);
-
-julia> f==g
-true
homMethod
hom(G::GAPGroup, H::GAPGroup, f::Function)

Return the group homomorphism defined by the function f.

source
homMethod
hom(G::GAPGroup, H::GAPGroup, gensG::Vector = gens(G), imgs::Vector; check::Bool = true)

Return the group homomorphism defined by gensG[i] -> imgs[i] for every i. In order to work, the elements of gensG must generate G.

If check is set to false then it is not checked whether the mapping defines a group homomorphism.

source
imageMethod
image(f::GAPGroupHomomorphism, x::GAPGroupElem)
-(f::GAPGroupHomomorphism)(x::GAPGroupElem)

Return f(x).

source
restrict_homomorphismMethod
restrict_homomorphism(f::GAPGroupHomomorphism, H::Group)
-restrict_homomorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::T) where T <: Group

Return the restriction of f to H. An exception is thrown if H is not a subgroup of domain(f).

source

OSCAR has also the following standard homomorphism.

id_homFunction
id_hom(G::GAPGroup)

Return the identity homomorphism on the group G.

source
id_hom(T::TorQuadModule) -> TorQuadModuleMor

Alias for identity_map.

trivial_morphismFunction
trivial_morphism(G::GAPGroup, H::GAPGroup = G)

Return the homomorphism from G to H sending every element of G into the identity of H.

source
trivial_morphism(T::TorQuadModule, U::TorQuadModule) -> TorQuadModuleMor

Return the abelian group homomorphism between T and U sending every elements of T to the zero element of U.

trivial_morphism(T::TorQuadModule) -> TorQuadModuleMor

Return the abelian group endomorphism of T sending every elements of T to the zero element of T.

To evaluate the homomorphism f in the element x of G, it is possible to use the instruction

image(f,x)

or the more compact notations f(x) and x^f.

Example:

julia> S=symmetric_group(4);
-
-julia> f=hom(S,S,x->x^S[1]);
-
-julia> x=cperm(S,[1,2]);
-
-julia> image(f,x)
-(2,3)
-
-julia> f(x)
-(2,3)
-
-julia> x^f
-(2,3)

A sort of "inverse" of the evaluation is the following

haspreimageMethod
haspreimage(f::GAPGroupHomomorphism, x::GAPGroupElem; check::Bool = true)

Return (true, y) if there exists y in domain(f) such that f(y) = x holds; otherwise, return (false, o) where o is the identity of domain(f).

If check is set to false then the test whether x is an element of image(f) is omitted.

source

Example:

julia> S=symmetric_group(4);
-
-julia> f=hom(S,S,x->x^S[1]);
-
-julia> x=cperm(S,[1,2]);
-
-julia> haspreimage(f,x)
-(true, (1,4))
Warning

Do not confuse haspreimage with the function has_preimage, which works on variable of type GrpGenToGrpGenMor.

Operations on homomorphisms

OSCAR supports the following operations on homomorphisms.

  • inv(f) = the inverse of f. An exception is thrown if f is not bijective.

  • f^n = the homomorphism f composed n times with itself. An exception is thrown if the domain and the codomain of f do not coincide (unless n=1). If n is negative, the result is the inverse of f composed n times with itself.

  • compose(f, g) = composition of f and g. This works only if the codomain of f coincides with the domain of g. Shorter equivalent expressions are f*g and g(f).

    Example:

julia> S=symmetric_group(4);
-
-julia> f=hom(S,S,x->x^S[1]);
-
-julia> g=hom(S,S,x->x^S[2]);
-
-julia> f*g==hom(S,S,x->x^(S[1]*S[2]))
-true
-
-julia> f==f^-3
-true
Note

The composition operation * has to be read from the right to the left. So, (f*g)(x) is equivalent to g(f(x)).

Properties of homomorphisms

OSCAR implements the following attributes of homomorphisms, in addition to the usual domain and codomain.

is_injectiveMethod
is_injective(f::GAPGroupHomomorphism)

Return whether f is injective.

source
is_surjectiveMethod
is_surjective(f::GAPGroupHomomorphism)

Return whether f is surjective.

source
is_bijectiveMethod
is_bijective(f::GAPGroupHomomorphism)

Return whether f is bijective.

source
is_invertibleMethod
is_invertible(f::GAPGroupHomomorphism)

Return whether f is invertible.

source
is_invariantMethod
is_invariant(f::GAPGroupHomomorphism, H::Group)
-is_invariant(f::GAPGroupElem{AutomorphismGroup{T}}, H::T)

Return whether f(H) == H holds. An exception is thrown if domain(f) and codomain(f) are not equal or if H is not contained in domain(f).

source

Subgroups described by homomorphisms

The following functions compute subgroups or quotients of either the domain or the codomain. Analogously to the functions described in Sections Subgroups and Quotients, the output consists of a pair (H, g), where H is a subgroup (resp. quotient) and g is its embedding (resp. projection) homomorphism.

kernelMethod
kernel(f::GAPGroupHomomorphism)

Return the kernel of f, together with its embedding into domain(f).

source
imageMethod
image(f::GAPGroupHomomorphism)

Return the image of f as subgroup of codomain(f), together with the embedding homomorphism.

source
imageMethod
image(f::GAPGroupHomomorphism{S, T}, H::S) where S <: GAPGroup where T <: GAPGroup
-(f::GAPGroupHomomorphism{S, T})(H::S)

Return f(H), together with the embedding homomorphism into codomain(f).

source
cokernelMethod
cokernel(f::GAPGroupHomomorphism)

Return the cokernel of f, that is, the quotient of the codomain of f by the normal closure of the image.

source
preimageMethod
preimage(f::GAPGroupHomomorphism{S, T}, H::T) where S <: GAPGroup where T <: GAPGroup

If H is a subgroup of the codomain of f, return the subgroup f^-1(H), together with its embedding homomorphism into the domain of f.

source

Group isomorphisms

is_isomorphicMethod
is_isomorphic(G::Group, H::Group)

Return true if G and H are isomorphic groups, and false otherwise.

Examples

julia> is_isomorphic(symmetric_group(3), dihedral_group(6))
-true
source
is_isomorphic_with_mapMethod
is_isomorphic_with_map(G::Group, H::Group)

Return (true,f) if G and H are isomorphic groups, where f is a group isomorphism. Otherwise, return (false,f), where f is the trivial homomorphism.

Examples

julia> is_isomorphic_with_map(symmetric_group(3), dihedral_group(6))
-(true, Group homomorphism from
-Sym( [ 1 .. 3 ] )
-to
-<pc group of size 6 with 2 generators>)
source
isomorphismMethod
isomorphism(G::Group, H::Group)

Return a group isomorphism between G and H if they are isomorphic groups. Otherwise throw an exception.

Examples

julia> isomorphism(symmetric_group(3), dihedral_group(6))
-Group homomorphism from
-Sym( [ 1 .. 3 ] )
-to
-<pc group of size 6 with 2 generators>
source
isomorphismMethod
isomorphism(::Type{T}, G::GAPGroup) where T <: Union{FPGroup, PcGroup, PermGroup}

Return an isomorphism from G to a group of type T. An exception is thrown if no such isomorphism exists.

Isomorphisms are cached in G, subsequent calls of isomorphism with the same T yield identical results.

If only the image of such an isomorphism is needed, use T(G).

Examples

julia> G = dihedral_group(6)
-<pc group of size 6 with 2 generators>
-
-julia> iso = isomorphism(PermGroup, G)
-Group homomorphism from
-<pc group of size 6 with 2 generators>
-to
-Group([ (1,2)(3,6)(4,5), (1,3,5)(2,4,6) ])
-
-julia> PermGroup(G)
-Group([ (1,2)(3,6)(4,5), (1,3,5)(2,4,6) ])
-
-julia> codomain(iso) === ans
-true
source
isomorphismMethod
isomorphism(::Type{GrpAbFinGen}, G::GAPGroup)

Return a map from G to an isomorphic (additive) group of type GrpAbFinGen. An exception is thrown if G is not abelian or not finite.

source
simplified_fp_groupMethod
simplified_fp_group(G::FPGroup)

Return a group H of type FPGroup and an isomorphism f from G to H, where the presentation of H was obtained from the presentation of G by applying Tietze transformations in order to reduce it with respect to the number of generators, the number of relators, and the relator lengths.

Examples

julia> F = free_group(3)
-<free group on the generators [ f1, f2, f3 ]>
-
-julia> G = quo(F, [gen(F,1)])[1]
-<fp group of size infinity on the generators [ f1, f2, f3 ]>
-
-julia> simplified_fp_group(G)[1]
-<fp group of size infinity on the generators [ f2, f3 ]>
source

Other homomorphisms

epimorphism_from_free_groupMethod
epimorphism_from_free_group(G::GAPGroup)

Return an epimorphism epi from a free group F == domain(epi) onto G, where F has the same number of generators as G and such that for each i it maps gen(F,i) to gen(G,i).

A useful application of this function is expressing an element of G as a word in its generators.

Examples

julia> G = symmetric_group(4);
-
-julia> epi = epimorphism_from_free_group(G)
-Group homomorphism from
-<free group on the generators [ x1, x2 ]>
-to
-Sym( [ 1 .. 4 ] )
-
-julia> pi = G([2,4,3,1])
-(1,2,4)
-
-julia> w = preimage(epi, pi);
-
-julia> map_word(w, gens(G))
-(1,2,4)
source
diff --git a/previews/PR2578/Groups/grouplib/index.html b/previews/PR2578/Groups/grouplib/index.html deleted file mode 100644 index 80c7959cc752..000000000000 --- a/previews/PR2578/Groups/grouplib/index.html +++ /dev/null @@ -1,247 +0,0 @@ - -Group libraries · Oscar.jl

Group libraries

Transitive permutation groups of small degree

TODO: explain about the scope of this.

TODO: give proper attribution to the transgrp package (in particular, cite it)

The arrangement and the names of the groups of degree up to 15 is the same as given in John H. Conway, Alexander Hulpke, John McKay (1998). With the exception of the symmetric and alternating group (which are represented as symmetric_group and alternating_group) the generators for these groups also conform to this paper with the only difference that 0 (which is not permitted in GAP for permutations to act on) is always replaced by the degree.

The arrangement for all degrees is intended to be equal to the arrangement within the systems GAP and Magma, thus it should be safe to refer to particular (classes of) groups by their index numbers.

all_transitive_groupsFunction
all_transitive_groups(L...)

Return the list of all transitive groups (up to permutation isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:

  • func => intval selects groups for which the function func returns intval
  • func => list selects groups for which the function func returns any element inside list
  • func selects groups for which the function func returns true
  • !func selects groups for which the function func returns false

The following functions are currently supported as values for func:

  • degree
  • is_abelian
  • is_almostsimple
  • is_cyclic
  • is_nilpotent
  • is_perfect
  • is_primitive
  • is_quasisimple
  • is_simple
  • is_sporadic_simple
  • is_solvable
  • is_supersolvable
  • is_transitive
  • number_conjugacy_classes
  • number_moved_points
  • order
  • transitivity

The type of the returned groups is PermGroup.

Examples

julia> all_transitive_groups(degree => 3:5, is_abelian)
-4-element Vector{PermGroup}:
- A3
- C(4) = 4
- E(4) = 2[x]2
- C(5) = 5

returns the list of all abelian transitive groups acting on 3, 4 or 5 points.

source
has_number_transitive_groupsFunction
has_number_transitive_groups(deg::Int)

Return whether the number transitive groups groups of degree deg are available for use via number_transitive_groups.

Examples

julia> has_number_transitive_groups(30)
-true
-
-julia> has_number_transitive_groups(64)
-false
source
has_transitive_group_identificationFunction
has_transitive_group_identification(deg::Int)

Return whether identification of transitive groups groups of degree deg is available via transitive_group_identification.

Examples

julia> has_transitive_group_identification(30)
-true
-
-julia> has_transitive_group_identification(64)
-false
source
has_transitive_groupsFunction
has_transitive_groups(deg::Int)

Return whether the transitive groups groups of degree deg are available for use. This function should be used to test for the scope of the library available.

Examples

julia> has_transitive_groups(30)
-true
-
-julia> has_transitive_groups(64)
-false
source
number_transitive_groupsFunction
number_transitive_groups(deg::Int)

Return the number of transitive groups of degree deg, up to permutation isomorphism.

Examples

julia> number_transitive_groups(30)
-5712
-
-julia> number_transitive_groups(64)
-ERROR: ArgumentError: the number of transitive groups of degree 64 is not available
source
transitive_groupFunction
transitive_group(deg::Int, i::Int)

Return the i-th group in the catalogue of transitive groups over the set {1, ..., deg} in GAP's Transitive Groups Library. The output is a group of type PermGroup.

Examples

julia> transitive_group(5,4)
-A5
-
-julia> transitive_group(5,6)
-ERROR: ArgumentError: there are only 5 transitive groups of degree 5, not 6
source
transitive_group_identificationFunction
transitive_group_identification(G::PermGroup)

Return a pair (d,n) such that G is permutation isomorphic with transitive_group(d,n), where G acts transitively on d points.

If G is not transitive on its moved points, or if the transitive groups of degree d are not available, an exception is thrown.

Examples

julia> G = symmetric_group(7);  m = transitive_group_identification(G)
-(7, 7)
-
-julia> order(transitive_group(m...)) == order(G)
-true
-
-julia> S = sub(G, [perm([1, 3, 4, 5, 2])])[1]
-Group([ (2,3,4,5) ])
-
-julia> is_transitive(S)
-false
-
-julia> is_transitive(S, moved_points(S))
-true
-
-julia> m = transitive_group_identification(S)
-(4, 1)
-
-julia> order(transitive_group(m...)) == order(S)
-true
-
-julia> transitive_group_identification(symmetric_group(64))
-ERROR: ArgumentError: identification of transitive groups of degree 64 are not available
-
-julia> S = sub(G, [perm([1,3,4,5,2,7,6])])[1];
-
-julia> transitive_group_identification(S)
-ERROR: ArgumentError: group is not transitive on its moved points
source

Primitive permutation groups of small degree

TODO: explain about the scope of this.

TODO: give proper attribution to the primitive groups library (in particular, cite it)

all_primitive_groupsFunction
all_primitive_groups(L...)

Return the list of all primitive permutation groups (up to permutation isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:

  • func => intval selects groups for which the function func returns intval
  • func => list selects groups for which the function func returns any element inside list
  • func selects groups for which the function func returns true
  • !func selects groups for which the function func returns false

The following functions are currently supported as values for func:

  • degree
  • is_abelian
  • is_almostsimple
  • is_cyclic
  • is_nilpotent
  • is_perfect
  • is_primitive
  • is_quasisimple
  • is_simple
  • is_sporadic_simple
  • is_solvable
  • is_supersolvable
  • is_transitive
  • number_conjugacy_classes
  • number_moved_points
  • order
  • transitivity

The type of the returned groups is PermGroup.

Examples

julia> all_primitive_groups(degree => 3:5, is_abelian)
-2-element Vector{PermGroup}:
- A(3)
- C(5)

returns the list of all abelian primitive permutation groups acting on 3, 4 or 5 points.

source
has_number_primitive_groupsFunction
has_number_primitive_groups(deg::Int)

Return true if the number of primitive permutation groups of degree deg is available via number_primitive_groups, otherwise false.

Currently the number of primitive permutation groups is available up to degree 4095.

Examples

julia> has_number_primitive_groups(50)
-true
-
-julia> has_number_primitive_groups(5000)
-false
source
has_primitive_group_identificationFunction
has_primitive_group_identification(deg::Int)

Return true if identification is supported for the primitive permutation groups of degree deg via primitive_group_identification, otherwise false.

Currently identification is available for all primitive permutation groups up to degree 4095.

Examples

julia> has_primitive_group_identification(50)
-true
-
-julia> has_primitive_group_identification(5000)
-false
source
has_primitive_groupsFunction
has_primitive_groups(deg::Int)

Return true if the primitive permutation groups of degree deg are available via primitive_group and all_primitive_groups, otherwise false.

Currently all primitive permutation groups up to degree 4095 are available.

Examples

julia> has_primitive_groups(50)
-true
-
-julia> has_primitive_groups(5000)
-false
source
number_primitive_groupsFunction
number_primitive_groups(deg::Int)

Return the number of primitive permutation groups of degree deg, up to permutation isomorphism.

Examples

julia> number_primitive_groups(10)
-9
-
-julia> number_primitive_groups(4096)
-ERROR: ArgumentError: the number of primitive permutation groups of degree 4096 is not available
source
primitive_groupFunction
primitive_group(deg::Int, i::Int)

Return the i-th group in the catalogue of primitive permutation groups over the set {1, ..., deg} in GAP's library of primitive permutation groups. The output is a group of type PermGroup.

Examples

julia> primitive_group(10,1)
-A(5)
-
-julia> primitive_group(10,10)
-ERROR: ArgumentError: there are only 9 primitive permutation groups of degree 10, not 10
source
primitive_group_identificationFunction
primitive_group_identification(G::PermGroup)

Return a pair (d,n) such that G is permutation isomorphic with primitive_group(d,n), where G acts primitively on d points.

If G is not primitive on its moved points, or if the primitive permutation groups of degree d are not available, an exception is thrown.

Examples

julia> G = symmetric_group(7);  m = primitive_group_identification(G)
-(7, 7)
-
-julia> order(primitive_group(m...)) == order(G)
-true
-
-julia> S = stabilizer(G, 1)[1]
-Group([ (2,7,6,5,4,3), (6,7) ])
-
-julia> is_primitive(S)
-false
-
-julia> is_primitive(S, moved_points(S))
-true
-
-julia> m = primitive_group_identification(S)
-(6, 4)
-
-julia> order(primitive_group(m...)) == order(S)
-true
-
-julia> primitive_group_identification(symmetric_group(4096))
-ERROR: ArgumentError: identification of primitive permutation groups of degree 4096 is not available
-
-julia> S = sub(G, [perm([1,3,4,5,2,7,6])])[1];
-
-julia> primitive_group_identification(S)
-ERROR: ArgumentError: group is not primitive on its moved points
source

Perfect groups of small order

The functions in this section are wrappers for the GAP library of finite perfect groups which provides, up to isomorphism, a list of all perfect groups whose sizes are less than $2\cdot 10^6$. The groups of most orders up to $10^6$ have been enumerated by Derek Holt and Wilhelm Plesken, see Derek F. Holt, W. Plesken (1989). For orders $n = 86016$, 368640, or 737280 this work only counted the groups (but did not explicitly list them), the groups of orders $n = 61440$, 122880, 172032, 245760, 344064, 491520, 688128, or 983040 were omitted.

Several additional groups omitted from the book Derek F. Holt, W. Plesken (1989) have also been included. Two groups – one of order 450000 with a factor group of type $A_6$ and the one of order 962280 – were found by Jack Schmidt in

  1. Two groups of order 243000 and one each of orders 729000, 871200, 878460

were found in 2020 by Alexander Hulpke.

The perfect groups of size less than $2\cdot 10^6$ which had not been classified in the work of Holt and Plesken have been enumerated by Alexander Hulpke. They are stored directly and provide less construction information in their names.

As all groups are stored by presentations, a permutation representation is obtained by coset enumeration. Note that some of the library groups do not have a faithful permutation representation of small degree. Computations in these groups may be rather time consuming.

has_number_perfect_groupsFunction
has_number_perfect_groups(n::Int)

Return true if the number of perfect groups of order n are available via number_perfect_groups, otherwise false.

Currently the number of perfect groups is available up to order $2 \cdot 10^6$.

Examples

julia> has_number_perfect_groups(7200)
-true
-
-julia> has_number_perfect_groups(2*10^6+1)
-false
source
has_perfect_group_identificationFunction
has_perfect_group_identification(n::Int)

Return true if identification is supported for the perfect groups of order n via perfect_group_identification, otherwise false.

Currently identification is available for all perfect groups up to order $2 \cdot 10^6$.

Examples

julia> has_perfect_group_identification(7200)
-true
-
-julia> has_perfect_group_identification(2*10^6+1)
-false
source
has_perfect_groupsFunction
has_perfect_groups(deg::Int)

Return true if the perfect groups of order n are available via perfect_group and all_perfect_groups, otherwise false.

Currently all perfect groups up to order $2 \cdot 10^6$ are available.

Examples

julia> has_perfect_groups(7200)
-true
-
-julia> has_perfect_groups(2*10^6+1)
-false
source
number_perfect_groupsFunction
number_perfect_groups(n::IntegerUnion)

Return the number of perfect groups of order n, up to isomorphism.

Examples

julia> number_perfect_groups(60)
-1
-
-julia> number_perfect_groups(1966080)
-7344
source
orders_perfect_groupsFunction
orders_perfect_groups()

Return a sorted vector of all numbers to $2 \cdot 10^6$ that occur as orders of perfect groups.

Examples

julia> orders_perfect_groups()[1:10]
-10-element Vector{Int64}:
-   1
-  60
- 120
- 168
- 336
- 360
- 504
- 660
- 720
- 960
source
perfect_groupFunction
perfect_group(::Type{T} = PermGroup, n::IntegerUnion, k::IntegerUnion)

Return the k-th group of order n and type T in the catalogue of perfect groups in GAP's Perfect Groups Library. The type T can be either PermGroup or FPGroup.

Examples

julia> perfect_group(60, 1)
-A5
-
-julia> gens(ans)
-2-element Vector{PermGroupElem}:
- (1,2)(4,5)
- (2,3,4)
-
-julia> perfect_group(FPGroup, 60, 1)
-A5
-
-julia> gens(ans)
-2-element Vector{FPGroupElem}:
- a
- b
-
-julia> perfect_group(60, 2)
-ERROR: ArgumentError: there are only 1 perfect groups of order 60
source
perfect_group_identificationFunction
perfect_group_identification(G::GAPGroup)

Return (n, m) such that G is isomorphic with perfect_group(n, m). If G is not perfect, an exception is thrown.

Examples

julia> perfect_group_identification(alternating_group(5))
-(60, 1)
-
-julia> perfect_group_identification(SL(2,7))
-(336, 1)
source

Groups of small order

TODO: explain about the scope of this.

TODO: give proper attribution to the smallgrp package and other things used (in particular, cite it)

all_small_groupsFunction
all_small_groups(L...)

Return the list of all groups (up to isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:

  • func => intval selects groups for which the function func returns intval
  • func => list selects groups for which the function func returns any element inside list
  • func selects groups for which the function func returns true
  • !func selects groups for which the function func returns false

As a special case, the first argument may also be one of the following:

  • intval selects groups whose order equals intval; this is equivalent to order => intval
  • intlist selects groups whose order is in intlist; this is equivalent to order => intlist

Note that at least one of the conditions must impose a limit on the group order, otherwise an exception is thrown.

The following functions are currently supported as values for func:

  • is_abelian
  • is_almostsimple
  • is_cyclic
  • is_nilpotent
  • is_perfect
  • is_quasisimple
  • is_simple
  • is_sporadic_simple
  • is_solvable
  • is_supersolvable
  • number_conjugacy_classes
  • order

The type of the returned groups is PcGroup if the group is solvable, PermGroup otherwise.

Examples

List all abelian non-cyclic groups of order 12:

julia> all_small_groups(12, !is_cyclic, is_abelian)
-1-element Vector{PcGroup}:
- <pc group of size 12 with 3 generators>

List groups of order 1 to 10 which are not abelian:

julia> all_small_groups(1:10, !is_abelian)
-4-element Vector{PcGroup}:
- <pc group of size 6 with 2 generators>
- <pc group of size 8 with 3 generators>
- <pc group of size 8 with 3 generators>
- <pc group of size 10 with 2 generators>
source
has_number_small_groupsFunction
has_number_small_groups(n::IntegerUnion)

Return true if the number of groups of order n is known, otherwise false.

Examples

julia> has_number_small_groups(1024)
-true
-
-julia> has_number_small_groups(2048)
-false
source
has_small_group_identificationFunction
has_small_group_identification(n::IntegerUnion)

Return true if identification for groups of order n is available via small_group_identification, otherwise false.

Examples

julia> has_small_group_identification(256)
-true
-
-julia> has_small_group_identification(512)
-false
source
has_small_groupsFunction
has_small_groups(n::IntegerUnion)

Return true if the groups of order n are available via small_group and all_small_groups, otherwise false.

Examples

julia> has_small_groups(512)
-true
-
-julia> has_small_groups(1024)
-false
source
number_small_groupsFunction
number_small_groups(n::IntegerUnion)

Return the number of groups of order n, up to isomorphism.

Examples

julia> number_small_groups(8)
-5
-
-julia> number_small_groups(4096)
-ERROR: ArgumentError: the number of groups of order 4096 is not available
-
-julia> number_small_groups(next_prime(ZZRingElem(2)^64))
-1
source
small_groupFunction
small_group(::Type{T}, n::IntegerUnion, i::IntegerUnion) where T
-small_group(n::IntegerUnion, i::IntegerUnion)

Return the i-th group of order n in the Small Groups Library. If a type T is specified then an attempt is made to return the result with that type. If T is omitted then the resulting group will have type PcGroup if it is solvable, otherwise it will be of type PermGroup.

Examples

julia> small_group(60, 4)
-<pc group of size 60 with 4 generators>
-
-julia> small_group(60, 5)
-Group([ (1,2,3,4,5), (1,2,3) ])
-
-julia> small_group(PcGroup, 60, 4)
-<pc group of size 60 with 4 generators>
source
small_group_identificationFunction
small_group_identification(G::Group)

Return a pair of integer (n, m), where G is isomorphic with small_group(n, m).

Examples

julia> small_group_identification(alternating_group(5))
-(60, 5)
-
-julia> small_group_identification(symmetric_group(20))
-ERROR: ArgumentError: identification is not available for groups of order 2432902008176640000
source

Atlas of Group Representations

The functions in this section give access to data in the Atlas of Group Representations R. A. Wilson, P. Walsh, J. Tripp, I. Suleiman, R. A. Parker, S. P. Norton, S. Nickerson, S. Linton, J. Bray, R. Abbott (). The isomorphism types of the groups in question are specified via names for the groups, which coincide with the names of the corresponding character tables in the library of character tables, see character_table(id::String, p::Int = 0).

number_atlas_groupsFunction
number_atlas_groups([::Type{T}, ]name::String) where T <: Union{PermGroup, MatrixGroup}

Return the number of groups from the Atlas of Group Representations whose isomorphism type is given by name and have the type T.

Examples

julia> number_atlas_groups("A5")
-18
-
-julia> number_atlas_groups(PermGroup, "A5")
-3
-
-julia> number_atlas_groups(MatrixGroup, "A5")
-15
-
source
all_atlas_group_infosFunction
all_atlas_group_infos(name::String, L...)

Return the vector of dictionaries that describe Atlas groups whose isomorphism types are given by name and which satisfy the conditions in L. These conditions may be of one of the following forms:

  • func => intval selects groups for which the function func returns intval
  • func => list selects groups for which the function func returns any element inside list
  • func selects groups for which the function func returns true
  • !func selects groups for which the function func returns false

The following functions are currently supported as values for func:

For permutation groups

  • degree
  • is_primitive
  • is_transitive
  • rank_action
  • transitivity

and for matrix groups

  • base_ring
  • character
  • characteristic
  • dim

Examples

julia> info = all_atlas_group_infos("A5", degree => [5, 6])
-2-element Vector{Dict{Symbol, Any}}:
- Dict(:repname => "A5G1-p5B0", :degree => 5, :name => "A5")
- Dict(:repname => "A5G1-p6B0", :degree => 6, :name => "A5")
-
-julia> atlas_group(info[1])
-Group([ (1,2)(3,4), (1,3,5) ])
-
-julia> info = all_atlas_group_infos("A5", dim => 4, characteristic => 3)
-1-element Vector{Dict{Symbol, Any}}:
- Dict(:dim => 4, :repname => "A5G1-f3r4B0", :name => "A5")
-
-julia> atlas_group(info[1])
-Matrix group of degree 4 over Finite field of degree 1 over GF(3)
-
source
atlas_groupFunction
atlas_group([::Type{T}, ]name::String) where T <: Union{PermGroup, MatrixGroup}

Return a group from the Atlas of Group Representations whose isomorphism type is given by name and have the type T. If T is not given then PermGroup is chosen if a permutation group for name is available, and MatrixGroup otherwise.

Examples

julia> atlas_group("A5")  # alternating group A5
-Group([ (1,2)(3,4), (1,3,5) ])
-
-julia> atlas_group(MatrixGroup, "A5")
-Matrix group of degree 4 over Finite field of degree 1 over GF(2)
-
-julia> atlas_group("M11")  # Mathieu group M11
-Group([ (2,10)(4,11)(5,7)(8,9), (1,4,3,8)(2,5,6,9) ])
-
-julia> atlas_group("M")  # Monster group M
-ERROR: ArgumentError: the group atlas does not provide a representation for M
source
atlas_group(info::Dict)

Return the group from the Atlas of Group Representations that is defined by info. Typically, info is obtained from all_atlas_group_infos.

Examples

julia> info = all_atlas_group_infos("A5", degree => 5)
-1-element Vector{Dict{Symbol, Any}}:
- Dict(:repname => "A5G1-p5B0", :degree => 5, :name => "A5")
-
-julia> atlas_group(info[1])
-Group([ (1,2)(3,4), (1,3,5) ])
-
source
atlas_subgroupFunction
atlas_subgroup(G::GAPGroup, nr::Int)
-atlas_subgroup([::Type{T}, ]name::String, nr::Int) where T <: Union{PermGroup, MatrixGroup}
-atlas_subgroup(info::Dict, nr::Int)

Return a pair (H, emb) where H is a representative of the nr-th class of maximal subgroups of the group G, and emb is an embedding of H into G.

The group G can be given as the first argument, in this case it is assumed that G has been created with atlas_group. Otherwise G is the group obtained by calling atlas_group with (T and) name or with info.

If the Atlas of Group Representations does not provide the information to compute G or to compute generators of H from G then an exception is thrown.

Examples

julia> g = atlas_group("M11");  # Mathieu group M11
-
-julia> h1, emb = atlas_subgroup(g, 1);  h1
-Group([ (1,4)(2,10)(3,7)(6,9), (1,6,10,7,11,3,9,2)(4,5) ])
-
-julia> order(h1)  # largest maximal subgroup of M11
-720
-
-julia> h2, emb = atlas_subgroup("M11", 1);  h2
-Group([ (1,4)(2,10)(3,7)(6,9), (1,6,10,7,11,3,9,2)(4,5) ])
-
-julia> h3, emb = atlas_subgroup(MatrixGroup, "M11", 1 );  h3
-Matrix group of degree 10 over Finite field of degree 1 over GF(2)
-
-julia> info = all_atlas_group_infos("M11", degree => 11);
-
-julia> h4, emb = atlas_subgroup(info[1], 1);  h4
-Group([ (1,4)(2,10)(3,7)(6,9), (1,6,10,7,11,3,9,2)(4,5) ])
source
diff --git a/previews/PR2578/Groups/intro/index.html b/previews/PR2578/Groups/intro/index.html deleted file mode 100644 index ba158bb3a55d..000000000000 --- a/previews/PR2578/Groups/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The groups part of OSCAR provides functionality for handling

General textbooks offering details on theory and algorithms include:

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/Groups/matgroup/index.html b/previews/PR2578/Groups/matgroup/index.html deleted file mode 100644 index c10867a2ace3..000000000000 --- a/previews/PR2578/Groups/matgroup/index.html +++ /dev/null @@ -1,99 +0,0 @@ - -Matrix groups · Oscar.jl

Matrix groups

matrix_groupMethod
matrix_group(R::Ring, m::Int, V::T...) where T<:Union{MatElem,MatrixGroupElem}
-matrix_group(R::Ring, m::Int, V::AbstractVector{T}) where T<:Union{MatElem,MatrixGroupElem}
-matrix_group(V::T...) where T<:Union{MatElem,MatrixGroupElem}
-matrix_group(V::AbstractVector{T}) where T<:Union{MatElem,MatrixGroupElem}

Return the matrix group generated by matrices in V. If the degree m and coefficient ring R are not given, then V must be non-empty

source
MatrixGroupType
MatrixGroup{RE<:RingElem, T<:MatElem{RE}} <: GAPGroup

Type of groups G of n x n matrices over the ring R, where n = degree(G) and R = base_ring(G).

source
MatrixGroupElemType
MatrixGroupElem{RE<:RingElem, T<:MatElem{RE}} <: AbstractMatrixGroupElem

Elements of a group of type MatrixGroup{RE<:RingElem, T<:MatElem{RE}}

source
base_ringMethod
base_ring(G::MatrixGroup)

Return the base ring of the matrix group G.

source
degreeMethod
degree(G::MatrixGroup)

Return the degree of the matrix group G, i.e. the number of rows of its matrices.

source
centralizerMethod
centralizer(G::MatrixGroup{T}, x::MatrixGroupElem{T})

Return (C,f), where C is the centralizer of x in C and f is the embedding of C into G. If G = GL(n,F) or SL(n,F), then f = nothing. In this case, to get the embedding homomorphism of C into G, use

is_subgroup(C, G)[2]

source

Elements of matrix groups

matrixMethod
matrix(x::MatrixGroupElem)

Return the underlying matrix of x.

source
base_ringMethod
base_ring(x::MatrixGroupElem)

Return the base ring of the underlying matrix of x.

source
nrowsMethod
nrows(x::MatrixGroupElem)

Return the number of rows of the underlying matrix of x.

source
detMethod
det(x::MatrixGroupElem)

Return the determinant of the underlying matrix of x.

source
trMethod
tr(x::MatrixGroupElem)

Return the trace of the underlying matrix of x.

source
multiplicative_jordan_decompositionMethod
multiplicative_jordan_decomposition(M::MatrixGroupElem)

Return S and U in the group G = parent(M) such that S is semisimple, U is unipotent and M = SU = US.

WARNING:

this is NOT, in general, the same output returned when M has type MatElem.

source
is_semisimpleMethod
is_semisimple(x::MatrixGroupElem{T}) where T <: FinFieldElem

Return whether x is semisimple, i.e. has order coprime with the characteristic of its base ring.

source
is_unipotentMethod
is_unipotent(x::MatrixGroupElem{T}) where T <: FinFieldElem

Return whether x is unipotent, i.e. its order is a power of the characteristic of its base ring.

source

Sesquilinear forms

SesquilinearFormType
SesquilinearForm{T<:RingElem}

Type of groups G of n x n matrices over the ring R, where n = degree(G) and R = base_ring(G). At the moment, only rings of type fqPolyRepField are supported.

source
is_alternatingMethod
is_alternating(f::SesquilinearForm)

Return whether the form f is an alternating form.

source
is_hermitianMethod
is_hermitian(f::SesquilinearForm)

Return whether the form f is a hermitian form.

source
is_quadraticMethod
is_quadratic(f::SesquilinearForm)

Return whether the form f is a quadratic form.

source
is_symmetricMethod
is_symmetric(f::SesquilinearForm)

Return whether the form f is a symmetric form.

source
alternating_formMethod
alternating_form(B::MatElem{T})

Return the alternating form with Gram matrix B.

source
symmetric_formMethod
symmetric_form(B::MatElem{T})

Return the symmetric form with Gram matrix B.

source
hermitian_formMethod
hermitian_form(B::MatElem{T})

Return the hermitian form with Gram matrix B.

source
quadratic_formMethod
quadratic_form(B::MatElem{T})

Return the quadratic form with Gram matrix B.

source
quadratic_formMethod
quadratic_form(f::MPolyRingElem{T}; check=true)

Return the quadratic form described by the polynomial f. Here, f must be a homogeneous polynomial of degree 2. If check is set as false, it does not check whether the polynomial is homogeneous of degree 2. To define quadratic forms of dimension 1, f can also have type PolyRingElem{T}.

source
corresponding_bilinear_formMethod
corresponding_bilinear_form(Q::SesquilinearForm)

Given a quadratic form Q, return the bilinear form B defined by B(u,v) = Q(u+v)-Q(u)-Q(v).

source
corresponding_quadratic_formMethod
corresponding_quadratic_form(Q::SesquilinearForm)

Given a symmetric form f, returns the quadratic form Q defined by Q(v) = f(v,v)/2. It is defined only in odd characteristic.

source
gram_matrixMethod
gram_matrix(B::SesquilinearForm)

Return the Gram matrix of a sesquilinear or quadratic form B.

source
defining_polynomialMethod
defining_polynomial(f::SesquilinearForm)

Return the polynomial that defines the quadratic form f.

source
radicalMethod
radical(f::SesquilinearForm{T})

Return the radical of the sesquilinear form f, i.e. the subspace of all v such that f(u,v)=0 for all u. The radical of a quadratic form Q is the set of vectors v such that Q(v)=0 and v lies in the radical of the corresponding bilinear form.

source
 radical(A::AbsAlgAss) -> AbsAlgAssIdl

Returns the Jacobson-Radical of $A$.

witt_indexMethod
witt_index(f::SesquilinearForm{T})

Return the Witt index of the form induced by f on V/Rad(f). The Witt Index is the dimension of a maximal totally isotropic (singular for quadratic forms) subspace.

source
is_degenerateMethod
is_degenerate(f::SesquilinearForm{T})

Return whether f is degenerate, i.e. f has nonzero radical. A quadratic form is degenerate if the corresponding bilinear form is.

source
is_singularMethod
is_singular(Q::SesquilinearForm{T})

For a quadratic form Q, return whether Q is singular, i.e. Q has nonzero radical.

source
is_congruentMethod
is_congruent(f::SesquilinearForm{T}, g::SesquilinearForm{T}) where T <: RingElem

If f and g are sesquilinear forms, return (true, C) if there exists a matrix C such that f^C = g, or equivalently, CBC* = A, where A and B are the Gram matrices of f and g respectively, and C* is the transpose-conjugate matrix of C. If such C does not exist, then return (false, nothing).

If f and g are quadratic forms, return (true, C) if there exists a matrix C such that f^A = ag for some scalar a. If such C does not exist, then return (false, nothing).

source

Invariant forms

invariant_bilinear_formsMethod
invariant_bilinear_forms(G::MatrixGroup)

Return a generating set for the vector spaces of bilinear forms preserved by the group G.

Note:

At the moment, elements of the generating set are returned of type mat_elem_type(G).

source
invariant_sesquilinear_formsMethod
invariant_sesquilinear_forms(G::MatrixGroup)

Return a generating set for the vector spaces of sesquilinear non-bilinear forms preserved by the group G. An exception is thrown if base_ring(G) is not a finite field with even degree over its prime subfield.

Note:

At the moment, elements of the generating set are returned of type mat_elem_type(G).

source
invariant_quadratic_formsMethod
invariant_quadratic_forms(G::MatrixGroup)

Return a generating set for the vector spaces of quadratic forms preserved by the group G.

Note:

At the moment, elements of the generating set are returned of type mat_elem_type(G).

source
invariant_symmetric_formsMethod
invariant_symmetric_forms(G::MatrixGroup)

Return a generating set for the vector spaces of symmetric forms preserved by the group G.

Note:

At the moment, elements of the generating set are returned of type mat_elem_type(G).

Note:

Work properly only in odd characteristic. In even characteristic, only alternating forms are found.

source
invariant_alternating_formsMethod
invariant_alternating_forms(G::MatrixGroup)

Return a generating set for the vector spaces of alternating forms preserved by the group G.

Note:

At the moment, elements of the generating set are returned of type mat_elem_type(G).

source
invariant_hermitian_formsMethod
invariant_hermitian_forms(G::MatrixGroup)

Return a generating set for the vector spaces of hermitian forms preserved by the group G. An exception is thrown if base_ring(G) is not a finite field with even degree over its prime subfield.

Note:

At the moment, elements of the generating set are returned of type mat_elem_type(G).

source
invariant_bilinear_formMethod
invariant_bilinear_form(G::MatrixGroup)

Return an invariant bilinear form for the group G. An exception is thrown if the module induced by the action of G is not absolutely irreducible.

Note:

At the moment, the output is returned of type mat_elem_type(G).

source
invariant_sesquilinear_formMethod
invariant_sesquilinear_form(G::MatrixGroup)

Return an invariant sesquilinear (non bilinear) form for the group G. An exception is thrown if the module induced by the action of G is not absolutely irreducible or if the group is defined over a finite field of odd degree over the prime field.

Note:

At the moment, the output is returned of type mat_elem_type(G).

source
invariant_quadratic_formMethod
invariant_quadratic_form(G::MatrixGroup)

Return an invariant quadratic form for the group G. An exception is thrown if the module induced by the action of G is not absolutely irreducible.

Note:

At the moment, the output is returned of type mat_elem_type(G).

source
preserved_quadratic_formsMethod
preserved_quadratic_forms(G::MatrixGroup)

Uses random methods to find all of the quadratic forms preserved by G up to a scalar (i.e. such that G is a group of similarities for the forms). Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant quadratic forms.

source
preserved_sesquilinear_formsMethod
preserved_sesquilinear_forms(G::MatrixGroup)

Uses random methods to find all of the sesquilinear forms preserved by G up to a scalar (i.e. such that G is a group of similarities for the forms). Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant sesquilinear forms.

source
isometry_groupMethod
isometry_group(f::SesquilinearForm{T})

Return the group of isometries for the sesquilinear form f.

source
orthogonal_signMethod
orthogonal_sign(G::MatrixGroup)

For absolutely irreducible G of degree n and such that base_ring(G) is a finite field, return

  • nothing if G does not preserve a nonzero quadratic form,
  • 0 if n is odd and G preserves a nonzero quadratic form,
  • 1 if n is even and G preserves a nonzero quadratic form of + type,
  • -1 if n is even and G preserves a nonzero quadratic form of - type.
source

Utilities for matrices (replace by available functions, or document elsewhere?)

pol_elementary_divisorsMethod
pol_elementary_divisors(x::MatElem)
-pol_elementary_divisors(x::MatrixGroupElem)

Return a list of pairs (f_i,m_i), for irreducible polynomials f_i and positive integers m_i, where the f_i^m_i are the elementary divisors of x.

source
generalized_jordan_blockMethod
generalized_jordan_block(f::T, n::Int) where T<:PolyRingElem

Return the Jordan block of dimension n corresponding to the polynomial f.

source
generalized_jordan_formMethod
generalized_jordan_form(A::MatElem{T}; with_pol::Bool=false) where T

Return (J,Z), where Z^-1*J*Z = A and J is a diagonal join of Jordan blocks (corresponding to irreducible polynomials).

source
matrixMethod
matrix(A::Vector{AbstractAlgebra.Generic.FreeModuleElem})

Return the matrix whose rows are the vectors in A. All vectors in A must have the same length and the same base ring.

source
upper_triangular_matrixMethod
upper_triangular_matrix(L)

Return the upper triangular matrix whose entries on and above the diagonal are the elements of L.

An exception is thrown whenever the length of L is not equal to $n(n+1)/2$, for some integer $n$.

source
lower_triangular_matrixMethod
lower_triangular_matrix(L)

Return the upper triangular matrix whose entries on and below the diagonal are the elements of L.

An exception is thrown whenever the length of L is not equal to $n(n+1)/2$, for some integer $n$.

source
conjugate_transposeMethod
conjugate_transpose(x::MatElem{T}) where T <: FinFieldElem

If the base ring of x is GF(q^2), return the matrix transpose( map ( y -> y^q, x) ). An exception is thrown if the base ring does not have even degree.

source
complementMethod
complement(V::AbstractAlgebra.Generic.FreeModule{T}, W::AbstractAlgebra.Generic.Submodule{T}) where T <: FieldElem

Return a complement for W in V, i.e. a subspace U of V such that V is direct sum of U and W.

source
permutation_matrixMethod
permutation_matrix(F::Ring, Q::AbstractVector{T}) where T <: Int
-permutation_matrix(F::Ring, p::PermGroupElem)

Return the permutation matrix over the ring R corresponding to the sequence Q or to the permutation p. If Q is a sequence, then Q must contain exactly once every integer from 1 to some n.

Examples

julia> s = perm([3,1,2])
-(1,3,2)
-
-julia> permutation_matrix(QQ,s)
-[0   0   1]
-[1   0   0]
-[0   1   0]
-
source
is_alternatingMethod
is_alternating(B::MatElem)

Return whether the form corresponding to the matrix B is alternating, i.e. B = -transpose(B) and B has zeros on the diagonal. Return false if B is not a square matrix.

source
is_hermitianMethod
is_hermitian(B::MatElem{T}) where T <: FinFieldElem

Return whether the matrix B is hermitian, i.e. B = conjugate_transpose(B). Return false if B is not a square matrix, or the field has not even degree.

source

Classical groups

general_linear_groupMethod
general_linear_group(n::Int, q::Int)
-general_linear_group(n::Int, R::Ring)
-GL = general_linear_group

Return the general linear group of dimension n over the ring R respectively the field GF(q).

Currently, this function only supports rings of type fqPolyRepField.

Examples

julia> F = GF(7,1)
-Finite field of degree 1 over GF(7)
-
-julia> H = general_linear_group(2,F)
-GL(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [3 0; 0 1]
- [6 1; 6 0]
-
source
special_linear_groupMethod
special_linear_group(n::Int, q::Int)
-special_linear_group(n::Int, R::Ring)
-SL = special_linear_group

Return the special linear group of dimension n over the ring R respectively the field GF(q).

Currently, this function only supports rings of type fqPolyRepField.

Examples

julia> F = GF(7,1)
-Finite field of degree 1 over GF(7)
-
-julia> H = special_linear_group(2,F)
-SL(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [3 0; 0 5]
- [6 1; 6 0]
-
source
symplectic_groupMethod
symplectic_group(n::Int, q::Int)
-symplectic_group(n::Int, R::Ring)
-Sp = symplectic_group

Return the symplectic group of dimension n over the ring R respectively the field GF(q). The dimension n must be even.

Currently, this function only supports rings of type fqPolyRepField.

Examples

julia> F = GF(7,1)
-Finite field of degree 1 over GF(7)
-
-julia> H = symplectic_group(2,F)
-Sp(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [3 0; 0 5]
- [6 1; 6 0]
-
source
orthogonal_groupMethod
orthogonal_group(e::Int, n::Int, R::Ring)
-orthogonal_group(e::Int, n::Int, q::Int)
-GO = orthogonal_group

Return the orthogonal group of dimension n over the ring R respectively the field GF(q), and of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.

Currently, this function only supports rings of type fqPolyRepField.

Examples

julia> F = GF(7,1)
-Finite field of degree 1 over GF(7)
-
-julia> H = symplectic_group(2,F)
-Sp(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [3 0; 0 5]
- [6 1; 6 0]
-
source
special_orthogonal_groupMethod
special_orthogonal_group(e::Int, n::Int, R::Ring)
-special_orthogonal_group(e::Int, n::Int, q::Int)
-SO = special_orthogonal_group

Return the special orthogonal group of dimension n over the ring R respectively the field GF(q), and of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.

Currently, this function only supports rings of type fqPolyRepField.

Examples

julia> F = GF(7,1)
-Finite field of degree 1 over GF(7)
-
-julia> H = special_orthogonal_group(1,2,F)
-SO+(2,7)
-
-julia> gens(H)
-3-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [3 0; 0 5]
- [5 0; 0 3]
- [1 0; 0 1]
-
source
omega_groupMethod
omega_group(e::Int, n::Int, R::Ring)
-omega_group(e::Int, n::Int, q::Int)

Return the Omega group of dimension n over the field GF(q) of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.

Currently, this function only supports rings of type fqPolyRepField.

Examples

julia> F = GF(7,1)
-Finite field of degree 1 over GF(7)
-
-julia> H = omega_group(1,2,F)
-Omega+(2,7)
-
-julia> gens(H)
-1-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [2 0; 0 4]
-
source
unitary_groupMethod
unitary_group(n::Int, q::Int)
-GU = unitary_group

Return the unitary group of dimension n over the field GF(q^2).

Examples

julia> H = unitary_group(2,3)
-GU(2,3)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [o 0; 0 2*o]
- [2 2*o+2; 2*o+2 0]
source
special_unitary_groupMethod
special_unitary_group(n::Int, q::Int)
-SU = special_unitary_group

Return the special unitary group of dimension n over the field with q^2 elements.

Examples

julia> H = special_unitary_group(2,3)
-SU(2,3)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:
- [1 2*o+2; 0 1]
- [0 2*o+2; 2*o+2 0]
source
diff --git a/previews/PR2578/Groups/pcgroup/index.html b/previews/PR2578/Groups/pcgroup/index.html deleted file mode 100644 index 03d7c61889da..000000000000 --- a/previews/PR2578/Groups/pcgroup/index.html +++ /dev/null @@ -1,41 +0,0 @@ - -Polycyclic groups · Oscar.jl

Polycyclic groups

PcGroupType
PcGroup

Polycyclic group, a group that is defined by a finite presentation of a special kind, a so-called polycyclic presentation. Contrary to arbitrary finitely presented groups (see Finitely presented groups), this presentation allows for efficient computations with the group elements.

Examples

  • cyclic_group(n::Int): cyclic group of order n
  • abelian_group(PcGroup, v::Vector{Int}): direct product of cyclic groups of the orders v[1], v[2], ..., v[length(v)]
source
PcGroupElemType
PcGroupElem

Element of a polycyclic group.

The generators of a polycyclic group are displayed as f1, f2, f3, etc., and every element of a polycyclic group is displayed as product of the generators.

Examples

julia> G = abelian_group(PcGroup, [2, 4]);
-
-julia> G[1], G[2]
-(f1, f2)
-
-julia> G[2]*G[1]
-f1*f2

Note that this does not define Julia variables named f1, f2, etc.! To get the generators of the group G, use gens(G); for convenience they can also be accessed as G[1], G[2], as shown in Section Elements of groups.

source

Julia has the following functions that allow to generate polycyclic groups:

abelian_groupMethod
abelian_group(::Type{T}, v::Vector{Int}) where T <: Group -> PcGroup

Return the direct product of cyclic groups of the orders v[1], v[2], $\ldots$, v[n], as an instance of T. Here, T must be one of PermGroup, FPGroup, or PcGroup.

Warning

The type need to be specified in the input of the function abelian_group, otherwise a group of type GrpAbFinGen is returned, which is not a GAP group type. In future versions of Oscar, this may change.

source
cyclic_groupFunction
cyclic_group(::Type{T} = PcGroup, n::IntegerUnion)
-cyclic_group(::Type{T} = PcGroup, n::PosInf)

Return the cyclic group of order n, as an instance of type T.

Examples

julia> G = cyclic_group(5)
-<pc group of size 5 with 1 generator>
-
-julia> G = cyclic_group(PermGroup, 5)
-Group([ (1,2,3,4,5) ])
-
-julia> G = cyclic_group(PosInf())
-Pcp-group with orders [ 0 ]
-
source
dihedral_groupFunction
dihedral_group(::Type{T} = PcGroup, n::Union{IntegerUnion,PosInf})

Return the dihedral group of order n, as an instance of T, where T is in {PcGroup,PermGroup,FPGroup}.

Warning

There are two competing conventions for interpreting the argument n: In the one we use, the returned group has order n, and thus n must always be even. In the other, n indicates that the group describes the symmetry of an n-gon, and thus the group has order 2n.

Examples

julia> dihedral_group(6)
-<pc group of size 6 with 2 generators>
-
-julia> dihedral_group(PermGroup, 6)
-Group([ (1,2,3), (2,3) ])
-
-julia> dihedral_group(PosInf())
-Pcp-group with orders [ 2, 0 ]
-
-julia> dihedral_group(7)
-ERROR: ArgumentError: n must be a positive even integer or infinity
source
quaternion_groupFunction
quaternion_group(::Type{T} = PcGroup, n::IntegerUnion)

Return the (generalized) quaternion group of order n, as an instance of T, where n is a power of 2 and T is in {PcGroup,PermGroup,FPGroup}.

Examples

julia> g = quaternion_group(8)
-<pc group of size 8 with 3 generators>
-
-julia> quaternion_group(PermGroup, 8)
-Group([ (1,5,3,7)(2,8,4,6), (1,2,3,4)(5,6,7,8) ])
-
-julia> g = quaternion_group(FPGroup, 8)
-<fp group of size 8 on the generators [ r, s ]>
-
-julia> relators(g)
-3-element Vector{FPGroupElem}:
- r^2*s^-2
- s^4
- r^-1*s*r*s
-
source
diff --git a/previews/PR2578/Groups/permgroup/index.html b/previews/PR2578/Groups/permgroup/index.html deleted file mode 100644 index c10e81df45f4..000000000000 --- a/previews/PR2578/Groups/permgroup/index.html +++ /dev/null @@ -1,383 +0,0 @@ - -Permutation groups · Oscar.jl

Permutation groups

Permutation groups can be defined as symmetric groups, alternating groups or their subgroups.

PermGroupType
PermGroup

Groups of permutations. Every group of this type is a subgroup of Sym(n) for some n.

Examples

  • symmetric_group(n::Int): the symmetric group Sym(n)
  • alternating_group(n::Int): the alternating group Alt(n)
  • subgroups of Sym(n)
  • dihedral_group(PermGroup, n::Int): the dihedral group of order n as a group of permutations. Same holds replacing dihedral_group by quaternion_group

If G is a permutation group and x is a permutation, G(x) returns a permutation x with parent G; an exception is thrown if x does not embed into G.

julia> G=symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> x=cperm([1,2,3])
-(1,2,3)
-
-julia> parent(x)
-Sym( [ 1 .. 3 ] )
-
-julia> y=G(x)
-(1,2,3)
-
-julia> parent(y)
-Sym( [ 1 .. 5 ] )

If G is a permutation group and x is a vector of integers, G(x) returns a PermGroupElem with parent G; an exception is thrown if the element does not embed into G.

Examples

julia> G = symmetric_group(6)
-Sym( [ 1 .. 6 ] )
-
-julia> x = G([2,4,6,1,3,5])
-(1,2,4)(3,6,5)
-
-julia> parent(x)
-Sym( [ 1 .. 6 ] )
source
PermGroupElemType
PermGroupElem

Element of a group of permutations. It is displayed as product of disjoint cycles.

Assumptions:

  • for x,y in Sym(n), the product xy is read from left to right;
  • for x in Sym(n) and i in {1,...,n}, i^x and x(i) return the image of i under the action of x.
source
symmetric_groupFunction
symmetric_group(n::Int)

Return the full symmetric group on the set {1, 2, ..., n}.

Examples

julia> G = symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> order(G)
-120
-
source
is_natural_symmetric_groupMethod
is_natural_symmetric_group(G::GAPGroup)

Return true if G is a permutation group acting as the symmetric group on its moved points, and false otherwise.

source
alternating_groupFunction
alternating_group(n::Int)

Return the full alternating group on the set {1, 2, ..., n}..

Examples

julia> G = alternating_group(5)
-Alt( [ 1 .. 5 ] )
-
-julia> order(G)
-60
-
source
is_natural_alternating_groupMethod
is_natural_alternating_group(G::GAPGroup)

Return true if G is a permutation group acting as the alternating group on its moved points, and false otherwise.

source
permutation_groupFunction
permutation_group(n::IntegerUnion, perms::Vector{PermGroupElem})

Return the permutation group of degree n that is generated by the elements in perms.

Examples

julia> x = cperm([1,2,3], [4,5]);  y = cperm([1,4]);
-
-julia> permutation_group(5, [x, y])
-Group([ (1,2,3)(4,5), (1,4) ])
source
@permutation_groupMacro
@permutation_group(n, gens...)

Input the permutation group of degree n with generators gens..., given by permutations in cycle notation.

Examples

julia> g = @permutation_group(7, (1,2), (1,2,3)(4,5))
-Group([ (1,2), (1,2,3)(4,5) ])
-
-julia> degree(g)
-7
source
projective_general_linear_groupFunction
projective_general_linear_group(n::Int, q::Int)

Return the factor group of general_linear_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.

Examples

julia> g = projective_general_linear_group(2, 3)
-Group([ (3,4), (1,2,4) ])
-
-julia> order(g)
-24
source
projective_special_linear_groupFunction
projective_special_linear_group(n::Int, q::Int)

Return the factor group of special_linear_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.

Examples

julia> g = projective_special_linear_group(2, 3)
-Group([ (2,3,4), (1,2)(3,4) ])
-
-julia> order(g)
-12
source
projective_symplectic_groupFunction
projective_symplectic_group(n::Int, q::Int)

Return the factor group of symplectic_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.

Examples

julia> g = projective_symplectic_group(2, 3)
-Group([ (2,3,4), (1,2)(3,4) ])
-
-julia> order(g)
-12
source
projective_orthogonal_groupFunction
projective_orthogonal_group(e::Int, n::Int, q::Int)

Return the factor group of orthogonal_group, called with the same parameters, by its scalar matrices.

As for orthogonal_group, e can be omitted if n is odd.

Examples

julia> g = projective_orthogonal_group(1, 4, 3);  order(g)
-576
-
-julia> g = projective_orthogonal_group(3, 3);  order(g)
-24
source
projective_special_orthogonal_groupFunction
projective_special_orthogonal_group(e::Int, n::Int, q::Int)

Return the factor group of special_orthogonal_group, called with the same parameters, by its scalar matrices.

As for special_orthogonal_group, e can be omitted if n is odd.

Examples

julia> g = projective_special_orthogonal_group(1, 4, 3);  order(g)
-288
-
-julia> g = projective_special_orthogonal_group(3, 3);  order(g)
-24
source
projective_omega_groupFunction
projective_omega_group(e::Int, n::Int, q::Int)

Return the factor group of omega_group, called with the same parameters, by its scalar matrices.

As for omega_group, e can be omitted if n is odd.

Examples

julia> g = projective_omega_group(1, 4, 3);  order(g)
-144
-
-julia> g = projective_omega_group(3, 3);  order(g)
-12
source
projective_unitary_groupFunction
projective_unitary_group(n::Int, q::Int)

Return the factor group of unitary_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.

Examples

julia> g = projective_unitary_group(2, 3)
-Group([ (3,4)(5,8)(6,9)(7,10), (1,2,6)(3,7,10)(4,8,5) ])
-
-julia> order(g)
-24
source
projective_special_unitary_groupFunction
projective_special_unitary_group(n::Int, q::Int)

Return the factor group of special_unitary_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.

Examples

julia> g = projective_special_unitary_group(2, 3)
-Group([ (2,9,6)(3,8,10)(4,7,5), (1,2)(5,10)(6,9)(7,8) ])
-
-julia> order(g)
-12
source

In OSCAR, every permutation group has a degree n, that corresponds to the size of the set on which G acts.

degreeMethod
degree(G::PermGroup) -> Int

Return the degree of G as a permutation group, that is, an integer n that is stored in G, with the following meaning.

  • G embeds into symmetric_group(n).
  • Two permutation groups of different degrees are regarded as not equal, even if they contain the same permutations.
  • Subgroups constructed with derived_subgroup, sylow_subgroup, etc., get the same degree as the given group.
  • The range 1:degree(G) is used as the default set of points on which G and its element acts.
Note

The degree of a group of permutations is not necessarily equal to the largest moved point of the group G. For example, the trivial subgroup of symmetric_group(n) has degree n even though it fixes n.

Examples

julia> degree(symmetric_group(4))
-4
-
-julia> t4 = trivial_subgroup(symmetric_group(4))[1];
-
-julia> degree(t4)
-4
-
-julia> t4 == trivial_subgroup(symmetric_group(5))[1]
-false
-
-julia> show(Vector(gen(symmetric_group(4), 2)))
-[2, 1, 3, 4]
-julia> show(Vector(gen(symmetric_group(5), 2)))
-[2, 1, 3, 4, 5]
source

Permutations

Permutations in OSCAR are displayed as products of disjoint cycles, as in GAP. An explicit permutation can be built using the functions perm, cperm, or @perm.

permFunction
perm(L::AbstractVector{<:IntegerUnion})

Return the permutation $x$ which maps every $i$ from 1 to $n$= length(L) to L$[i]$. The parent of $x$ is set to symmetric_group$(n)$. An exception is thrown if L does not contain every integer from 1 to $n$ exactly once.

The parent group of $x$ is set to symmetric_group$(n)$.

Examples

julia> x = perm([2,4,6,1,3,5])
-(1,2,4)(3,6,5)
-
-julia> parent(x)
-Sym( [ 1 .. 6 ] )
source
perm(G::PermGroup, L::AbstractVector{<:IntegerUnion})
-(G::PermGroup)(L::AbstractVector{<:IntegerUnion})

Return the permutation $x$ which maps every i from 1 to $n$= length(L) to L$[i]$. The parent of $x$ is G. An exception is thrown if $x$ is not contained in G or L does not contain every integer from 1 to $n$ exactly once.

Examples

julia> perm(symmetric_group(6),[2,4,6,1,3,5])
-(1,2,4)(3,6,5)

Equivalent permutations can be created using cperm and @perm

julia> x = perm(symmetric_group(8),[2,3,1,5,4,7,8,6])
-(1,2,3)(4,5)(6,7,8)
-
-julia> y = cperm([1,2,3],[4,5],[6,7,8])
-(1,2,3)(4,5)(6,7,8)
-
-julia> x == y
-true
-
-julia> z = @perm (1,2,3)(4,5)(6,7,8)
-(1,2,3)(4,5)(6,7,8)
-
-julia> x == z
-true
source
cpermFunction
cperm(L::AbstractVector{<:T}...) where T <: IntegerUnion
-cperm(G::PermGroup, L::AbstractVector{<:T}...)
-cperm(L::Vector{Vector{T}}) where T <: IntegerUnion
-cperm(g::PermGroup,L::Vector{Vector{T}}) where T <: IntegerUnion

For given lists $[a_1, a_2, \ldots, a_n], [b_1, b_2, \ldots , b_m], \ldots$ of positive integers, return the permutation $x = (a_1, a_2, \ldots, a_n) * (b_1, b_2, \ldots, b_m) * \ldots$. Arrays of the form [n, n+1, ..., n+k] can be replaced by n:n+k.

The parent of $x$ is G. If G is not specified then the parent of $x$ is set to symmetric_group$(n)$, where $n$ is the largest integer that occurs in an entry of L.

An exception is thrown if $x$ is not contained in G or one of the given vectors is empty or contains duplicates.

Examples

julia> cperm([1,2,3],4:7)
-(1,2,3)(4,5,6,7)
-
-julia> cperm([1,2],[2,3])
-(1,3,2)
-
-julia> cperm()
-()
-
-julia> p = cperm([1,2,3],[7])
-(1,2,3)
-
-julia> degree(p)
-7

Two permutations coincide if, and only if, they move the same points and their parent groups have the same degree.

julia> G=symmetric_group(5);
-
-julia> A=alternating_group(5);
-
-julia> x=cperm(G,[1,2,3]);
-
-julia> y=cperm(A,[1,2,3]);
-
-julia> z=cperm([1,2,3]); parent(z)
-Sym( [ 1 .. 3 ] )
-
-julia> x==y
-true
-
-julia> x==z
-false

In the example above, x and y are equal because both act on a set of cardinality 5, while x and z are different because x belongs to Sym(5) and z belongs to Sym(3).

cperm can also handle cycles passed in inside of a vector

julia> x = cperm([[1,2],[3,4]])
-(1,2)(3,4)
-
-julia> y = cperm([1,2],[3,4])
-(1,2)(3,4)
-
-julia> x == y
-true
julia> G=symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> x = cperm(G,[[1,2],[3,4]])
-(1,2)(3,4)
-
-julia> parent(x)
-Sym( [ 1 .. 5 ] )

Equivalent permutations can be created using perm and @perm:

julia> x = cperm([1,2,3],[4,5],[6,7,8])
-(1,2,3)(4,5)(6,7,8)
-
-julia> y = perm(symmetric_group(8),[2,3,1,5,4,7,8,6])
-(1,2,3)(4,5)(6,7,8)
-
-julia> x == y
-true
-
-julia> z = @perm (1,2,3)(4,5)(6,7,8)
-(1,2,3)(4,5)(6,7,8)
-
-julia> x == z
-true

At the moment, the input vectors of the function cperm need not be disjoint.

source
@permMacro
@perm ex

Input a permutation in cycle notation. Supports arbitrary expressions for generating the integer entries of the cycles. The parent group is inferred to be the symmetric group with a degree of the highest integer referenced in the permutation.

The actual work is done by cperm. Thus, for the time being, cycles which are not disjoint actually are supported.

Examples

julia> x = @perm (1,2,3)(4,5)(factorial(3),7,8)
-(1,2,3)(4,5)(6,7,8)
-
-julia> parent(x)
-Sym( [ 1 .. 8 ] )
-
-julia> y = cperm([1,2,3],[4,5],[6,7,8])
-(1,2,3)(4,5)(6,7,8)
-
-julia> x == y
-true
-
-julia> z = perm(symmetric_group(8),[2,3,1,5,4,7,8,6])
-(1,2,3)(4,5)(6,7,8)
-
-julia> x == z
-true
source
@perm n gens

Input a list of permutations in cycle notation, created as elements of the symmetric group of degree n, i.e., symmetric_group(n), by invoking cperm suitably.

Examples

julia> gens = @perm 14 [
-              (1,10)
-              (2,11)
-              (3,12)
-              (4,13)
-              (5,14)
-              (6,8)
-              (7,9)
-              (1,2,3,4,5,6,7)(8,9,10,11,12,13,14)
-              (1,2)(10,11)
-             ]
-9-element Vector{PermGroupElem}:
- (1,10)
- (2,11)
- (3,12)
- (4,13)
- (5,14)
- (6,8)
- (7,9)
- (1,2,3,4,5,6,7)(8,9,10,11,12,13,14)
- (1,2)(10,11)
- 
-julia> parent(gens[1])
-Sym( [ 1 .. 14 ] )
source

The function Vector{T} works in the opposite way with respect to perm:

VectorType
Vector{T}(x::PermGroupElem, n::Int = x.parent.deg) where T <: IntegerUnion
-Vector(x::PermGroupElem, n::Int = x.parent.deg)

Return the list of length n that contains x(i) at position i. If not specified, T is set as Int.

Examples

julia> pi = cperm(1:3)
-(1,2,3)
-julia> Vector(pi)
-3-element Vector{Int64}:
- 2
- 3
- 1
-julia> Vector(pi, 2)
-2-element Vector{Int64}:
- 2
- 3
-julia> Vector(pi, 4)
-4-element Vector{Int64}:
- 2
- 3
- 1
- 4
-julia> Vector{ZZRingElem}(pi, 2)
-2-element Vector{ZZRingElem}:
- 2
- 3
source

Operations on permutations

signMethod
sign(g::PermGroupElem) -> Int

Return the sign of the permutation g.

The sign of a permutation $g$ is defined as $(-1)^k$ where $k$ is the number of cycles of $g$ of even length.

Examples

julia> sign(cperm(1:2))
--1
-
-julia> sign(cperm(1:3))
-1
source
isoddMethod
isodd(g::PermGroupElem)

Return true if the permutation g is odd, false otherwise.

A permutation is odd if it has an odd number of cycles of even length. Equivalently, a permutation is odd if it has sign $-1$.

Examples

julia> isodd(cperm(1:2))
-true
-
-julia> isodd(cperm(1:3))
-false
-
-julia> isodd(cperm(1:2,3:4))
-false
source
isevenMethod
iseven(g::PermGroupElem)

Return true if the permutation g is even, false otherwise.

A permutation is even if it has an even number of cycles of even length. Equivalently, a permutation is even if it has sign $+1$.

Examples

julia> iseven(cperm(1:2))
-false
-
-julia> iseven(cperm(1:3))
-true
-
-julia> iseven(cperm(1:2,3:4))
-true
source
cycle_structureMethod
cycle_structure(g::PermGroupElem) -> CycleType

Return the cycle structure of the permutation g as a cycle type. A cycle type behaves similar to a vector of pairs k => n indicating that there are n cycles of length k.

Examples

julia> g = cperm(1:3, 4:5, 6:7, 8:10, 11:15)
-(1,2,3)(4,5)(6,7)(8,9,10)(11,12,13,14,15)
-
-julia> cycle_structure(g)
-3-element Oscar.CycleType:
- 2 => 2
- 3 => 2
- 5 => 1
-
-julia> g = cperm()
-()
-
-julia> cycle_structure(g)
-1-element Oscar.CycleType:
- 1 => 1
source

Permutations as functions

A permutation can be viewed as a function on the set {1,...,n}, hence it can be evaluated on integers.

Note

The multiplication between permutations works from the left to the right. So, if x and y are permutations and n is an integer, then (x*y)(n) = (y(x(n)), NOT x(y(n)). This works also if the argument is not in the range 1:n; in such a case, the output coincides with the input.

julia> x = cperm([1,2,3,4,5]);
-
-julia> x(2)
-3
-
-julia> x(6)
-6

Operations for permutation groups

cycle_structuresMethod
cycle_structures(G::PermGroup) -> Set{CycleType}

Return the set of cycle structures of elements in G, see cycle_structure.

Examples

julia> g = symmetric_group(3);
-
-julia> sort!(collect(cycle_structures(g)))
-3-element Vector{Oscar.CycleType}:
- [1 => 1, 2 => 1]
- [1 => 3]
- [3 => 1]
source
is_transitiveFunction
is_transitive(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))

Return whether G acts transitively on L, that is, L is an orbit of G.

Examples

julia> G = symmetric_group(6);
-
-julia> is_transitive(G)
-true
-
-julia> is_transitive(sylow_subgroup(G, 2)[1])
-false
-
-julia> is_transitive(stabilizer(G, 1)[1])
-false
-
source
transitivityFunction
transitivity(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))

Return the maximum k such that G acts k-transitively on L, that is, every k-tuple of points in L can be mapped simultaneously to every other k-tuple by an element of G.

The output is 0 if G acts intransitively on L, and an exception is thrown if G does not act on L.

Examples

julia> transitivity(mathieu_group(24))
-5
-
-julia> transitivity(symmetric_group(6))
-6
-
-julia> transitivity(symmetric_group(6), 1:7)
-0
-
-julia> transitivity(symmetric_group(6), 1:5)
-ERROR: ArgumentError: the group does not act
source
is_primitiveFunction
is_primitive(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))

Return whether the action of G on L is primitive, that is, the action is transitive and the point stabilizers are maximal in G.

Examples

julia> G = alternating_group(6);
-
-julia> mx = filter(is_transitive, maximal_subgroup_reps(G))
-3-element Vector{PermGroup}:
- Group([ (1,2)(3,4), (1,2)(5,6), (1,3,5)(2,4,6), (1,3)(2,4) ])
- Group([ (1,2,3), (4,5,6), (1,2)(4,5), (1,5,2,4)(3,6) ])
- PSL(2,5)
-
-julia> [(order(H), is_primitive(H)) for H in mx]
-3-element Vector{Tuple{ZZRingElem, Bool}}:
- (24, 0)
- (36, 0)
- (60, 1)
-
source
is_regularFunction
is_regular(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))

Return whether the action of G on L is regular (i.e., transitive and semiregular).

Examples

julia> G = symmetric_group(6);
-
-julia> H = sub(G, [G([2, 3, 4, 5, 6, 1])])[1]
-Group([ (1,2,3,4,5,6) ])
-
-julia> is_regular(H)
-true
-
-julia> is_regular(G)
-false
-
source
is_semiregularFunction
is_semiregular(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))

Return whether the action of G on L is semiregular (i.e., the stabilizer of each point is the identity).

Examples

julia> G = symmetric_group(6);
-
-julia> H = sub(G, [G([2, 3, 1, 5, 6, 4])])[1]
-Group([ (1,2,3)(4,5,6) ])
-
-julia> is_semiregular(H)
-true
-
-julia> is_regular(H)
-false
-
source
rank_actionFunction
rank_action(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))

Return the rank of the transitive action of G on L. This is defined as the number of G-orbits in the action on ordered pairs of points in L, and is equal to the number of orbits of the stabilizer of a point in L on L, see Peter J. Cameron (1999) Section 1.11.

An exception is thrown if G is not transitive on L.

Examples

julia> G = symmetric_group(4); rank_action(G)  # 4-transitive
-2
-
-julia> H = sylow_subgroup(G, 2)[1]
-Group([ (1,2), (3,4), (1,3)(2,4) ])
-
-julia> rank_action(H)  # not 2-transitive
-3
-
-julia> K = stabilizer(G, 1)[1]
-Group([ (2,4,3), (3,4) ])
-
-julia> rank_action(K, 2:4)  # 2-transitive
-2
-
-julia> rank_action(K, 3:5)
-ERROR: ArgumentError: the group is not transitive
source
blocksFunction
blocks(G::PermGroup, L::AbstractVector{Int} = moved_points(G))

Return a G-set that is a block system for the action of G on L, i.e., a non-trivial partition of L preserved by the action of G.

Here, L must be a subvector of 1:degree(G) on which G acts transitively. G may move points outside L, in this case the restriction of the action of the set stabilizer of L in G to L is considered.

An exception is thrown if this action is not transitive.

Examples

julia> g = sylow_subgroup(symmetric_group(4), 2)[1]
-Group([ (1,2), (3,4), (1,3)(2,4) ])
-
-julia> collect(blocks(g))
-2-element Vector{Vector{Int64}}:
- [1, 2]
- [3, 4]
-
source
maximal_blocksFunction
maximal_blocks(G::PermGroup, L::AbstractVector{Int} = moved_points(G))

Return a G-set that is a maximal block system for the action of G on L, i.e., a maximal non-trivial partition of L preserved by the action of G.

Here, L must be a subvector of 1:degree(G) on which G acts transitively. G may move points outside L, in this case the restriction of the action of the set stabilizer of L in G to L is considered.

An exception is thrown if this action is not transitive.

Examples

julia> G = transitive_group(8, 2)
-4[x]2
-
-julia> collect(maximal_blocks(G))
-2-element Vector{Vector{Int64}}:
- [1, 2, 3, 8]
- [4, 5, 6, 7]
-
source
minimal_block_repsFunction
minimal_block_reps(G::PermGroup, L::AbstractVector{Int} = moved_points(G))

Return a vector of block representatives for all minimal non-trivial block systems for the action of G on L.

Here, L must be a subvector of 1:degree(G) on which G acts transitively. G may move points outside L, in this case the restriction of the action of the set stabilizer of L in G to L is considered.

An exception is thrown if this action is not transitive.

Examples

julia> G = transitive_group(8, 2)
-4[x]2
-
-julia> minimal_block_reps(G)
-3-element Vector{Vector{Int64}}:
- [1, 3]
- [1, 5]
- [1, 7]
-
source
all_blocksMethod
all_blocks(G::PermGroup)

Return a vector of smallest representatives of all block systems for the action of G on the set of moved points of G.

Examples

julia> G = transitive_group(8, 2)
-4[x]2
-
-julia> all_blocks(G)
-6-element Vector{Vector{Int64}}:
- [1, 2, 3, 8]
- [1, 5]
- [1, 3, 5, 7]
- [1, 3]
- [1, 3, 4, 6]
- [1, 7]
-
source

Cycle structures

For a permutation, its cycle structure cycle_structure determines the degree, order, number of moved points, sign.

degreeMethod
degree(c::CycleType) -> Int

Return the degree of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> degree(cycle_structure(x)) == degree(g), gens(g))
-true
source
isevenMethod
iseven(c::CycleType) -> Bool

Return whether the permutations with cycle structure c are even.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> iseven(cycle_structure(x)) == iseven(x), gens(g))
-true
source
isoddMethod
isodd(c::CycleType) -> Bool

Return whether the permutations with cycle structure c are odd.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> isodd(cycle_structure(x)) == isodd(x), gens(g))
-true
source
orderMethod
order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion

Return the order of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> order(cycle_structure(x)) == order(x), gens(g))
-true
source
signMethod
sign(c::CycleType) -> Int

Return the sign of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> sign(cycle_structure(x)) == sign(x), gens(g))
-true
source
diff --git a/previews/PR2578/Groups/products/index.html b/previews/PR2578/Groups/products/index.html deleted file mode 100644 index 7c50f55e9f5f..000000000000 --- a/previews/PR2578/Groups/products/index.html +++ /dev/null @@ -1,151 +0,0 @@ - -Products of groups · Oscar.jl

Products of groups

Direct products

DirectProductGroupType
DirectProductGroup

Either direct product of two or more groups of any type, or subgroup of a direct product of groups.

source
direct_productMethod
direct_product(L::AbstractVector{<:GAPGroup}; morphisms)
-direct_product(L::GAPGroup...)

Return the direct product of the groups in the collection L.

The keyword argument morphisms is false by default. If it is set true, then the output is a triple (G, emb, proj), where emb and proj are the vectors of the embeddings (resp. projections) of the direct product G.

Examples

julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> K = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> G = direct_product(H,K)
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-
-julia> elements(G)
-12-element Vector{Oscar.BasicGAPGroupElem{DirectProductGroup}}:
- ()
- (4,5)
- (2,3)
- (2,3)(4,5)
- (1,2)
- (1,2)(4,5)
- (1,2,3)
- (1,2,3)(4,5)
- (1,3,2)
- (1,3,2)(4,5)
- (1,3)
- (1,3)(4,5)
source
inner_direct_productMethod
inner_direct_product(L::AbstractVector{T}; morphisms)
-inner_direct_product(L::T...)

Return a direct product of groups of the same type T as a group of type T. It works for T of the following types:

  • PermGroup, PcGroup, FPGroup.

The keyword argument morphisms is false by default. If it is set true, then the output is a triple (G, emb, proj), where emb and proj are the vectors of the embeddings (resp. projections) of the direct product G.

source
cartesian_powerMethod
cartesian_power(G::GAPGroup, n::Int)

Return the direct product of n copies of G.

source
inner_cartesian_powerMethod
inner_cartesian_power(G::T, n::Int; morphisms)

Return the direct product of n copies of G as group of type T.

The keyword argument morphisms is false by default. If it is set true, then the output is a triple (G, emb, proj), where emb and proj are the vectors of the embeddings (resp. projections) of the direct product G.

source
as_perm_groupMethod
as_perm_group(G::DirectProductGroup)

If G is direct product of permutations groups, return G as permutation group.

Examples

julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> K = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> G = direct_product(H,K)
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-
-julia> as_perm_group(G)
-Group([ (1,2,3), (1,2), (4,5) ])
source
as_polycyclic_groupMethod
as_polycyclic_group(G::DirectProductGroup)

If G is direct product of polycyclic groups, return G as polycyclic group.

source
embeddingMethod
embedding(G::DirectProductGroup, j::Int)

Return the embedding of the j-th component of G into G, for j = 1,...,#factors of G.

Examples

julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> K = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> G = direct_product(H,K)
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-
-julia> emb1 = embedding(G,1)
-Group homomorphism from
-Sym( [ 1 .. 3 ] )
-to
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-
-julia> h = perm(H,[2,3,1])
-(1,2,3)
-
-julia> emb1(h)
-(1,2,3)
-
-julia> emb2 = embedding(G,2)
-Group homomorphism from
-Sym( [ 1 .. 2 ] )
-to
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-
-julia> k = perm(K,[2,1])
-(1,2)
-
-julia> emb2(k)
-(4,5)
-
-julia> emb1(h)*emb2(k)
-(1,2,3)(4,5)
source
projectionMethod
projection(G::DirectProductGroup, j::Int)

Return the projection of G into the j-th component of G, for j = 1,...,#factors of G.

Examples

julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> K = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> G = direct_product(H,K)
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-
-julia> proj1 = projection(G,1)
-Group homomorphism from
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-to
-Sym( [ 1 .. 3 ] )
-
-julia> proj2 = projection(G,2)
-Group homomorphism from
-DirectProduct of
- Sym( [ 1 .. 3 ] )
- Sym( [ 1 .. 2 ] )
-to
-Sym( [ 1 .. 2 ] )
-
-julia> g = perm([2,3,1,5,4])
-(1,2,3)(4,5)
-
-julia> proj1(g)
-(1,2,3)
-
-julia> proj2(g)
-(1,2)
source
write_as_fullMethod
write_as_full(G::DirectProductGroup)

If G is a subgroup of the direct product $G_1 \times G_2 \times \cdots \times G_n$ such that G has the form $H_1 \times H_2 \times \cdots \times H_n$, for subgroups $H_i$ of $G_i$, return this full direct product of the $H_i$.

An exception is thrown if such $H_i$ do not exist.

source
is_full_direct_productMethod
is_full_direct_product(G::DirectProductGroup)

Return whether G is direct product of its factors (false if it is a proper subgroup).

source

Semidirect products

SemidirectProductGroupType
SemidirectProductGroup{S,T}

Semidirect product of two groups of type S and T respectively, or subgroup of a semidirect product of groups.

source
semidirect_productMethod
semidirect_product(N::S, f::GAPGroupHomomorphism, H::T)

Return the semidirect product of N and H, of type SemidirectProductGroup{S,T}, where f is a group homomorphism from H to the automorphism group of N.

source
normal_subgroupMethod
normal_subgroup(G::SemidirectProductGroup)

Return N, where G is the semidirect product of the normal subgroup N and H.

source
acting_subgroupMethod
acting_subgroup(G::SemidirectProductGroup)

Return H, where G is the semidirect product of the normal subgroup N and H.

source
homomorphism_of_semidirect_productMethod
homomorphism_of_semidirect_product(G::SemidirectProductGroup)

Return f, where G is the semidirect product of the normal subgroup N and the group H acting on N via the homomorphism h.

source
is_full_semidirect_productMethod
is_full_semidirect_product(G::SemidirectProductGroup)

Return whether G is a semidirect product of two groups, instead of a proper subgroup.

source
embeddingMethod
embedding(G::SemidirectProductGroup, n::Int)

Return the embedding of the n-th component of G into G, for n = 1,2. It is not defined for proper subgroups of semidirect products.

source
projectionMethod
projection(G::SemidirectProductGroup)

Return the projection of G into the second component of G.

source

Wreath products

WreathProductGroupType
WreathProductGroup

Wreath product of a group G and a group of permutations H, or a generic group H together with the homomorphism a from H to a permutation group.

source
wreath_productMethod
wreath_product(G::T, H::S, a::GAPGroupHomomorphism{S,PermGroup})
-wreath_product(G::T, H::PermGroup) where T<: Group

Return the wreath product of the group G and the group H, where H acts on n copies of G through the homomorphism a from H to a permutation group, and n is the number of moved points of Image(a).

If a is not specified, then H must be a group of permutations. In this case, n is NOT the number of moved points, but the degree of H.

If W is a wreath product of G and H, {g_1, ..., g_n} are elements of G and h in H, the element (g_1, ..., h) of W can be obtained by typing

    W(g_1,...,g_n, h).

Examples

julia> G = cyclic_group(3)
-<pc group of size 3 with 1 generator>
-
-julia> H = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> W = wreath_product(G,H)
-<group of size 18 with 2 generators>
-
-julia> a = gen(W,1)
-WreathProductElement(f1,<identity> of ...,())
-
-julia> b = gen(W,2)
-WreathProductElement(<identity> of ...,<identity> of ...,(1,2))
-
-julia> a*b
-WreathProductElement(f1,<identity> of ...,(1,2))
source
normal_subgroupMethod
normal_subgroup(W::WreathProductGroup)

Return G, where W is the wreath product of G and H.

Examples

julia> G = cyclic_group(3)
-<pc group of size 3 with 1 generator>
-
-julia> H = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> W = wreath_product(G,H)
-<group of size 18 with 2 generators>
-
-julia> normal_subgroup(W)
-<pc group of size 3 with 1 generator>
source
acting_subgroupMethod
acting_subgroup(W::WreathProductGroup)

Return H, where W is the wreath product of G and H.

Examples

julia> G = cyclic_group(3)
-<pc group of size 3 with 1 generator>
-
-julia> H = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> W = wreath_product(G,H)
-<group of size 18 with 2 generators>
-
-julia> acting_subgroup(W)
-Sym( [ 1 .. 2 ] )
source
homomorphism_of_wreath_productMethod
homomorphism_of_wreath_product(G::WreathProductGroup)

If W is the wreath product of G and H, then return the homomorphism f from H to Sym(n), where n is the number of copies of G.

source
is_full_wreath_productMethod
is_full_wreath_product(G::WreathProductGroup)

Return whether G is a wreath product of two groups, instead of a proper subgroup.

source
projectionMethod
projection(G::WreathProductGroup)

Return the projection of wreath_product(G,H) onto the permutation group H.

source
embeddingMethod
embedding(G::WreathProductGroup, n::Int)

Return the embedding of the n-th component of G into G.

source
diff --git a/previews/PR2578/Groups/quotients/index.html b/previews/PR2578/Groups/quotients/index.html deleted file mode 100644 index f3b8ef1a8b6e..000000000000 --- a/previews/PR2578/Groups/quotients/index.html +++ /dev/null @@ -1,38 +0,0 @@ - -Quotients · Oscar.jl

Quotients

Quotient groups in OSCAR can be defined using the instruction quo in two ways.

  • Quotients by normal subgroups.
quoMethod
quo([::Type{Q}, ]G::T, N::T) where {Q <: GAPGroup, T <: GAPGroup}

Return the quotient group G/N, together with the projection G -> G/N.

If Q is given then G/N has type Q if possible, and an exception is thrown if not.

If Q is not given then the type of G/N is not determined by the type of G.

  • G/N may have the same type as G (which is reasonable if N is trivial),
  • G/N may have type PcGroup (which is reasonable if G/N is finite and solvable), or
  • G/N may have type PermGroup (which is reasonable if G/N is finite and non-solvable).
  • G/N may have type FPGroup (which is reasonable if G/N is infinite).

An exception is thrown if N is not a normal subgroup of G.

Examples

julia> G = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> N = pcore(G, 2)[1];
-
-julia> typeof(quo(G, N)[1])
-PcGroup
-
-julia> typeof(quo(PermGroup, G, N)[1])
-PermGroup
source
  • Quotients by elements.
quoMethod
quo([::Type{Q}, ]G::T, elements::Vector{elem_type(G)})) where {Q <: GAPGroup, T <: GAPGroup}

Return the quotient group G/N, together with the projection G -> G/N, where N is the normal closure of elements in G.

See quo(G::T, N::T) where T <: GAPGroup for information about the type of G/N.

source

This is the typical way to build finitely presented groups.

Example:

julia> F=free_group(2);
-
-julia> (f1,f2)=gens(F);
-
-julia> G,_=quo(F,[f1^2,f2^3,(f1*f2)^2]);
-
-julia> is_finite(G)
-true
-
-julia> is_isomorphic(G,symmetric_group(3))
-true

Similarly to the subgroups, the output consists of a pair (Q,p), where Q is the quotient group and p is the projection homomorphism of G into Q.

maximal_abelian_quotientFunction
maximal_abelian_quotient([::Type{Q}, ]G::GAPGroup) where Q <: Union{GAPGroup, GrpAbFinGen}

Return F, epi such that F is the largest abelian factor group of G and epi is an epimorphism from G to F.

If Q is given then F has type Q if possible, and an exception is thrown if not.

If Q is not given then the type of F is not determined by the type of G.

  • F may have the same type as G (which is reasonable if G is abelian),
  • F may have type PcGroup (which is reasonable if F is finite), or
  • F may have type FPGroup (which is reasonable if F is infinite).

Examples

julia> G = symmetric_group(4);
-
-julia> F, epi = maximal_abelian_quotient(G);
-
-julia> order(F)
-2
-
-julia> domain(epi) === G && codomain(epi) === F
-true
-
-julia> typeof(F)
-PcGroup
-
-julia> typeof(maximal_abelian_quotient(free_group(1))[1])
-FPGroup
-
-julia> typeof(maximal_abelian_quotient(PermGroup, G)[1])
-PermGroup
source
diff --git a/previews/PR2578/Groups/subgroups/index.html b/previews/PR2578/Groups/subgroups/index.html deleted file mode 100644 index 4ca994e07ce6..000000000000 --- a/previews/PR2578/Groups/subgroups/index.html +++ /dev/null @@ -1,284 +0,0 @@ - -Subgroups · Oscar.jl

Subgroups

The following functions are available in OSCAR for subgroup properties:

subMethod
sub(G::GAPGroup, gens::AbstractVector{<:GAPGroupElem}; check::Bool = true)
-sub(gens::GAPGroupElem...)

Return two objects: a group H, that is the subgroup of G generated by the elements x,y,..., and the embedding homomorphism of H into G. The object H has the same type of G, and it has no memory of the "parent" group G: it is an independent group.

If check is set to false then it is not checked whether each element of gens is an element of G.

Examples

julia> G = symmetric_group(4); H, _ = sub(G,[cperm([1,2,3]),cperm([2,3,4])]);
-
-julia> H == alternating_group(4)
-true
source
is_subsetMethod
is_subset(H::T, G::T) where T <: GAPGroup

Return true if H is a subset of G, otherwise return false.

Examples

julia> g = symmetric_group(300); h = derived_subgroup(g)[1];
-
-julia> is_subset(h, g)
-true
-
-julia> is_subset(g, h)
-false
source
embeddingMethod
embedding(H::T, G::T) where T <: GAPGroup

Return the embedding morphism of H into G. An exception is thrown if H is not a subgroup of G.

source
indexMethod
index(::Type{I} = ZZRingElem, G::T, H::T) where I <: IntegerUnion where T <: Union{GAPGroup, GrpAbFinGen}

Return the index of H in G, as an instance of I.

source
is_maximal_subgroupMethod
is_maximal_subgroup(H::T, G::T; check::Bool = true) where T <: GAPGroup

Return whether H is a maximal subgroup of G, i. e., whether H is a proper subgroup of G and there is no proper subgroup of G that properly contains H.

If check is set to false then it is not checked whether H is a subgroup of G. If check is not set to false then an exception is thrown if H is not a subgroup of G.

Examples

julia> G = symmetric_group(4);
-
-julia> is_maximal_subgroup(sylow_subgroup(G, 2)[1], G)
-true
-
-julia> is_maximal_subgroup(sylow_subgroup(G, 3)[1], G)
-false
-
-julia> is_maximal_subgroup(sylow_subgroup(G, 3)[1], sylow_subgroup(G, 2)[1])
-ERROR: ArgumentError: H is not a subgroup of G
source
is_normalized_byMethod
is_normalized_by(H::T, G::T) where T <: GAPGroup

Return whether the group H is normalized by G, i.e., whether H is invariant under conjugation with elements of G.

Note that H need not be a subgroup of G. To test whether H is a normal subgroup of G, use is_normal_subgroup.

Examples

julia> G = symmetric_group(4);
-
-julia> is_normalized_by(sylow_subgroup(G, 2)[1], G)
-false
-
-julia> is_normalized_by(derived_subgroup(G)[1], G)
-true
-
-julia> is_normalized_by(derived_subgroup(G)[1], sylow_subgroup(G, 2)[1])
-true
source
is_normal_subgroupMethod
is_normal_subgroup(H::T, G::T) where T <: GAPGroup

Return whether the group H is a normal subgroup of G, i.e., whether H is a subgroup of G that is invariant under conjugation with elements of G.

(See is_normalized_by for an invariance check only.)

Examples

julia> G = symmetric_group(4);
-
-julia> is_normal_subgroup(sylow_subgroup(G, 2)[1], G)
-false
-
-julia> is_normal_subgroup(derived_subgroup(G)[1], G)
-true
-
-julia> is_normal_subgroup(derived_subgroup(G)[1], sylow_subgroup(G, 2)[1])
-false
source
is_characteristic_subgroupMethod
is_characteristic_subgroup(H::T, G::T; check::Bool = true) where T <: GAPGroup

Return whether the subgroup H of G is characteristic in G, i.e., H is invariant under all automorphisms of G.

If check is set to false then it is not checked whether H is a subgroup of G. If check is not set to false then an exception is thrown if H is not a subgroup of G.

Examples

julia> G = symmetric_group(4);
-
-julia> is_characteristic_subgroup(derived_subgroup(G)[1], G)
-true
-
-julia> is_characteristic_subgroup(sylow_subgroup(G, 3)[1], G)
-false
-
-julia> is_characteristic_subgroup(sylow_subgroup(G, 3)[1], sylow_subgroup(G, 2)[1])
-ERROR: ArgumentError: H is not a subgroup of G
source

Standard subgroups

The following functions are available in OSCAR to obtain standard subgroups of a group G. Every such function returns a tuple (H,f), where H is a group of the same type of G and f is the embedding homomorphism of H into G.

trivial_subgroupFunction
trivial_subgroup(G::GAPGroup)

Return the trivial subgroup of G, together with its embedding morphism into G.

source
centerMethod
center(G::Group)

Return the center of G, i.e., the subgroup of all $x$ in G such that $x y$ equals $y x$ for every $y$ in G, together with its embedding morphism into G.

source
sylow_subgroupMethod
sylow_subgroup(G::Group, p::IntegerUnion)

Return a Sylow p-subgroup of the finite group G, for a prime p. This is a subgroup of p-power order in G whose index in G is coprime to p.

Examples

julia> g = symmetric_group(4); order(g)
-24
-
-julia> s = sylow_subgroup(g, 2); order(s[1])
-8
-
-julia> s = sylow_subgroup(g, 3); order(s[1])
-3
-
source
derived_subgroupFunction
derived_subgroup(G::GAPGroup)

Return the derived subgroup of G, i.e., the subgroup generated by all commutators of G.

source
fitting_subgroupFunction
fitting_subgroup(G::GAPGroup)

Return the Fitting subgroup of G, i.e., the largest nilpotent normal subgroup of G.

source
frattini_subgroupFunction
frattini_subgroup(G::GAPGroup)

Return the Frattini subgroup of G, i.e., the intersection of all maximal subgroups of G.

source
solvable_radicalFunction
solvable_radical(G::GAPGroup)

Return the solvable radical of G, i.e., the largest solvable normal subgroup of G.

source
pcoreMethod
pcore(G::Group, p::IntegerUnion)

Return C, f, where C is the p-core (i.e. the largest normal p-subgroup) of G and f is the embedding morphism of C into G.

source
intersectMethod
intersect(V::T...) where T <: Group
-intersect(V::AbstractVector{T}) where T <: Group

If V is $[ G_1, G_2, \ldots, G_n ]$, return the intersection $K$ of the groups $G_1, G_2, \ldots, G_n$, together with the embeddings of $K into $G_i$.

source

The following functions return a vector of subgroups.

subgroupsMethod
subgroups(G::Group)

Return the vector of all subgroups of G.

source
maximal_normal_subgroupsFunction
maximal_normal_subgroups(G::Group)

Return the vector of maximal normal subgroups of G, i.e., of those proper normal subgroups of G that are maximal among the proper normal subgroups.

source
minimal_normal_subgroupsFunction
minimal_normal_subgroups(G::Group)

Return the vector of minimal normal subgroups of G, i.e., of those nontrivial normal subgroups of G that are minimal among the nontrivial normal subgroups.

source
characteristic_subgroupsFunction
characteristic_subgroups(G::Group)

Return the list of characteristic subgroups of G, i.e., those subgroups that are invariant under all automorphisms of G.

source
derived_seriesFunction
derived_series(G::GAPGroup)

Return the vector $[ G_1, G_2, \ldots ]$, where $G_1 =$ G and $G_{i+1} =$ derived_subgroup$(G_i)$.

source
sylow_systemFunction
sylow_system(G::Group)

Return a vector of Sylow $p$-subgroups of the finite group G, where $p$ runs over the prime factors of the order of G, such that every two such subgroups commute with each other (as subgroups).

Sylow systems exist only for solvable groups, an exception is thrown if G is not solvable.

source
hall_subgroup_repsFunction
hall_subgroup_reps(G::Group, P::AbstractVector{<:IntegerUnion})

Return a vector that contains representatives of conjugacy classes of Hall P-subgroups of the finite group G, for a vector P of primes. A Hall P-subgroup of G is a subgroup the order of which is only divisible by primes in P and whose index in G is coprime to all primes in P.

For solvable G, Hall P-subgroups exist and are unique up to conjugacy. For nonsolvable G, Hall P-subgroups may not exist or may not be unique up to conjugacy.

Examples

julia> g = dihedral_group(30);
-
-julia> h = hall_subgroup_reps(g, [2, 3]);
-
-julia> (length(h), order(h[1]))
-(1, 6)
-
-julia> g = GL(3, 2)
-GL(3,2)
-
-julia> h = hall_subgroup_reps(g, [2, 3]);
-
-julia> (length(h), order(h[1]))
-(2, 24)
-
-julia> h = hall_subgroup_reps(g, [2, 7]); length(h)
-0
-
source
hall_systemFunction
hall_system(G::Group)

Return a vector of Hall $P$-subgroups of the finite group G, where $P$ runs over the subsets of prime factors of the order of G.

Hall systems exist only for solvable groups, an exception is thrown if G is not solvable.

source
complement_class_repsFunction
complement_class_reps(G::T, N::T) where T <: GAPGroup

Return a vector of representatives of the conjugacy classes of complements of the normal subgroup N in G. This function may throw an error exception if both N and G/N are nonsolvable.

A complement is a subgroup of G which intersects trivially with N and together with N generates G.

Examples

julia> G = symmetric_group(3);
-
-julia> complement_class_reps(G, derived_subgroup(G)[1])
-1-element Vector{PermGroup}:
- Group([ (2,3) ])
-
-julia> G = dihedral_group(8)
-<pc group of size 8 with 3 generators>
-
-julia> complement_class_reps(G, center(G)[1])
-PcGroup[]
source
complement_systemFunction
complement_system(G::Group)

Return a vector of Hall $p'$-subgroups of the finite group G, where $p$ runs over the prime factors of the order of G.

Complement systems exist only for solvable groups, an exception is thrown if G is not solvable.

source
Note

When a function returns a vector of subgroups, the output consists in the subgroups only; the embeddings are not returned as well. To get the embedding homomorphism of the subgroup H in G, one can type embedding(G,H).

Conjugation action of elements and subgroups

is_conjugateMethod
is_conjugate(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem)

Return whether x and y are conjugate elements in G, i.e., there is an element $z$ in G such that x^$z$ equals y.

source
is_conjugateMethod
is_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup)

Return whether H and K are conjugate subgroups in G.

Examples

julia> G = symmetric_group(4);
-
-julia> H = sub(G, [G([2, 1, 3, 4])])[1]
-Group([ (1,2) ])
-
-julia> K = sub(G, [G([1, 2, 4, 3])])[1]
-Group([ (3,4) ])
-
-julia> is_conjugate(G, H, K)
-true
-
-julia> K = sub(G, [G([2, 1, 4, 3])])[1]
-Group([ (1,2)(3,4) ])
-
-julia> is_conjugate(G, H, K)
-false
-
source
is_conjugate_with_dataMethod
is_conjugate_with_data(G::Group, x::GAPGroupElem, y::GAPGroupElem)

If x and y are conjugate in G, return (true, z), where x^z == y holds; otherwise, return (false, nothing).

source
is_conjugate_with_dataMethod
is_conjugate_with_data(G::Group, H::Group, K::Group)

If H and K are conjugate subgroups in G, return true, z where H^z = K; otherwise, return false, nothing.

Examples

julia> G = symmetric_group(4);
-
-julia> H = sub(G, [G([2, 1, 3, 4])])[1]
-Group([ (1,2) ])
-
-julia> K = sub(G, [G([1, 2, 4, 3])])[1]
-Group([ (3,4) ])
-
-julia> is_conjugate_with_data(G, H, K)
-(true, (1,3)(2,4))
-
-julia> K = sub(G, [G([2, 1, 4, 3])])[1]
-Group([ (1,2)(3,4) ])
-
-julia> is_conjugate_with_data(G, H, K)
-(false, nothing)
-
source
centralizerMethod
centralizer(G::Group, x::GroupElem)

Return the centralizer of x in G, i.e., the subgroup of all $g$ in G such that $g$ x equals x $g$, together with its embedding morphism into G.

source
centralizerMethod
centralizer(G::Group, H::Group)

Return the centralizer of H in G, i.e., the subgroup of all $g$ in G such that $g h$ equals $h g$ for every $h$ in H, together with its embedding morphism into G.

source
normalizerMethod
normalizer(G::Group, x::GAPGroupElem)

Return N, f, where N is the normalizer of the cyclic subgroup generated by x in G and f is the embedding morphism of N into G.

source
normalizerMethod
normalizer(G::Group, H::Group)

Return N, f, where N is the normalizer of H in G, i.e., the largest subgroup of G in which H is normal, and f is the embedding morphism of N into G.

source
coreMethod
core(G::Group, H::Group)

Return C, f, where C is the normal core of H in G, that is, the largest normal subgroup of G that is contained in H, and f is the embedding morphism of C into G.

source
normal_closureMethod
normal_closure(G::Group, H::Group)

Return N, f, where N is the normal closure of H in G, that is, the smallest normal subgroup of G that contains H, and f is the embedding morphism of N into G.

Note that H must be a subgroup of G.

source
GroupConjClassType
GroupConjClass{T, S}

It can be either the conjugacy class of an element or of a subgroup of type S in a group G of type T. It is displayed as

     cc = x ^ G

where G is a group and x = representative(cc) is either an element or a subgroup of G.

source
representativeMethod
representative(C::GroupConjClass)

Return a representative of the conjugacy class C.

Examples

julia> G = symmetric_group(4);
-
-julia> C = conjugacy_class(G, G([2, 1, 3, 4]))
-(1,2) ^ Sym( [ 1 .. 4 ] )
-
-julia> representative(C)
-(1,2)
-
source
acting_groupMethod
acting_group(C::GroupConjClass)

Return the acting group of C.

Examples

julia> G = symmetric_group(4);
-
-julia> C = conjugacy_class(G, G([2, 1, 3, 4]))
-(1,2) ^ Sym( [ 1 .. 4 ] )
-
-julia> acting_group(C) === G
-true
-
source
conjugacy_classMethod
conjugacy_class(G::Group, g::GAPGroupElem) -> GroupConjClass

Return the conjugacy class cc of g in G, where g = representative(cc).

Examples

julia> G = symmetric_group(4);
-
-julia> C = conjugacy_class(G, G([2, 1, 3, 4]))
-(1,2) ^ Sym( [ 1 .. 4 ] )
-
source
conjugacy_classMethod
conjugacy_class(G::T, H::T) where T<:Group -> GroupConjClass

Return the subgroup conjugacy class cc of H in G, where H = representative(cc).

source
conjugacy_classesMethod
conjugacy_classes(G::Group)

Return the vector of all conjugacy classes of elements in G. It is guaranteed that the class of the identity is in the first position.

source
conjugacy_classes_subgroupsMethod
conjugacy_classes_subgroups(G::Group)

Return the vector of all conjugacy classes of subgroups of G.

Examples

julia> G = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> conjugacy_classes_subgroups(G)
-4-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:
- Group(()) ^ Sym( [ 1 .. 3 ] )
- Group([ (2,3) ]) ^ Sym( [ 1 .. 3 ] )
- Group([ (1,2,3) ]) ^ Sym( [ 1 .. 3 ] )
- Group([ (1,2,3), (2,3) ]) ^ Sym( [ 1 .. 3 ] )
-
source
conjugacy_classes_maximal_subgroupsMethod
conjugacy_classes_maximal_subgroups(G::Group)

Return the vector of all conjugacy classes of maximal subgroups of G.

Examples

julia> G = symmetric_group(3);
-
-julia> conjugacy_classes_maximal_subgroups(G)
-2-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:
- Group([ (1,2,3) ]) ^ Sym( [ 1 .. 3 ] )
- Group([ (2,3) ]) ^ Sym( [ 1 .. 3 ] )
-
source

Cosets (left/right/double)

GroupCosetType
GroupCoset{T<: Group, S <: GAPGroupElem}

Type of group cosets. It is displayed as H * x (right cosets) or x * H (left cosets), where H is a subgroup of a group G and x is an element of G. Two cosets are equal if, and only if, they are both left (resp. right) and they contain the same elements.

source
right_cosetMethod
right_coset(H::Group, g::GAPGroupElem)
-*(H::Group, g::GAPGroupElem)

Return the coset Hg.

Examples

julia> G = symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
source
left_cosetMethod
left_coset(H::Group, g::GAPGroupElem)
-*(g::GAPGroupElem, H::Group)

Return the coset gH.

Note

Since GAP supports right cosets only, the underlying GAP object of left_coset(H,g) is the right coset H^(g^-1) * g.

Examples

julia> g = perm([3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> gH = left_coset(H,g)
-Left coset   (1,3)(2,4,5) * Sym( [ 1 .. 3 ] )
source
is_rightMethod
is_right(c::GroupCoset)

Return whether the coset c is a right coset of its acting domain.

source
is_leftMethod
is_left(c::GroupCoset)

Return whether the coset c is a left coset of its acting domain.

source
is_bicosetMethod
is_bicoset(C::GroupCoset)

Return whether C is simultaneously a right coset and a left coset for the same subgroup H. This is the case if and only if the coset representative normalizes the acting domain subgroup.

Examples

julia> G = symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> H = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> gH = left_coset(H,g)
-Left coset   (1,3)(2,4,5) * Sym( [ 1 .. 4 ] )
-
-julia> is_bicoset(gH)
-false
-
-julia> f = perm(G,[2,1,4,3,5])
-(1,2)(3,4)
-
-julia> fH = left_coset(H,f)
-Left coset   (1,2)(3,4) * Sym( [ 1 .. 4 ] )
-
-julia> is_bicoset(fH)
-true
source
acting_domainMethod
acting_domain(C::GroupCoset)

If C = Hx or xH, return H.

Examples

julia> G = symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> gH = left_coset(H,g)
-Left coset   (1,3)(2,4,5) * Sym( [ 1 .. 3 ] )
-
-julia> acting_domain(gH)
-Sym( [ 1 .. 3 ] )
source
representativeMethod
representative(C::GroupCoset)

If C = Hx or xH, return x.

Examples

julia> G = symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> gH = left_coset(H,g)
-Left coset   (1,3)(2,4,5) * Sym( [ 1 .. 3 ] )
-
-julia> representative(gH)
-(1,3)(2,4,5)
source
right_cosetsMethod
right_cosets(G::T, H::T; check::Bool=true) where T<: GAPGroup

Return the vector of the right cosets of H in G.

If check == false, do not check whether H is a subgroup of G.

Examples

julia> G = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> right_cosets(G,H)
-4-element Vector{GroupCoset{PermGroup, PermGroupElem}}:
- Right coset   Sym( [ 1 .. 3 ] ) * ()
- Right coset   Sym( [ 1 .. 3 ] ) * (1,4)
- Right coset   Sym( [ 1 .. 3 ] ) * (1,4,2)
- Right coset   Sym( [ 1 .. 3 ] ) * (1,4,3)
source
left_cosetsMethod
left_cosets(G::T, H::T; check::Bool=true) where T<: GAPGroup

Return the vector of the left cosets of H in G.

If check == false, do not check whether H is a subgroup of G.

Examples

julia> G = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> left_cosets(G,H)
-4-element Vector{GroupCoset{PermGroup, PermGroupElem}}:
- Left coset   () * Sym( [ 1 .. 3 ] )
- Left coset   (1,4) * Sym( [ 1 .. 3 ] )
- Left coset   (1,2,4) * Sym( [ 1 .. 3 ] )
- Left coset   (1,3,4) * Sym( [ 1 .. 3 ] )
source
right_transversalMethod
right_transversal(G::T, H::T; check::Bool=true) where T<: GAPGroup

Return a vector containing a complete set of representatives for the right cosets of H in G.

If check == false, do not check whether H is a subgroup of G.

Examples

julia> G = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> right_transversal(G,H)
-4-element Vector{PermGroupElem}:
- ()
- (1,4)
- (1,4,2)
- (1,4,3)
source
left_transversalMethod
left_transversal(G::T, H::T; check::Bool=true) where T<: Group

Return a vector containing a complete set of representatives for the left cosets for H in G.

If check == false, do not check whether H is a subgroup of G.

Examples

julia> G = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> left_transversal(G,H)
-4-element Vector{PermGroupElem}:
- ()
- (1,4)
- (1,2,4)
- (1,3,4)
source
GroupDoubleCosetType
GroupDoubleCoset{T<: Group, S <: GAPGroupElem}

Group double coset. It is displayed as H * x * K, where H and K are subgroups of a group G and x is an element of G. Two double cosets are equal if, and only if, they contain the same elements.

source
double_cosetMethod
double_coset(H::Group, x::GAPGroupElem, K::Group)
-*(H::Group, x::GAPGroupElem, K::Group)

Return the double coset HxK.

Examples

julia> G = symmetric_group(5)
-Sym( [ 1 .. 5 ] )
-
-julia> g = perm(G,[3,4,5,1,2])
-(1,3,5,2,4)
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> K = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> double_coset(H,g,K)
-Sym( [ 1 .. 3 ] ) * (1,3,5,2,4) * Sym( [ 1 .. 2 ] )
source
double_cosetsMethod
double_cosets(G::T, H::T, K::T; check::Bool=true) where T<: GAPGroup

Return the vector of all the double cosets HxK for x in G. If check == false, do not check whether H and K are subgroups of G.

Examples

julia> G = symmetric_group(4)
-Sym( [ 1 .. 4 ] )
-
-julia> H = symmetric_group(3)
-Sym( [ 1 .. 3 ] )
-
-julia> K = symmetric_group(2)
-Sym( [ 1 .. 2 ] )
-
-julia> double_cosets(G,H,K)
-3-element Vector{GroupDoubleCoset{PermGroup, PermGroupElem}}:
- Sym( [ 1 .. 3 ] ) * () * Sym( [ 1 .. 2 ] )
- Sym( [ 1 .. 3 ] ) * (1,4) * Sym( [ 1 .. 2 ] )
- Sym( [ 1 .. 3 ] ) * (1,4,3) * Sym( [ 1 .. 2 ] )
source
representativeMethod
representative(C::GroupDoubleCoset)

Return a representative x of the double coset C = HxK.

source
orderMethod
order(C::Union{GroupCoset,GroupDoubleCoset})

Return the cardinality of the (double) coset C.

source
randMethod
rand(rng::Random.AbstractRNG = Random.GLOBAL_RNG, C::Union{GroupCoset,GroupDoubleCoset})

Return a random element of the (double) coset C, using the random number generator rng.

source
intersectMethod
intersect(V::AbstractVector{Union{T, GroupCoset, GroupDoubleCoset}}) where T <: GAPGroup

Return a vector containing all elements belonging to all groups and cosets in V.

source
diff --git a/previews/PR2578/Hecke/FacElem/index.html b/previews/PR2578/Hecke/FacElem/index.html deleted file mode 100644 index 2b172307eb6a..000000000000 --- a/previews/PR2578/Hecke/FacElem/index.html +++ /dev/null @@ -1,9 +0,0 @@ - -Factored Elements · Oscar.jl

Factored Elements

In many applications in number theory related to the multiplicative structure of number fields, interesting elements, e.g. units, are extremely large when written wrt. to a fxied basis for the field: for the fundamental unit in $Q[\sqrt d]$ it is known that the coefficients wrt. the canonical basis $1, \sqrt d$ can have $O(\exp \sqrt d)$ many digits. All currently known, fast methods construct those elements as power products of smaller elements, allowing the computer to handle them.

Mathematically, one can think of factored elements to formally live in the ring $Z[K]$ the group ring of the non-zero field elements. Thus elements are of the form $ \prod ai^{ei}$ where $a_i$ are elements in $K$, typically small and the $e_i\in Z$ are frequently large exponents. We refer to the $a_i$ as the base and the $e_i$ as the exponents of the factored element.

Since $K$ is, in general, no PID, this presentation is non-unique, elements in this form can easily be multiplied, raised to large powers, but in general not compared and not added.

In Hecke, this is caputured more generally by the type FacElem, parametrized by the type of the elements in the base and the type of their parent.

Important special cases are

  • FacElem{ZZRingElem, ZZRing}, factored integers
  • FacElem{nf_elem, AnticNumberField}, factored algerbaic numbers
  • FacElem{NfAbsOrdIdl, NfAbsOrdIdlSet}, factored ideals

It should be noted that an object of type `$FacElem{ZZRingElem, ZZRing}$ will, in general, not represent an integer as the exponents can be negative.

Construction

In general one can define factored elements by giving 2 arrays, the base and the exponent, or a dictionary containing the pairs:

FacElemType
FacElem{B, S}

Type for factored elements, that is elements of the form prod ai^ki for elements a_i of type B in a ring of type S.

FacElemMethod
FacElem{B}(R, base::Vector{B}, exp::Vector{ZZRingElem}) -> FacElem{B}

Returns the element $\prod b_i^{e_i}$, un-expanded.

FacElem{B}(base::Vector{B}, exp::Vector{ZZRingElem}) -> FacElem{B}

Returns the element $\prod b_i^{e_i}$, un-expanded.

FacElem{B}(R, d::Dict{B, ZZRingElem}) -> FacElem{B}
-FacElem{B}(R, d::Dict{B, Integer}) -> FacElem{B}

Returns the element $\prod b^{d[p]}$, un-expanded.

FacElem{B}(d::Dict{B, ZZRingElem}) -> FacElem{B}
-FacElem{B}(d::Dict{B, Integer}) -> FacElem{B}

Returns the element $\prod b^{d[p]}$, un-expanded.

idealMethod
 ideal(O::NfOrd, a::FacElem{nf_elem, AnticNumberField)

The factored fractional ideal $a*O$.

Conversion

The process of computing the value defined by a factored element is available as evaluate. Depending on the types involved this can be very efficient.

evaluateMethod
evaluate{T}(x::FacElem{T}) -> T

Expands or evaluates the factored element, i.e. actually computes the value. Does "square-and-multiply" on the exponent vectors.

evaluateMethod
evaluate(x::FacElem{QQFieldElem}) -> QQFieldElem
-evaluate(x::FacElem{ZZRingElem}) -> ZZRingElem

Expands or evaluates the factored element, i.e. actually computes the the element. Works by first obtaining a simplified version of the power product into coprime base elements.

evaluateMethod
evaluate{T}(x::FacElem{T}) -> T

Expands or evaluates the factored element, i.e. actually computes the value. Does "square-and-multiply" on the exponent vectors.

evaluate_naiveMethod
evaluate_naive{T}(x::FacElem{T}) -> T

Expands or evaluates the factored element, i.e. actually computes the value. Uses the obvious naive algorithm. Faster for input in finite rings.

Special functions

In the case where the parent of the base allows for efficient gcd computation, power products can be made unique:

simplifyMethod
simplify(x::FacElem{NfOrdIdl, NfOrdIdlSet}) -> FacElem
-simplify(x::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}) -> FacElem

Uses coprime_base to obtain a simplified version of $x$, ie. in the simplified version all base ideals will be pariwise coprime but not necessarily prime!.

simplifyMethod
simplify(x::FacElem{QQFieldElem}) -> FacElem{QQFieldElem}
-simplify(x::FacElem{ZZRingElem}) -> FacElem{ZZRingElem}

Simplfies the factored element, i.e. arranges for the base to be coprime.

The simplified version can then be used further:

isoneMethod
isone(x::FacElem{QQFieldElem}) -> Bool
-isone(x::FacElem{ZZRingElem}) -> Bool

Tests if $x$ represents $1$ without an evaluation.

factor_coprimeMethod
factor_coprime(x::FacElem{ZZRingElem}) -> Fac{ZZRingElem}

Computed a partial factorisation of $x$, ie. writes $x$ as a product of pariwise coprime integers.

factor_coprimeMethod
factor_coprime(x::FacElem{NfOrdIdl, NfOrdIdlSet}) -> Dict{NfOrdIdl, Int}

Computed a partial factorisation of $x$, ie. writes $x$ as a product of pariwise coprime integral ideals.

factor_coprimeMethod
factor_coprime(Q::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}) -> Dict{NfOrdIdl, Int}

A coprime factorisation of $Q$: each ideal in $Q$ is split using \code{integral_split} and then a coprime basis is computed. This does {\bf not} use any factorisation.

factor_coprimeMethod
factor_coprime(I::NfOrdIdlSet, a::FacElem{nf_elem, AnticNumberField}) -> Dict{NfOrdIdl, ZZRingElem}

Factors the rincipal ideal generated by $a$ into coprimes by computing a coprime basis from the principal ideals in the factorisation of $a$.

factorMethod
 factor(Q::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}) -> Dict{NfOrdIdl, Int}

The factorisation of $Q$, by refining a coprime factorisation.

factorMethod
factor(I::NfOrdIdlSet, a::FacElem{nf_elem, AnticNumberField}) -> Dict{NfOrdIdl, ZZRingElem}

Factors the principal ideal generated by $a$ by refining a coprime factorisation.

For factorised algebraic numbers a unique simplification is not possible, however, this allows still do obtain partial results:

compact_presentationFunction
compact_presentation(a::FacElem{nf_elem, AnticNumberField}, n::Int = 2; decom, arb_prec = 100, short_prec = 1000) -> FacElem

Computes a presentation $a = \prod a_i^{n_i}$ where all the exponents $n_i$ are powers of $n$ and, the elements $a_i$ are "small", generically, they have a norm bounded by $d^{n/2}$ where $d$ is the discriminant of the maximal order. As the algorithm needs the factorisation of the principal ideal generated by $a$, it can be passed in in \code{decom}.

valuationMethod
valuation(a::FacElem{nf_elem, AnticNumberField}, P::NfOrdIdl) -> ZZRingElem

The valuation of $a$ at $P$.

valuationMethod
valuation(A::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}, p::NfOrdIdl)
-valuation(A::FacElem{NfOrdIdl, NfOrdIdlSet}, p::NfOrdIdl)

The valuation of $A$ at $P$.

evaluate_modMethod
evaluate_mod(a::FacElem{nf_elem, AnticNumberField}, B::NfOrdFracIdl) -> nf_elem

Evaluates $a$ using CRT and small primes. Assumes that the ideal generated by $a$ is in fact $B$. Useful in cases where $a$ has huge exponents, but the evaluated element is actually "small".

reduce_idealMethod
reduce_ideal(A::FacElem{NfOrdIdl}) -> NfOrdIdl, FacElem{nf_elem}

Computes $B$ and $\alpha$ in factored form, such that $\alpha B = A$.

modular_projMethod
modular_proj(a::FacElem{nf_elem, AnticNumberField}, me::modular_env) -> Vector{fqPolyRepFieldElem}

Given an algebraic number $a$ in factored form and data \code{me} as computed by \code{modular_init}, project $a$ onto the residue class fields.

Positivity & Signs

Factored elements can be used instead of number field elements for the functions sign, signs, is_positive, is_negative and is_totally_positive, see Positivity & Signs

Miscellaneous

max_expMethod
max_exp(a::FacElem)

Finds the largest exponent in the factored element $a$.

min_expMethod
min_exp(a::FacElem)

Finds the smallest exponent in the factored element $a$.

maxabs_expMethod
maxabs_exp(a::FacElem)

Finds the largest exponent by absolute value in the factored element $a$.

diff --git a/previews/PR2578/Hecke/Hecke.bib b/previews/PR2578/Hecke/Hecke.bib deleted file mode 100644 index d7da01f34cf3..000000000000 --- a/previews/PR2578/Hecke/Hecke.bib +++ /dev/null @@ -1,96 +0,0 @@ -@book{Coh93, - AUTHOR = {Cohen, Henri}, - TITLE = {A course in computational algebraic number theory}, - SERIES = {Graduate Texts in Mathematics}, - VOLUME = {138}, - PUBLISHER = {Springer-Verlag, Berlin}, - YEAR = {1993}, - PAGES = {xii+534}, - ISBN = {3-540-55640-0}, - MRCLASS = {11Y40 (11Rxx 68Q40)}, - MRNUMBER = {1228206}, -MRREVIEWER = {Joe P. Buhler}, - DOI = {10.1007/978-3-662-02945-9}, - URL = {https://doi.org/10.1007/978-3-662-02945-9}, -} - -@book{Coh00, - AUTHOR = {Cohen, Henri}, - TITLE = {Advanced topics in computational number theory}, - SERIES = {Graduate Texts in Mathematics}, - VOLUME = {193}, - PUBLISHER = {Springer-Verlag, New York}, - YEAR = {2000}, - PAGES = {xvi+578}, - ISBN = {0-387-98727-4}, - MRCLASS = {11Y40 (11Rxx)}, - MRNUMBER = {1728313}, -MRREVIEWER = {Ken Yamamura}, - DOI = {10.1007/978-1-4419-8489-0}, - URL = {https://doi.org/10.1007/978-1-4419-8489-0}, -} - -@book{PZ97, - AUTHOR = {Pohst, M. and Zassenhaus, H.}, - TITLE = {Algorithmic algebraic number theory}, - SERIES = {Encyclopedia of Mathematics and its Applications}, - VOLUME = {30}, - NOTE = {Revised reprint of the 1989 original}, - PUBLISHER = {Cambridge University Press, Cambridge}, - YEAR = {1997}, - PAGES = {xiv+499}, - ISBN = {0-521-59669-6}, - MRCLASS = {11Rxx (11Y40)}, - MRNUMBER = {1483321}, -} -@book{Mar18, - AUTHOR = {Marcus, Daniel A.}, - TITLE = {Number fields}, - SERIES = {Universitext}, - NOTE = {Second edition of [ MR0457396], - With a foreword by Barry Mazur}, - PUBLISHER = {Springer, Cham}, - YEAR = {2018}, - PAGES = {xviii+203}, - ISBN = {978-3-319-90232-6; 978-3-319-90233-3}, - MRCLASS = {11-01 (11Rxx 11Txx 12-01)}, - MRNUMBER = {3822326}, - DOI = {10.1007/978-3-319-90233-3}, - URL = {https://doi.org/10.1007/978-3-319-90233-3}, -} - -@book{CS99, - AUTHOR = {Conway, J. H. and Sloane, N. J. A.}, - TITLE = {Sphere packings, lattices and groups}, - SERIES = {Grundlehren der mathematischen Wissenschaften [Fundamental - Principles of Mathematical Sciences]}, - VOLUME = {290}, - EDITION = {Third}, - NOTE = {With additional contributions by E. Bannai, R. E. Borcherds, - J. Leech, S. P. Norton, A. M. Odlyzko, R. A. Parker, L. Queen - and B. B. Venkov}, - PUBLISHER = {Springer-Verlag, New York}, - YEAR = {1999}, - PAGES = {lxxiv+703}, - ISBN = {0-387-98585-9}, - MRCLASS = {11H31 (05B40 11H06 20D08 52C07 52C17 94B75 94C30)}, - MRNUMBER = {1662447}, -MRREVIEWER = {Renaud Coulangeon}, - DOI = {10.1007/978-1-4757-6568-7}, - URL = {https://doi.org/10.1007/978-1-4757-6568-7}, -} -@article{Nik79, - AUTHOR = {Nikulin, V. V.}, - TITLE = {Integer symmetric bilinear forms and some of their geometric - applications}, - JOURNAL = {Izv. Akad. Nauk SSSR Ser. Mat.}, - FJOURNAL = {Izvestiya Akademii Nauk SSSR. Seriya Matematicheskaya}, - VOLUME = {43}, - YEAR = {1979}, - NUMBER = {1}, - PAGES = {111--177, 238}, - ISSN = {0373-2436}, - MRCLASS = {10C05 (14G30 14J17 14J25 57M99 57R45 58C27)}, - MRNUMBER = {525944}, -MRREVIEWER = {I. Dolgachev}, -} diff --git a/previews/PR2578/Hecke/abelian/elements/index.html b/previews/PR2578/Hecke/abelian/elements/index.html deleted file mode 100644 index fdb33e6d8f7c..000000000000 --- a/previews/PR2578/Hecke/abelian/elements/index.html +++ /dev/null @@ -1,16 +0,0 @@ - -- · Oscar.jl

Elements

Elements in a finitely generated abelian group are of type GrpAbFinGenElem and are always given as a linear combination of the generators. Internally this representation is normliased to have a unique representative.

Creation

In addition to the standard function id, zero and one that can be used to create the neutral element, we also support more targeted creation:

gensMethod
gens(G::GrpAbFinGen) -> Vector{GrpAbFinGenElem}

The sequence of generators of $G$.

GrpAbFinGenMethod
(A::GrpAbFinGen)(x::Vector{ZZRingElem}) -> GrpAbFinGenElem

Given an array x of elements of type ZZRingElem of the same length as ngens($A$), this function returns the element of $A$ with components x.

GrpAbFinGenMethod
(A::GrpAbFinGen)(x::ZZMatrix) -> GrpAbFinGenElem

Given a matrix over the integers with either $1$ row and ngens(A) columns or ngens(A) rows and $1$ column, this function returns the element of $A$ with components x.

getindexMethod
getindex(A::GrpAbFinGen, i::Int) -> GrpAbFinGenElem

Returns the element of $A$ with components $(0,\dotsc,0,1,0,\dotsc,0)$, where the $1$ is at the $i$-th position.

randMethod
rand(G::GrpAbFinGen) -> GrpAbFinGenElem

Returns an element of $G$ chosen uniformly at random.

randMethod
rand(G::GrpAbFinGen, B::ZZRingElem) -> GrpAbFinGenElem

For a (potentially infinite) abelian group $G$, return an element chosen uniformly at random with coefficients bounded by $B$.

parentMethod
parent(x::GrpAbFinGenElem) -> GrpAbFinGen

Returns the parent of $x$.

Access

getindexMethod
getindex(x::GrpAbFinGenElem, i::Int) -> ZZRingElem

Returns the $i$-th component of the element $x$.

Predicates

We have the standard predicates iszero, isone and is_identity to test an element for being trivial.

Invariants

orderMethod
order(A::GrpAbFinGenElem) -> ZZRingElem

Returns the order of $A$. It is assumed that the order is finite.

Iterator

One can iterate over the elements of a finite abelian group.


julia> G = abelian_group(ZZRingElem[1 2; 3 4])(General) abelian group with relation matrix -[1 2; 3 4]
julia> for g = G - println(g) - endElement of -(General) abelian group with relation matrix -[1 2; 3 4] -with structure of GrpAb: Z/2 - -with components [0 0] -Element of -(General) abelian group with relation matrix -[1 2; 3 4] -with structure of GrpAb: Z/2 - -with components [0 1]
diff --git a/previews/PR2578/Hecke/abelian/introduction/index.html b/previews/PR2578/Hecke/abelian/introduction/index.html deleted file mode 100644 index 7fb377107036..000000000000 --- a/previews/PR2578/Hecke/abelian/introduction/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Abelian Groups · Oscar.jl

Abelian Groups

Here we describe the interface to abelian groups in Hecke.

Introduction

Within Hecke, abelian groups are of generic abstract type GrpAb which does not have to be finitely generated, $\mathbb Q/\mathbb Z$ is an example of a more general abelian group. Having said that, most of the functionality is restricted to abelian groups that are finitely presented as $\mathbb Z$-modules.

Basic Creation

Finitely presented (as $\mathbb Z$-modules) abelian groups are of type GrpAbFinGen with elements of type GrpAbFinGenElem. The creation is mostly via a relation matrix $M = (m_{i,j})$ for $1\le i\le n$ and $1\le j\le m$. This creates a group with $m$ generators $e_j$ and relations

\[ \sum_{i=1}^n m_{i,j} e_j = 0.\]

abelian_groupMethod
abelian_group(::Type{T} = GrpAbFinGen, M::ZZMatrix) -> GrpAbFinGen

Creates the abelian group with relation matrix M. That is, the group will have ncols(M) generators and each row of M describes one relation.

abelian_groupMethod
abelian_group(::Type{T} = GrpAbFinGen, M::AbstractMatrix{<:IntegerUnion})

Creates the abelian group with relation matrix M. That is, the group will have ncols(M) generators and each row of M describes one relation.

abelian_groupMethod
abelian_group(::Type{T} = GrpAbFinGen, M::AbstractMatrix{<:IntegerUnion})

Creates the abelian group with relation matrix M. That is, the group will have ncols(M) generators and each row of M describes one relation.

Alternatively, there are shortcuts to create products of cyclic groups:

abelian_groupMethod
abelian_group(::Type{T} = GrpAbFinGen, M::AbstractVector{<:IntegerUnion}) -> GrpAbFinGen
-abelian_group(::Type{T} = GrpAbFinGen, M::IntegerUnion...) -> GrpAbFinGen

Creates the direct product of the cyclic groups $\mathbf{Z}/m_i$, where $m_i$ is the $i$th entry of M.


julia> G = abelian_group(2, 2, 6)GrpAb: (Z/2)^2 x Z/6

or even

free_abelian_groupMethod
free_abelian_group(::Type{T} = GrpAbFinGen, n::Int) -> GrpAbFinGen

Creates the free abelian group of rank n.

abelian_groupsMethod
abelian_groups(n::Int) -> Vector{GrpAbFinGen}

Given a positive integer $n$, return a list of all abelian groups of order $n$.


julia> abelian_groups(8)3-element Vector{GrpAbFinGen}: - GrpAb: (Z/2)^3 - GrpAb: Z/2 x Z/4 - GrpAb: Z/8

Invariants

is_snfMethod
is_snf(G::GrpAbFinGen) -> Bool

Return whether the current relation matrix of the group $G$ is in Smith normal form.

ngensMethod
ngens(G::GrpAbFinGen) -> Int

Return the number of generators of $G$ in the current representation.

nrelsMethod
nrels(G::GrpAbFinGen) -> Int

Return the number of relations of $G$ in the current representation.

relsMethod
rels(A::GrpAbFinGen) -> ZZMatrix

Return the currently used relations of $G$ as a single matrix.

isfiniteMethod
isfinite(A::GrpAbFinGen) -> Bool

Return whether $A$ is finite.

is_infiniteMethod
is_infinite(x::Any) -> Bool

Tests whether $x$ is infinite, by returning !isfinite(x).

rankMethod
rank(A::GrpAbFinGen) -> Int

Return the rank of $A$, that is, the dimension of the $\mathbf{Q}$-vectorspace $A \otimes_{\mathbf Z} \mathbf Q$.

orderMethod
order(A::GrpAbFinGen) -> ZZRingElem

Return the order of $A$. It is assumed that $A$ is finite.

exponentMethod
exponent(A::GrpAbFinGen) -> ZZRingElem

Return the exponent of $A$. It is assumed that $A$ is finite.

istrivialMethod
istrivial(A::GrpAbFinGen) -> Bool

Return whether $A$ is the trivial group.

is_torsionMethod
is_torsion(G::GrpAbFinGen) -> Bool

Return whether G is a torsion group.

is_cyclicMethod
is_cyclic(G::GrpAbFinGen) -> Bool

Return whether $G$ is cyclic.

elementary_divisorsMethod
elementary_divisors(G::GrpAbFinGen) -> Vector{ZZRingElem}

Given $G$, return the elementary divisors of $G$, that is, the unique positive integers $e_1,\dotsc,e_k$ with $e_i \mid e_{i + 1}$ and $G \cong \mathbf{Z}/e_1\mathbf{Z} \times \dotsb \times \mathbf{Z}/e_k\mathbf{Z}$.

diff --git a/previews/PR2578/Hecke/abelian/maps/index.html b/previews/PR2578/Hecke/abelian/maps/index.html deleted file mode 100644 index 63b4f93f41d3..000000000000 --- a/previews/PR2578/Hecke/abelian/maps/index.html +++ /dev/null @@ -1,20 +0,0 @@ - -- · Oscar.jl

Maps between abelian groups are mainly of type GrpAbFinGenMap. They allow normal map operations such as image, preimage, domain, codomain and can be created in a variety of situations.

Maps

Maps between abelian groups can be constructed via

  • images of the generators
  • pairs of elements
  • via composition
  • and isomorphism/ inclusion testing
homMethod
hom(G::GrpAbFinGen, H::GrpAbFinGen, A::Matrix{ <: Map{GrpAbFinGen, GrpAbFinGen}}) -> Map

Given groups $G$ and $H$ that are created as direct products as well as a matrix $A$ containing maps $A[i,j] : G_i \to H_j$, return the induced homomorphism.

is_isomorphicMethod
is_isomorphic(G::GrpAbFinGen, H::GrpAbFinGen) -> Bool

Return whether $G$ and $H$ are isomorphic.


julia> G = free_abelian_group(2)GrpAb: Z^2
julia> h = hom(G, G, [gen(G, 2), 3*gen(G, 1)])Map with following data -Domain: -======= -Abelian group with structure: Z^2 -Codomain: -========= -Abelian group with structure: Z^2
julia> h(gen(G, 1))Element of -GrpAb: Z^2 -with components [0 1]
julia> h(gen(G, 2))Element of -GrpAb: Z^2 -with components [3 0]

Homomorphisms also allow addition and subtraction corresponding to the pointwise operation:


julia> G = free_abelian_group(2)GrpAb: Z^2
julia> h = hom(G, G, [2*gen(G, 2), 3*gen(G, 1)])Map with following data -Domain: -======= -Abelian group with structure: Z^2 -Codomain: -========= -Abelian group with structure: Z^2
julia> (h+h)(gen(G, 1))Element of -GrpAb: Z^2 -with components [0 4]
diff --git a/previews/PR2578/Hecke/abelian/structural/index.html b/previews/PR2578/Hecke/abelian/structural/index.html deleted file mode 100644 index eecbfa51d70a..000000000000 --- a/previews/PR2578/Hecke/abelian/structural/index.html +++ /dev/null @@ -1,99 +0,0 @@ - -- · Oscar.jl

Structural Computations

Abelian groups support a wide range of structural operations such as

  • enumeration of subgroups
  • (outer) direct products
  • tensor and hom constructions
  • free resolutions and general complexes
  • (co)-homology and tensor and hom-functors
snfMethod
snf(A::GrpAbFinGen) -> GrpAbFinGen, GrpAbFinGenMap

Return a pair $(G, f)$, where $G$ is an abelian group in canonical Smith normal form isomorphic to $A$ and an isomorphism $f : G \to A$.

find_isomorphismMethod
find_isomorphism(G, op, A::GrpAb) -> Dict, Dict

Given an abelian group $A$ and a collection $G$ which is an abelian group with the operation op, this functions returns isomorphisms $G \to A$ and $A \to G$ encoded as dictionaries.

It is assumed that $G$ and $A$ are isomorphic.

Subgroups and Quotients

torsion_subgroupMethod
torsion_subgroup(G::GrpAbFinGen) -> GrpAbFinGen, Map

Return the torsion subgroup of G.

subMethod
sub(G::GrpAbFinGen, s::Vector{GrpAbFinGenElem}) -> GrpAbFinGen, GrpAbFinGenMap

Create the subgroup $H$ of $G$ generated by the elements in s together with the injection $\iota : H \to G$.

subMethod
sub(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}, task::Symbol = :with_morphism) where T

Given a vector V of (homogeneous) elements of F, return the (graded) submodule of F generated by these elements.

Put more precisely, return the submodule as an object of type SubquoModule.

Additionally, if N denotes this object,

  • return the inclusion map N $\to$ F if task = :with_morphism (default),
  • return and cache the inclusion map N $\to$ F if task = :cache_morphism,
  • do none of the above if task = :none.

If task = :only_morphism, return only the inclusion map.

source
sub(F::FreeMod{T}, A::MatElem{T}, task::Symbol = :with_morphism) where {T}

Given a (homogeneous) matrix A, return the (graded) submodule of F generated by the rows of A.

Put more precisely, return this submodule as an object of type SubquoModule.

Additionally, if N denotes this submodule,

  • return the inclusion map N $\to$ F if task = :with_morphism (default),
  • return and cache the inclusion map N $\to$ F if task = :cache_morphism,
  • do none of the above if task = :none.

If task = :only_morphism, return only the inclusion map.

source
sub(F::FreeMod{T}, O::Vector{<:SubquoModuleElem{T}}, task::Symbol = :with_morphism) where T

Return S as a submodule of F, where S is generated by O. The embedding module of the parent of the elements of O must be F. If task is set to :none or to :module return only S. If task is set to :with_morphism (default option) or to :both return also the canonical injection morphism $S \to F$. If task is set to :cache_morphism the morphism is also cached. If task is set to :only_morphism return only the morphism.

source
sub(F::FreeMod{T}, s::SubquoModule{T}, task::Symbol = :with_morphism) where T

Return s as a submodule of F, that is the embedding free module of s must be F and s has no relations. If task is set to :none or to :module return only s. If task is set to :with_morphism (default option) or to :both return also the canonical injection morphism $s \to F$. If task is set to :cache_morphism the morphism is also cached. If task is set to :only_morphism return only the morphism.

source
sub(M::SubquoModule{T}, V::Vector{<:SubquoModuleElem{T}}, task::Symbol = :with_morphism) where T

Given a vector V of (homogeneous) elements of M, return the (graded) submodule of M generated by these elements.

Put more precisely, return this submodule as an object of type SubquoModule.

Additionally, if N denotes this object,

  • return the inclusion map N $\to$ M if task = :with_morphism (default),
  • return and cache the inclusion map N $\to$ M if task = :cache_morphism,
  • do none of the above if task = :none.

If task = :only_morphism, return only the inclusion map.

source
sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T

Given a vector V of (homogeneous) elements of M, return the (graded) submodule of M generated by these elements.

Put more precisely, return this submodule as an object of type SubquoModule.

Additionally, if N denotes this object,

  • return the inclusion map N $\to$ M if task = :with_morphism (default),
  • return and cache the inclusion map N $\to$ M if task = :cache_morphism,
  • do none of the above if task = :none.

If task = :only_morphism, return only the inclusion map.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> F = free_module(R, 1);
-
-julia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];
-
-julia> N, incl = sub(F, V);
-
-julia> N
-Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-represented as subquotient with no relations.
-
-julia> incl
-Map with following data
-Domain:
-=======
-Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-represented as subquotient with no relations.
-Codomain:
-=========
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
source
sub(A::SMat, r::AbstractUnitRange, c::AbstractUnitRange) -> SMat

Return the submatrix of $A$, where the rows correspond to $r$ and the columns correspond to $c$.

sub(s::Vector{GrpAbFinGenElem}) -> GrpAbFinGen, GrpAbFinGenMap

Assuming that the non-empty array s contains elements of an abelian group $G$, this functions returns the subgroup $H$ of $G$ generated by the elements in s together with the injection $\iota : H \to G$.

subMethod
sub(G::GrpAbFinGen, M::ZZMatrix) -> GrpAbFinGen, GrpAbFinGenMap

Create the subgroup $H$ of $G$ generated by the elements corresponding to the rows of $M$ together with the injection $\iota : H \to G$.

subMethod
sub(G::GrpAbFinGen, n::ZZRingElem) -> GrpAbFinGen, GrpAbFinGenMap

Create the subgroup $n \cdot G$ of $G$ together with the injection $\iota : n\cdot G \to G$.

subMethod
sub(G::GrpAbFinGen, n::Integer) -> GrpAbFinGen, Map

Create the subgroup $n \cdot G$ of $G$ together with the injection $\iota : n \cdot G \to G$.

psylow_subgroupMethod
psylow_subgroup(G::GrpAbFinGen, p::IntegerUnion) -> GrpAbFinGen, GrpAbFinGenMap

Return the $p$-Sylow subgroup of G.

has_quotientMethod
has_quotient(G::GrpAbFinGen, invariant::Vector{Int}) -> Bool

Given an abelian group $G$, return true if it has a quotient with given elementary divisors and false otherwise.

has_complementMethod
has_complement(f::GrpAbFinGenMap) -> Bool, GrpAbFinGenMap
-has_complement(U::GrpAbFinGen, G::GrpAbFinGen) -> Bool, GrpAbFinGenMap

Given a map representing a subgroup of a group $G$, or a subgroup U of a group G, return either true and an injection of a complement in $G$, or false.

See also: is_pure

is_pureMethod
is_pure(U::GrpAbFinGen, G::GrpAbFinGen) -> Bool

A subgroup U of G is called pure if for all n an element in U that is in the image of the multiplication by n map of G is also a multiple of an element in U.

For finite abelian groups this is equivalent to U having a complement in G. They are also know as isolated subgroups and serving subgroups.

See also: is_neat, has_complement

EXAMPLES

julia> G = abelian_group([2, 8]);
-
-julia> U, _ = sub(G, [G[1]+2*G[2]]);
-
-julia> is_pure(U, G)
-false
-
-julia> U, _ = sub(G, [G[1]+4*G[2]]);
-
-julia> is_pure(U)
-true
-
-julia> has_complement(U, G)[1]
-true
is_neatMethod
is_neat(U::GrpAbFinGen, G::GrpAbFinGen) -> Bool

A subgroup U of G is called neat if for all primes p an element in U that is in the image of the multiplication by p map of G is also a multiple of an element in U.

See also: is_pure

EXAMPLES

julia> G = abelian_group([2, 8]);
-
-julia> U, _ = sub(G, [G[1] + 2*G[2]]);
-
-julia> is_neat(U, G)
-true
-
-julia> is_pure(U, G)
-false
saturateMethod
saturate(U::GrpAbFinGen, G::GrpAbFinGen) -> GrpAbFinGen

For a subgroup U of G find a minimal overgroup that is pure, and thus has a complement.

See also: is_pure, has_complement

A sophisticated algorithm for the enumeration of all (or selected) subgroups of a finite abelian group is available.

psubgroupsMethod
psubgroups(g::GrpAbFinGen, p::Integer;
-           subtype = :all,
-           quotype = :all,
-           index = -1,
-           order = -1)

Return an iterator for the subgroups of $G$ of the specific form. Note that subtype (and quotype) is the type of the subgroup as an abelian $p$-group.


julia> G = abelian_group([6, 12])GrpAb: Z/6 x Z/12
julia> shapes = MSet{Vector{ZZRingElem}}()MSet{Vector{ZZRingElem}}()
julia> for U = psubgroups(G, 2) - push!(shapes, elementary_divisors(U[1])) - end
julia> shapesMSet(ZZRingElem[], ZZRingElem[4] : 2, ZZRingElem[2, 4], ZZRingElem[2] : 3, ZZRingElem[2, 2])

So there are $2$ subgroups isomorphic to $C_4$ (ZZRingElem[4] : 2), $1$ isomorphic to $C_2\times C_4$, 1 trivial and $3$ $C_2$ subgroups.

subgroupsMethod
subgroups(g::GrpAbFinGen;
-          subtype = :all ,
-          quotype = :all,
-          index = -1,
-          order = -1)

Return an iterator for the subgroups of $G$ of the specific form.

julia> for U = subgroups(G, subtype = [2])
-         @show U[1], map(U[2], gens(U[1]))
-       end(U[1], map(U[2], gens(U[1]))) = (GrpAb: Z/2, GrpAbFinGenElem[Element of
-GrpAb: Z/6 x Z/12
-with components [0 6]])
-(U[1], map(U[2], gens(U[1]))) = (GrpAb: Z/2, GrpAbFinGenElem[Element of
-GrpAb: Z/6 x Z/12
-with components [3 6]])
-(U[1], map(U[2], gens(U[1]))) = (GrpAb: Z/2, GrpAbFinGenElem[Element of
-GrpAb: Z/6 x Z/12
-with components [3 0]])
julia> for U = subgroups(G, quotype = [2]) - @show U[1], map(U[2], gens(U[1])) - end(U[1], map(U[2], gens(U[1]))) = ((General) abelian group with relation matrix -[4 0 0; 0 3 0; 0 0 3], GrpAbFinGenElem[Element of -GrpAb: Z/6 x Z/12 -with components [3 3], Element of -GrpAb: Z/6 x Z/12 -with components [0 4], Element of -GrpAb: Z/6 x Z/12 -with components [2 0]]) -(U[1], map(U[2], gens(U[1]))) = ((General) abelian group with relation matrix -[4 0 0; 0 3 0; 0 0 3], GrpAbFinGenElem[Element of -GrpAb: Z/6 x Z/12 -with components [0 3], Element of -GrpAb: Z/6 x Z/12 -with components [0 4], Element of -GrpAb: Z/6 x Z/12 -with components [2 0]]) -(U[1], map(U[2], gens(U[1]))) = ((General) abelian group with relation matrix -[2 0 0 0; 0 2 0 0; 0 0 3 0; 0 0 0 3], GrpAbFinGenElem[Element of -GrpAb: Z/6 x Z/12 -with components [3 6], Element of -GrpAb: Z/6 x Z/12 -with components [0 6], Element of -GrpAb: Z/6 x Z/12 -with components [0 4], Element of -GrpAb: Z/6 x Z/12 -with components [2 0]])
quoMethod
quo(G::GrpAbFinGen, s::Vector{GrpAbFinGenElem}) -> GrpAbFinGen, GrpAbfinGemMap

Create the quotient $H$ of $G$ by the subgroup generated by the elements in $s$, together with the projection $p : G \to H$.

quoMethod
quo(G::GrpAbFinGen, M::ZZMatrix) -> GrpAbFinGen, GrpAbFinGenMap

Create the quotient $H$ of $G$ by the subgroup generated by the elements corresponding to the rows of $M$, together with the projection $p : G \to H$.

quoMethod
quo(G::GrpAbFinGen, n::Integer}) -> GrpAbFinGen, Map
-quo(G::GrpAbFinGen, n::ZZRingElem}) -> GrpAbFinGen, Map

Returns the quotient $H = G/nG$ together with the projection $p : G \to H$.

quoMethod
quo(G::GrpAbFinGen, n::Integer}) -> GrpAbFinGen, Map
-quo(G::GrpAbFinGen, n::ZZRingElem}) -> GrpAbFinGen, Map

Returns the quotient $H = G/nG$ together with the projection $p : G \to H$.

quoMethod
quo(G::GrpAbFinGen, U::GrpAbFinGen) -> GrpAbFinGen, Map

Create the quotient $H$ of $G$ by $U$, together with the projection $p : G \to H$.

For 2 subgroups U and V of the same group G, U+V returns the smallest subgroup of G containing both. Similarly, $U\cap V$ computes the intersection and $U \subset V$ tests for inclusion. The difference between issubset = $\subset$ and is_subgroup is that the inclusion map is also returned in the 2nd call.

intersectMethod
intersect(mG::GrpAbFinGenMap, mH::GrpAbFinGenMap) -> GrpAbFinGen, Map

Given two injective maps of abelian groups with the same codomain $G$, return the intersection of the images as a subgroup of $G$.

Direct Products

direct_productMethod
direct_product(G::GrpAbFinGen...) -> GrpAbFinGen, Vector{GrpAbFinGenMap}

Return the direct product $D$ of the (finitely many) abelian groups $G_i$, together with the projections $D \to G_i$.

For finite abelian groups, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $D$ as a direct sum together with the injections $D \to G_i$, one should call direct_sum(G...). If one wants to obtain $D$ as a biproduct together with the projections and the injections, one should call biproduct(G...).

Otherwise, one could also call canonical_injections(D) or canonical_projections(D) later on.

canonical_injectionMethod
canonical_injection(G::GrpAbFinGen, i::Int) -> GrpAbFinGenMap

Given a group $G$ that was created as a direct product, return the injection from the $i$th component.

canonical_projectionMethod
canonical_projection(G::GrpAbFinGen, i::Int) -> GrpAbFinGenMap

Given a group $G$ that was created as a direct product, return the projection onto the $i$th component.

flatMethod
flat(G::GrpAbFinGen) -> GrpAbFinGenMap

Given a group $G$ that is created using (iterated) direct products, or (iterated) tensor products, return a group isomorphism into a flat product: for $G := (A \oplus B) \oplus C$, it returns the isomorphism $G \to A \oplus B \oplus C$ (resp. $\otimes$).

Tensor Producs

tensor_productMethod
tensor_product(G::GrpAbFinGen...; task::Symbol = :map) -> GrpAbFinGen, Map

Given groups $G_i$, compute the tensor product $G_1\otimes \cdots \otimes G_n$. If task is set to ":map", a map $\phi$ is returned that maps tuples in $G_1 \times \cdots \times G_n$ to pure tensors $g_1 \otimes \cdots \otimes g_n$. The map admits a preimage as well.

homMethod
hom(G::GrpAbFinGen, H::GrpAbFinGen, A::Vector{ <: Map{GrpAbFinGen, GrpAbFinGen}}) -> Map

Given groups $G = G_1 \otimes \cdots \otimes G_n$ and $H = H_1 \otimes \cdot \otimes H_n$ as well as maps $\phi_i: G_i\to H_i$, compute the tensor product of the maps.

Hom-Group

homMethod
hom(G::GrpAbFinGen, H::GrpAbFinGen; task::Symbol = :map) -> GrpAbFinGen, Map

Computes the group of all homomorpisms from $G$ to $H$ as an abstract group. If task is ":map", then a map $\phi$ is computed that can be used to obtain actual homomorphisms. This map also allows preimages. Set task to ":none" to not compute the map.

diff --git a/previews/PR2578/Hecke/class_fields/intro/index.html b/previews/PR2578/Hecke/class_fields/intro/index.html deleted file mode 100644 index 300e47e77340..000000000000 --- a/previews/PR2578/Hecke/class_fields/intro/index.html +++ /dev/null @@ -1,16 +0,0 @@ - -Class Field Theory · Oscar.jl

Class Field Theory

Introduction

This chapter deals with abelian extensions of number fields and the rational numbers.

Class Field Theory, here specifically, class field theory of global number fields, deals with abelian extension, ie. fields where the group of automorphisms is abelian. For extensions of $\mathbb Q$, the famous Kronnecker-Weber theorem classifies all such fields: a field is abelian if and only if it is contained in some cyclotomic field. For general number fields this is more involved and even for extensions of $\mathbb Q$ is is not practical.

In Hecke, abelian extensions are parametrized by quotients of so called ray class groups. The language of ray class groups while dated is more applicable to algorithms than the modern language of idel class groups and quotients.

Ray Class Groups

Given an integral ideal $m_0 \le Z_K$ and a list of real places $m_\infty$, the ray class group modulo $(m_0, m_\infty)$, $C(m)$ is defined as the group of ideals coprime to $m_0$ modulo the elements $a\in K^*$ s.th. $v_p(a-1) \ge v_p(m_0)$ and for all $v\in m_\infty$, $a^{(v)} >0$. This is a finite abelian group. For $m_0 = Z_K$ and $m_\infty = \{\}$ we get $C()$ is the class group, if $m_\infty$ contains all real places, we obtain the narrow class group, or strict class group.

ray_class_groupMethod
ray_class_group(m::NfOrdIdl, inf_plc::Vector{InfPlc}; n_quo::Int, lp::Dict{NfOrdIdl, Int}) -> GrpAbFinGen, MapRayClassGrp

Given an ideal $m$ and a set of infinite places of $K$, this function returns the corresponding ray class group as an abstract group $\mathcal {Cl}_m$ and a map going from the group into the group of ideals of $K$ that are coprime to $m$. If n_quo is set, it will return the group modulo n_quo. The factorization of $m$ can be given with the keyword argument lp.

class_groupMethod
class_group(K::AnticNumberField) -> GrpAbFinGen, Map

Shortcut for class_group(maximal_order(K)): returns the class group as an abelian group and a map from this group to the set of ideals of the maximal order.

norm_groupMethod
norm_group(f::Nemo.PolyElem, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap
-
-norm_group(f::Array{PolyElem{nf_elem}}, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap

Computes the subgroup of the Ray Class Group $R$ given by the norm of the extension generated by a/the roots of $f$. If is_abelian is set to true, then the code assumes the field to be abelian, hence the algorithm stops when the quotient by the norm group has the correct order. Even though the algorithm is probabilistic by nature, in this case the result is guaranteed. If of_closure is given, then the norm group of the splitting field of the polynomial(s) is computed. It is the callers responsibility to ensure that the ray class group passed in is large enough.

norm_groupMethod
norm_group(K::NfRel{nf_elem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap
-
-norm_group(K::NfRelNS{nf_elem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap

Computes the subgroup of the Ray Class Group $R$ given by the norm of the extension.

Ray Class Fields

In general, the construction of a class field starts with a (ray) class group. Each quotient of a ray class group then defines a ray class field, the defining property is that the (relative) automorphism group is canonically isomorphic to the quotient of the ray class group where the isomorphism is given by the Artin (or Frobenius) map. Since, in Hecke, the (ray) class groups have no link to the field, actually this has to be specified using the maps.

It should be noted that this is a lazy construction: nothing is computed at this point.

ray_class_fieldMethod
ray_class_field(m::MapClassGrp) -> ClassField
-ray_class_field(m::MapRayClassGrp) -> ClassField

Creates the (formal) abelian extension defined by the map $m: A \to I$ where $I$ is the set of ideals coprime to the modulus defining $m$ and $A$ is a quotient of the ray class group (or class group). The map $m$ must be the map returned from a call to {classgroup} or {rayclass_group}.

ray_class_fieldMethod
ray_class_field(m::Union{MapClassGrp, MapRayClassGrp}, quomap::GrpAbFinGenMap) -> ClassField

For $m$ a map computed by either {rayclassgroup} or {class_group} and $q$ a canonical projection (quotient map) as returned by {quo} for q quotient of the domain of $m$ and a subgroup of $m$, create the (formal) abelian extension where the (relative) automorphism group is canonically isomorphic to the codomain of $q$.

ray_class_fieldMethod
ray_class_field(I::NfAbsOrdIdl; n_quo = 0) -> ClassField

The ray class field modulo $I$. If n_quo is given, then the largest subfield of exponent $n$ is computed.

ray_class_fieldMethod
ray_class_field(I::NfAbsOrdIdl, inf::Vector{InfPlc}; n_quo = 0) -> ClassField

The ray class field modulo $I$ and the infinite places given. If n_quo is given, then the largest subfield of exponent $n$ is computed.

hilbert_class_fieldMethod
hilbert_class_field(k::AnticNumberField) -> ClassField

The Hilbert class field of $k$ as a formal (ray-) class field.

ring_class_fieldMethod
ring_class_field(O::NfAbsOrd) -> ClassField

The ring class field of $O$, i.e. the maximal abelian extension ramified only at primes dividing the conductor with the automorphism group isomorphic to the Picard group.

Example


julia> Qx, x = polynomial_ring(FlintQQ, "x");
julia> K, a = number_field(x^2 - 10, "a");
julia> c, mc = class_group(K)(GrpAb: Z/2, ClassGroup map of -Set of ideals of Maximal order of Number field of degree 2 over QQ -with basis nf_elem[1, a] -)
julia> A = ray_class_field(mc)Class field defined mod (<1, 1>, InfPlc{AnticNumberField, NumFieldEmbNfAbs}[]) of structure Abelian group with structure: Z/2

Conversions

Given a ray class field, it is possible to actually compute defining equation(s) for this field. In general, the number field constructed this way will be non-simple by type and is defined by a polynomial for each maximal cyclic quotient of prime power order in the defining group.

The algorithm employed is based on Kummer-theory and requires the addition of a suitable root of unity. Progress can be monitored by setting set_verbose_level(:ClassField, n) where $0\le n\le 3$

number_fieldMethod
number_field(CF::ClassField) -> NfRelNS{nf_elem}

Given a (formal) abelian extension, compute the class field by finding defining polynomials for all prime power cyclic subfields.

Note, the return type is always a non-simple extension.


julia> Qx, x = polynomial_ring(FlintQQ, "x");
julia> k, a = number_field(x^2 - 10, "a");
julia> c, mc = class_group(k);
julia> A = ray_class_field(mc)Class field defined mod (<1, 1>, InfPlc{AnticNumberField, NumFieldEmbNfAbs}[]) of structure Abelian group with structure: Z/2
julia> K = number_field(A)Non-simple number field with defining polynomials [x^2 - 2] - over number field with defining polynomial x^2 - 10 - over rational field
julia> ZK = maximal_order(K)Relative maximal order of Non-simple number field of degree 2 over number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(_$1 + a, 1//4 * <2, a>)
julia> isone(discriminant(ZK))true
ray_class_fieldMethod
ray_class_field(K::NfRel{nf_elem}) -> ClassField
-ray_class_field(K::AnticNumberField) -> ClassField

For a (relative) abelian extension, compute an abstract representation as a class field.

genus_fieldMethod
genus_field(A::ClassField, k::AnticNumberField) -> ClassField

The maximal extension contained in $A$ that is the compositum of $K$ with an abelian extension of $k$.

maximal_abelian_subfieldMethod
maximal_abelian_subfield(A::ClassField, k::AnticNumberField) -> ClassField

The maximal abelian extension of $k$ contained in $A$. $k$ must be a subfield of the base field of $A$.

maximal_abelian_subfieldMethod
maximal_abelian_subfield(K::NfRel{nf_elem}; of_closure::Bool = false) -> ClassField

Using a probabilistic algorithm for the norm group computation, determine the maximal abelian subfield in $K$ over its base field. If of_closure is set to true, then the algorithm is applied to the normal closure of $K$ (without computing it).

Invariants

degreeMethod
degree(A::ClassField)

The degree of $A$ over its base field, i.e. the size of the defining ideal group.

base_ringMethod
base_ring(A::ClassField)

The maximal order of the field that $A$ is defined over.

base_fieldMethod
base_field(A::ClassField)

The number field that $A$ is defined over.

discriminantMethod
discriminant(C::ClassField) -> NfOrdIdl

Using the conductor-discriminant formula, compute the (relative) discriminant of $C$. This does not use the defining equations.

conductorMethod
conductor(C::ClassField) -> NfOrdIdl, Vector{InfPlc}

Return the conductor of the abelian extension corresponding to $C$.

defining_modulusMethod
defining_modulus(CF::ClassField)

The modulus, i.e. an ideal of the set of real places, used to create the class field.

is_cyclicMethod
is_cyclic(C::ClassField)

Tests if the (relative) automorphism group of $C$ is cyclic (by checking the defining ideal group).

is_conductorMethod
is_conductor(C::Hecke.ClassField, m::NfOrdIdl, inf_plc::Vector{InfPlc}=InfPlc[]; check) -> NfOrdIdl, Vector{InfPlc}

Checks if (m, inf_plc) is the conductor of the abelian extension corresponding to $C$. If check is false, it assumes that the given modulus is a multiple of the conductor. This is usually faster than computing the conductor.

is_normalMethod
is_normal(C::ClassField) -> Bool

For a class field $C$ defined over a normal base field $k$, decide if $C$ is normal over $Q$.

is_centralMethod
is_central(C::ClassField) -> Bool

For a class field $C$ defined over a normal base field $k$, decide if $C$ is central over $Q$.

Operations

*Method
*(A::ClassField, B::ClassField) -> ClassField

The compositum of $a$ and $b$ as a (formal) class field.

compositumMethod
compositum(a::ClassField, b::ClassField) -> ClassField

The compositum of $a$ and $b$ as a (formal) class field.

==Method
==(a::ClassField, b::ClassField)

Tests if $a$ and $b$ are equal.

intersectMethod
intersect(a::ClassField, b::ClassField) -> ClassField

The intersection of $a$ and $b$ as a class field.

prime_decomposition_typeMethod
prime_decomposition_type(C::ClassField, p::NfAbsOrdIdl) -> (Int, Int, Int)

For a prime $p$ in the base ring of $r$, determine the splitting type of $p$ in $r$. ie. the tuple $(e, f, g)$ giving the ramification degree, the inertia and the number of primes above $p$.

is_subfieldMethod
is_subfield(a::ClassField, b::ClassField) -> Bool

Determines if $a$ is a subfield of $b$.

is_local_normMethod
is_local_norm(r::ClassField, a::NfAbsOrdElem) -> Bool

Tests if $a$ is a local norm at all finite places in the extension implicitly given by $r$.

is_local_normMethod
is_local_norm(r::ClassField, a::NfAbsOrdElem, p::NfAbsOrdIdl) -> Bool

Tests if $a$ is a local norm at $p$ in the extension implicitly given by $r$. Currently the conductor cannot have infinite places.

normal_closureMethod
normal_closure(C::ClassField) -> ClassField

For a ray class field $C$ extending a normal base field $k$, compute the normal closure over $Q$.

subfieldsMethod
subfields(C::ClassField; degree::Int) -> Vector{ClassField}

Find all subfields of $C$ over the base field.

If the optional keyword argument degree is positive, then only those with prescribed degree will be returned.

Note

This will not find all subfields over $\mathbf{Q}$, but only the ones sharing the same base field.

diff --git a/previews/PR2578/Hecke/css/extra.css b/previews/PR2578/Hecke/css/extra.css deleted file mode 100644 index b445b7fb8e88..000000000000 --- a/previews/PR2578/Hecke/css/extra.css +++ /dev/null @@ -1,64 +0,0 @@ -blockquote { - background: #f9f9f9; - font-size: 0.8em; - border-left: 5px solid #ccc; - margin: 1.5em 10px; - padding: 0.0em 0px; - quotes: "\201C""\201D""\2018""\2019"; -} - -.md-typeset code { -font-size: 13.6px; -} - -.md-typeset pre { -font-size: 0.8em; -} - -.md-typeset h1 { -font-size: 1.7em; -font-weight: 400; -color: rgba(0,0,0,.87); -} - -.md-typeset h2 { - font-size: 1.4em; - font-weight: 400; - color: rgba(0,0,0,.87); -} - -.md-typeset h3 { - font-size: 1.2em; - font-weight: 400; - color: rgba(0,0,0,.87); -} - -.md-typeset h4 { - font-size: 1.0em; - font-weight: 400; - color: rgba(0,0,0,.87); -} - -.md-typeset p { - font-size: 16px; - line-height: 1.5; - text-align: justify; -} - -.md-typeset li { - font-size: 16px; - line-height: 1.4; -} - -.md-typeset hr { - font-size: .8rem; - line-height: 1.1; - margin: 1.1em 0; - margin-top: 1.1em; - margin-right: 0px; - margin-bottom: 1.1em; - margin-left: 0px; - height: 3px; - border-top: 2px solid #8c8b8b; - border-bottom: 0px; -} diff --git a/previews/PR2578/Hecke/dev/test/index.html b/previews/PR2578/Hecke/dev/test/index.html deleted file mode 100644 index 7dc5b26ca9aa..000000000000 --- a/previews/PR2578/Hecke/dev/test/index.html +++ /dev/null @@ -1,35 +0,0 @@ - -Testing · Oscar.jl

Testing

Structure

The Hecke tests can be found in Hecke/test/ and are organized in such a way that the file hierarchy mirrors the source directory Hecke/src/. For example, here is a subset of the src/QuadForm and the test/QuadForm directories:

├── src
-│   ├── QuadForm
-│   │   ├── Enumeration.jl
-│   │   ├── Herm
-│   │   │   ├── Genus.jl
-│   │   ├── Quad
-│   │   │   ├── Genus.jl
-│   │   │   ├── GenusRep.jl
-│   │   │   ├── NormalForm.jl
-│   │   │   ├── Spaces.jl
-│   │   │   ├── Types.jl
-│   │   │   ├── ZGenus.jl
-│   │   │   └── ZLattices.jl
-│   │   ├── QuadBin.jl
-│   │   ├── Torsion.jl
-│   ├── QuadForm.jl
-│
-│
-│
-├── test
-│   ├── QuadForm
-│   │   ├── Enumeration.jl
-│   │   ├── Herm
-│   │   │   ├── Genus.jl
-│   │   ├── Quad
-│   │   │   ├── Genus.jl
-│   │   │   ├── GenusRep.jl
-│   │   │   ├── NormalForm.jl
-│   │   │   ├── Spaces.jl
-│   │   │   ├── ZGenus.jl
-│   │   │   └── ZLattices.jl
-│   │   ├── QuadBin.jl
-│   │   └── Torsion.jl
-│   ├── QuadForm.jl

Adding tests

  • If one adds functionality to a file, say src/QuadForm/Quad/Genus.jl, a corresponding a test should be added to the corresponding test file. In this case this would be test/QuadForm/Quad/Genus.jl.
  • Assume one adds a new file, say src/QuadForm/New.jl, which is included in src/QuadForm.jl. Then a corresponding file test/QuadForm/Test.jl containing the tests must be added. This new file must then also be included in test/QuadForm.jl.
  • Similar to the above, if a new directory in src/ is added, the same must apply in test/.

Adding long tests

If one knows that running a particular test will take a long time, one can use @long_test instead of @test inside the test suite. When running the test suite, tests annotated with @long_test will not be run, unless specifically asked for (see below). The continuous integration servers will run at least one job including the long tests.

Running the tests

Running all tests

All tests can be run as usual with Pkg.test("Hecke"). The whole test suite can be run in parallel using the following options:

  • Set the environment variable HECKE_TEST_VARIABLE=n, where n is the number of processes.
  • On julia >= 1.3, run Pkg.test("Hecke", test_args = ["-j$(n)"]), where n is the number of processes.

The tests annotated with @long_test can be invoked by setting HECKE_TESTLONG=1 or adding "long" to the test_args keyword argument on julia >= 1.3.

Running a subset of tests

Because the test structure mirrors the source directory, it is easy to run only a subset of tests. For example, to run all the tests in test/QuadForm/Quad/Genus.jl, one can invoke:

julia> Hecke.test_module("QuadForm/Quad/Genus")

This also works on the directory level. If one wants to add run all tests for quadratic forms, one can just run

julia> Hecke.test_module("QuadForm")
diff --git a/previews/PR2578/Hecke/elliptic_curves/basics/index.html b/previews/PR2578/Hecke/elliptic_curves/basics/index.html deleted file mode 100644 index edf1185e73fc..000000000000 --- a/previews/PR2578/Hecke/elliptic_curves/basics/index.html +++ /dev/null @@ -1,51 +0,0 @@ - -Basics · Oscar.jl

Basics

Creation

elliptic_curveFunction
elliptic_curve([K::Field], x::Vector; check::Bool = true) -> EllCrv

Construct an elliptic curve with Weierstrass equation specified by the coefficients in x, which must have either length 2 or 5.

Per default, it is checked whether the discriminant is non-zero. This can be disabled by setting check = false.

Examples

julia> elliptic_curve(QQ, [1, 2, 3, 4, 5])
-Elliptic curve with equation
-y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5
-
-julia> elliptic_curve(GF(3), [1, 1])
-Elliptic curve with equation
-y^2 = x^3 + x + 1
elliptic_curve_from_j_invariantFunction
elliptic_curve_from_j_invariant(j::FieldElem) -> EllCrv

Return an elliptic curve with the given $j$-invariant.

Examples

julia> K = GF(3)
-Finite field of characteristic 3
-
-julia> elliptic_curve_from_j_invariant(K(2))
-Elliptic curve with equation
-y^2 + x*y = x^3 + 1

Basic properties

base_fieldMethod
base_field(E::EllCrv) -> Field

Return the base field over which E is defined.

base_field(C::HypellCrv) -> Field

Return the base field over which C is defined.

base_changeMethod
base_change(K::Field, E::EllCrv) -> EllCrv

Return the base change of the elliptic curve $E$ over $K$ if coercion is possible.

base_changeMethod
base_change(f, E::EllCrv) -> EllCrv

Return the base change of the elliptic curve $E$ using the map $f$.

coefficientsMethod
coefficients(E::EllCrv{T}) -> Tuple{T, T, T, T, T}

Return the Weierstrass coefficients of $E$ as a tuple (a1, a2, a3, a4, a6) such that $E$ is given by y^2 + a1xy + a3y = x^3 + a2x^2 + a4x + a6.

a_invarsMethod
a_invars(E::EllCrv{T}) -> Tuple{T, T, T, T, T}

Return the Weierstrass coefficients of $E$ as a tuple $(a_1, a_2, a_3, a_4, a_6)$ such that $E$ is given by $y^2 + a_1xy + a_3y = x^3 + a_2x^2 + a_4x + a_6$.

b_invarsMethod
b_invars(E::EllCrv{T}) -> Tuple{T, T, T, T}

Return the b-invariants of $E$ as a tuple $(b_2, b_4, b_6, b_8)$.

c_invarsMethod
c_invars(E::EllCrv{T}) -> Tuple{T, T}

Return the c-invariants of $E as a tuple $(c_4, c_6)$.

discriminantMethod
discriminant(E::EllCrv) -> FieldElem

Return the discriminant of $E$.

discriminant(C::HypellCrv{T}) -> T

Compute the discriminant of $C$.

discriminant(O::AlgssRelOrd)

Returns the discriminant of $O$.

j_invariantMethod
j_invariant(E::EllCrv) -> FieldElem

Compute the j-invariant of $E$.

equationMethod
equation([R::MPolyRing,] E::EllCrv) -> MPolyElem

Return the equation defining the elliptic curve $E$ as a bivariate polynomial. If the polynomial ring $R$ is specified, it must by a bivariate polynomial ring.

Examples

julia> E = elliptic_curve(QQ, [1, 2, 3, 4, 5]);
-
-julia> equation(E)
--x^3 - 2*x^2 + x*y - 4*x + y^2 + 3*y - 5
hyperelliptic_polynomialsMethod
hyperelliptic_polynomials([R::PolyRing,] E::EllCrv) -> PolyElem, PolyElem

Return univariate polynomials $f, h$ such that $E$ is given by $y^2 + h*y = f$.

Examples

julia> E = elliptic_curve(QQ, [1, 2, 3, 4, 5]);
-
-julia> hyperelliptic_polynomials(E)
-(x^3 + 2*x^2 + 4*x + 5, x + 3)

Points

    (E::EllCrv)(coords::Vector; check::Bool = true)

Return the point $P$ of $E$ with coordinates specified by coords, which can be either affine coordinates (length(coords) == 2) or projective coordinates (length(coords) == 3).

Per default, it is checked whether the point lies on $E$. This can be disabled by setting check = false.

Examples
julia> E = elliptic_curve(QQ, [1, 2]);
-
-julia> E([1, -2])
-Point  (1 : -2 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
-
-julia> E([2, -4, 2])
-Point  (1 : -2 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
infinityMethod
infinity(E::EllCrv) -> EllCrvPt

Return the point at infinity with project coordinates $[0 : 1 : 0]$.

parentMethod
parent(P::EllCrvPt) -> EllCrv

Return the elliptic curve on which $P$ lies.

Examples

julia> E = elliptic_curve(QQ, [1, 2]);
-
-julia> P = E([1, -2]);
-
-julia> E == parent(P)
-true
is_on_curveMethod
is_on_curve(E::EllCrv, coords::Vector) -> Bool

Return true if coords defines a point on $E$ and false otherwise. The array coords must have length 2.

Examples

julia> E = elliptic_curve(QQ, [1, 2]);
-
-julia> is_on_curve(E, [1, -2])
-true
-
-julia> is_on_curve(E, [1, -1])
-false
+Method
+(P::EllCrvPt, Q::EllCrvPt) -> EllCrvPt

Add two points on an elliptic curve.

Examples

julia> E = elliptic_curve(QQ, [1, 2]);
-
-julia> P = E([1, -2]);
-
-julia> P + P
-Point  (-1 : 0 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
division_pointsMethod
division_points(P::EllCrvPt, m::Int) -> EllCrvPt

Compute the set of points $Q$ defined over the base field such that $mQ = P$. Returns the empty list if no such points exist.

Examples

julia> E = elliptic_curve(QQ, [1, 2]);
-
-julia> division_points(infinity(E), 2)
-2-element Vector{EllCrvPt{QQFieldElem}}:
- Point  (0 : 1 : 0)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
- Point  (-1 : 0 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
diff --git a/previews/PR2578/Hecke/elliptic_curves/finite_fields/index.html b/previews/PR2578/Hecke/elliptic_curves/finite_fields/index.html deleted file mode 100644 index 95e22a821f1a..000000000000 --- a/previews/PR2578/Hecke/elliptic_curves/finite_fields/index.html +++ /dev/null @@ -1,62 +0,0 @@ - -Elliptic curves over finite fields · Oscar.jl

Elliptic curves over finite fields

Random points

  rand(E::EllCrv{<: FinFieldElem})

Return a random point on the elliptic curve $E$ defined over a finite field.

julia> E = elliptic_curve(GF(3), [1, 2]);
-
-julia> rand(E)
-Point  (2 : 0 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2

Cardinality and orders

orderMethod
order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion

Return the order of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> order(cycle_structure(x)) == order(x), gens(g))
-true
source
order(E::EllCrv{<: FinFieldElem}) -> ZZRingElem

Given an elliptic curve $E$ over a finite field $\mathbf F$, compute $\#E(\mathbf F)$.

Examples

julia> E = elliptic_curve(GF(101), [1, 2]);
-
-julia> order(E)
-100
orderMethod
order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion

Return the order of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> order(cycle_structure(x)) == order(x), gens(g))
-true
source
order(P::EllCrvPt, [fac::Fac{ZZRingElem}]) -> ZZRingElem

Given a point $P$ on an elliptic curve $E$ over a finite field, return the order of this point.

Optionally, one can supply the factorization of a multiple of the point order, for example the order of $E$.

Examples

julia> E = elliptic_curve(GF(101), [1, 2]);
-
-julia> P = E([17, 65]);
-
-julia> order(P)
-100
-
-julia> fac = factor(order(E))
-1 * 5^2 * 2^2
-
-julia> order(P, fac)
-100

Frobenius

trace_of_frobeniusMethod
trace_of_frobenius(E::EllCrv{FinFieldElem}) -> Int

Return the trace of the Frobenius endomorphism on the elliptic curve $E$ over $\mathbf{F}_q$. This is equal to $q + 1 - n$ where n is the number of points on $E$ over $\mathbf{F}_q$.

Examples

julia> E = elliptic_curve(GF(101), [1, 2]);
-
-julia> trace_of_frobenius(E) == 101 + 1 - order(E)
-true
trace_of_frobeniusMethod
trace_of_frobenius(E::EllCrv{<: FinFieldElem}, r::Int) -> ZZRingElem

Return the trace of the $r$-th power of the Frobenius endomorphism on the elliptic curve $E$.

julia> E = elliptic_curve(GF(101, 2), [1, 2]);
-
-julia> trace_of_frobenius(E, 2)
-18802

Group structure of rational points

gensMethod
gens(E::EllCrv{<:FinFieldElem}) -> Vector{EllCrvPt}

Return a list of generators of the group of rational points on $E$.

Examples

julia> E = elliptic_curve(GF(101, 2), [1, 2]);
-
-julia> gens(E)
-2-element Vector{EllCrvPt{fqPolyRepFieldElem}}:
- Point  (93*o + 10 : 22*o + 69 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
- Point  (89*o + 62 : 14*o + 26 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
-
-julia> E = elliptic_curve(GF(101), [1, 2]);
-
-julia> gens(E)
-1-element Vector{EllCrvPt{fpFieldElem}}:
- Point  (50 : 69 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
abelian_groupMethod
abelian_group(E::EllCrv{<:FinFieldElem}) -> GrpAbFinGen, Map

Return an abelian group $A$ isomorphic to the group of rational points of $E$ and a map $E \to A$.

Warning

The map is not implemented yet.

julia> E = elliptic_curve(GF(101, 2), [1, 2]);
-
-julia> A, _ = abelian_group(E);
-
-julia> A
-GrpAb: Z/2 x Z/5200

Discrete logarithm

disc_logMethod
disc_log(P::EllCrvPt, Q::EllCrvPt, [n::IntegerUnion]) -> ZZRingElem

Return the discrete logarithm $m$ of $Q$ with respect to the base $P$, that is, $mP = Q$.

If a multiple $n$ of the order of $P$ is known, this can be supplied as an optional argument.

julia> E = elliptic_curve(GF(101), [1, 2]);
-
-julia> P = E([6, 74])
-Point  (6 : 74 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
-
-julia> Q = E([85, 43])
-Point  (85 : 43 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
-
-julia> disc_log(P, Q)
-13
diff --git a/previews/PR2578/Hecke/elliptic_curves/intro/index.html b/previews/PR2578/Hecke/elliptic_curves/intro/index.html deleted file mode 100644 index 04fa8bff8864..000000000000 --- a/previews/PR2578/Hecke/elliptic_curves/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This chapter deals with functionality for elliptic curves, which is available over arbitrary fields, with specific features available for curvers over the rationals and number fields, and finite fields.

An elliptic curve $E$ is the projective closure of the curve given by the Weierstrass equation

\[y^2 + a_1 x y + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6\]

specified by the list of coefficients [a1, a2, a3, a4, a6]. If $a_1 = a_2 = a_3 = 0$, this simplifies to

\[y^2 = x^3 + a_4 x + a_6\]

which we refer to as a short Weierstrass equation and which is specified by the two element list [a4, a6].

diff --git a/previews/PR2578/Hecke/elliptic_curves/number_fields/index.html b/previews/PR2578/Hecke/elliptic_curves/number_fields/index.html deleted file mode 100644 index e31ffb5597e0..000000000000 --- a/previews/PR2578/Hecke/elliptic_curves/number_fields/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Elliptic curves over rationals and number fields · Oscar.jl
diff --git a/previews/PR2578/Hecke/examples/index.html b/previews/PR2578/Hecke/examples/index.html deleted file mode 100644 index 6eb3d7503b7a..000000000000 --- a/previews/PR2578/Hecke/examples/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Examples and sample code · Oscar.jl
diff --git a/previews/PR2578/Hecke/examples/reduction/index.html b/previews/PR2578/Hecke/examples/reduction/index.html deleted file mode 100644 index e444e7d7c770..000000000000 --- a/previews/PR2578/Hecke/examples/reduction/index.html +++ /dev/null @@ -1,18 +0,0 @@ - -Reduction of polynomials over number fields modulo a prime ideal · Oscar.jl

Reduction of polynomials over number fields modulo a prime ideal

Given a polynomial $f \in K[x]$ and a prime ideal $\mathfrak p$ of $\mathcal O_K$, we want to determine the reduction $\bar f \in F[x]$, where $F = \mathcal O_K/\mathfrak p$ is the residue field. Concretely, we want to reduce the polynomial $f = x^3 + (1 + ζ_7 + ζ_7^2)x^2 + (23 + 55ζ_7^5)x + (ζ_7 + 77)/2$ over $\mathbf{Q}(\zeta_7)$. We begin by defining the cyclomotic field and the polynomial.


julia> K, ζ = cyclotomic_field(7);
julia> Kx, x = K['x'];
julia> f = x^3 + (1 + ζ + ζ^2)*x^2 + (23 + 55ζ^5)x + (ζ + 77)//2x^3 + (z_7^2 + z_7 + 1)*x^2 + (55*z_7^5 + 23)*x + 1//2*z_7 + 77//2

Next we determine the ring of integers $\mathcal O_K$ and a prime ideal $\mathfrak p$ lying above the prime $p = 29$.

julia> OK = maximal_order(K);
julia> p = 29;
julia> frakp = prime_decomposition(OK, p)[1][1]<29, z_7 + 22> -Norm: 29 -Minimum: 29 -two normal wrt: 29

We can now determine the residue field $F = \mathcal{O}_K/\mathfrak p$ and the canonical map $\mathcal O_K \to F$.

julia> F, reduction_map_OK = residue_field(OK, frakp);
julia> FFinite field of degree 1 over GF(29)
julia> reduction_map_OKMap with following data -Domain: -======= -Maximal order of Cyclotomic field of order 7 -with basis nf_elem[1, z_7, z_7^2, z_7^3, z_7^4, z_7^5] -Codomain: -========= -Finite field of degree 1 over GF(29)

Not that the reduction map has domain $\mathcal O_K$ and thus cannot be applied to elements of $K$. We can extend it to the set of $\mathfrak p$-integral elements by invoking the extend function. Not that the domain of the extended map will be the whole $K$, but the map will throw an error when applied to elements which are not $\mathfrak p$-integral.

julia> reduction_map_extended = extend(reduction_map_OK, K)Map with following data
-Domain:
-=======
-Cyclotomic field of order 7
-Codomain:
-=========
-Finite field of degree 1 over GF(29)
julia> reduction_map_extended(K(1//3))10
julia> reduction_map_extended(K(1//29))ERROR: Element not p-integral

Finally we can reduce $f$ modulo $\mathfrak p$, which we obtain by applying the reduction map to the coefficients.

julia> fbar = map_coefficients(reduction_map_extended, f)x^3 + 28*x^2 + 4*x + 13
julia> base_ring(fbar) === Ftrue
diff --git a/previews/PR2578/Hecke/features/macros/index.html b/previews/PR2578/Hecke/features/macros/index.html deleted file mode 100644 index c3212107d1ca..000000000000 --- a/previews/PR2578/Hecke/features/macros/index.html +++ /dev/null @@ -1,143 +0,0 @@ - -Macros · Oscar.jl

Macros

We describe here various macros provided by Hecke.

Verbosity macros

There is a list of symbols called verbosity scopes which represent keywords used to trigger some particular macros within the codes. Each of these verbosity scopes is associated with a verbosity level, being set to $0$ by default. A verbosity macro is joined to a verbosity scope S and a value k (set to $1$ by default) such that, if the current verbosity level l of S is bigger than or equal to k, then the macro triggers a given action.

add_verbosity_scopeMethod
add_verbosity_scope(s::Symbol) -> Nothing

Add the symbol s to the list of (global) verbosity scopes.

Examples

julia> add_verbosity_scope(:MyScope)
-
set_verbosity_levelMethod
set_verbosity_level(s::Symbol, l::Int) -> Int

If s represents a known verbosity scope, set the current verbosity level of s to l.

One can access the current verbosity level of s by calling the function get_verbosity_level.

If s is not yet known as a verbosity scope, the function raises an ErrorException showing the error message "Not a valid symbol". One can add s to the list of verbosity scopes by calling the function add_verbosity_scope.

Examples

julia> add_verbosity_scope(:MyScope)
-
-julia> set_verbosity_level(:MyScope, 4)
-4
-
-julia> set_verbosity_level(:MyScope, 0)
-0
get_verbosity_levelMethod
get_verbosity_level(s::Symbol) -> Int

If s represents a known verbosity scope, return the current verbosity level of s.

One can modify the current verbosity level of s by calling the function set_verbosity_level.

If s is not yet known as a verbosity scope, the function raises an ErrorException showing the error message "Not a valid symbol". One can add s to the list of verbosity scopes by calling the function add_verbosity_scope.

Examples

julia> add_verbosity_scope(:MyScope)
-
-julia> get_verbosity_level(:MyScope)
-0
-
-julia> set_verbosity_level(:MyScope, 4)
-4
-
-julia> get_verbosity_level(:MyScope)
-4
-
-julia> set_verbosity_level(:MyScope, 0)
-0
-
-julia> get_verbosity_level(:MyScope)
-0

Printings

@vprintlnMacro
@vprintln(S::Symbol, k::Int, msg::String)
-@vprintln S k msg
-
-@vprintln(S::Symbol, msg::String)
-@vprintln S msg

This macro can be used to control printings inside the code.

The macro @vprintln takes two or three arguments: a symbol S specifying a verbosity scope, an optional integer k and a string msg. If k is not specified, it is set by default to $1$.

To each verbosity scope S is associated a verbosity level l which is cached. If the verbosity level $l$ of S is bigger than or equal to $k$, the macro @vprintln triggers the printing of the associated string msg followed by a newline.

One can add a new verbosity scope by calling the function add_verbosity_scope.

When starting a new instance, all the verbosity levels are set to $0$. One can adjust the verbosity level of a verbosity scope by calling the function set_verbosity_level.

One can access the current verbosity level of a verbosity scope by calling the function get_verbosity_level.

Examples

We will set up different verbosity scopes with different verbosity levels in a custom function to show how to use this macro.

julia> add_verbosity_scope(:Test1);
-
-julia> add_verbosity_scope(:Test2);
-
-julia> add_verbosity_scope(:Test3);
-
-julia> set_verbosity_level(:Test1, 1);
-
-julia> set_verbosity_level(:Test2, 3);
-
-julia> function vprint_example()
-       @vprintln :Test1 "Triggered"
-       @vprintln :Test2 2 "Triggered"
-       @vprintln :Test3 "Not triggered"
-       @vprintln :Test2 4 "Not triggered"
-       end
-vprint_example (generic function with 1 method)
-
-julia> vprint_example()
-Triggered
-Triggered

If one does not setup in advance a verbosity scope, the macro will raise an ExceptionError showing the error message "Not a valid symbol".

@vprintMacro
@vprint(S::Symbol, k::Int, msg::String)
-@vprint S k msg
-
-@vprint(S::Symbol, msg::String)
-@vprint S msg

The same as @vprintln, but without the final newline.

Actions

@v_doMacro
@v_do(S::Symbol, k::Int, act::Expr)
-@v_do S k act
-
-@v_do(S::Symbol, act::Expr)
-@v_do S act

This macro can be used to control actions inside the code.

The macro @v_do takes two or three arguments: a symbol S specifying a verbosity scope, an optional integer k and an action act. If k is not specified, it is set by default to $1$.

To each verbosity scope S is associated a verbosity level l. If the verbosity level $l$ of S is bigger than or equal to $k$, the macro @v_do triggers the action act.

One can add a new verbosity scope by calling the function add_verbosity_scope.

When starting a new instance, all the verbosity levels are set to $0$. One can adjust the verbosity level of a verbosity scope by calling the function set_verbosity_level.

One can access the current verbosity level of a verbosity scope by calling the function get_verbosity_level.

Examples

We will set up different verbosity scopes with different verbosity levels in a custom function to show how to use this macro.

julia> add_verbosity_scope(:Test1);
-
-julia> add_verbosity_scope(:Test2);
-
-julia> add_verbosity_scope(:Test3);
-
-julia> set_verbosity_level(:Test1, 1);
-
-julia> set_verbosity_level(:Test2, 3);
-
-julia> function v_do_example(a::Int, b::Int, c::Int, d::Int)
-       @v_do :Test1 a = 2*a
-       @v_do :Test2 2 b = 3*b
-       @v_do :Test3 c = 4*c
-       @v_do :Test2 4 d = 5*d
-       return (a, b, c, d)
-       end
-v_do_example (generic function with 1 method)
-
-julia> v_do_example(1,1,1,1)
-(2, 3, 1, 1)

If one does not setup in advance a verbosity scope, the macro will raise an ExceptionError showing the error message "Not a valid symbol".

Assertion macros

There is a list of symbols called assertion scopes which represent keywords used to trigger some particular macros within the codes. Each of these assertion scopes is associated with an assertion level, being set to $0$ by default. An assertion macro is joined to an assertion scope S and a value k (set to $1$ by default) such that, if the current assertion level l of S is bigger than or equal to k, then the macro triggers an action on the given assertion

add_assertion_scopeMethod
add_assertion_scope(s::Symbol) -> Nothing

Add the symbol s to the list of (global) assertion scopes.

Examples

julia> add_assertion_scope(:MyScope)
-
set_assertion_levelMethod
set_assertion_level(s::Symbol, l::Int) -> Int

If s represents a known assertion scope, set the current assertion level of s to l.

One can access the current assertion level of s by calling the function get_assertion_level.

If s is not yet known as an assertion scope, the function raises an ErrorException showing the error message "Not a valid symbol". One can add s to the list of assertion scopes by calling the function add_assertion_scope.

Examples

julia> add_assertion_scope(:MyScope)
-
-julia> set_assertion_level(:MyScope, 4)
-4
-
-julia> set_assertion_level(:MyScope, 0)
-0
get_assertion_levelMethod
get_assertion_level(s::Symbol) -> Int

If s represents a symbol of a known assertion scope, return the current assertion level of s.

One can modify the current assertion level of s by calling the function set_assertion_level.

If s is not yet known as an assertion scope, the function raises an ErrorException showing the error message "Not a valid symbol". One can add s to the list of assertion scopes by calling the function add_assertion_scope.

Examples

julia> add_assertion_scope(:MyScope)
-
-julia> get_assertion_level(:MyScope)
-0
-
-julia> set_assertion_level(:MyScope, 1)
-1
-
-julia> get_assertion_level(:MyScope)
-1
-
-julia> set_assertion_level(:MyScope, 0)
-0
-
-julia> get_assertion_level(:MyScope)
-0

Check

@hassertMacro
@hassert(S::Symbol, k::Int, assert::Expr)
-@hassert S k assert
-
-@hassert(S::Symbol, assert::Expr)
-@hassert S assert

This macro can be used to control assertion checks inside the code.

The macro @hassert takes two or three arguments: a symbol S specifying an assertion scope, an optional integer k and an assertion assert. If k is not specified, it is set by default to $1$.

To each assertion scope S is associated an assertion level l which is cached. If the assertion level $l$ of S is bigger than or equal to $k$, the macro @hassert triggers the check of the assertion assert. If assert is wrong, an AssertionError is thrown.

One can add a new assertion scope by calling the function add_assertion_scope.

When starting a new instance, all the assertion levels are set to $0$. One can adjust the assertion level of an assertion scope by calling the function set_assertion_level.

One can access the current assertion level of an assertion scope by calling the function get_assertion_level.

Examples

We will set up different assertion scopes with different assertion levels in a custom function to show how to use this macro.

julia> add_assertion_scope(:MyScope)
-
-julia> get_assertion_level(:MyScope)
-0
-
-julia> function hassert_test(x::Int)
-       @hassert :MyScope 700 mod(x, 3) == 0
-       return div(x, 3)
-       end
-hassert_test (generic function with 1 method)
-
-julia> hassert_test(2)
-0
-
-julia> set_assertion_level(:MyScope, 701);
-
-julia> try hassert_test(2)
-       catch e e
-       end
-AssertionError("\$(Expr(:escape, :(mod(x, 3) == 0)))")
-
-julia> hassert_test(3)
-1
-
-julia> set_assertion_level(:MyScope, 0)
-0

If one does not setup in advance an assertion scope, the macro will raise an ExceptionError showing the error message "Not a valid symbol".

Miscellaneous

@reqMacro
@req(assert, msg)
-@req assert msg

Check whether the assertion assert is true. If not, throw an ArgumentError with error message msg.

The macro @req takes two arguments: the first one is an assertion assert (an expression which returns a boolean) and a string msg corresponding to the desired error message to be returned whenever assert is false.

If the number of arguments is not 2, an AssertionError is raised.

Examples

julia> function req_test(x::Int)
-       @req iseven(x) "x must be even"
-       return div(x,2)
-       end
-req_test (generic function with 1 method)
-
-julia> try req_test(3)
-       catch e e
-       end
-ArgumentError("x must be even")
-
-julia> try req_test(2)
-       catch e e
-       end
-1
-
diff --git a/previews/PR2578/Hecke/function_fields/basics/index.html b/previews/PR2578/Hecke/function_fields/basics/index.html deleted file mode 100644 index a0f70b3c73dd..000000000000 --- a/previews/PR2578/Hecke/function_fields/basics/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -- · Oscar.jl
diff --git a/previews/PR2578/Hecke/function_fields/degree_localization/index.html b/previews/PR2578/Hecke/function_fields/degree_localization/index.html deleted file mode 100644 index 867fb5aaba9d..000000000000 --- a/previews/PR2578/Hecke/function_fields/degree_localization/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Degree localization of a rational function field · Oscar.jl

Degree localization of a rational function field

Degree localization

Given $k(x)$ a (univariate) rational function field, there are two rings of interest, both of which are Euclidean:

  • \[k[x]\]

  • k_\infty(x) = {a/b | a, b \in k[x] \;\;\mbox{where}\;\; \deg(a) \leq \deg(b)}

The second of these rings is the localization of $k[1/x]$ at $(1/x)$ inside the rational function field $k(x)$, i.e. the localization of the function field at the point at infinity, i.e. the valuation ring for valuation $-$degree$(x)$.

We refer to this ring as the degree localization of the rational function field $k(x)$.

Construction of the degree localization

The degree localization of a rational function field $k(x)$ can be constructed using a localization constructor, passing in the degree function as argument.

localizationMethod
localization(K::RationalFunctionField{T}, ::typeof(degree)) where T <: FieldElement

Return the localization of $k[1/x]$ at $(1/x)$ inside the rational function field $k(x)$, i.e. the localization of the function field at the point at infinity, i.e. the valuation ring for valuation $-$degree$(x)$. This is the ring $k_\infty(x) = \{ f/g | \deg(f) \leq \deg(g)\}$.


Example +


julia> K, x = RationalFunctionField(FlintQQ, "x");
julia> R = localization(K, degree)Degree localization of Rational function field over QQ

Elements of the degree localization

Elements of the degree localization are created using the parent object $R$ representing the degree localization


Example +


julia> K, x = RationalFunctionField(FlintQQ, "x");
julia> R = localization(K, degree)Degree localization of Rational function field over QQ
julia> a = R()0
julia> b = R(1)1
julia> c = R((x + 1)//x)(x + 1)//x

Note that the degree of the denominator of the function field element passed to the constructor must be at least that of the numerator or an exception is raised.

Element functionality

degreeMethod
 degree(a::KInftyElem)

Return the degree of the given element, i.e. degree(numerator) - degree(denominator).

valuationMethod
valuation(a::KInftyElem)

Return the degree valuation of the given element, i.e. -degree(a).

One can test whether a given element of a rational function field is in the degree localization.

inMethod
in(a::Generic.RationalFunctionFieldElem{T}, R::KInftyRing{T}) where T <: FieldElement

Return true if the given element of the rational function field is an element of k_\infty(x), i.e. if degree(numerator) <= degree(denominator).

All basic arithmetic operations are provided for elements of the degree localization.

As the degree localization is a Euclidean ring, all standard Euclidean functions, including div, divrem, mod, gcd, gcdx, are provided.

diff --git a/previews/PR2578/Hecke/function_fields/elements/index.html b/previews/PR2578/Hecke/function_fields/elements/index.html deleted file mode 100644 index 5c425a39104c..000000000000 --- a/previews/PR2578/Hecke/function_fields/elements/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -- · Oscar.jl
diff --git a/previews/PR2578/Hecke/function_fields/internal/index.html b/previews/PR2578/Hecke/function_fields/internal/index.html deleted file mode 100644 index 3f891fc6d12a..000000000000 --- a/previews/PR2578/Hecke/function_fields/internal/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -- · Oscar.jl

Function fields, in Hecke, come in several different types:

  • RationalFunctionField: a field of the form $k(x)$ for a field $k$.
  • FunctionField: a finite extension of a rational function field given by a polynomial.

Function fields with the type FunctionField are referred to as simple fields in the rest of this document. They are also referred to as being absolute.

Absolute Simple Fields

Internally function fields of type FunctionField are essentially represented as a unvariate quotient with the arithmetic provided by the AbstractAlgebra and Nemo packages. As they are defined generically for all AbstractAlgebra, Nemo and Hecke fields $k$ the function field type is implemented in AbstractAlgebra.

diff --git a/previews/PR2578/Hecke/function_fields/intro/index.html b/previews/PR2578/Hecke/function_fields/intro/index.html deleted file mode 100644 index b5b7c482f79c..000000000000 --- a/previews/PR2578/Hecke/function_fields/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Function Fields · Oscar.jl

Function Fields

By definition, a (univariate) function field can be written as a finite extension of a rational function field $k(x)$ for a field $k$ (commonly $k = \mathbb{Q}$ or $k = \mathbb{F}_p$). In Hecke, a function field $L$ is currently defined as being a (univariate) rational function field $k(x)$ or a finite extension thereof. In other words, the extension is defined in the the following way:

  • We have $L = k(x)/(f)$, where $f \in k(x)[y]$ is an irreducible polynomial (simple extension)

We refer to $k(x)$ as the base field of the function field $L$. We call $L$ an absolute function field if the base field is equal to the rational function field $k(x)$.

diff --git a/previews/PR2578/Hecke/index.html b/previews/PR2578/Hecke/index.html deleted file mode 100644 index 514e9290829b..000000000000 --- a/previews/PR2578/Hecke/index.html +++ /dev/null @@ -1,32 +0,0 @@ - -Hecke · Oscar.jl

Hecke

About

Hecke is a software package for algebraic number theory maintained by Claus Fieker, Carlo Sircana and Tommy Hofmann. It is written in julia and is based on the computer algebra package Nemo.

So far, Hecke provides the following features:

  • Orders (including element and ideal arithmetic) in number fields
  • Computation of maximal orders
  • Verified residue computations of Dedekind zeta functions
  • Class and Unit group computation, S-units, PID testing
  • Lattice enumeration
  • Sparse linear algebra
  • Normal forms for modules over maximal orders
  • Extensions of number fields, non-simple extensions of number fields
  • Orders and ideals in extensions of fields
  • Abelian groups
  • Ray class groups, quotients of ray class groups
  • Invariant subgroups
  • Class Field Theory
  • Associative Algebras

Installation

To use Hecke, a julia version of 1.6 is necessary (the latest stable julia version will do). Please see https://julialang.org/downloads/ for instructions on how to obtain julia for your system. Once a suitable julia version is installed, use the following steps at the julia prompt to install Hecke:

julia> using Pkg
-julia> Pkg.add("Hecke")

Quick start

Here is a quick example of using Hecke:

julia> using Hecke
-...
-
-Welcome to
-
-  _    _           _
- | |  | |         | |
- | |__| | ___  ___| | _____
- |  __  |/ _ \/ __| |/ / _ \
- | |  | |  __/ (__|   <  __/
- |_|  |_|\___|\___|_|\_\___|
-
-Version 0.9.0 ...
- ... which comes with absolutely no warranty whatsoever
-(c) 2015-2018 by Claus Fieker, Tommy Hofmann and Carlo Sircana
-
-julia> Qx, x = polynomial_ring(FlintQQ, "x");
-julia> f = x^3 + 2;
-julia> K, a = number_field(f, "a");
-julia> O = maximal_order(K);
-julia> O
-Maximal order of Number field over Rational Field with defining polynomial x^3 + 2
-with basis [1,a,a^2]

The documentation of the single functions can also be accessed at the julia prompt. Here is an example:

help?> signature
-search: signature
-
-  ----------------------------------------------------------------------------
-
-  signature(O::NfMaximalOrder) -> Tuple{Int, Int}
-
-  |  Returns the signature of the ambient number field of \mathcal O.
diff --git a/previews/PR2578/Hecke/misc/Map/index.html b/previews/PR2578/Hecke/misc/Map/index.html deleted file mode 100644 index e38793f988b9..000000000000 --- a/previews/PR2578/Hecke/misc/Map/index.html +++ /dev/null @@ -1,16 +0,0 @@ - -Map from julia functions · Oscar.jl

Map from julia functions

For the situation where it is desirable to create a Map given arbitrary callable julia objects (like anonymous functions), the type MapFromFunc is provided.

MapFromFuncType
MapFromFunc(D, C, f, [g])

Creates the map D -> C, x -> f(x) given the callable object f. If g is provided, it is assumed to satisfy f(g(x)) = x and will be used as the preimage function.

Example

julia> F = GF(2);
-
-julia> f = MapFromFunc(QQ, F, x -> F(numerator(x)) * inv(F(denominator(x))))
-Map from
-Rational field to Finite field of characteristic 2 defined by a julia-function
-
-julia> f(QQ(1//3))
-1
-
-julia> f = MapFromFunc(QQ, F, x -> F(numerator(x)) * inv(F(denominator(x))), y -> QQ(lift(y)),)
-Map from
-Rational field to Finite field of characteristic 2 defined by a julia-function with inverse
-
-julia> preimage(f, F(1))
-1
Note

When applying an object f of type MapFromFunc to an element x, it will be checked whether the parent of x coincides with the domain and whether the parent of f(x) coincides with the codomain of f. Similar for the optional preimage function.

diff --git a/previews/PR2578/Hecke/misc/conjugacy/index.html b/previews/PR2578/Hecke/misc/conjugacy/index.html deleted file mode 100644 index d0ff25e7988b..000000000000 --- a/previews/PR2578/Hecke/misc/conjugacy/index.html +++ /dev/null @@ -1,15 +0,0 @@ - -Conjugacy of integral matrices · Oscar.jl

Conjugacy of integral matrices

is_GLZ_conjugateMethod
is_GLZ_conjugate(A::MatElem, B::MatElem) -> Bool, MatElem

Given two integral or rational matrices, determine whether there exists an invertible integral matrix $T$ with $TA = BT$. If true, the second argument is such a matrix $T$. Otherwise, the second argument is unspecified.

julia> A = matrix(ZZ, 4, 4, [ 0, 1,  0, 0,
-                             -4, 0,  0, 0,
-                              0, 0,  0, 1,
-                              0, 0, -4, 0]);
-
-julia> B = matrix(ZZ, 4, 4,  [ 0, 1,  4,  0,
-                              -4, 0,  0, -4,
-                               0, 0,  0,  1,
-                               0, 0, -4,  0]);
-
-julia> fl, T = is_GLZ_conjugate(A, B);
-
-julia> isone(abs(det(T))) && T * A == B * T
-true
diff --git a/previews/PR2578/Hecke/misc/index.html b/previews/PR2578/Hecke/misc/index.html deleted file mode 100644 index aa9204d3c941..000000000000 --- a/previews/PR2578/Hecke/misc/index.html +++ /dev/null @@ -1,25 +0,0 @@ - -Miscalleneous · Oscar.jl

Miscalleneous

euler_phi_invFunction
euler_phi_inv(n::Integer) -> Vector{ZZRingElem}

The inverse of the Euler totient functions: find all $x$ s.th. $phi(x) = n$ holds.

euler_phi_inv(n::ZZRingElem) -> Vector{ZZRingElem}

The inverse of the Euler totient functions: find all $x$ s.th. $phi(x) = n$ holds.

euler_phi_inv(n::ZZRingElem, zk::NfAbsOrd{AnticNumberField, nf_elem}) -> Vector{NfOrdIdl}

The inverse of the ideal totient function: all ideals $A$ s.th. the unit group of the residue ring has the required size.

modordMethod
modord(a::ZZRingElem, m::ZZRingElem) -> Int
-modord(a::Integer, m::Integer)

The multiplicative order of a modulo $m$ (not a good algorithm).

is_prime_powerMethod
is_prime_power(n::ZZRingElem) -> Bool
-is_prime_power(n::Integer) -> Bool

Tests if $n$ is the exact power of a prime number.

primes_up_toMethod
primes_up_to(n::Int) -> Vector{Int}

Returns a vector containing all the prime numbers up to $n$.

Analytic

dickman_rhoFunction
dickman_rho(x::Number, prec::Int=55) Number

Evaluates the Dickman-$\rho$ function at $x$.

dickman_rho(x::Number, e::AbstractUnitRange{Int}, prec::Int=55) Number[]

Evaluates the Dickman-$\rho$ function at $i*x$ for all $i\in e$.

psi_guessFunction
psi_guess(x::Number, B::Int) Number

Uses the dickman_rho function to estimate $\psi(x, B)$ the number of $B$-smooth integers bounded by $x$.

psi_guess(x::Number, e::AbstractUnitRange, B::Int) Number

Uses the dickman_rho function to estimate $\psi(x^i, B)$ the number of $B$-smooth integers bounded by $x^i$ for $i \in e$.

psi_lowerFunction
psi_lower(N::Integer, B::Int, a::Int = 776) -> Vector{Int}, ZZAbsPowerSeriesRingElem
-psi_lower(N::ZZRingElem, B::Int, a::Int = 776) -> Vector{Int}, ZZAbsPowerSeriesRingElem

Uses Bernstein's ideas: https://cr.yp.to/papers/psi.pdf to compute lower bounds on the psi function counting smooth numbers. An array $L$ is returned s.th. $\psi(2^{i-1}, B) \ge L_i$ for $1\le i\le \rceil \log_2(B)\lceil$. The second return value is Bernstein's power series.

The optional other parameter $a$ controls the precision of the result, it defaults to 776.

psi_lower(N::Integer, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem
-psi_lower(N::ZZRingElem, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem
-
-psi_upper(N::Integer, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem
-psi_upper(N::ZZRingElem, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem

Uses Bernstein's techniques to bound the number of ideals $A$ of norm bounded by $N$ that are smooth over the factor base $B$.

Linear Algebra

largest_elementary_divisorFunction
largest_elementary_divisor(A::ZZMatrix) -> ZZRingElem

The largest elementary divisor of $A$, that is, the last diagonal entry of the Smith normal form of $A$.

maximal_elementary_divisorMethod
maximal_elementary_divisor(A::ZZMatrix) -> ZZRingElem

The largest elementary divisor of $A$, that is, the last diagonal entry of the Smith normal form of $A$.

mod_symMethod
mod_sym(M::ZZMatrix, p::ZZRingElem) -> ZZMatrix

Reduces every entry modulo $p$ into the symmetric residue system.

mod_sym!Method
mod_sym!(M::ZZMatrix, p::ZZRingElem)

Reduces every entry modulo $p$ in-place, into the symmetric residue system.

mod!Method
mod!(M::ZZMatrix, p::ZZRingElem)

Reduces every entry modulo $p$ in-place, i.e. applies the mod function to every entry. Positive residue system.

saturateMethod
saturate(A::ZZMatrix) -> ZZMatrix

Computes the saturation of $A$, that is, a basis for $\mathbf{Q}\otimes M \cap \mathbf{Z}^n$, where $M$ is the row span of $A$ and $n$ the number of columns of $A$.

Equivalently, return $TA$ (minus zero rows) for an invertible rational matrix $T$ such that $TA$ is integral and the elementary divisors of $TA$ are all trivial.

Examples

julia> saturate(ZZ[1 2 3;4 5 6;7 0 7])
-[1    2    3]
-[1    1    1]
-[0   -1   -1]
-
-julia> saturate(ZZ[1 2 3;4 5 6;7 8 9])
-[1   2   3]
-[1   1   1]
-
-julia> saturate(ZZ[1 2 3;4 5 6])
-[1   2   3]
-[1   1   1]
-
-julia> saturate(ZZ[1 2;3 4;5 6])
-[1   2]
-[1   1]
-
elementary_divisorsMethod
elementary_divisors(A::ZZMatrix) -> Vector{ZZRingElem}

The elementary divisors of $A$, that is, the diagonal entries of the Smith normal form of $A$.

jordan_normal_formFunction
jordan_normal_form(M::MatElem{T}) where T <: FieldElem -> MatElem{T}, MatElem{T}

Returns matrices $J$ and $S$ such that $J = SMS^{-1}$ and $J$ is in Jordan normal form.

divisorsMethod
divisors(A::ZZMatrix, d::ZZRingElem) -> ZZRingElem

Returns the diagonal entries of a diagonal form of $A$. We assume that all the elementary divisors are divisors of $d$.

snf_with_transformMethod
snf_with_transform(A::ZZMatrix, l::Bool = true, r::Bool = true) -> ZZMatrix, ZZMatrix, ZZMatrix

Given some integer matrix $A$, compute the Smith normal form (elementary divisor normal form) of $A$. If l and/ or r are true, then the corresponding left and/ or right transformation matrices are computed as well.

snf_with_transform(A)

Return the tuple $S, T, U$ consisting of the Smith normal form $S$ of $A$ together with invertible matrices $T$ and $U$ such that $TAU = S$.

Polynomials

CRT

induce_crtFunction
induce_crt(a::ZZPolyRingElem, p::ZZRingElem, b::ZZPolyRingElem, q::ZZRingElem, signed::Bool = false) -> ZZPolyRingElem

Given integral polynomials $a$ and $b$ as well as coprime integer moduli $p$ and $q$, find $f = a \bmod p$ and $f=b \bmod q$. If signed is set, the symmetric representative is used, the positive one otherwise.

induce_crt(L::Vector{PolyElem}, c::crt_env{ZZRingElem}) -> ZZPolyRingElem

Given ZZRingElem_poly polynomials $L[i]$ and a crt\_env, apply the crt function to each coefficient resulting in a polynomial $f = L[i] \bmod p[i]$.

induce_crt(L::Vector{MatElem}, c::crt_env{ZZRingElem}) -> ZZMatrix

Given matrices $L[i]$ and a crt\_env, apply the crt function to each coefficient resulting in a matrix $M = L[i] \bmod p[i]$.

induce_crt(a::Generic.Poly{nf_elem}, p::ZZRingElem, b::Generic.Poly{nf_elem}, q::ZZRingElem) -> Generic.Poly{nf_elem}, ZZRingElem

Given polynomials $a$ defined modulo $p$ and $b$ modulo $q$, apply the CRT to all coefficients recursively. Implicitly assumes that $a$ and $b$ have integral coefficients (i.e. no denominators).

induce_rational_reconstructionFunction
induce_rational_reconstruction(a::ZZPolyRingElem, M::ZZRingElem) -> QQPolyRingElem

Apply rational_reconstruction to each coefficient of $a$, resulting in either a fail (return (false, s.th.)) or (true, g) for some rational polynomial $g$ s.th. $g \equiv a \bmod M$.

induce_rational_reconstruction(a::Generic.Poly{nf_elem}, M::ZZRingElem) -> bool, Generic.Poly{nf_elem}

Apply rational reconstruction to the coefficients of $a$. Implicitly assumes the coefficients to be integral (no checks done) returns true iff this is successful for all coefficients.

diff --git a/previews/PR2578/Hecke/number_fields/complex_embeddings/index.html b/previews/PR2578/Hecke/number_fields/complex_embeddings/index.html deleted file mode 100644 index 43b51a46a065..000000000000 --- a/previews/PR2578/Hecke/number_fields/complex_embeddings/index.html +++ /dev/null @@ -1,135 +0,0 @@ - -Complex embedding · Oscar.jl

Complex embedding

We describe functionality for complex embeddings of arbitrary number fields. Note that a complex embeddding of a number field $L$ is a morphism $\iota \colon L \to \mathbf{C}$. Such an embedding is called real if $\operatorname{im}(\iota) \subseteq \mathbf{R}$ and imaginary otherwise.

Construction of complex embeddings

complex_embeddingsMethod
complex_embeddings(K::NumField; conjugates::Bool = true) -> Vector{NumFieldEmb}

Return the complex embeddings of $K$. If conjugates is false, only one imaginary embedding per conjugated pairs is returned.

Examples

julia> K, a = quadratic_field(-3);
-
-julia> complex_embeddings(K)
-2-element Vector{Hecke.NumFieldEmbNfAbs}:
- Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field defined by x^2 + 3
- Complex embedding corresponding to 0.00 - 1.73 * i of imaginary quadratic field defined by x^2 + 3
-
-julia> complex_embeddings(K, conjugates = false)
-1-element Vector{Hecke.NumFieldEmbNfAbs}:
- Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field defined by x^2 + 3
real_embeddingsMethod
real_embeddings(K::NumField) -> Vector{NumFieldEmb}

Return the real embeddings of $K$.

Examples

julia> K, a = quadratic_field(3);
-
-julia> real_embeddings(K)
-2-element Vector{Hecke.NumFieldEmbNfAbs}:
- Embedding corresponding to ≈ -1.73
- Embedding corresponding to ≈ 1.73

Properties

number_fieldMethod
number_field(f::NumFieldEmb) -> NumField

Return the corresponding number field of the embedding $f$.

Examples

julia> K, a = quadratic_field(-3); e = complex_embeddings(K)[1];
-
-julia> number_field(e)
-Imaginary quadratic field defined by x^2 + 3
is_realMethod
is_real(f::NumFieldEmb) -> Bool

Return true if the embedding is real.

Examples

julia> K, a = quadratic_field(3); e = complex_embeddings(K)[1];
-
-julia> is_real(e)
-true
is_imaginaryMethod
is_imaginary(f::NumFieldEmb) -> Bool

Returns true if the embedding is imaginary, that is, not real.

Examples

julia> K, a = quadratic_field(-3); e = complex_embeddings(K)[1];
-
-julia> is_imaginary(e)
-true

Conjugated embedding

conjMethod
conj(f::NumFieldEmb) -> NumFieldEmb

Returns the conjugate embedding of f.

Examples

julia> K, a = quadratic_field(-3); e = complex_embeddings(K);
-
-julia> conj(e[1]) == e[2]
-true

Evaluating elements at complex embeddings

Given an embedding $f \colon K \to \mathbf{C}$ and an element $x$ of $K$, the image $f(x)$ of $x$ under $f$ can be constructed as follows.

    (f::NumFieldEmb)(x::NumFieldElem, prec::Int = 32) -> acb
  • Note that the return type will be a complex ball of type acb. The radius r of the ball is guaranteed to satisfy r < 2^(-prec).
  • If the embedding is real, then the value c will satisfy is_real(c) == true.

For convenience, we also provide the following function to quickly create a corresponding anonymous function:

evaluation_functionMethod
evaluation_function(e::NumFieldEmb, prec::Int) -> Function

Return the anonymous function x -> e(x, prec).

Examples

julia> K, a = quadratic_field(-3);
-
-julia> e = complex_embeddings(K)[1];
-
-julia> fn = evaluation_function(e, 64);
-
-julia> fn(a)
-[+/- 3.99e-77] + [1.73205080756887729353 +/- 5.41e-21]*im

Logarithmic embedding

Given an object e representing an embedding $\iota \colon L \to \mathbf{C}$, the corresponding logarithmic embedding $L \to \mathbf{R}, \ x \mapsto \log(\lvert \iota(x) \rvert)$ can be constructed as log(abs(e)).

julia> K, a = quadratic_field(2);
-
-julia> e = complex_embedding(K, 1.41)
-Embedding of
-Real quadratic field defined by x^2 - 2
-corresponding to ≈ 1.41
-
-julia> log(abs(e))(a, 128)
-[0.346573590279972654708616060729088284037750067180127627 +/- 4.62e-55]
-
-julia> log(abs(e(a)))
-[0.346573590 +/- 2.99e-10]

Restriction

Given a subfield $\iota \colon k \to K$, any embedding $f \colon K \to \mathbf{C}$ naturally restricts to a complex embedding of $K$. Computing this restriction is supported in case $k$ appears as a base field of (a base field) of $K$ or $\iota$ is provided:

restrictMethod
restrict(f::NumFieldEmb, K::NumField)

Given an embedding $f$ of a number field $L$ and a number field $K$ appearing as a base field of $L$, return the restriction of $f$ to $K$.

Examples

julia> K, a = quadratic_field(3);
-
-julia> L, b = number_field(polynomial(K, [1, 0, 1]), "b");
-
-julia> e = complex_embeddings(L);
-
-julia> restrict(e[1], K)
-Complex embedding corresponding to -1.73
-  of number field with defining polynomial x^2 - 3
-    over rational field
restrictMethod
restrict(f::NumFieldEmb, g::NumFieldMor)

Given an embedding $f$ of a number field $L$ and a morphism $g \colon K \to L$, return the embedding $g \circ f$ of $K$.

This is the same as g * f.

Examples

julia> K, a = CyclotomicField(5, "a");
-
-julia> k, ktoK = Hecke.subfield(K, [a + inv(a)]);
-
-julia> e = complex_embeddings(K);
-
-julia> restrict(e[1], ktoK)
-Complex embedding corresponding to 0.62
-  of number field with defining polynomial x^2 + x - 1
-    over rational field

Extension

Given a complex embedding $f \colon k \to \mathbf{C}$ and a morphism $\iota \colon k \to K$, an embedding $g \colon K \to \mathbf{C}$ is extension of $f$, if $g$ restricts to $f$. Given an embedding and a morphism, all extensions can be computed as follows:

extendMethod
extend(e::NumFieldEmb, f::NumFieldMor)

Given an embedding $e$ of $k$ and a morphism $f \colon k \to K$, determine all embedings of $K$ which restrict to $e$ along $f$.

Example

julia> K, a = CyclotomicField(5, "a");
-
-julia> k, ktoK = Hecke.subfield(K, [a + inv(a)]);
-
-julia> e = complex_embeddings(k)[1];
-
-julia> extend(e, ktoK)
-2-element Vector{Hecke.NumFieldEmbNfAbs}:
- Complex embedding corresponding to -0.81 + 0.59 * i of cyclotomic field of order 5
- Complex embedding corresponding to -0.81 - 0.59 * i of cyclotomic field of order 5

Positivity & Signs

signMethod
sign(x::NumFieldElem, e::NumFieldEmb) -> Int

Given a number field element x and a complex embedding e, return 1, -1 or 0 depending on whether e(x) is positive, negative, or zero.

Examples

julia> K, a = quadratic_field(3);
-
-julia> e = complex_embedding(K, 1.7);
-
-julia> sign(a, e)
-1
signsMethod
signs(a::NumFieldElem, [embs::Vector{NumFieldEmb} = real_embeddings(K)])
-                                                   -> Dict{NumFieldEmb, Int}

Return the signs of a at the real embeddings in embs as a dictionary, which are by default all real embeddings of the number field.

Examples

julia> K, a = quadratic_field(3);
-
-julia> signs(a)
-Dict{Hecke.NumFieldEmbNfAbs, Int64} with 2 entries:
-  Complex embedding corresponding to -1.73 of real quadratic field define… => -1
-  Complex embedding corresponding to 1.73 of real quadratic field defined… => 1
is_positiveMethod
is_positive(a::NumFieldElem, e::NumFieldEmb)   -> Bool

Given a number field element a and a real embedding e, return whether a is positive at e.

Examples

julia> K, a  = quadratic_field(5);
-
-julia> e = complex_embedding(K, 2.1);
-
-julia> is_positive(a, e)
-true
is_positiveMethod
is_positive(a::NumFieldElem, embs::Vector{NumFieldEmb}) -> Bool

Return whether the element $a$ is positive at all embeddings of embs. All embeddings in embs must be real.

julia> K, a  = quadratic_field(5);
-
-julia> e = complex_embedding(K, 2.1);
-
-julia> e(a)
-[2.236067977 +/- 5.02e-10]
-
-julia> is_positive(a, [e])
-true
is_totally_positiveMethod
is_totally_positive(a::NumFieldElem) -> Bool

Return whether the element $a$ is totally positive, that is, whether it is positive at all real embeddings of the ambient number field.

is_negativeMethod
is_negative(a::NumFieldElem, e::NumFieldEmb)   -> Bool

Given a number field element a and a real embedding e, return whether a is positive at e.

Examples

julia> K, a  = quadratic_field(5);
-
-julia> e = complex_embedding(K, 2.1);
-
-julia> is_negative(a, e)
-false
is_negativeMethod
is_negative(a::NumFieldElem, embs::Vector{NumFieldEmb}) -> Bool

Return whether the element $a$ is positive at all embeddings of embs. All embeddings in embs must be real.

Examples

julia> K, a  = quadratic_field(5);
-
-julia> e = complex_embedding(K, -2.1);
-
-julia> e(a)
-[-2.236067977 +/- 5.02e-10]
-
-julia> is_negative(a, [e])
-true

Example

As mentioned, this functionality works for all types of number fields. Here is an example of an absolute non-simple number field.

julia> Qx, x = QQ["x"];
-
-julia> K, a = number_field([x^2 + 1, x^3 + 2], "a");
-
-julia> emb = complex_embeddings(K)
-6-element Vector{Hecke.NumFieldEmbNfAbsNS}:
- Complex embedding corresponding to [1.00 * i, -1.26] of non-simple number field
- Complex embedding corresponding to [1.00 * i, 0.63 + 1.09 * i] of non-simple number field
- Complex embedding corresponding to [-1.00 * i, 0.63 + 1.09 * i] of non-simple number field
- Complex embedding corresponding to [-1.00 * i, -1.26] of non-simple number field
- Complex embedding corresponding to [-1.00 * i, 0.63 - 1.09 * i] of non-simple number field
- Complex embedding corresponding to [1.00 * i, 0.63 - 1.09 * i] of non-simple number field
-
-julia> k, b = quadratic_field(-1);
-
-julia> i = hom(k, K, a[1]);
-
-julia> restrict(emb[1], i)
-Complex embedding corresponding to 1.00 * i
-  of number field with defining polynomial x^2 + 1
-    over rational field
-
-julia> restrict(emb[3], i)
-Complex embedding corresponding to -1.00 * i
-  of number field with defining polynomial x^2 + 1
-    over rational field
diff --git a/previews/PR2578/Hecke/number_fields/conventions/index.html b/previews/PR2578/Hecke/number_fields/conventions/index.html deleted file mode 100644 index 3b3e7d88f08c..000000000000 --- a/previews/PR2578/Hecke/number_fields/conventions/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -- · Oscar.jl

Number fields

By an absolute number field we mean finite extensions of $\mathbf Q$, which is of type AnticNumberField and whose elements are of type nf_elem. Such an absolute number field $K$ is always given in the form $K = \mathbf Q(\alpha) = \mathbf Q[X]/(f)$, where $f \in \mathbf Q[X]$ is an irreducible polynomial. See here for more information on the different types of fields supported.

We call $(1,\alpha,\alpha^2,\dotsc,\alpha^{d-1})$, where $d$ is the degree $[K : \mathbf Q]$ the power basis of $K$. If $\beta$ is any element of $K$, then the representation matrix of $\beta$ is the matrix representing $K \to K, \gamma \mapsto \beta \gamma$ with respect to the power basis, that is,

\[\beta \cdot (1,\alpha,\dotsc,\alpha^{d-1}) = M_\alpha (1, \alpha, \dotsc, \alpha^{d-1}).\]

Let $(r,s)$ be the signature of $K$, that is, $K$ has $r$ real embeddings $\sigma_i \colon K \to \mathbf{R}$, $1 \leq i \leq r$, and $2s$ complex embeddings $\sigma_i \colon K \to \mathbf{C}$, $1 \leq i \leq 2s$. In Hecke the complex embeddings are always ordered such that $\sigma_i = \overline{\sigma_{i+s}}$ for $r + 1 \leq i \leq r + s$. The $\mathbf{Q}$-linear function

\[\begin{gather*} - K \longrightarrow \mathbf R^{d} \\ - \alpha \longmapsto \Bigl( \sigma_1(\alpha), \dotsc, \sigma_r(\alpha), \sqrt{2}\operatorname{Re}\bigl(\sigma_{r+1}(\alpha)\bigr), \sqrt{2}\operatorname{Im}\bigl(\sigma_{r+1}(\alpha)\bigr), \dotsc, \sqrt{2}\operatorname{Re}\bigl(\sigma_{r+s}(\alpha)\bigr), \sqrt{2}\operatorname{Im}\bigl(\sigma_{r+s}(\alpha)\bigr) \Bigr) -\end{gather*}\]

is called the Minkowski map (or Minkowski embedding).

If $K = \mathbf Q(\alpha)$ is an absolute number field, then an order $\mathcal O$ of $K$ is a subring of the ring of integers $\mathcal O_K$, which is free of rank $[ K : \mathbf Q]$ as a $\mathbf Z$-module. The natural order $\mathbf Z[\alpha]$ is called the equation order of $K$. In Hecke orders of absolute number fields are constructed (implicitly) by specifying a $\mathbf Z$-basis, which is referred to as the basis of $\mathcal O$. If $(\omega_1,\dotsc,\omega_d)$ is the basis of $\mathcal O$, then the matrix $B \in \operatorname{Mat}_{d \times d}(\mathbf Q)$ with

is called the basis matrix of $\mathcal O$. We call $\det(B)$ the generalized index of $\mathcal O$. In case $\mathbf Z[\alpha] \subseteq \mathcal O$, the determinant $\det(B)^{-1}$ is in fact equal to $[ \mathcal O : \mathbf Z[\alpha]]$ and is called the index of $\mathcal O$. The matrix

\[\begin{pmatrix} -\sigma_1(\omega_1) & \dotsc & \sigma_r(\omega_1) & \sqrt{2}\operatorname{Re}(\sigma_{r+1}(\omega_1)) & \sqrt{2}\operatorname{Im}(\sigma_{r+1}(\omega_1)) & \dotsc & \sqrt{2}\operatorname{Im}(\sigma_{r+s}(\omega_1)) \\\\ -\sigma_1(\omega_2) & \dotsc & \sigma_r(\omega_2) & \sqrt{2}\operatorname{Re}(\sigma_{r+1}(\omega_2)) & \sqrt{2}\operatorname{Im}(\sigma_{r+1}(\omega_2)) & \dotsc & \sqrt{2}\operatorname{Im}(\sigma_{r+s}(\omega_2)) \\\\ -\vdots & \ddots & \vdots & \vdots & \vdots & \ddots & \vdots\\\\ -\sigma_1(\omega_d) & \dotsc & \sigma_r(\omega_d) & \sqrt{2}\operatorname{Re}(\sigma_{r+1}(\omega_d)) & \sqrt{2}\operatorname{Im}(\sigma_{r+2}(\omega_d)) & \dotsc & \sqrt{2}\operatorname{Im}(\sigma_{r+s}(\omega_d)) -\end{pmatrix} -\in \operatorname{Mat}_{d\times d}(\mathbf R).\]

is called the Minkowski matrix of $\mathcal O$.

diff --git a/previews/PR2578/Hecke/number_fields/elements/index.html b/previews/PR2578/Hecke/number_fields/elements/index.html deleted file mode 100644 index 8da73f75237d..000000000000 --- a/previews/PR2578/Hecke/number_fields/elements/index.html +++ /dev/null @@ -1,14 +0,0 @@ - -Element operations · Oscar.jl

Element operations

Creation

genMethod
gen(L::SimpleNumField) -> NumFieldElem

Given a simple number field $L = K[x]/(f)$ over $K$, this functions returns the class of $x$, which is the canonical primitive element of $L$ over $K$.

gensMethod
gens(L::NonSimpleNumField) -> Vector{NumFieldElem}

Given a non-simple number field $L = K[x_1,\dotsc,x_n]/(f_1,\dotsc,f_n)$ over $K$, this functions returns the list $\bar x_1,\dotsc,\bar x_n$.

Elements can also be created by specifying the coordinates with respect to the basis of the number field:

    (L::number_field)(c::Vector{NumFieldElem}) -> NumFieldElem

Given a number field $L/K$ of degree $d$ and a vector c length $d$, this constructs the element a with coordinates(a) == c.

julia> Qx, x = QQ["x"];
-
-julia> K, a = number_field(x^2 - 2, "a");
-
-julia> K([1, 2])
-2*a + 1
-
-julia> L, b = radical_extension(3, a, "b")
-(Relative number field of degree 3 over number field, b)
-
-julia> L([a, 1, 1//2])
-1//2*b^2 + b + a
quadratic_defectMethod
quadratic_defect(a::Union{NumFieldElem,Rational,QQFieldElem}, p) -> Union{Inf, PosInf}

Returns the valuation of the quadratic defect of the element $a$ at $p$, which can either be prime object or an infinite place of the parent of $a$.

hilbert_symbolMethod
hilbert_symbol(a::NumFieldElem, b::NumFieldElem, p::NfOrdIdl) -> Int

Returns the local Hilbert symbol $(a,b)_p$.

representation_matrixMethod
representation_matrix(a::NumFieldElem) -> MatElem

Returns the representation matrix of $a$, that is, the matrix representing multiplication with $a$ with respect to the canonical basis of the parent of $a$.

basis_matrixMethod
basis_matrix(v::Vector{NumFieldElem}) -> Mat

Given a vector $v$ of $n$ elements of a number field $K$ of degree $d$, this function returns an $n \times d$ matrix with entries in the base field of $K$, where row $i$ contains the coefficients of $v[i]$ with respect of the canonical basis of $K$.

coefficientsMethod
coefficients(a::SimpleNumFieldElem, i::Int) -> Vector{FieldElem}

Given a number field element a of a simple number field extension L/K, this function returns the coefficients of a, when expanded in the canonical power basis of L.

coordinatesMethod
coordinates(x::NumFieldElem{T}) -> Vector{T}

Given an element $x$ in a number field $K$, this function returns the coordinates of $x$ with respect to the basis of $K$ (the output of the 'basis' function).

absolute_coordinatesMethod
absolute_coordinates(x::NumFieldElem{T}) -> Vector{T}

Given an element $x$ in a number field $K$, this function returns the coordinates of $x$ with respect to the basis of $K$ over the rationals (the output of the absolute_basis function).

coeffMethod
coeff(a::SimpleNumFieldElem, i::Int) -> FieldElem

Given a number field element a of a simple number field extension L/K, this function returns the i-th coefficient of a, when expanded in the canonical power basis of L. The result is an element of K.

valuationMethod
valuation(a::NumFieldElem, p::NfOrdIdl) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

torsion_unit_orderMethod
torsion_unit_order(x::nf_elem, n::Int)

Given a torsion unit $x$ together with a multiple $n$ of its order, compute the order of $x$, that is, the smallest $k \in \mathbb Z_{\geq 1}$ such that $x^k = 1$.

It is not checked whether $x$ is a torsion unit.

trMethod
tr(a::NumFieldElem) -> NumFieldElem

Returns the trace of an element $a$ of a number field extension $L/K$. This will be an element of $K$.

absolute_trMethod
absolute_tr(a::NumFieldElem) -> QQFieldElem

Given a number field element $a$, returns the absolute trace of $a$.

algebraic_splitMethod
algebraic_split(a::nf_elem) -> nf_elem, nf_elem

Writes the input as a quotient of two "small" algebraic integers.

Conjugates

conjugatesMethod
conjugates(x::nf_elem, C::AcbField) -> Vector{acb}

Compute the conjugates of $x$ as elements of type acb. Recall that we order the complex conjugates $\sigma_{r+1}(x),...,\sigma_{r+2s}(x)$ such that $\sigma_{i}(x) = \overline{\sigma_{i + s}(x)}$ for $r + 1 \leq i \leq r + s$.

Let p be the precision of C, then every entry $y$ of the vector returned satisfies radius(real(y)) < 2^-p and radius(imag(y)) < 2^-p respectively.

conjugatesMethod
conjugates(x::nf_elem, abs_tol::Int) -> Vector{acb}

Compute the conjugates of $x$ as elements of type acb. Recall that we order the complex conjugates $\sigma_{r+1}(x),...,\sigma_{r+2s}(x)$ such that $\sigma_{i}(x) = \overline{\sigma_{i + s}(x)}$ for $r + 1 \leq i \leq r + s$.

Every entry $y$ of the vector returned satisfies radius(real(y)) < 2^-abs_tol and radius(imag(y)) < 2^-abs_tol respectively.

conjugates_logMethod
conjugates_arb_log(x::nf_elem, abs_tol::Int) -> Vector{arb}

Returns the elements $(\log(\lvert \sigma_1(x) \rvert),\dotsc,\log(\lvert\sigma_r(x) \rvert), \dotsc,2\log(\lvert \sigma_{r+1}(x) \rvert),\dotsc, 2\log(\lvert \sigma_{r+s}(x)\rvert))$ as elements of type arb with radius less then 2^-abs_tol.

conjugates_realMethod
conjugates_arb_real(x::nf_elem, abs_tol::Int) -> Vector{arb}

Compute the real conjugates of $x$ as elements of type arb.

Every entry $y$ of the array returned satisfies radius(y) < 2^-abs_tol.

conjugates_complexMethod
conjugates_complex(x::nf_elem, abs_tol::Int) -> Vector{acb}

Compute the complex conjugates of $x$ as elements of type acb. Recall that we order the complex conjugates $\sigma_{r+1}(x),...,\sigma_{r+2s}(x)$ such that $\sigma_{i}(x) = \overline{\sigma_{i + s}(x)}$ for $r + 1 \leq i \leq r + s$.

Every entry $y$ of the array returned satisfies radius(real(y)) < 2^-abs_tol and radius(imag(y)) < 2^-abs_tol.

conjugates_arb_log_normaliseMethod
conjugates_arb_log_normalise(x::nf_elem, p::Int = 10)
-conjugates_arb_log_normalise(x::FacElem{nf_elem, AnticNumberField}, p::Int = 10)

The "normalised" logarithms, i.e. the array $c_i\log |x^{(i)}| - 1/n\log|N(x)|$, so the (weighted) sum adds up to zero.

minkowski_mapMethod
minkowski_map(a::nf_elem, abs_tol::Int) -> Vector{arb}

Returns the image of $a$ under the Minkowski embedding. Every entry of the array returned is of type arb with radius less then 2^(-abs_tol).

Predicates

is_integralMethod
is_integral(a::NumFieldElem) -> Bool

Returns whether $a$ is integral, that is, whether the minimal polynomial of $a$ has integral coefficients.

is_torsion_unitMethod
is_torsion_unit(x::nf_elem, checkisunit::Bool = false) -> Bool

Returns whether $x$ is a torsion unit, that is, whether there exists $n$ such that $x^n = 1$.

If checkisunit is true, it is first checked whether $x$ is a unit of the maximal order of the number field $x$ is lying in.

is_local_normMethod
is_local_norm(L::NumField, a::NumFieldElem, P)

Given a number field $L/K$, an element $a \in K$ and a prime ideal $P$ of $K$, returns whether $a$ is a local norm at $P$.

The number field $L/K$ must be a simple extension of degree 2.

is_norm_divisibleMethod
is_norm_divisible(a::nf_elem, n::ZZRingElem) -> Bool

Checks if the norm of $a$ is divisible by $n$, assuming that the norm of $a$ is an integer.

is_normMethod
is_norm(K::AnticNumberField, a::ZZRingElem; extra::Vector{ZZRingElem}) -> Bool, nf_elem

For a ZZRingElem $a$, try to find $T \in K$ s.th. $N(T) = a$ holds. If successful, return true and $T$, otherwise false and some element. In \testtt{extra} one can pass in additional prime numbers that are allowed to occur in the solution. This will then be supplemented. The element will be returned in factored form.

Invariants

normMethod
norm(a::NumFieldElem) -> NumFieldElem

Returns the norm of an element $a$ of a number field extension $L/K$. This will be an element of $K$.

absolute_normMethod
absolute_norm(a::NumFieldElem) -> QQFieldElem

Given a number field element $a$, returns the absolute norm of $a$.

minpolyMethod
minpoly(a::NumFieldElem) -> PolyElem

Given a number field element $a$ of a number field $K$, this function returns the minimal polynomial of $a$ over the base field of $K$.

absolute_minpolyMethod
absolute_minpoly(a::NumFieldElem) -> PolyElem

Given a number field element $a$ of a number field $K$, this function returns the minimal polynomial of $a$ over the rationals $\mathbf{Q}$.

charpolyMethod
charpoly(a::NumFieldElem) -> PolyElem

Given a number field element $a$ of a number field $K$, this function returns the characteristic polynomial of $a$ over the base field of $K$.

absolute_charpolyMethod
absolute_charpoly(a::NumFieldElem) -> PolyElem

Given a number field element $a$ of a number field $K$, this function returns the characteristic polynomial of $a$ over the rationals $\mathbf{Q}$.

normMethod
norm(a::NumFieldElem, k::NumField) -> NumFieldElem

Returns the norm of an element $a$ of a number field $L$ with respect to a subfield $k$ of $L$. This will be an element of $k$.

diff --git a/previews/PR2578/Hecke/number_fields/fields/index.html b/previews/PR2578/Hecke/number_fields/fields/index.html deleted file mode 100644 index 685157b5c586..000000000000 --- a/previews/PR2578/Hecke/number_fields/fields/index.html +++ /dev/null @@ -1,59 +0,0 @@ - -Number field operations · Oscar.jl

Number field operations

Creation of number fields

General number fields can be created using the function number_field. To create a simple number field given by a defining polynomial or a non-simple number field given by defining polynomials, the following functions can be used.

number_fieldMethod
number_field(f::Poly{NumFieldElem}, s::String;
-            cached::Bool = false, check::Bool = false) -> NumField, NumFieldElem

Given an irreducible polynomial $f \in K[x]$ over some number field $K$, this function creates the simple number field $L = K[x]/(f)$ and returns $(L, b)$, where $b$ is the class of $x$ in $L$. The string s is used only for printing the primitive element $b$.

  • check: Controls whether irreducibility of $f$ is checked.
  • cached: Controls whether the result is cached.

Examples

julia> K, a = quadratic_field(5);
-
-julia> Kt, t = K["t"];
-
-julia> L, b = number_field(t^3 - 3, "b");
number_fieldMethod
number_field(f::Vector{PolyElem{<:NumFieldElem}}, s::String="_\$", check = true)
-                                          -> NumField, Vector{NumFieldElem}

Given a list $f_1, \ldots, f_n$ of univariate polynomials in $K[x]$ over some number field $K$, constructs the extension $K[x_1, \ldots, x_n]/(f_1(x_1), \ldots, f_n(x_n))$.

Examples

julia> Qx, x = QQ["x"];
-
-julia> K, a = number_field([x^2 - 2, x^2 - 3], "a")
-(Non-simple number field of degree 4 over QQ, NfAbsNSElem[a1, a2])
Tip

Many of the constructors have arguments of type Symbol or AbstractString. If used, they define the appearance in printing, and printing only. The named parameter check can be true or false, the default being true. This parameter controls whether the polynomials defining the number field are tested for irreducibility or not. Given that this can be potentially very time consuming if the degree if large, one can disable this test. Note however, that the behaviour of Hecke is undefined if a reducible polynomial is used to define a field.

The named boolean parameter cached can be used to disable caching. Two number fields defined using the same polynomial from the identical polynomial ring and the same (identical) symbol/string will be identical if cached == true and different if cached == false.

For frequently used number fields like quadratic fields, cyclotomic fields or radical extensions, the following functions are provided:

cyclotomic_fieldMethod
cyclotomic_field(n::Int, s::VarName = "z_$n", t = "_\$"; cached = true)

Return a tuple $R, x$ consisting of the parent object $R$ and generator $x$ of the $n$-th cyclotomic field, $\mathbb{Q}(\zeta_n)$. The supplied string s specifies how the generator of the number field should be printed. If provided, the string t specifies how the generator of the polynomial ring from which the number field is constructed, should be printed. If it is not supplied, a default dollar sign will be used to represent the variable.

quadratic_fieldMethod
quadratic_field(d::IntegerUnion) -> AnticNumberField, nf_elem

Returns the field with defining polynomial $x^2 - d$.

Examples

julia> quadratic_field(5)
-(Real quadratic field defined by x^2 - 5, sqrt(5))
wildanger_fieldMethod
wildanger_field(n::Int, B::ZZRingElem) -> AnticNumberField, nf_elem

Returns the field with defining polynomial $x^n + \sum_{i=0}^{n-1} (-1)^{n-i}Bx^i$. These fields tend to have non-trivial class groups.

Examples

julia> wildanger_field(3, ZZ(10), "a")
-(Number field of degree 3 over QQ, a)
radical_extensionMethod
radical_extension(n::Int, a::NumFieldElem, s = "_$";
-               check = true, cached = true) -> NumField, NumFieldElem

Given an element $a$ of a number field $K$ and an integer $n$, create the simple extension of $K$ with the defining polynomial $x^n - a$.

Examples

julia> radical_extension(5, QQ(2), "a")
-(Number field of degree 5 over QQ, a)
rationals_as_number_fieldMethod
rationals_as_number_field() -> AnticNumberField, nf_elem

Returns the rational numbers as the number field defined by $x - 1$.

Examples

julia> rationals_as_number_field()
-(Number field of degree 1 over QQ, 1)

Basic properties

basisMethod
basis(L::SimpleNumField) -> Vector{NumFieldElem}

Return the canonical basis of a simple extension $L/K$, that is, the elements $1,a,\dotsc,a^{d - 1}$, where $d$ is the degree of $K$ and $a$ the primitive element.

Examples

julia> Qx, x = QQ["x"];
-
-julia> K, a = number_field(x^2 - 2, "a");
-
-julia> basis(K)
-2-element Vector{nf_elem}:
- 1
- a
basisMethod
basis(L::NonSimpleNumField) -> Vector{NumFieldElem}

Returns the canonical basis of a non-simple extension $L/K$. If $L = K(a_1,\dotsc,a_n)$ where each $a_i$ has degree $d_i$, then the basis will be $a_1^{i_1}\dotsm a_d^{i_d}$ with $0 \leq i_j \leq d_j - 1$ for $1 \leq j \leq n$.

Examples

julia> Qx, x = QQ["x"];
-
-julia> K, (a1, a2) = number_field([x^2 - 2, x^2 - 3], "a");
-
-julia> basis(K)
-4-element Vector{NfAbsNSElem}:
- 1
- a1
- a2
- a1*a2
absolute_basisMethod
absolute_basis(K::NumField) -> Vector{NumFieldElem}

Returns an array of elements that form a basis of $K$ (as a vector space) over the rationals.

defining_polynomialMethod
defining_polynomial(L::SimpleNumField) -> PolyElem

Given a simple number field $L/K$, constructed as $L = K[x]/(f)$, this function returns $f$.

defining_polynomialsMethod
defining_polynomials(L::NonSimpleNumField) -> Vector{PolyElem}

Given a non-simple number field $L/K$, constructed as $L = K[x]/(f_1,\dotsc,f_r)$, return the vector containing the $f_i$'s.

absolute_primitive_elementMethod
absolute_primitive_element(K::NumField) -> NumFieldElem

Given a number field $K$, this function returns an element $\gamma \in K$ such that $K = \mathbf{Q}(\gamma)$.

componentMethod
component(L::NonSimpleNumField, i::Int) -> SimpleNumField, Map

Given a non-simple extension $L/K$, this function returns the simple number field corresponding to the $i$-th component of $L$ together with its embedding.

base_fieldMethod
base_field(L::NumField) -> NumField

Given a number field $L/K$ this function returns the base field $K$. For absolute extensions this returns $\mathbf{Q}$.

Invariants

degreeMethod
degree(L::NumField) -> Int

Given a number field $L/K$, this function returns the degree of $L$ over $K$.

Examples

julia> Qx, x = QQ["x"];
-
-julia> K, a = number_field(x^2 - 2, "a");
-
-julia> degree(K)
-2
absolute_degreeMethod
absolute_degree(L::NumField) -> Int

Given a number field $L/K$, this function returns the degree of $L$ over $\mathbf Q$.

signatureMethod
signature(K::NumField)

Return the signature of the number field of $K$.

Examples

julia> Qx, x = QQ["x"];
-
-julia> K, a = number_field(x^2 - 2, "a");
-
-julia> signature(K)
-(2, 0)
unit_group_rankMethod
unit_group_rank(K::NumField) -> Int

Return the rank of the unit group of any order of $K$.

class_numberMethod
class_number(K::AnticNumberField) -> ZZRingElem

Returns the class number of $K$.

relative_class_numberMethod
relative_class_number(K::AnticNumberField) -> ZZRingElem

Returns the relative class number of $K$. The field must be a CM-field.

regulatorMethod
regulator(K::AnticNumberField)

Computes the regulator of $K$, i.e. the discriminant of the unit lattice for the maximal order of $K$.

discriminantMethod
discriminant(L::SimpleNumField) -> NumFieldElem

The discriminant of the defining polynomial of $L$, not the discriminant of the maximal order of $L$.

absolute_discriminantMethod
absolute_discriminant(L::SimpleNumField, QQ) -> QQFieldElem

The absolute discriminant of the defining polynomial of $L$, not the discriminant of the maximal order of $L$. This is the norm of the discriminant times the $d$-th power of the discriminant of the base field, where $d$ is the degree of $L$.

Predicates

is_simpleMethod
is_simple(L::NumField) -> Bool

Given a number field $L/K$ this function returns whether $L$ is simple, that is, whether $L/K$ is defined by a univariate polynomial.

is_absoluteMethod
is_absolute(L::NumField) -> Bool

Returns whether $L$ is an absolute extension, that is, whether the base field of $L$ is $\mathbf{Q}$.

is_totally_realMethod
is_totally_real(K::number_field) -> Bool

Returns true if and only if $K$ is totally real, that is, if all roots of the defining polynomial are real.

is_totally_complexMethod
is_totally_complex(K::AnticNumberField) -> Bool

Returns true if and only if $K$ is totally complex, that is, if all roots of the defining polynomial are not real.

is_cm_fieldMethod
is_cm_field(K::AnticNumberField) -> Bool, NfToNfMor

Given a number field $K$, this function returns true and the complex conjugation if the field is CM, false and the identity otherwise.

is_kummer_extensionMethod
is_kummer_extension(L::SimpleNumField) -> Bool

Tests if $L/K$ is a Kummer extension, that is, if the defining polynomial is of the form $x^n - b$ for some $b \in K$ and if $K$ contains the $n$-th roots of unity.

is_radical_extensionMethod
is_radical_extension(L::SimpleNumField) -> Bool

Tests if $L/K$ is pure, that is, if the defining polynomial is of the form $x^n - b$ for some $b \in K$.

is_linearly_disjointMethod
is_linearly_disjoint(K::SimpleNumField, L::SimpleNumField) -> Bool

Given two number fields $K$ and $L$ with the same base field $k$, this function returns whether $K$ and $L$ are linear disjoint over $k$.

is_weakly_ramifiedMethod
is_weakly_ramified(K::AnticNumberField, P::NfOrdIdl) -> Bool

Given a prime ideal $P$ of a number field $K$, return whether $P$ is weakly ramified, that is, whether the second ramification group is trivial.

is_tamely_ramifiedMethod
is_tamely_ramified(K::AnticNumberField) -> Bool

Returns whether the number field $K$ is tamely ramified.

is_tamely_ramifiedMethod
is_tamely_ramified(O::NfOrd, p::Union{Int, ZZRingElem}) -> Bool

Returns whether the integer $p$ is tamely ramified in $\mathcal O$. It is assumed that $p$ is prime.

is_abelianMethod
is_abelian(L::NumField) -> Bool

Check if the number field $L/K$ is abelian over $K$. The function is probabilistic and assumes GRH.

Subfields

is_subfieldMethod
is_subfield(K::SimpleNumField, L::SimpleNumField) -> Bool, Map

Return true and an injection from $K$ to $L$ if $K$ is a subfield of $L$. Otherwise the function returns false and a morphism mapping everything to $0$.

subfieldsMethod
subfields(L::SimpleNumField) -> Vector{Tuple{NumField, Map}}

Given a simple extension $L/K$, returns all subfields of $L$ containing $K$ as tuples $(k, \iota)$ consisting of a simple extension $k$ and an embedding $\iota k \to K$.

principal_subfieldsMethod
principal_subfields(L::SimpleNumField) -> Vector{Tuple{NumField, Map}}

Return the principal subfields of $L$ as pairs consisting of a subfield $k$ and an embedding $k \to L$.

compositumMethod
compositum(K::AnticNumberField, L::AnticNumberField) -> AnticNumberField, Map, Map

Assuming $L$ is normal (which is not checked), compute the compositum $C$ of the 2 fields together with the embedding of $K \to C$ and $L \to C$.

embeddingMethod
embedding(k::NumField, K::NumField) -> Map

Assuming $k$ is known to be a subfield of $K$, return the embedding map.

normal_closureMethod
normal_closure(K::AnticNumberField) -> AnticNumberField, NfToNfMor

The normal closure of $K$ together with the embedding map.

relative_simple_extensionMethod
relative_simple_extension(K::NumField, k::NumField) -> NfRel

Given two fields $K\supset k$, it returns $K$ as a simple relative extension $L$ of $k$ and an isomorphism $L \to K$.

is_subfield_normalMethod
  is_subfield_normal(K::AnticNumberField, L::AnticNumberField) -> Bool, NfToNfMor

Returns true and an injection from $K$ to $L$ if $K$ is a subfield of $L$. Otherwise the function returns "false" and a morphism mapping everything to 0.

This function assumes that $K$ is normal.

Conversion

simplifyMethod
simplify(K::AnticNumberField; canonical::Bool = false) -> AnticNumberField, NfToNfMor

Tries to find an isomorphic field $L$ given by a "simpler" defining polynomial. By default, "simple" is defined to be of smaller index, testing is done only using a LLL-basis of the maximal order.

If canonical is set to true, then a canonical defining polynomial is found, where canonical is using the definition of PARI's polredabs, which is described in http://beta.lmfdb.org/knowledge/show/nf.polredabs.

Both versions require a LLL reduced basis for the maximal order.

absolute_simple_fieldMethod
absolute_simple_field(K::NumField) -> NumField, Map

Given a number field $K$, this function returns an absolute simple number field $M/\mathbf{Q}$ together with a $\mathbf{Q}$-linear isomorphism $M \to K$.

simple_extensionMethod
simple_extension(L::NonSimpleNumField) -> SimpleNumField, Map

Given a non-simple extension $L/K$, this function computes a simple extension $M/K$ and a $K$-linear isomorphism $M \to L$.

simplified_simple_extensionMethod
simplified_simple_extension(L::NonSimpleNumField) -> SimpleNumField, Map

Given a non-simple extension $L/K$, this function returns an isomorphic simple number field with a "small" defining equation together with the isomorphism.

Morphisms

is_isomorphicMethod
is_isomorphic(K::SimpleNumField, L::SimpleNumField) -> Bool

Return true if $K$ and $L$ are isomorphic, otherwise false.

is_isomorphic_with_mapMethod
is_isomorphic_with_map(K::SimpleNumField, L::SimpleNumField) -> Bool, Map

Return true and an isomorphism from $K$ to $L$ if $K$ and $L$ are isomorphic. Otherwise the function returns false and a morphism mapping everything to $0$.

is_involutionMethod
is_involution(f::NfToNfMor) -> Bool

Returns true if $f$ is an involution, i.e. if $f^2$ is the identity, false otherwise.

fixed_fieldMethod
fixed_field(K::SimpleNumField,
-            sigma::Map;
-            simplify::Bool = true) -> number_field, NfToNfMor

Given a number field $K$ and an automorphism $\sigma$ of $K$, this function returns the fixed field of $\sigma$ as a pair $(L, i)$ consisting of a number field $L$ and an embedding of $L$ into $K$.

By default, the function tries to find a small defining polynomial of $L$. This can be disabled by setting simplify = false.

automorphism_listMethod
automorphism_list(L::NumField) -> Vector{NumFieldMor}

Given a number field $L/K$, return a list of all $K$-automorphisms of $L$.

automorphism_groupMethod
automorphism_group(K::NumField) -> GenGrp, GrpGenToNfMorSet

Given a number field $K$, this function returns a group $G$ and a map from $G$ to the automorphisms of $K$.

complex_conjugationMethod
complex_conjugation(K::AnticNumberField)

Given a totally complex normal number field, this function returns an automorphism which is the restriction of complex conjugation at one embedding.

Galois theory

normal_basisMethod
normal_basis(L::NumField) -> NumFieldElem

Given a normal number field $L/K$, this function returns an element $a$ of $L$, such that the orbit of $a$ under the Galois group of $L/K$ is an $K$-basis of $L$.

decomposition_groupMethod
decomposition_group(K::AnticNumberField, P::NfOrdIdl, m::Map)
-                                              -> Grp, GrpToGrp

Given a prime ideal $P$ of a number field $K$ and a map m return from automorphism_group(K), return the decomposition group of $P$ as a subgroup of the domain of m.

ramification_groupMethod
ramification_group(K::AnticNumberField, P::NfOrdIdl, m::Map) -> Grp, GrpToGrp

Given a prime ideal $P$ of a number field $K$ and a map m return from automorphism_group(K), return the ramification group of $P$ as a subgroup of the domain of m.

inertia_subgroupMethod
inertia_subgroup(K::AnticNumberField, P::NfOrdIdl, m::Map) -> Grp, GrpToGrp

Given a prime ideal $P$ of a number field $K$ and a map m return from automorphism_group(K), return the inertia subgroup of $P$ as a subgroup of the domain of m.

Infinite places

infinite_placesMethod
infinite_places(K::NumField) -> Vector{InfPlc}

Return all infinite places of the number field.

Examples

julia> K,  = quadratic_field(5);
-
-julia> infinite_places(K)
-2-element Vector{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}}:
- Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field defined by x^2 - 5)
- Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field defined by x^2 - 5)
real_placesMethod
real_places(K::NumField) -> Vector{InfPlc}

Return all infinite real places of the number field.

Examples

julia> K,  = quadratic_field(5);
-
-julia> infinite_places(K)
-2-element Vector{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}}:
- Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field defined by x^2 - 5)
- Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field defined by x^2 - 5)
complex_placesMethod
complex_places(K::NumField) -> Vector{InfPlc}

Return all infinite complex places of $K$.

Examples

julia> K,  = quadratic_field(-5);
-
-julia> complex_places(K)
-1-element Vector{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}}:
- Infinite place corresponding to (Complex embedding corresponding to 0.00 + 2.24 * i of imaginary quadratic field defined by x^2 + 5)
isrealMethod
isreal(P::Plc)

Return whether the embedding into $\mathbf{C}$ defined by $P$ is real or not.

is_complexMethod
is_complex(P::Plc) -> Bool

Return whether the embedding into $\mathbf{C}$ defined by $P$ is complex or not.

Miscellaneous

norm_equationMethod
norm_equation(K::AnticNumerField, a) -> nf_elem

For $a$ an integer or rational, try to find $T \in K$ s.th. $N(T) = a$. Raises an error if unsuccessful.

lorenz_moduleMethod
lorenz_module(k::AnticNumberField, n::Int) -> NfOrdIdl

Finds an ideal $A$ s.th. for all positive units $e = 1 \bmod A$ we have that $e$ is an $n$-th power. Uses Lorenz, number theory, 9.3.1. If containing is set, it has to be an integral ideal. The resulting ideal will be a multiple of this.

kummer_failureMethod
kummer_failure(x::nf_elem, M::Int, N::Int) -> Int

Computes the quotient of $N$ and $[K(\zeta_M, \sqrt[N](x))\colon K(\zeta_M)]$, where $K$ is the field containing $x$ and $N$ divides $M$.

is_defining_polynomial_niceMethod
is_defining_polynomial_nice(K::AnticNumberField)

Tests if the defining polynomial of $K$ is integral and monic.

diff --git a/previews/PR2578/Hecke/number_fields/internal/index.html b/previews/PR2578/Hecke/number_fields/internal/index.html deleted file mode 100644 index 8a0637797b62..000000000000 --- a/previews/PR2578/Hecke/number_fields/internal/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Internals · Oscar.jl

Internals

Types of number fields

Number fields, in Hecke, come in several different types:

  • AnticNumberField: a finite simple extension of the rational numbers $\mathbf{Q}$
  • NfAbsNS: a finite extension of $\mathbf{Q}$ given by several polynomials. We will refer to this as a non-simple field - even though mathematically we can find a primitive elements.
  • NfRel: a finite simple extension of a number field. This is actually parametried by the (element) type of the coefficient field. The complete type of an extension of an absolute field (AnticNumberField) is NfRel{nf_elem}. The next extension thus will be NfRel{NfRelElem{nf_elem}}.
  • NfRelNS: extensions of number fields given by several polynomials. This too will be referred to as a non-simple field.

The simple types AnticNumberField and NfRel are also called simple fields in the rest of this document, NfRel and NfRelNS are referred to as relative extensions while AnticNumberField and NfAbsNS are called absolute.

Internally, simple fields are essentially just (univariate) polynomial quotients in a dense representation, while non-simple fields are multivariate quotient rings, thus have a sparse presentation. In general, simple fields allow much faster arithmetic, while the non-simple fields give easy access to large degree fields.

Absolute simple fields

The most basic number field type is that of AnticNumberField. Internally this is essentially represented as a unvariate quotient with the arithmetic provided by the C-library antic with the binding provided by Nemo.

diff --git a/previews/PR2578/Hecke/number_fields/intro/index.html b/previews/PR2578/Hecke/number_fields/intro/index.html deleted file mode 100644 index eca9e7d34584..000000000000 --- a/previews/PR2578/Hecke/number_fields/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

By definition, mathematically a number field is just a finite extension of the rational $\mathbf{Q}$. In Hecke, a number field $L$ is recursively defined as being the field of rational numbers $\mathbf{Q}$ or a finite extension of a number field $K$. In the second case, the extension can be defined in the one of the following two ways:

  • We have $L = K[x]/(f)$, where $f \in K[x]$ is an irreducible polynomial (simple extension), or
  • We have $L = K[x_1,\dotsc,x_n]/(f_1(x_1),\dotsc,f_n(x_n))$, where $f_1,\dotsc,f_n \in K[x]$ are univariate polynomials (non-simple extension).

In both cases we refer to $K$ as the base field of the number field $L$. Another useful dichotomy comes from the type of the base field. We call $L$ an absolute number field, if the base field is equal to the rational numbers $\mathbf{Q}$.

diff --git a/previews/PR2578/Hecke/orders/elements/index.html b/previews/PR2578/Hecke/orders/elements/index.html deleted file mode 100644 index a6caac457226..000000000000 --- a/previews/PR2578/Hecke/orders/elements/index.html +++ /dev/null @@ -1,37 +0,0 @@ - -Elements · Oscar.jl

Elements

Elements in orders have two representations: they can be viewed as elements in the $\mathbf Z^n$ giving the coefficients wrt to the order basis where they are elements in. On the other hand, as every order is in a field, they also have a representation as number field elements. Since, asymptotically, operations are more efficient in the field (due to fast polynomial arithmetic) than in the order, the primary representation is that as a field element.

Creation

Elements are constructed either as linear combinations of basis elements or via explicit coercion. Elements will be of type NfAbsOrdElem, the type if actually parametrized by the type of the surrounding field and the type of the field elements. E.g. the type of any element in any order of an absolute simple field will be NfAbsOrdElem{AnticNumberField,nf_elem}

NfAbsOrdType
  (O::NumFieldOrd)(a::NumFieldElem, check::Bool = true) -> NumFieldOrdElem

Given an element $a$ of the ambient number field of $\mathcal O$, this function coerces the element into $\mathcal O$. It will be checked that $a$ is contained in $\mathcal O$ if and only if check is true.

  (O::NumFieldOrd)(a::NumFieldOrdElem, check::Bool = true) -> NumFieldOrdElem

Given an element $a$ of some order in the ambient number field of $\mathcal O$, this function coerces the element into $\mathcal O$. It will be checked that $a$ is contained in $\mathcal O$ if and only if check is true.

  (O::NumFieldOrd)(a::IntegerUnion) -> NumFieldOrdElem

Given an element $a$ of type ZZRingElem or Integer, this function coerces the element into $\mathcal O$.

  (O::NfAbsOrd)(arr::Vector{ZZRingElem})

Returns the element of $\mathcal O$ with coefficient vector arr.

  (O::NfAbsOrd)(arr::Vector{Integer})

Returns the element of $\mathcal O$ with coefficient vector arr.

Basic properties

parentMethod
parent(a::AbstractAlgebra.MatElem{T}) where T <: NCRingElement

Return the parent object of the given matrix.

parent(a::MatAlgElem{T}) where T <: NCRingElement

Return the parent object of the given matrix.

parent(a::NumFieldOrdElem) -> NumFieldOrd

Returns the order of which $a$ is an element.

elem_in_nfMethod
elem_in_nf(a::NumFieldOrdElem) -> NumFieldElem

Returns the element $a$ considered as an element of the ambient number field.

coordinatesMethod
coordinates(a::NfAbsOrdElem) -> Vector{ZZRingElem}

Returns the coefficient vector of $a$ with respect to the basis of the order.

discriminantMethod
discriminant(g::Vector)

Compute the product of all differences of distinct elements in the array.

source
discriminant(B::Vector{NumFieldOrdElem})

Returns the discriminant of the family $B$ of algebraic numbers, i.e. $det((tr(B[i]*B[j]))_{i, j})^2$.

discriminant(E::EllCrv) -> FieldElem

Return the discriminant of $E$.

discriminant(C::HypellCrv{T}) -> T

Compute the discriminant of $C$.

discriminant(O::AlgssRelOrd)

Returns the discriminant of $O$.

==Method
==(x::NumFieldOrdElem, y::NumFieldOrdElem) -> Bool

Returns whether $x$ and $y$ are equal.

Arithmetic

All the usual arithmetic operatinos are defined:

  • -(::NUmFieldOrdElem)
  • +(::NumFieldOrdElem, ::NumFieldOrdElem)
  • -(::NumFieldOrdElem, ::NumFieldOrdElem)
  • *(::NumFieldOrdElem, ::NumFieldOrdElem)
  • ^(::NumFieldOrdElem, ::Int)
  • mod(::NfAbsOrdElem, ::Int)
  • mod_sym(::NumFieldOrdElem, ::ZZRingElem)
  • powermod(::NfAbsOrdElem, ::ZZRingElem, ::Int)

Miscellaneous

representation_matrixMethod
representation_matrix(a::NfAbsOrdElem) -> ZZMatrix

Returns the representation matrix of the element $a$.

representation_matrixMethod
representation_matrix(a::NfAbsOrdElem, K::AnticNumberField) -> FakeFmpqMat

Returns the representation matrix of the element $a$ considered as an element of the ambient number field $K$. It is assumed that $K$ is the ambient number field of the order of $a$.

trMethod
tr(a::NumFieldOrdElem)

Returns the trace of $a$ as an element of the base ring.

normMethod
norm(a::NumFieldOrdElem)

Returns the norm of $a$ as an element in the base ring.

absolute_normMethod
absolute_norm(a::NumFieldOrdElem) -> ZZRingElem

Return the absolute norm as an integer.

absolute_trMethod
absolute_tr(a::NumFieldOrdElem) -> ZZRingElem

Return the absolute trace as an integer.

randMethod
rand(O::NfOrd, n::IntegerUnion) -> NfAbsOrdElem

Computes a coefficient vector with entries uniformly distributed in $\{-n,\dotsc,-1,0,1,\dotsc,n\}$ and returns the corresponding element of the order $\mathcal O$.

minkowski_mapMethod
minkowski_map(a::NumFieldOrdElem, abs_tol::Int) -> Vector{arb}

Returns the image of $a$ under the Minkowski embedding. Every entry of the array returned is of type arb with radius less then 2^-abs_tol.

conjugates_arbMethod
conjugates_arb(x::NumFieldOrdElem, abs_tol::Int) -> Vector{acb}

Compute the conjugates of $x$ as elements of type acb. Recall that we order the complex conjugates $\sigma_{r+1}(x),...,\sigma_{r+2s}(x)$ such that $\sigma_{i}(x) = \overline{\sigma_{i + s}(x)}$ for $r + 2 \leq i \leq r + s$.

Every entry $y$ of the array returned satisfies radius(real(y)) < 2^-abs_tol, radius(imag(y)) < 2^-abs_tol respectively.

conjugates_arb_logMethod
conjugates_arb_log(x::NumFieldOrdElem, abs_tol::Int) -> Vector{arb}

Returns the elements $(\log(\lvert \sigma_1(x) \rvert),\dotsc,\log(\lvert\sigma_r(x) \rvert), \dotsc,2\log(\lvert \sigma_{r+1}(x) \rvert),\dotsc, 2\log(\lvert \sigma_{r+s}(x)\rvert))$ as elements of type arb radius less then 2^-abs_tol.

t2Method
t2(x::NumFieldOrdElem, abs_tol::Int = 32) -> arb

Return the $T_2$-norm of $x$. The radius of the result will be less than 2^-abs_tol.

minpolyMethod
minpoly(S::Ring, M::MatAlgElem{T}, charpoly_only::Bool = false) where {T <: RingElement}

Return the minimal polynomial $p$ of the matrix $M$. The polynomial ring $S$ of the resulting polynomial must be supplied and the matrix must be square.

minpoly(a::NfAbsOrdElem) -> ZZPolyRingElem

The minimal polynomial of $a$.

minpoly(S::Ring, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}

Return the minimal polynomial $p$ of the matrix $M$. The polynomial ring $S$ of the resulting polynomial must be supplied and the matrix must be square.

Examples

julia> R = GF(13)
-Finite field F_13
-
-julia> T, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over finite field F_13, y)
-
-julia> M = R[7 6 1;
-             7 7 5;
-             8 12 5]
-[7    6   1]
-[7    7   5]
-[8   12   5]
-
-julia> A = minpoly(T, M)
-y^2 + 10*y
-
charpolyMethod
charpoly(a::NfAbsOrdElem) -> ZZPolyRingElem
-charpoly(a::NfAbsOrdElem, FlintZZ) -> ZZPolyRingElem

The characteristic polynomial of $a$.

charpoly(V::Ring, Y::MatrixElem{T}) where {T <: RingElement}

Return the characteristic polynomial $p$ of the matrix $M$. The polynomial ring $R$ of the resulting polynomial must be supplied and the matrix is assumed to be square.

Examples

julia> R = residue_ring(ZZ, 7)
-Residue ring of integers modulo 7
-
-julia> S = matrix_space(R, 4, 4)
-Matrix space of 4 rows and 4 columns
-  over residue ring of integers modulo 7
-
-julia> T, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over residue ring, x)
-
-julia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);
-              R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])
-[1   2   4   3]
-[2   5   1   0]
-[6   1   3   2]
-[1   1   3   5]
-
-julia> A = charpoly(T, M)
-x^4 + 2*x^2 + 6*x + 2
-
factorMethod
factor(a::NfOrdElem) -> Fac{NfOrdElem}

Computes a factorization of $a$ into irreducible elements. The return value is a factorization fac, which satisfies a = unit(fac) * prod(p^e for (p, e) in fac).

The function requires that $a$ is non-zero and that all prime ideals containing $a$ are principal, which is for example satisfied if class group of the order of $a$ is trivial.

denominatorMethod
denominator(a::NumFieldElem, O::NfOrd) -> ZZRingElem

Returns the smallest positive integer $k$ such that $k \cdot a$ is contained in $\mathcal O$.

discriminantMethod
discriminant(g::Vector)

Compute the product of all differences of distinct elements in the array.

source
discriminant(B::Vector{NumFieldOrdElem})

Returns the discriminant of the family $B$ of algebraic numbers, i.e. $det((tr(B[i]*B[j]))_{i, j})^2$.

discriminant(E::EllCrv) -> FieldElem

Return the discriminant of $E$.

discriminant(C::HypellCrv{T}) -> T

Compute the discriminant of $C$.

discriminant(O::AlgssRelOrd)

Returns the discriminant of $O$.

diff --git a/previews/PR2578/Hecke/orders/frac_ideals/index.html b/previews/PR2578/Hecke/orders/frac_ideals/index.html deleted file mode 100644 index 7d6c6e68acda..000000000000 --- a/previews/PR2578/Hecke/orders/frac_ideals/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Fractional ideals · Oscar.jl

Fractional ideals

A fractional ideal in the number field $K$ is a $Z_K$-module $A$ such that there exists an integer $d>0$ which $dA$ is an (integral) ideal in $Z_K$. Due to the Dedekind property of $Z_K$, the ideals for a multiplicative group.

Fractional ideals are represented as an integral ideal and an additional denominator. They are of type NfOrdFracIdl.

Creation

fractional_idealMethod
fractional_ideal(O::NfAbsOrd, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> NfAbsOrdFracIdl

Creates the fractional ideal of $\mathcal O$ with basis matrix $M/b$. If M_in_hnf is set, then it is assumed that $A$ is already in lower left HNF.

fractional_idealMethod
fractional_ideal(O::NfAbsOrd, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> NfAbsOrdFracIdl

Creates the fractional ideal of $\mathcal O$ with basis matrix $M/b$. If M_in_hnf is set, then it is assumed that $A$ is already in lower left HNF.

fractional_idealMethod
fractional_ideal(O::NfAbsOrd, M::FakeFmpqMat; M_in_hnf::Bool = false) -> NfAbsOrdFracIdl

Creates the fractional ideal of $\mathcal O$ with basis matrix $M$. If M_in_hnf is set, then it is assumed that the numerator of $M$ is already in lower left HNF.

fractional_idealMethod
fractional_ideal(O::NfOrd, I::NfAbsOrdIdl) -> NfOrdFracIdl

The fractional ideal of $O$ generated by a $Z$-basis of $I$.

fractional_ideal(O::NfAbsOrd, I::NfAbsOrdIdl) -> NfAbsOrdFracIdl

Turns the ideal $I$ into a fractional ideal of $\mathcal O$.

fractional_idealMethod
fractional_ideal(O::NfAbsOrd, I::NfAbsOrdIdl, b::ZZRingElem) -> NfAbsOrdFracIdl

Creates the fractional ideal $I/b$ of $\mathcal O$.

fractional_idealMethod
fractional_ideal(O::NfAbsOrd, a::nf_elem) -> NfAbsOrdFracIdl

Creates the principal fractional ideal $(a)$ of $\mathcal O$.

fractional_idealMethod
fractional_ideal(O::NfAbsOrd, a::NfAbsOrdElem) -> NfAbsOrdFracIdl

Creates the principal fractional ideal $(a)$ of $\mathcal O$.

invMethod
 inv(a::LocElem{T}, checked::Bool = true)  where {T <: RingElem}

Returns the inverse element of $a$ if $a$ is a unit. If 'checked = false' the invertibility of $a$ is not checked and the corresponding inverse element of the Fraction Field is returned.

inv(A::NfAbsOrdIdl) -> NfOrdFracIdl

Computes the inverse of $A$, that is, the fractional ideal $B$ such that $AB = \mathcal O_K$.

Arithmetic

All the normal operations are provided as well.

invMethod
 inv(a::LocElem{T}, checked::Bool = true)  where {T <: RingElem}

Returns the inverse element of $a$ if $a$ is a unit. If 'checked = false' the invertibility of $a$ is not checked and the corresponding inverse element of the Fraction Field is returned.

inv(A::NfAbsOrdFracIdl) -> NfAbsOrdFracIdl

Returns the fractional ideal $B$ such that $AB = \mathcal O$.

integral_splitMethod
integral_split(A::NfAbsOrdFracIdl) -> NfAbsOrdIdl, NfAbsOrdIdl

Computes the unique coprime integral ideals $N$ and $D$ s.th. $A = ND^{-1}$

numeratorMethod
numerator(a::NfRelOrdFracIdl) -> NfRelOrdIdl

Returns the ideal $d*a$ where $d$ is the denominator of $a$.

denominatorMethod
denominator(a::NfRelOrdFracIdl) -> ZZRingElem

Returns the smallest positive integer $d$ such that $da$ is contained in the order of $a$.

Miscaellenous

orderMethod
order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion

Return the order of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> order(cycle_structure(x)) == order(x), gens(g))
-true
source
order(a::NfAbsOrdFracIdl) -> NfAbsOrd

The order that was used to define the ideal $a$.

basis_matrixMethod
basis_matrix(I::NfAbsOrdFracIdl) -> FakeFmpqMat

Returns the basis matrix of $I$ with respect to the basis of the order.

basis_mat_invMethod
basis_mat_inv(I::NfAbsOrdFracIdl) -> FakeFmpqMat

Returns the inverse of the basis matrix of $I$.

basis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat

Return the inverse of the basis matrix of $A$.

basisMethod
basis(I::NfAbsOrdFracIdl) -> Vector{nf_elem}

Returns the $\mathbf Z$-basis of $I$.

normMethod
norm(I::NfAbsOrdFracIdl) -> QQFieldElem

Returns the norm of $I$.

norm(a::NfRelOrdIdl) -> NfOrdIdl

Returns the norm of $a$.

norm(a::NfRelOrdFracIdl{T, S}) -> S

Returns the norm of $a$.

norm(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd; copy::Bool = true) -> QQFieldElem

Returns the norm of $a$ considered as an (possibly fractional) ideal of $O$.

norm(a::AlgAssRelOrdIdl{S, T, U}, O::AlgAssRelOrd{S, T, U}; copy::Bool = true)
-  where { S, T, U } -> T

Returns the norm of $a$ considered as an (possibly fractional) ideal of $O$.

diff --git a/previews/PR2578/Hecke/orders/ideals/index.html b/previews/PR2578/Hecke/orders/ideals/index.html deleted file mode 100644 index 9ae0906d9059..000000000000 --- a/previews/PR2578/Hecke/orders/ideals/index.html +++ /dev/null @@ -1,112 +0,0 @@ - -Ideals · Oscar.jl

Ideals

(Integral) ideals in orders are always free $Z$-module of the same rank as the order, hence have a representation via a $Z$-basis. This can be made unique by normalising the corresponding matrix to be in reduced row echelon form (HNF).

For ideals in maximal orders $Z_K$, we also have a second presentation coming from the $Z_K$ module structure and the fact that $Z_K$ is a Dedekind ring: ideals can be generated by 2 elements, one of which can be any non-zero element in the ideal.

For efficiency, we will choose the 1st generator to be an integer.

Ideals here are of type NfAbsOrdIdl, which is, similar to the elements above, also indexed by the type of the field and their elements: NfAbsOrdIdl{AnticNumberField,nf_elem} for ideals in simple absolute fields.

Different to elements, the parentof an ideal is the set of all ideals in the ring, of type NfAbsOrdIdlSet.

Creation

idealMethod
ideal(O::NfOrd, a::ZZRingElem) -> NfAbsOrdIdl
-ideal(O::NfOrd, a::Integer) -> NfAbsOrdIdl

Returns the ideal of $\mathcal O$ which is generated by $a$.

idealMethod
ideal(O::NfOrd, M::ZZMatrix; check::Bool = false, M_in_hnf::Bool = false) -> NfAbsOrdIdl

Creates the ideal of $\mathcal O$ with basis matrix $M$. If check is set, then it is checked whether $M$ defines an ideal (expensive). If M_in_hnf is set, then it is assumed that $M$ is already in lower left HNF.

idealMethod
ideal(O::NfOrd, x::NfOrdElem) -> NfAbsOrdIdl

Creates the principal ideal $(x)$ of $\mathcal O$.

idealMethod
ideal(O::NfOrd, x::ZZRingElem, y::NfOrdElem) -> NfAbsOrdIdl
-ideal(O::NfOrd, x::Integer, y::NfOrdElem) -> NfAbsOrdIdl

Creates the ideal $(x, y)$ of $\mathcal O$.

idealMethod
ideal(O::NfOrd, x::ZZRingElem, y::NfOrdElem) -> NfAbsOrdIdl
-ideal(O::NfOrd, x::Integer, y::NfOrdElem) -> NfAbsOrdIdl

Creates the ideal $(x, y)$ of $\mathcal O$.

idealMethod
ideal(O::NfOrd, a::ZZRingElem) -> NfAbsOrdIdl
-ideal(O::NfOrd, a::Integer) -> NfAbsOrdIdl

Returns the ideal of $\mathcal O$ which is generated by $a$.

idealMethod
ideal(O::NfOrd, x::NfOrdElem) -> NfAbsOrdIdl

Creates the principal ideal $(x)$ of $\mathcal O$.

*Method
*(O::NfOrd, x::NfOrdElem) -> NfAbsOrdIdl
-*(x::NfAbsOrdElem, O::NfAbsOrd) -> NfAbsOrdIdl

Returns the principal ideal $(x)$ of $\mathcal O$.

factorMethod
factor(A::NfOrdIdl) -> Dict{NfOrdIdl, Int}

Computes the prime ideal factorization $A$ as a dictionary, the keys being the prime ideal divisors: If lp = factor_dict(A), then keys(lp) are the prime ideal divisors of $A$ and lp[P] is the $P$-adic valuation of $A$ for all $P$ in keys(lp).

factorMethod
factor(I::NfOrdIdlSet, a::nf_elem) -> Dict{NfOrdIdl, ZZRingElem}

Factors the principal ideal generated by $a$.

coprime_baseMethod
coprime_base(A::Vector{NfOrdIdl}) -> Vector{NfOrdIdl}
-coprime_base(A::Vector{NfOrdElem}) -> Vector{NfOrdIdl}

A coprime base for the (principal) ideals in $A$, i.e. the returned array generated multiplicatively the same ideals as the input and are pairwise coprime.

Arithmetic

All the usual operations are supported:

  • ==, +, *
  • divexact, divides
  • lcm, gcd
  • in
intersectMethod
intersect(x::NfOrdIdl, y::NfOrdIdl) -> NfOrdIdl

Returns $x \cap y$.

colonMethod
colon(a::NfAbsOrdIdl, b::NfAbsOrdIdl) -> NfOrdFracIdl

The ideal $(a:b) = \{x \in K | xb \subseteq a\} = \hom(b, a)$ where $K$ is the number field.

inMethod
in(x::NumFieldOrdElem, y::NumFieldOrdIdl)
-in(x::NumFieldElem, y::NumFieldOrdIdl)
-in(x::ZZRingElem, y::NumFieldOrdIdl)

Returns whether $x$ is contained in $y$.

is_powerMethod
is_power(A::NfAbsOrdIdl, n::Int) -> Bool, NfAbsOrdIdl
-is_power(A::NfOrdFracIdl, n::Int) -> Bool, NfOrdFracIdl

Computes, if possible, an ideal $B$ s.th. $B^n==A$ holds. In this case, true and $B$ are returned.

is_powerMethod
is_power(I::NfAbsOrdIdl) -> Int, NfAbsOrdIdl
-is_power(a::NfOrdFracIdl) -> Int, NfOrdFracIdl

Writes $a = r^e$ with $e$ maximal. Note: $1 = 1^0$.

is_invertibleMethod
is_invertible(A::NfAbsOrdIdl) -> Bool, NfOrdFracIdl

Returns true and an inverse of $A$ or false and an ideal $B$ such that $A*B \subsetneq order(A)$, if $A$ is not invertible.

isoneMethod
isone(A::NfAbsOrdIdl) -> Bool
-is_unit(A::NfAbsOrdIdl) -> Bool

Tests if $A$ is the trivial ideal generated by $1$.

Class Group

The group of invertable ideals in any order forms a group and the principal ideals a subgroup. The finite quotient is called class group for maximal orders and Picard group or ring class group in general.

class_groupMethod
class_group(O::NfOrd; bound = -1, method = 3, redo = false, large = 1000) -> GrpAbFinGen, Map

Returns a group $A$ and a map $f$ from $A$ to the set of ideals of $O$. The inverse of the map is the projection onto the group of ideals modulo the group of principal ideals. redo allows to trigger a re-computation, thus avoiding the cache. bound, when given, is the bound for the factor base.

narrow_class_groupMethod
narrow_class_group(O::NfOrd) -> GrpAbFinGen, Map

Computes the narrow (or strict) class group of $O$, ie. the group of invertable ideals modulo principal ideals generated by elements that are positive at all real places.

picard_groupMethod
picard_group(O::NfOrd) -> GrpAbFinGen, MapClassGrp

Returns the Picard group of $O$ and a map from the group in the set of (invertible) ideals of $O$.

ring_class_groupMethod
ring_class_group(O::NfAbsOrd)

The ring class group (Picard group) of $O$.


julia> k, a = wildanger_field(3, 13);
julia> zk = maximal_order(k);
julia> c, mc = class_group(zk)(GrpAb: Z/9, ClassGroup map of -Set of ideals of Maximal order of Number field of degree 3 over QQ -with basis nf_elem[1, _$, 1//2*_$^2 + 1//2] -)
julia> lp = prime_ideals_up_to(zk, 20);
julia> [ mc \ I for I = lp]10-element Vector{GrpAbFinGenElem}: - Element of -GrpAb: Z/9 -with components [1] - Element of -GrpAb: Z/9 -with components [7] - Element of -GrpAb: Z/9 -with components [1] - Element of -GrpAb: Z/9 -with components [8] - Element of -GrpAb: Z/9 -with components [3] - Element of -GrpAb: Z/9 -with components [5] - Element of -GrpAb: Z/9 -with components [4] - Element of -GrpAb: Z/9 -with components [7] - Element of -GrpAb: Z/9 -with components [0] - Element of -GrpAb: Z/9 -with components [5]
julia> mc(c[1])<2, 3//2*_$^2 + 2*_$ + 3//2> -Norm: 2 -Minimum: 2 -two normal wrt: 2
julia> order(c[1])9
julia> mc(c[1])^Int(order(c[1]))<32, 42356734006825450665//2*_$^2 - 21019337737156744045*_$ + 45857766179621516487//2> -Norm: 512 -Minimum: 32 -two normal wrt: 2
julia> mc \ ansElement of -GrpAb: Z/9 -with components [0]

The class group, or more precisely the information used to compute it also allows for principal ideal testing and related tasks. In general, due to the size of the objects, the fac_elem versions are more efficient.

is_principalMethod
is_principal(A::NfOrdIdl) -> Bool, NfOrdElem
-is_principal(A::NfOrdFracIdl) -> Bool, NfOrdElem

Tests if $A$ is principal and returns $(\mathtt{true}, \alpha)$ if $A = \langle \alpha\rangle$ or $(\mathtt{false}, 1)$ otherwise.

is_principal_fac_elemMethod
is_principal_fac_elem(A::NfOrdIdl) -> Bool, FacElem{nf_elem, number_field}

Tests if $A$ is principal and returns $(\mathtt{true}, \alpha)$ if $A = \langle \alpha\rangle$ or $(\mathtt{false}, 1)$ otherwise. The generator will be in factored form.

power_classMethod
power_class(A::NfOrdIdl, e::ZZRingElem) -> NfOrdIdl

Computes a (small) ideal in the same class as $A^e$.

power_product_classMethod
power_product_class(A::Vector{NfOrdIdl}, e::Vector{ZZRingElem}) -> NfOrdIdl

Computes a (small) ideal in the same class as $\prod A_i^{e_i}$.

power_reduceMethod
power_reduce(A::NfOrdIdl, e::ZZRingElem) -> NfOrdIdl, FacElem{nf_elem}

Computes $B$ and $\alpha$ in factored form, such that $\alpha B = A^e$ $B$ has small norm.

class_group_ideal_relationMethod
class_group_ideal_relation(I::NfOrdIdl, c::ClassGrpCtx) -> nf_elem, SRow{ZZRingElem}

Finds a number field element $\alpha$ such that $\alpha I$ factors over the factor base in $c$.

factor_base_bound_grhMethod
factor_base_bound_grh(O::NfOrd) -> Int

Returns an integer $B$, such that under GRH the ideal class group of $\mathcal O$ is generated by the prime ideals of norm bounded by $B$.

factor_base_bound_bachMethod
factor_base_bound_bach(O::NfOrd) -> Int

Use the theorem of Bach to find $B$ such that under GRH the ideal class group of $\mathcal O$ is generated by the prime ideals of norm bounded by $B$.

prime_ideals_up_toFunction
prime_ideals_up_to(O::NfOrd,
-                   B::Int;
-                   degree_limit::Int = 0, index_divisors::Bool = true) -> Vector{NfOrdIdl}

Computes the prime ideals $\mathcal O$ with norm up to $B$.

If degree_limit is a nonzero integer $k$, then prime ideals $\mathfrak p$ with $\deg(\mathfrak p) > k$ will be discarded. If 'index_divisors' is set to false, only primes not dividing the index of the order will be computed.

prime_ideals_up_to(O::NfOrd,
-                   B::Int;
-                   complete::Bool = false,
-                   degree_limit::Int = 0,
-                   F::Function,
-                   bad::ZZRingElem)

Computes the prime ideals $\mathcal O$ with norm up to $B$.

If degree_limit is a nonzero integer $k$, then prime ideals $\mathfrak p$ with $\deg(\mathfrak p) > k$ will be discarded.

The function $F$ must be a function on prime numbers not dividing bad such that $F(p) = \deg(\mathfrak p)$ for all prime ideals $\mathfrak p$ lying above $p$.

julia> I = mc(c[1])<2, 3//2*_$^2 + 2*_$ + 3//2>
-Norm: 2
-Minimum: 2
-two normal wrt: 2
julia> is_principal(I)(false, 1)
julia> I = I^Int(order(c[1]))<32, 42356734006825450665//2*_$^2 - 21019337737156744045*_$ + 45857766179621516487//2> -Norm: 512 -Minimum: 32 -two normal wrt: 2
julia> is_principal(I)(true, 1//2*_$^2 - 5*_$ - 17//2)
julia> is_principal_fac_elem(I)(true, (1//2*_$^2 - 5*_$ - 17//2)^1)

The computation of $S$-units is also tied to the class group:

torsion_unitsMethod
torsion_units(O::NfOrd) -> Vector{NfOrdElem}

Given an order $O$, compute the torsion units of $O$.

torsion_unit_groupMethod
torsion_unit_group(O::NfOrd) -> GrpAb, Map

Given an order $\mathcal O$, returns the torsion units as an abelian group $G$ together with a map $G \to \mathcal O^\times$.

torsion_units_generatorMethod
torsion_units_generator(O::NfOrd) -> NfOrdElem

Given an order $O$, compute a generator of the torsion units of $O$.

torsion_units_gen_orderMethod
torsion_units_gen_order(O::NfOrd) -> NfOrdElem

Given an order $O$, compute a generator of the torsion units of $O$ as well as its order.

unit_groupMethod
unit_group(O::NfOrd) -> GrpAbFinGen, Map

Returns a group $U$ and an isomorphism map $f \colon U \to \mathcal O^\times$. A set of fundamental units of $\mathcal O$ can be obtained via [ f(U[1+i]) for i in 1:unit_group_rank(O) ]. f(U[1]) will give a generator for the torsion subgroup.

unit_group_fac_elemMethod
unit_group_fac_elem(O::NfOrd) -> GrpAbFinGen, Map

Returns a group $U$ and an isomorphism map $f \colon U \to \mathcal O^\times$. A set of fundamental units of $\mathcal O$ can be obtained via [ f(U[1+i]) for i in 1:unit_group_rank(O) ]. f(U[1]) will give a generator for the torsion subgroup. All elements will be returned in factored form.

sunit_groupMethod
sunit_group(I::Vector{NfOrdIdl}) -> GrpAb, Map

For an array $I$ of (coprime prime) ideals, find the $S$-unit group defined by $I$, ie. the group of non-zero field elements which are only divisible by ideals in $I$.

sunit_group_fac_elemMethod
sunit_group_fac_elem(I::Vector{NfOrdIdl}) -> GrpAb, Map

For an array $I$ of (coprime prime) ideals, find the $S$-unit group defined by $I$, ie. the group of non-zero field elements which are only divisible by ideals in $I$. The map will return elements in factored form.

sunit_mod_units_group_fac_elemMethod
sunit_mod_units_group_fac_elem(I::Vector{NfOrdIdl}) -> GrpAb, Map

For an array $I$ of (coprime prime) ideals, find the $S$-unit group defined by $I$, ie. the group of non-zero field elements which are only divisible by ideals in $I$ modulo the units of the field. The map will return elements in factored form.

julia> u, mu = unit_group(zk)(GrpAb: Z/2 x Z, UnitGroup map of Maximal order of Number field of degree 3 over QQ
-with basis nf_elem[1, _$, 1//2*_$^2 + 1//2]
-)
julia> mu(u[2])_$^2 - _$ + 1
julia> u, mu = unit_group_fac_elem(zk)(GrpAb: Z/2 x Z, UnitGroup map of Factored elements over Number field of degree 3 over QQ -)
julia> mu(u[2])(6*_$^2 - 80*_$ + 60)^-1*(_$^2 + 1)^1*(3*_$^2 - 40*_$ + 30)^1*(1//2*_$^2 - 6*_$ + 7//2)^-1*2^-1*(_$ + 1)^1
julia> evaluate(ans)_$^2 - _$ + 1
julia> lp = factor(6*zk)Dict{NfOrdIdl, Int64} with 4 entries: - <3, _$ + 5> => 1 - <3, _$^2 + 1> => 1 - <2, 5//2*_$^2 + 2*_$ + 1//2> => 2 - <2, 1//2*_$^2 + 2*_$ + 7//2> => 1
julia> s, ms = Hecke.sunit_group(collect(keys(lp)))(GrpAb: Z/2 x Z^(5), SUnits map of Number field of degree 3 over QQ for NfOrdIdl[<3, _$ + 5> -Norm: 3 -Minimum: 3 -basis_matrix -[3 0 0; 2 1 0; 2 0 1] -two normal wrt: 3, <3, _$^2 + 1> -Norm: 9 -Minimum: 3 -basis_matrix -[3 0 0; 0 3 0; 0 0 1] -two normal wrt: 3, <2, 5//2*_$^2 + 2*_$ + 1//2> -Norm: 2 -Minimum: 2 -basis_matrix -[2 0 0; 1 1 0; 0 0 1] -two normal wrt: 2, <2, 1//2*_$^2 + 2*_$ + 7//2> -Norm: 2 -Minimum: 2 -basis_matrix -[2 0 0; 1 1 0; 1 0 1] -two normal wrt: 2] -)
julia> ms(s[4])-1//2*_$^2 + 6*_$ + 5//2
julia> norm(ans)144
julia> factor(numerator(ans))1 * 2^4 * 3^2

Miscaellenous

orderMethod
order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion

Return the order of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> order(cycle_structure(x)) == order(x), gens(g))
-true
source
order(I::NumFieldOrdIdl) -> NfOrd

Returns the order of $I$.

orderMethod
order(a::NfAbsOrdFracIdl) -> NfAbsOrd

The order that was used to define the ideal $a$.

orderMethod
order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion

Return the order of the permutations with cycle structure c.

Examples

julia> g = symmetric_group(3);
-
-julia> all(x -> order(cycle_structure(x)) == order(x), gens(g))
-true
source
order(I::NumFieldOrdIdl) -> NfOrd

Returns the order of $I$.

orderMethod
order(a::NfRelOrdFracIdl) -> NfRelOrd

Returns the order of $a$.

nfMethod
nf(x::NumFieldOrdIdl) -> AnticNumberField

Returns the number field, of which $x$ is an integral ideal.

basisMethod
basis(A::NfAbsOrdIdl) -> Vector{NfOrdElem}

Returns the basis of $A$.

basis(I::NfAbsOrdFracIdl) -> Vector{nf_elem}

Returns the $\mathbf Z$-basis of $I$.

lll_basisMethod
lll_basis(I::NumFieldOrdIdl) -> Vector{NumFieldElem}

A basis for $I$ that is reduced using the LLL algorithm for the Minkowski metric.

basis_matrixMethod
basis_matrix(A::NfAbsOrdIdl) -> ZZMatrix

Returns the basis matrix of $A$.

basis_mat_invMethod
basis_mat_inv(A::NfAbsOrdIdl) -> ZZMatrix

Returns the inverse basis matrix of $A$.

basis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat

Return the inverse of the basis matrix of $A$.

assure_has_basis_mat_invMethod
basis_mat_inv(A::NfAbsOrdIdl) -> FakeFmpqMat

Returns the inverse of the basis matrix of $A$.

has_basisMethod
has_basis(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ has a basis already computed.

has_basis_matrixMethod
has_basis_matrix(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ knows its basis matrix.

has_2_elemMethod
has_2_elem(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ is generated by two elements.

has_2_elem_normalMethod
has_2_elem_normal(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ has normal two element generators.

has_weakly_normalMethod
has_weakly_normal(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ has weakly normal two element generators.

has_princ_gen_specialMethod
has_princ_gen_special(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ knows if it is generated by a rational integer.

principal_generatorMethod
principal_generator(A::NfOrdIdl) -> NfOrdElem

For a principal ideal $A$, find a generator.

principal_generator_fac_elemMethod
principal_generator_fac_elem(A::NfOrdIdl) -> FacElem{nf_elem, number_field}

For a principal ideal $A$, find a generator in factored form.

minimumMethod
minimum(A::NfAbsOrdIdl) -> ZZRingElem

Returns the smallest nonnegative element in $A \cap \mathbf Z$.

  minimum(A::NfRelOrdIdl) -> NfOrdIdl
-  minimum(A::NfRelOrdIdl) -> NfRelOrdIdl

Returns the ideal $A \cap O$ where $O$ is the maximal order of the coefficient ideals of $A$.

minimumMethod
  minimum(A::NfRelOrdIdl) -> NfOrdIdl
-  minimum(A::NfRelOrdIdl) -> NfRelOrdIdl

Returns the ideal $A \cap O$ where $O$ is the maximal order of the coefficient ideals of $A$.

minimumMethod
minimum(A::NfAbsOrdIdl) -> ZZRingElem

Returns the smallest nonnegative element in $A \cap \mathbf Z$.

has_minimumMethod
has_minimum(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ knows its minimum.

normMethod
norm(A::NfAbsOrdIdl) -> ZZRingElem

Returns the norm of $A$, that is, the cardinality of $\mathcal O/A$, where $\mathcal O$ is the order of $A$.

norm(a::NfRelOrdIdl) -> NfOrdIdl

Returns the norm of $a$.

norm(a::NfRelOrdFracIdl{T, S}) -> S

Returns the norm of $a$.

norm(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd; copy::Bool = true) -> QQFieldElem

Returns the norm of $a$ considered as an (possibly fractional) ideal of $O$.

norm(a::AlgAssRelOrdIdl{S, T, U}, O::AlgAssRelOrd{S, T, U}; copy::Bool = true)
-  where { S, T, U } -> T

Returns the norm of $a$ considered as an (possibly fractional) ideal of $O$.

has_normMethod
has_norm(A::NfAbsOrdIdl) -> Bool

Returns whether $A$ knows its norm.

idempotentsMethod
idempotents(x::NfOrdIdl, y::NfOrdIdl) -> NfOrdElem, NfOrdElem

Returns a tuple (e, f) consisting of elements e in x, f in y such that 1 = e + f.

If the ideals are not coprime, an error is raised.

is_primeMethod
is_prime(A::NfOrdIdl) -> Bool

Returns whether $A$ is a prime ideal.

is_prime_knownMethod
is_prime_known(A::NfOrdIdl) -> Bool

Returns whether $A$ knows if it is prime.

is_ramifiedMethod
is_ramified(O::NfOrd, p::Int) -> Bool

Returns whether the integer $p$ is ramified in $\mathcal O$. It is assumed that $p$ is prime.

ramification_indexMethod
ramification_index(P::NfOrdIdl) -> Int

The ramification index of the prime-ideal $P$.

degreeMethod
degree(P::NfOrdIdl) -> Int

The inertia degree of the prime-ideal $P$.

valuationMethod
valuation(a::NumFieldElem, p::NfOrdIdl) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

valuationMethod
valuation(a::nf_elem, p::NfOrdIdl) -> ZZRingElem
-valuation(a::NfOrdElem, p::NfOrdIdl) -> ZZRingElem
-valuation(a::ZZRingElem, p::NfOrdIdl) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

valuationMethod
valuation(A::NfOrdIdl, p::NfOrdIdl) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $A$, that is, the largest $i$ such that $A$ is contained in $\mathfrak p^i$.

valuationMethod
valuation(a::Integer, p::NfOrdIdl) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

valuationMethod
valuation(a::nf_elem, p::NfOrdIdl) -> ZZRingElem
-valuation(a::NfOrdElem, p::NfOrdIdl) -> ZZRingElem
-valuation(a::ZZRingElem, p::NfOrdIdl) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

valuationMethod
valuation(A::NfAbsOrdFracIdl, p::NfAbsOrdIdl)

The valuation of $A$ at $p$.

idempotentsMethod
idempotents(x::NfOrdIdl, y::NfOrdIdl) -> NfOrdElem, NfOrdElem

Returns a tuple (e, f) consisting of elements e in x, f in y such that 1 = e + f.

If the ideals are not coprime, an error is raised.

Quotient Rings

quoMethod
quo(O::NfOrd, I::NfOrdIdl) -> NfOrdQuoRing, Map
-quo(O::AlgAssAbsOrd, I::AlgAssAbsOrdIdl) -> AbsOrdQuoRing, Map

The quotient ring $O/I$ as a ring together with the section $M: O/I \to O$. The pointwise inverse of $M$ is the canonical projection $O\to O/I$.

residue_ringMethod
residue_ring(O::NfOrd, I::NfOrdIdl) -> NfOrdQuoRing
-residue_ring(O::AlgAssAbsOrd, I::AlgAssAbsOrdIdl) -> AbsOrdQuoRing

The quotient ring $O$ modulo $I$ as a new ring.

residue_fieldMethod
residue_field(O::NfOrd, P::NfOrdIdl, check::Bool = true) -> Field, Map

Returns the residue field of the prime ideal $P$ together with the projection map. If check is true, the ideal is checked for being prime.

modMethod
mod(x::NfOrdElem, I::NfAbsOrdIdl)

Returns the unique element $y$ of the ambient order of $x$ with $x \equiv y \bmod I$ and the following property: If $a_1,\dotsc,a_d \in \mathbf{Z}_{\geq 1}$ are the diagonal entries of the unique HNF basis matrix of $I$ and $(b_1,\dotsc,b_d)$ is the coefficient vector of $y$, then $0 \leq b_i < a_i$ for $1 \leq i \leq d$.

crtMethod
crt(r1::NfOrdElem, i1::NfOrdIdl, r2::NfOrdElem, i2::NfOrdIdl) -> NfOrdElem

Find $x$ such that $x \equiv r_1 \bmod i_1$ and $x \equiv r_2 \bmod i_2$ using idempotents.

euler_phiMethod
euler_phi(A::NfOrdIdl) -> ZZRingElem

The ideal version of the totient function returns the size of the unit group of the residue ring modulo the ideal.

multiplicative_groupMethod
multiplicative_group(Q::NfOrdQuoRing) -> GrpAbFinGen, Map{GrpAbFinGen, NfOrdQuoRing}
-unit_group(Q::NfOrdQuoRing) -> GrpAbFinGen, Map{GrpAbFinGen, NfOrdQuoRing}

Returns the unit group of $Q$ as an abstract group $A$ and an isomorphism map $f \colon A \to Q^\times$.

multiplicative_group_generatorsMethod
multiplicative_group_generators(Q::NfOrdQuoRing) -> Vector{NfOrdQuoRingElem}

Return a set of generators for $Q^\times$.

diff --git a/previews/PR2578/Hecke/orders/introduction/index.html b/previews/PR2578/Hecke/orders/introduction/index.html deleted file mode 100644 index e87cb9003981..000000000000 --- a/previews/PR2578/Hecke/orders/introduction/index.html +++ /dev/null @@ -1,22 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This chapter deals with number fields and orders there of. We follow the common terminology and conventions as e.g. used in Henri Cohen (1993), Henri Cohen (2000), M. Pohst, H. Zassenhaus (1997) or Daniel A. Marcus (2018).

If $K$ is a number field, then an order $\mathcal O$ of $K$ is a subring of the ring of integers $\mathcal O_K$ of $K$, which is free of rank $[K : \mathbf Q]$ as a $\mathbf Z$-module. Depending on whether $K$ is an absolute field or relative field, orders are treated differently. As far as possible, the interaction and the interface for orders of absolute number fields and of relative number fields is the same.

Orders of absolute number fields

Assume that $K$ is defined as an absolute field. An order $\mathcal O$ of such a field are constructed (implicitly) by specifying a $\mathbf Z$-basis, which is referred to as the basis of $\mathcal O$. If $(\omega_1,\dotsc,\omega_d)$ is the basis of $\mathcal O$ and $(\alpha_1,\dotsc,\alpha_d)$ the basis of $K$, then the matrix $B \in \operatorname{Mat}_{d \times d}(\mathbf Q)$ with

\[\begin{pmatrix} \omega_1 \\ \vdots \\ \omega_d \end{pmatrix} = B \begin{pmatrix} \alpha_1 \\ \vdots \\ \alpha_d \end{pmatrix}\]

is the basis matrix of $K$. If $K = \mathbf{Q}(\alpha) = \mathbf{Q}[x]/(f)$ is simple with $f \in \mathbf{Z}[x]$, then natural order $\mathbf Z[\alpha] = \mathbf{Z}[x]/(f)$ is called the equation order of $K$.

Orders of relative number fields

Orders in non-absolute number fields, that is, relative extensions, are represented differently. Let $L/K$ be a finite extension of number fields, then currently we require any order in $L$ to contain $\mathcal O_K$, the ring of integers of $K$. In this case, an order $\mathcal O$ in $L$ is a finitly generated torsion-free module over the Dedekind domain $\mathcal O_K$. As a ring, the order $\mathcal O$ is unitary and has $L$ as a fraction field. Due to $\mathcal O_K$ in general not being a principal ideal domain, the module structure is more complicated and requires so called pseudo-matrices. See here for details on pseudo-matrices, or Henri Cohen (2000), Chapter 1 for an introduction.

In short, $\mathcal O$ is represented as $\sum \mathfrak a_i \omega_i$ with fractional $\mathcal O_K$ ideals $\mathfrak a_i\subset K$ and $K$-linear independent elements $\omega_i\in L$. In general it is impossible to have both $\mathfrak a_i$ integral and $\omega_i \in \mathcal O$, thus coefficients will not be integral and/or generators not in the structure.

Examples

Usually, to create an order, one starts with a field (or a polynomial):


julia> Qx, x = polynomial_ring(QQ, "x");
julia> K, a = number_field(x^2 - 10, "a");
julia> E = EquationOrder(K)Maximal order of Number field of degree 2 over QQ -with basis nf_elem[1, a]
julia> Z_K = MaximalOrder(K)Maximal order of Number field of degree 2 over QQ -with basis nf_elem[1, a]
julia> conductor(E)<no 2-elts present> -basis_matrix -[1 0; 0 1]
julia> E == Z_Ktrue

Once orders are created, we can play with elements and ideals:

julia> lp = prime_decomposition(Z_K, 2)1-element Vector{Tuple{NfOrdIdl, Int64}}:
- (<2, a>
-Norm: 2
-Minimum: 2
-two normal wrt: 2, 2)
julia> p = lp[1][1]<2, a> -Norm: 2 -Minimum: 2 -two normal wrt: 2
julia> is_principal(p)(false, 1)
julia> fl, alpha = is_principal(p^2)(true, 2)
julia> norm(alpha)4

It is possible to work with residue fields as well:

julia> Fp, mFp = residue_field(Z_K, p)(Finite field of degree 1 over GF(2), Map with following data
-Domain:
-=======
-Maximal order of Number field of degree 2 over QQ
-with basis nf_elem[1, a]
-Codomain:
-=========
-Finite field of degree 1 over GF(2))
julia> [ mFp(x) for x = basis(Z_K)]2-element Vector{FqFieldElem}: - 1 - 0
diff --git a/previews/PR2578/Hecke/orders/orders/index.html b/previews/PR2578/Hecke/orders/orders/index.html deleted file mode 100644 index cf20cb076cf6..000000000000 --- a/previews/PR2578/Hecke/orders/orders/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Orders · Oscar.jl

Orders

Orders, that is, unitary subrings that are free $\mathbf{Z}$-modules of rank equal to the degree of the number field, are at the core of the arithmetic of number fields. In Hecke, orders are always represented using the module structure, be it the $\mathbf{Z}$-module structure for orders of absolute numbers fields, or the structure as a module over the maximal order of the base field in the case of relative number fields. In this chapter we mainly deal with orders of absolute fields. However, many functions apply in same way to relative extensions. There are more general definitions of orders in number fields available, but those are (currently) not implemented in Hecke.

Among all orders in a fixed field, there is a unique maximal order, called the maximal order, or ring of integers of the number field. It is well known that this is the only order that is a Dedekind domain, hence has a rich ideal structure as well. The maximal order is also the integral closure of $\mathbf{Z}$ in the number field and can also be interpreted as a normalization of any other order.

Creation and basic properties

OrderMethod
Order(a::Vector{nf_elem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> NfOrd
-Order(K::AnticNumberField, a::Vector{nf_elem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> NfOrd

Returns the order generated by $a$. If check is set, it is checked whether $a$ defines an order, in particular the integrality of the elements is checked by computing minimal polynomials. If isbasis is set, then elements are assumed to form a $\mathbf{Z}$-basis. If cached is set, then the constructed order is cached for future use.

OrderMethod
Order(K::AnticNumberField, A::FakeFmpqMat; check::Bool = true) -> NfOrd

Returns the order which has basis matrix $A$ with respect to the power basis of $K$. If check is set, it is checked whether $A$ defines an order.

OrderMethod
Order(K::AnticNumberField, A::ZZMatrix, check::Bool = true) -> NfOrd

Returns the order which has basis matrix $A$ with respect to the power basis of $K$. If check is set, it is checked whether $A$ defines an order.

Order(A::AbsAlgAss{<: NumFieldElem}, M::PMat{<: NumFieldElem, T})
-  -> AlgAssRelOrd

Returns the order of $A$ with basis pseudo-matrix $M$.

EquationOrderMethod
EquationOrder(K::number_field) -> NumFieldOrd
-equation_order(K::number_field) -> NumFieldOrd

Returns the equation order of the number field $K$.

MaximalOrderMethod
MaximalOrder(K::NumField{QQFieldElem}; discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> NfAbsOrd

Returns the maximal order of $K$. Additional information can be supplied if they are already known, as the ramified primes or the discriminant of the maximal order.

Example

julia> Qx, x = FlintQQ["x"];
-julia> K, a = number_field(x^3 + 2, "a");
-julia> O = MaximalOrder(K);
MaximalOrderMethod
MaximalOrder(O::NfAbsOrd; index_divisors::Vector{ZZRingElem}, discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> NfAbsOrd

Returns the maximal order of the number field that contains $O$. Additional information can be supplied if they are already known, as the ramified primes, the discriminant of the maximal order or a set of integers dividing the index of $O$ in the maximal order.

MaximalOrder(O::AlgAssAbsOrd)

Given an order $O$, this function returns a maximal order containing $O$.

MaximalOrder(A::AbsAlgAss{QQFieldElem}) -> AlgAssAbsOrd

Returns a maximal order of $A$.

lllMethod
lll(M::NfAbsOrd) -> NfAbsOrd

The same order, but with the basis now being LLL reduced wrt. the Minkowski metric.

any_orderMethod
any_order(K::number_field)

Return some order in $K$. In case the defining polynomial for $K$ is monic and integral, this just returns the equation order. In the other case $\mathbb Z[\alpha]\cap \mathbb Z[1/\alpha]$ is returned.

Example


julia> Qx, x = polynomial_ring(FlintQQ, "x");
julia> K, a = number_field(x^2 - 2, "a");
julia> O = EquationOrder(K)Order of Number field of degree 2 over QQ -with Z-basis NfOrdElem[1, a]
parentMethod
parent(O::NfAbsOrd) -> NfOrdSet

Returns the parent of $\mathcal O$, that is, the set of orders of the ambient number field.

signatureMethod
signature(O::NumFieldOrd) -> Tuple{Int, Int}

Returns the signature of the ambient number field of $\mathcal O$.

nfMethod
nf(O::NumFieldOrd) -> NumField

Returns the ambient number field of $\mathcal O$.

basisMethod
basis(O::NfAbsOrd) -> Vector{NfAbsOrdElem}

Returns the $\mathbf Z$-basis of $\mathcal O$.

basis(I::NfAbsOrdFracIdl) -> Vector{nf_elem}

Returns the $\mathbf Z$-basis of $I$.

lll_basisMethod
lll_basis(M::NumFieldOrd) -> Vector{NumFieldElem}

A basis for $M$ that is reduced using the LLL algorithm for the Minkowski metric.

basisMethod
basis(O::NfOrd, K::AnticNumberField) -> Vector{nf_elem}

Returns the $\mathbf Z$-basis elements of $\mathcal O$ as elements of the ambient number field.

pseudo_basisMethod
  pseudo_basis(O::NfRelOrd{T, S}) -> Vector{Tuple{NumFieldElem{T}, S}}

Returns the pseudo-basis of $\mathcal O$.

basis_pmatrixMethod
  basis_pmatrix(O::NfRelOrd) -> PMat

Returns the basis pseudo-matrix of $\mathcal O$ with respect to the power basis of the ambient number field.

basis_nfMethod
  basis_nf(O::NfRelOrd) -> Vector{NumFieldElem}

Returns the elements of the pseudo-basis of $\mathcal O$ as elements of the ambient number field.

inv_coeff_idealsMethod
  inv_coeff_ideals(O::NfRelOrd{T, S}) -> Vector{S}

Returns the inverses of the coefficient ideals of the pseudo basis of $O$.

basis_matrixMethod
basis_matrix(O::NfAbsOrd) -> FakeFmpqMat

Returns the basis matrix of $\mathcal O$ with respect to the basis of the ambient number field.

basis_mat_invMethod
basis_mat_inv(O::NfAbsOrd) -> FakeFmpqMat

Returns the inverse of the basis matrix of $\mathcal O$.

basis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat

Return the inverse of the basis matrix of $A$.

gen_indexMethod
gen_index(O::NfOrd) -> QQFieldElem

Returns the generalized index of $\mathcal O$ with respect to the equation order of the ambient number field.

is_index_divisorMethod
is_index_divisor(O::NfOrd, d::ZZRingElem) -> Bool
-is_index_divisor(O::NfOrd, d::Int) -> Bool

Returns whether $d$ is a divisor of the index of $\mathcal O$. It is assumed that $\mathcal O$ contains the equation order of the ambient number field.

minkowski_matrixMethod
minkowski_matrix(O::NfAbsOrd, abs_tol::Int = 64) -> arb_mat

Returns the Minkowski matrix of $\mathcal O$. Thus if $\mathcal O$ has degree $d$, then the result is a matrix in $\operatorname{Mat}_{d\times d}(\mathbf R)$. The entries of the matrix are real balls of type arb with radius less then 2^-abs_tol.

inMethod
in(a::NumFieldElem, O::NumFieldOrd) -> Bool

Checks whether $a$ lies in $\mathcal O$.

norm_change_constMethod
norm_change_const(O::NfOrd) -> (Float64, Float64)

Returns $(c_1, c_2) \in \mathbf R_{>0}^2$ such that for all $x = \sum_{i=1}^d x_i \omega_i \in \mathcal O$ we have $T_2(x) \leq c_1 \cdot \sum_i^d x_i^2$ and $\sum_i^d x_i^2 \leq c_2 \cdot T_2(x)$, where $(\omega_i)_i$ is the $\mathbf Z$-basis of $\mathcal O$.

trace_matrixMethod
trace_matrix(O::NfAbsOrd) -> ZZMatrix

Returns the trace matrix of $\mathcal O$, that is, the matrix $(\operatorname{tr}_{K/\mathbf Q}(b_i \cdot b_j))_{1 \leq i, j \leq d}$.

+Method
+(R::NfOrd, S::NfOrd) -> NfOrd

Given two orders $R$, $S$ of $K$, this function returns the smallest order containing both $R$ and $S$. It is assumed that $R$, $S$ contain the ambient equation order and have coprime index.

poverorderMethod
poverorder(O::NfOrd, p::ZZRingElem) -> NfOrd
-poverorder(O::NfOrd, p::Integer) -> NfOrd

This function tries to find an order that is locally larger than $\mathcal O$ at the prime $p$: If $p$ divides the index $[ \mathcal O_K : \mathcal O]$, this function will return an order $R$ such that $v_p([ \mathcal O_K : R]) < v_p([ \mathcal O_K : \mathcal O])$. Otherwise $\mathcal O$ is returned.

poverordersMethod
poverorders(O, p) -> Vector{Ord}

Returns all p-overorders of O, that is all overorders M, such that the index of O in M is a p-power.

pmaximal_overorderMethod
pmaximal_overorder(O::NfOrd, p::ZZRingElem) -> NfOrd
-pmaximal_overorder(O::NfOrd, p::Integer) -> NfOrd

This function finds a $p$-maximal order $R$ containing $\mathcal O$. That is, the index $[ \mathcal O_K : R]$ is not divisible by $p$.

pradicalMethod
pradical(O::NfOrd, p::{ZZRingElem|Integer}) -> NfAbsOrdIdl

Given a prime number $p$, this function returns the $p$-radical $\sqrt{p\mathcal O}$ of $\mathcal O$, which is just $\{ x \in \mathcal O \mid \exists k \in \mathbf Z_{\geq 0} \colon x^k \in p\mathcal O \}$. It is not checked that $p$ is prime.

pradicalMethod
  pradical(O::NfRelOrd, P::NfOrdIdl) -> NfRelOrdIdl

Given a prime ideal $P$, this function returns the $P$-radical $\sqrt{P\mathcal O}$ of $\mathcal O$, which is just $\{ x \in \mathcal O \mid \exists k \in \mathbf Z_{\geq 0} \colon x^k \in P\mathcal O \}$. It is not checked that $P$ is prime.

ring_of_multipliersMethod
ring_of_multipliers(I::NfAbsOrdIdl) -> NfAbsOrd

Computes the order $(I : I)$, which is the set of all $x \in K$ with $xI \subseteq I$.

Invariants

discriminantMethod
discriminant(O::NfOrd) -> ZZRingElem

Returns the discriminant of $\mathcal O$.

discriminant(E::EllCrv) -> FieldElem

Return the discriminant of $E$.

discriminant(C::HypellCrv{T}) -> T

Compute the discriminant of $C$.

discriminant(O::AlgssRelOrd)

Returns the discriminant of $O$.

discriminantMethod
discriminant(O::NfOrd) -> ZZRingElem

Returns the discriminant of $\mathcal O$.

reduced_discriminantMethod
reduced_discriminant(O::NfOrd) -> ZZRingElem

Returns the reduced discriminant, that is, the largest elementary divisor of the trace matrix of $\mathcal O$.

degreeMethod
degree(O::NumFieldOrd) -> Int

Returns the degree of $\mathcal O$.

indexMethod
index(O::NfOrd) -> ZZRingElem

Assuming that the order $\mathcal O$ contains the equation order $\mathbf Z[\alpha]$ of the ambient number field, this function returns the index $[ \mathcal O : \mathbf Z]$.

differentMethod
different(R::NfAbsOrd) -> NfAbsOrdIdl

The different ideal of $R$, that is, the ideal generated by all differents of elements in $R$. For Gorenstein orders, this is also the inverse ideal of the co-different.

codifferentMethod
codifferent(R::NfAbsOrd) -> NfOrdIdl

The codifferent ideal of $R$, i.e. the trace-dual of $R$.

is_gorensteinMethod
is_gorenstein(O::NfOrd) -> Bool

Return whether the order \mathcal{O} is Gorenstein.

is_bassMethod
is_bass(O::NfOrd) -> Bool

Return whether the order \mathcal{O} is Bass.

is_equation_orderMethod
is_equation_order(O::NumFieldOrd) -> Bool

Returns whether $\mathcal O$ is the equation order of the ambient number field $K$.

zeta_log_residueMethod
zeta_log_residue(O::NfOrd, error::Float64) -> arb

Computes the residue of the zeta function of $\mathcal O$ at $1$. The output will be an element of type arb with radius less then error.

ramified_primesMethod
ramified_primes(O::NfAbsOrd) -> Vector{ZZRingElem}

Returns the list of prime numbers that divide $\operatorname{disc}(\mathcal O)$.

Arithmetic

Progress and intermediate results of the functions mentioned here can be obtained via verbose_level, supported are

  • ClassGroup
  • UnitGroup

All of the functions have a very similar interface: they return an abelian group and a map converting elements of the group into the objects required. The maps also allow a point-wise inverse to server as the discrete logarithm map. For more information on abelian group, see here, for ideals, here.

For the processing of units, there are a couple of helper functions also available:

is_independentFunction
is_independent{T}(x::Vector{T})

Given an array of non-zero units in a number field, returns whether they are multiplicatively independent.

Predicates

is_containedMethod
is_contained(R::NfAbsOrd, S::NfAbsOrd) -> Bool

Checks if $R$ is contained in $S$.

is_maximalMethod
is_maximal(R::NfAbsOrd) -> Bool

Tests if the order $R$ is maximal. This might trigger the computation of the maximal order.

diff --git a/previews/PR2578/Hecke/pmat/introduction/index.html b/previews/PR2578/Hecke/pmat/introduction/index.html deleted file mode 100644 index 5aea82eb30e2..000000000000 --- a/previews/PR2578/Hecke/pmat/introduction/index.html +++ /dev/null @@ -1,16 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This chapter deals with pseudo-matrices. We follow the common terminology and conventions introduced in Henri Cohen (2000), however, we operate on rows, not on columns.

Let $R$ be a Dedekind domain, typically, the maximal order of some number field $K$, further fix some finite dimensional $K$-vectorspace $V$ (with some basis), frequently $K^n$ or the $K$-structure of some extension of $K$. Since in general $R$ is not a PID, the $R$-modules in $V$ are usually not free, but still projective.

Any finitely generated $R$-module $M\subset V$ can be represented as a pseudo-matrix PMat as follows: The structure theory of $R$-modules gives the existence of (fractional) $R$-ideals $\mathfrak A_i$ and elements $\omega_i\in V$ such that $M = \sum \mathfrak A_i \omega_i$ and the sum is direct.

Following Cohen we call modules of the form $\mathfrak A\omega$ for some ideal $\mathfrak A$ and $\omega \in V$ a pseudo element. A system $(\mathfrak A_i, \omega_i)$ is called a pseudo-generating system for $M$ if $\langle \mathfrak A_i\omega_i|i\langle = M$. A pseudo-generating system is called a pseudo-basis if the $\omega_i$ are $K$-linear independent.

A pseudo-matrix $X$ is a tuple containing a vector of ideals $\mathfrak A_i$ ($1\le i\le r$) and a matrix $U\in K^{r\times n}$. The $i$-th row together with the $i$-th ideal defines a pseudo-element, thus an $R$-module, all of them together generate a module $M$.

A pseudo-matrix $X=((\mathfrak A_i)_i, U)$ is said to be in pseudo-hnf if $U$ is essentially upper triangular. Similar to the classical hnf, there is an algorithm that transforms any pseudo-matrix into one in pseudo-hnf while maintaining the module.

Creation

In general to create a PMat one has to specify a matrix and a vector of ideals:

pseudo_matrixMethod
pseudo_matrix(m::Generic.Mat{nf_elem}, c::Vector{NfOrdIdl}) -> PMat{nf_elem, NfOrdFracIdl}

Returns the (row) pseudo matrix representing the $Z_k$-module $\sum c_i m_i$ where $c_i$ are the ideals in $c$ and $m_i$ the rows of $M$.

pseudo_matrixMethod
pseudo_matrix(m::Generic.Mat{NfOrdElem}, c::Vector{NfOrdIdl}) -> PMat{nf_elem, NfOrdFracIdl}

Returns the (row) pseudo matrix representing the $Z_k$-module $\sum c_i m_i$ where $c_i$ are the ideals in $c$ and $m_i$ the rows of $M$.

pseudo_matrixMethod
pseudo_matrix(m::Generic.Mat{NfOrdElem}) -> PMat{nf_elem, NfOrdFracIdl}

Returns the free (row) pseudo matrix representing the $Z_k$-module $\sum Z_k m_i$ where $m_i$ are the rows of $M$.

(Those functions are also available as pseudo_matrix)

Operations

coefficient_idealsMethod
coefficient_ideals(M::PMat)

Returns the vector of coefficient ideals.

matrixMethod
matrix(M::PMat)

Returns the matrix part of the PMat.

base_ringMethod
base_ring(I::MPolyIdeal)

Return the ambient ring of I.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2
-ideal(x^2, x*y, y^2)
-
-julia> base_ring(I)
-Multivariate polynomial ring in 2 variables x, y
-  over rational field
source
base_ring(X::AbsSpec)

On an affine scheme $X/𝕜$ over $𝕜$ this returns the ring $𝕜$.

Examples

julia> X = affine_space(QQ,3)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
-
-julia> base_ring(X)
-Rational field
source
base_ring(M::PMat)

The PMat $M$ defines an $R$-module for some maximal order $R$. This function returns the $R$ that was used to defined $M$.

pseudo_hnfMethod
pseudo_hnf(P::PMat)

Transforms $P$ into pseudo-Hermite form as defined by Cohen. Essentially the matrix part of $P$ will be upper triangular with some technical normalisation for the off-diagonal elements. This operation preserves the module.

A optional second argument can be specified as a symbols, indicating the desired shape of the echelon form. Possible are :upperright (the default) and :lowerleft

pseudo_hnf_with_transformMethod
pseudo_hnf_with_transform(P::PMat)

Transforms $P$ into pseudo-Hermite form as defined by Cohen. Essentially the matrix part of $P$ will be upper triangular with some technical normalisation for the off-diagonal elements. This operation preserves the module. The used transformation is returned as a second return value.

A optional second argument can be specified as a symbol, indicating the desired shape of the echelon form. Possible are :upperright (the default) and :lowerleft

Examples

diff --git a/previews/PR2578/Hecke/quad_forms/Zgenera/index.html b/previews/PR2578/Hecke/quad_forms/Zgenera/index.html deleted file mode 100644 index d59cc827f48c..000000000000 --- a/previews/PR2578/Hecke/quad_forms/Zgenera/index.html +++ /dev/null @@ -1,5 +0,0 @@ - -Genera of Integer Lattices · Oscar.jl

Genera of Integer Lattices

Two $\mathbb{Z}$-lattices $M$ and $N$ are said to be in the same genus if their completions $M \otimes \mathbb{Z}_p$ and $N \otimes \mathbb{Z}_p$ are isometric for all prime numbers $p$ as well as $M \otimes \mathbb{R} \cong N\otimes \mathbb{R}$.

The genus of a $\mathbb{Z}$-lattice is encoded in its Conway-Sloane genus symbol. The genus symbol itself is a collection of its local genus symbols. See J. H. Conway, N. J. A. Sloane (1999) Chapter 15 for the definitions. Note that genera for non-integral lattices are supported.

The class ZZGenus supports genera of $\mathbb{Z}$-lattices.

ZZGenusType
ZZGenus

A collection of local genus symbols (at primes) and a signature pair. Together they represent the genus of a non-degenerate integer_lattice.

Creation of Genera

From an integral Lattice

genusMethod
genus(L::ZZLat) -> ZZGenus

Return the genus of the lattice L.

From a gram matrix

genusMethod
genus(A::MatElem) -> ZZGenus

Return the genus of a $\mathbb Z$-lattice with gram matrix A.

Enumeration of genus symbols

integer_generaMethod
integer_genera(sig_pair::Vector{Int}, determinant::RationalUnion;
-       min_scale::RationalUnion = min(one(QQ), QQ(abs(determinant))),
-       max_scale::RationalUnion = max(one(QQ), QQ(abs(determinant))),
-       even=false)                                         -> Vector{ZZGenus}

Return a list of all genera with the given conditions. Genera of non-integral $\mathbb Z$-lattices are also supported.

Arguments

  • sig_pair: a pair of non-negative integers giving the signature
  • determinant: a rational number; the sign is ignored
  • min_scale: a rational number; return only genera whose scale is an integer multiple of min_scale (default: min(one(QQ), QQ(abs(determinant))))
  • max_scale: a rational number; return only genera such that max_scale is an integer multiple of the scale (default: max(one(QQ), QQ(abs(determinant))))
  • even: boolean; if set to true, return only the even genera (default: false)

From other genus symbols

direct_sumMethod
direct_sum(G1::ZZGenus, G2::ZZGenus) -> ZZGenus

Return the genus of the direct sum of G1 and G2.

The direct sum is defined via representatives.

Attributes of the genus

dimMethod
dim(G::ZZGenus) -> Int

Return the dimension of this genus.

rankMethod
rank(G::ZZGenus) -> Int

Return the rank of a (representative of) the genus G.

signatureMethod
signature(G::ZZGenus) -> Int

Return the signature of this genus.

The signature is p - n where p is the number of positive eigenvalues and n the number of negative eigenvalues.

detMethod
det(G::ZZGenus) -> QQFieldElem

Return the determinant of this genus.

isevenMethod
iseven(G::ZZGenus) -> Bool

Return if this genus is even.

is_definiteMethod
is_definite(G::ZZGenus) -> Bool

Return if this genus is definite.

levelMethod
level(G::ZZGenus) -> QQFieldElem

Return the level of this genus.

This is the denominator of the inverse gram matrix of a representative.

scaleMethod
scale(G::ZZGenus) -> QQFieldElem

Return the scale of this genus.

Let L be a lattice with bilinear form b. The scale of (L,b) is defined as the ideal b(L,L).

normMethod
norm(G::ZZGenus) -> QQFieldElem

Return the norm of this genus.

Let L be a lattice with bilinear form b. The norm of (L,b) is defined as the ideal generated by $\{b(x,x) | x \in L\}$.

primesMethod
primes(G::ZZGenus) -> Vector{ZZRingElem}

Return the list of primes of the local symbols of G.

Note that 2 is always in the output since the 2-adic symbol of a ZZGenus is, by convention, always defined.

is_integralMethod
is_integral(G::ZZGenus) -> Bool

Return whether G is a genus of integral $\mathbb Z$-lattices.

Discriminant group

discriminant_group(::ZZGenus)

Primary genera

is_primary_with_primeMethod
is_primary_with_prime(G::ZZGenus) -> Bool, ZZRingElem

Given a genus of $\mathbb Z$-lattices G, return whether it is primary, that is whether the bilinear form is integral and the associated discriminant form (see discriminant_group) is a p-group for some prime number p. In case it is, p is also returned as second output.

Note that for unimodular genera, this function returns (true, 1). If the genus is not primary, the second return value is -1 by default.

is_primaryMethod
is_primary(G::ZZGenus, p::Union{Integer, ZZRingElem}) -> Bool

Given a genus of integral $\mathbb Z$-lattices G and a prime number p, return whether G is p-primary, that is whether the associated discriminant form (see discriminant_group) is a p-group.

is_elementary_with_primeMethod
is_elementary_with_prime(G::ZZGenus) -> Bool, ZZRingElem

Given a genus of $\mathbb Z$-lattices G, return whether it is elementary, that is whether the bilinear form is inegtral and the associated discriminant form (see discriminant_group) is an elementary p-group for some prime number p. In case it is, p is also returned as second output.

Note that for unimodular genera, this function returns (true, 1). If the genus is not elementary, the second return value is -1 by default.

is_elementaryMethod
is_elementary(G::ZZGenus, p::Union{Integer, ZZRingElem}) -> Bool

Given a genus of integral $\mathbb Z$-lattices G and a prime number p, return whether G is p-elementary, that is whether its associated discriminant form (see discriminant_group) is an elementary p-group.

local Symbol

local_symbolMethod
local_symbol(G::ZZGenus, p) -> ZZLocalGenus

Return the local symbol at p.

Representative(s)

quadratic_spaceMethod
quadratic_space(G::ZZGenus) -> QuadSpace{QQField, QQMatrix}

Return the quadratic space defined by this genus.

rational_representativeMethod
rational_representative(G::ZZGenus) -> QuadSpace{QQField, QQMatrix}

Return the quadratic space defined by this genus.

representativeMethod
representative(G::ZZGenus) -> ZZLat

Compute a representative of this genus && cache it.

representativesMethod
representatives(G::ZZGenus) -> Vector{ZZLat}

Return a list of representatives of the isometry classes in this genus.

massMethod
mass(G::ZZGenus) -> QQFieldElem

Return the mass of this genus.

The genus must be definite. Let L_1, ... L_n be a complete list of representatives of the isometry classes in this genus. Its mass is defined as $\sum_{i=1}^n \frac{1}{|O(L_i)|}$.

rescaleMethod
rescale(G::ZZGenus, a::RationalUnion) -> ZZGenus

Given a genus symbol G of $\mathbb Z$-lattices, return the genus symbol of any representative of G rescaled by a.

Embeddings and Representations

representsMethod
represents(G1::ZZGenus, G2::ZZGenus) -> Bool

Return if G1 represents G2. That is if some element in the genus of G1 represents some element in the genus of G2.

Local genus Symbols

ZZLocalGenusType
ZZLocalGenus

Local genus symbol over a p-adic ring.

The genus symbol of a component p^m A for odd prime = p is of the form (m,n,d), where

  • m = valuation of the component
  • n = rank of A
  • d = det(A) \in \{1,u\} for a normalized quadratic non-residue u.

The genus symbol of a component 2^m A is of the form (m, n, s, d, o), where

  • m = valuation of the component
  • n = rank of A
  • d = det(A) in {1,3,5,7}
  • s = 0 (or 1) if even (or odd)
  • o = oddity of A (= 0 if s = 0) in Z/8Z = the trace of the diagonalization of A

The genus symbol is a list of such symbols (ordered by m) for each of the Jordan blocks A_1,...,A_t.

Reference: J. H. Conway, N. J. A. Sloane (1999) Chapter 15, Section 7.

Arguments

  • prime: a prime number
  • symbol: the list of invariants for Jordan blocks A_t,...,A_t given as a list of lists of integers

Creation

genusMethod
genus(L::ZZLat, p) -> ZZLocalGenus

Return the local genus symbol of L at the prime p.

genusMethod
genus(A::MatElem, p) -> ZZLocalGenus

Return the local genus symbol of a Z-lattice with gram matrix A at the prime p.

Attributes

primeMethod
prime(S::ZZLocalGenus) -> ZZRingElem

Return the prime p of this p-adic genus.

isevenMethod
iseven(S::ZZLocalGenus) -> Bool

Return if the underlying p-adic lattice is even.

If p is odd, every lattice is even.

symbolMethod
symbol(S::ZZLocalGenus, scale::Int) -> Vector{Int}

Return a copy of the underlying lists of integers for the Jordan block of the given scale

hasse_invariantMethod
hasse_invariant(S::ZZLocalGenus) -> Int

Return the Hasse invariant of a representative. If the representative is diagonal (a1, ... , an) Then the Hasse invariant is

\[\prod_{i < j}(a_i, a_j)_p\]

.

detMethod
det(S::ZZLocalGenus) -> QQFieldElem

Return an rational representing the determinant of this genus.

dimMethod
dim(S::ZZLocalGenus) -> Int

Return the dimension of this genus.

rankMethod
rank(S::ZZLocalGenus) -> Int

Return the rank of (a representative of) S.

excessMethod
excess(S::ZZLocalGenus) -> zzModRingElem

Return the p-excess of the quadratic form whose Hessian matrix is the symmetric matrix A.

When p = 2 the p-excess is called the oddity. The p-excess is always even && is divisible by 4 if p is congruent 1 mod 4.

Reference

J. H. Conway, N. J. A. Sloane (1999) pp 370-371.

signatureMethod
signature(S::ZZLocalGenus) -> zzModRingElem

Return the $p$-signature of this $p$-adic form.

oddityMethod
oddity(S::ZZLocalGenus) -> zzModRingElem

Return the oddity of this even form. The oddity is also called the $2$-signature

scaleMethod
scale(S::ZZLocalGenus) -> QQFieldElem

Return the scale of this local genus.

Let L be a lattice with bilinear form b. The scale of (L,b) is defined as the ideal b(L,L).

normMethod
norm(S::ZZLocalGenus) -> QQFieldElem

Return the norm of this local genus.

Let L be a lattice with bilinear form b. The norm of (L,b) is defined as the ideal generated by $\{b(x,x) | x \in L\}$.

levelMethod
level(S::ZZLocalGenus) -> QQFieldElem

Return the maximal scale of a jordan component.

Representative

representativeMethod
representative(S::ZZLocalGenus) -> ZZLat

Return an integer lattice which represents this local genus.

gram_matrixMethod
gram_matrix(S::ZZLocalGenus) -> MatElem

Return a gram matrix of some representative of this local genus.

rescaleMethod
rescale(G::ZZLocalGenus, a::RationalUnion) -> ZZLocalGenus

Given a local genus symbol G of $\mathbb Z$-lattices, return the local genus symbol of any representative of G rescaled by a.

Direct sums

direct_sumMethod
direct_sum(S1::ZZLocalGenus, S2::ZZLocalGenus) -> ZZLocalGenus

Return the local genus of the direct sum of two representatives.

Embeddings/Representations

representsMethod
represents(g1::ZZLocalGenus, g2::ZZLocalGenus) -> Bool

Return whether g1 represents g2.

Based on O'Meara Integral Representations of Quadratic Forms Over Local Fields Note that for p == 2 there is a typo in O'Meara Theorem 3 (V). The correct statement is (V) $2^i(1+4\omega) \to \mathfrak{L}_{i+1}/\mathfrak{l}_{[i]}$.

diff --git a/previews/PR2578/Hecke/quad_forms/basics/index.html b/previews/PR2578/Hecke/quad_forms/basics/index.html deleted file mode 100644 index 254fa32290a9..000000000000 --- a/previews/PR2578/Hecke/quad_forms/basics/index.html +++ /dev/null @@ -1,62 +0,0 @@ - -Spaces · Oscar.jl

Spaces

Creation of spaces

quadratic_spaceMethod
quadratic_space(K::NumField, n::Int; cached::Bool = true) -> QuadSpace

Create the quadratic space over K with dimension n and Gram matrix equals to the identity matrix.

hermitian_spaceMethod
hermitian_space(E::NumField, n::Int; cached::Bool = true) -> HermSpace

Create the hermitian space over E with dimension n and Gram matrix equals to the identity matrix. The number field E must be a quadratic extension, that is, $degree(E) == 2$ must hold.

quadratic_spaceMethod
quadratic_space(K::NumField, G::MatElem; cached::Bool = true) -> QuadSpace

Create the quadratic space over K with Gram matrix G. The matrix G must be square and symmetric.

hermitian_spaceMethod
hermitian_space(E::NumField, gram::MatElem; cached::Bool = true) -> HermSpace

Create the hermitian space over E with Gram matrix equals to gram. The matrix gram must be square and hermitian with respect to the non-trivial automorphism of E. The number field E must be a quadratic extension, that is, $degree(E) == 2$ must hold.

Examples

Here are easy examples to see how these constructors work. We will keep the two following spaces for the rest of this section:


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2-a*t+1, "b");
julia> Q = quadratic_space(K, K[0 1; 1 0])Quadratic space of dimension 2 - over maximal real subfield of cyclotomic field of order 7 -with gram matrix -[0 1] -[1 0]
julia> H = hermitian_space(E, 3)Hermitian space of dimension 3 - over relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1 - over number field with defining polynomial $^3 + $^2 - 2*$ - 1 - over rational field -with gram matrix -[1 0 0] -[0 1 0] -[0 0 1]

Attributes

Let $(V, \Phi)$ be a space over $E/K$. We define its dimension to be its dimension as a vector space over its base ring $E$ and its rank to be the rank of its Gram matrix. If these two invariants agree, the space is said to be regular.

While dealing with lattices, one always works with regular ambient spaces.

The determinant $\text{det}(V, \Phi)$ of $(V, \Phi)$ is defined to be the class of the determinant of its Gram matrix in $K^{\times}/N(E^{\times})$ (which is similar to $K^{\times}/(K^{\times})^2$ in the quadratic case). The discriminant $\text{disc}(V, \Phi)$ of $(V, \Phi)$ is defined to be $(-1)^{(m(m-1)/2)}\text{det}(V, \Phi)$, where $m$ is the rank of $(V, \Phi)$.

rankMethod
rank(V::AbstractSpace) -> Int

Return the rank of the space V.

dimMethod
dim(V::AbstractSpace) -> Int

Return the dimension of the space V.

gram_matrixMethod
gram_matrix(V::AbstractSpace) -> MatElem

Return the Gram matrix of the space V.

involutionMethod
involution(V::AbstractSpace) -> NumFieldMor

Return the involution of the space V.

base_ringMethod
base_ring(V::AbstractSpace) -> NumField

Return the algebra over which the space V is defined.

fixed_fieldMethod
fixed_field(V::AbstractSpace) -> NumField

Return the fixed field of the space V.

detMethod
det(V::AbstractSpace) -> FieldElem

Return the determinant of the space V as an element of its fixed field.

discriminantMethod
discriminant(V::AbstractSpace) -> FieldElem

Return the discriminant of the space V as an element of its fixed field.

Examples

So for instance, one could get the following information about the hermitian space $H$:


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2-a*t+1, "b");
julia> H = hermitian_space(E, 3);
julia> rank(H), dim(H)(3, 3)
julia> gram_matrix(H)[1 0 0] -[0 1 0] -[0 0 1]
julia> involution(H)Map with following data -Domain: -======= -Relative number field of degree 2 over maximal real subfield of cyclotomic field of order 7 -Codomain: -========= -Relative number field of degree 2 over maximal real subfield of cyclotomic field of order 7
julia> base_ring(H)Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1 - over number field with defining polynomial $^3 + $^2 - 2*$ - 1 - over rational field
julia> fixed_field(H)Number field with defining polynomial $^3 + $^2 - 2*$ - 1 - over rational field
julia> det(H), discriminant(H)(1, -1)

Predicates

Let $(V, \Phi)$ be a hermitian space over $E/K$ (resp. quadratic space $K$). We say that $(V, \Phi)$ is definite if $E/K$ is CM (resp. $K$ is totally real) and if there exists an orthogonal basis of $V$ for which the diagonal elements of the associated Gram matrix of $(V, \Phi)$ are either all totally positive or all totally negative. In the former case, $V$ is said to be positive definite, while in the latter case it is negative definite. In all the other cases, we say that $V$ is indefinite.

is_regularMethod
is_regular(V::AbstractSpace) -> Bool

Return whether the space V is regular, that is, if the Gram matrix has full rank.

is_quadraticMethod
is_quadratic(V::AbstractSpace) -> Bool

Return whether the space V is quadratic.

ishermitianMethod
is_hermitian(V::AbstractSpace) -> Bool

Return whether the space V is hermitian.

is_positive_definiteMethod
is_positive_definite(V::AbstractSpace) -> Bool

Return whether the space V is positive definite.

is_negative_definiteMethod
is_negative_definite(V::AbstractSpace) -> Bool

Return whether the space V is negative definite.

is_definiteMethod
is_definite(V::AbstractSpace) -> Bool

Return whether the space V is definite.

Note that the is_hermitian function tests whether the space is non-quadratic.

Examples


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2-a*t+1, "b");
julia> Q = quadratic_space(K, K[0 1; 1 0]);
julia> H = hermitian_space(E, 3);
julia> is_regular(Q), is_regular(H)(true, true)
julia> is_quadratic(Q), ishermitian(H)(true, true)
julia> is_definite(Q), is_positive_definite(H)(false, true)

Inner products and diagonalization

gram_matrixMethod
gram_matrix(V::AbstractSpace, M::MatElem) -> MatElem

Return the Gram matrix of the rows of M with respect to the Gram matrix of the space V.

gram_matrixMethod
gram_matrix(V::AbstractSpace, S::Vector{Vector}) -> MatElem

Return the Gram matrix of the sequence S with respect to the Gram matrix of the space V.

inner_productMethod
inner_product(V::AbstractSpace, v::Vector, w::Vector) -> FieldElem

Return the inner product of v and w with respect to the bilinear form of the space V.

orthogonal_basisMethod
orthogonal_basis(V::AbstractSpace) -> MatElem

Return a matrix M, such that the rows of M form an orthogonal basis of the space V.

diagonalMethod
diagonal(V::AbstractSpace) -> Vector{FieldElem}

Return a vector of elements $a_1,\dotsc,a_n$ such that the space V is isometric to the diagonal space $\langle a_1,\dotsc,a_n \rangle$.

The elements are contained in the fixed field of V.

restrict_scalarsMethod
restrict_scalars(V::AbstractSpace, K::QQField,
-                                   alpha::FieldElem = one(base_ring(V)))
-                                                -> QuadSpace, AbstractSpaceRes

Given a space $(V, \Phi)$ and a subfield K of the base algebra E of V, return the quadratic space W obtained by restricting the scalars of $(V, \alpha\Phi)$ to K, together with the map f for extending the scalars back. The form on the restriction is given by $Tr \circ \Phi$ where $Tr: E \to K$ is the trace form. The rescaling factor $\alpha$ is set to 1 by default.

Note that for now one can only restrict scalars to $\mathbb Q$.

Examples


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2-a*t+1, "b");
julia> Q = quadratic_space(K, K[0 1; 1 0]);
julia> H = hermitian_space(E, 3);
julia> gram_matrix(Q, K[1 1; 2 0])[2 2] -[2 0]
julia> gram_matrix(H, E[1 0 0; 0 1 0; 0 0 1])[1 0 0] -[0 1 0] -[0 0 1]
julia> inner_product(Q, K[1 1], K[0 2])[2]
julia> orthogonal_basis(H)[1 0 0] -[0 1 0] -[0 0 1]
julia> diagonal(Q), diagonal(H)(nf_elem[1, -1], nf_elem[1, 1, 1])

Equivalence

Let $(V, \Phi)$ and $(V', \Phi')$ be spaces over the same extension $E/K$. A homomorphism of spaces from $V$ to $V'$ is a $E$-linear mapping $f \colon V \to V'$ such that for all $x,y \in V$, one has

\[ \Phi'(f(x), f(y)) = \Phi(x,y).\]

An automorphism of spaces is called an isometry and a monomorphism is called an embedding.

hasse_invariantMethod
hasse_invariant(V::QuadSpace, p::Union{InfPlc, NfOrdIdl}) -> Int

Returns the Hasse invariant of the quadratic space V at p. This is equal to the product of local Hilbert symbols $(a_i, a_j)_p$, $i < j$, where $V$ is isometric to $\langle a_1, \dotsc, a_n\rangle$. If V is degenerate return the hasse invariant of V/radical(V).

witt_invariantMethod
witt_invariant(V::QuadSpace, p::Union{InfPlc, NfOrdIdl}) -> Int

Returns the Witt invariant of the quadratic space V at p.

See [Definition 3.2.1, Kir16].

is_isometricMethod
is_isometric(L::AbstractSpace, M::AbstractSpace) -> Bool

Return whether the spaces L and M are isometric.

is_isometricMethod
is_isometric(L::AbstractSpace, M::AbstractSpace, p::Union{InfPlc, NfOrdIdl}) -> Bool

Return whether the spaces L and M are isometric over the completion at p.

invariantsMethod
invariants(M::QuadSpace)
-      -> FieldElem, Dict{NfOrdIdl, Int}, Vector{Tuple{InfPlc, Int}}

Returns a tuple (n, k, d, H, I) of invariants of M, which determine the isometry class completely. Here n is the dimension. The dimension of the kernel is k. The element d is the determinant of a Gram matrix of the non-degenerate part, H contains the non-trivial Hasse invariants and I contains for each real place the negative index of inertia.

Note that d is determined only modulo squares.

Examples

For instance, for the case of $Q$ and the totally ramified prime $\mathfrak p$ of $O_K$ above $7$, one can get:


julia> K, a = CyclotomicRealSubfield(7);
julia> Q = quadratic_space(K, K[0 1; 1 0]);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> hasse_invariant(Q, p), witt_invariant(Q, p)(1, 1)
julia> Q2 = quadratic_space(K, K[-1 0; 0 1]);
julia> is_isometric(Q, Q2, p)true
julia> is_isometric(Q, Q2)true
julia> invariants(Q2)(2, 0, -1, Dict{NfOrdIdl, Int64}(), Tuple{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}, Int64}[(Infinite place corresponding to (Complex embedding corresponding to -1.80 of maximal real subfield of cyclotomic field of order 7), 1), (Infinite place corresponding to (Complex embedding corresponding to -0.45 of maximal real subfield of cyclotomic field of order 7), 1), (Infinite place corresponding to (Complex embedding corresponding to 1.25 of maximal real subfield of cyclotomic field of order 7), 1)])

Embeddings

Let $(V, \Phi)$ and $(V', \Phi')$ be two spaces over the same extension $E/K$, and let $\sigma \colon V \to V'$ be an $E$-linear morphism. $\sigma$ is called a representation of $V$ into $V'$ if for all $x \in V$

\[ \Phi'(\sigma(x), \sigma(x)) = \Phi(x,x).\]

In such a case, $V$ is said to be represented by $V'$ and $\sigma$ can be seen as an embedding of $V$ into $V'$. This representation property can be also tested locally with respect to the completions at some finite places. Note that in both quadratic and hermitian cases, completions are taken at finite places of the fixed field $K$.

is_locally_represented_byMethod
is_locally_represented_by(U::T, V::T, p::NfOrdIdl) where T <: AbstractSpace -> Bool

Given two spaces U and V over the same algebra E, and a prime ideal p in the maximal order $\mathcal O_K$ of their fixed field K, return whether U is represented by V locally at p, i.e. whether $U_p$ embeds in $V_p$.

is_represented_byMethod
is_represented_by(U::T, V::T) where T <: AbstractSpace -> Bool

Given two spaces U and V over the same algebra E, return whether U is represented by V, i.e. whether U embeds in V.

Examples

Still using the spaces $Q$ and $H$, we can decide whether some other spaces embed respectively locally or globally into $Q$ or $H$:


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2-a*t+1, "b");
julia> Q = quadratic_space(K, K[0 1; 1 0]);
julia> H = hermitian_space(E, 3);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> Q2 = quadratic_space(K, K[-1 0; 0 1]);
julia> H2 = hermitian_space(E, E[-1 0 0; 0 1 0; 0 0 -1]);
julia> is_locally_represented_by(Q2, Q, p)true
julia> is_represented_by(Q2, Q)true
julia> is_locally_represented_by(H2, H, p)true
julia> is_represented_by(H2, H)false

Categorical constructions

One can construct direct sums of spaces of the same kind. Since those are also direct products, they are called biproducts in this context. Depending on the user usage, one of the following three methods can be called to obtain the direct sum of a finite collection of spaces. Note that the corresponding copies of the original spaces in the direct sum are pairwise orthogonal.

direct_sumMethod
direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T

Given modules $M_1\dots M_n$, say, return the direct sum $\bigoplus_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical injections $M_i\to\bigoplus_{i=1}^n M_i$ if task = :sum (default),
  • a vector containing the canonical projections $\bigoplus_{i=1}^n M_i\to M_i$ if task = :prod,
  • two vectors containing the canonical injections and projections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_sum(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}
-direct_sum(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian spaces $V_1, \ldots, V_n$, return their direct sum $V := V_1 \oplus \ldots \oplus V_n$, together with the injections $V_i \to V$.

For objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct product with the projections $V \to V_i$, one should call direct_product(x). If one wants to obtain V as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

direct_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls

Return the isometry class of the direct sum of two representatives.

direct_productMethod
direct_product(F::FreeMod{T}...; task::Symbol = :prod) where T

Given free modules $F_1\dots F_n$, say, return the direct product $\prod_{i=1}^n F_i$.

Additionally, return

  • a vector containing the canonical projections $\prod_{i=1}^n F_i\to F_i$ if task = :prod (default),
  • a vector containing the canonical injections $F_i\to\prod_{i=1}^n F_i$ if task = :sum,
  • two vectors containing the canonical projections and injections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T

Given modules $M_1\dots M_n$, say, return the direct product $\prod_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical projections $\prod_{i=1}^n M_i\to M_i$ if task = :prod (default),
  • a vector containing the canonical injections $M_i\to\prod_{i=1}^n M_i$ if task = :sum,
  • two vectors containing the canonical projections and injections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_product(algebras::AlgAss...; task::Symbol = :sum)
-  -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
-direct_product(algebras::Vector{AlgAss}; task::Symbol = :sum)
-  -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}

Returns the algebra $A = A_1 \times \cdots \times A_k$. task can be ":sum", ":prod", ":both" or ":none" and determines which canonical maps are computed as well: ":sum" for the injections, ":prod" for the projections.

direct_product(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}
-direct_product(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian spaces $V_1, \ldots, V_n$, return their direct product $V := V_1 \times \ldots \times V_n$, together with the projections $V \to V_i$.

For objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct sum with the injections $V_i \to V$, one should call direct_sum(x). If one wants to obtain V as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

biproductMethod
biproduct(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
-biproduct(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian spaces $V_1, \ldots, V_n$, return their biproduct $V := V_1 \oplus \ldots \oplus V_n$, together with the injections $V_i \to V$ and the projections $V \to V_i$.

For objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct sum with the injections $V_i \to V$, one should call direct_sum(x). If one wants to obtain V as a direct product with the projections $V \to V_i$, one should call direct_product(x).

Example


julia> E, b = cyclotomix_field_as_cm_extensions(7);ERROR: UndefVarError: `cyclotomix_field_as_cm_extensions` not defined
julia> H = hermitian_space(E, 3);
julia> H2 = hermitian_space(E, E[-1 0 0; 0 1 0; 0 0 -1]);
julia> H3, inj, proj = biproduct(H, H2)(Hermitian space of dimension 6, AbstractSpaceMor[Map with following data -Domain: -======= -Hermitian space of dimension 3 -Codomain: -========= -Hermitian space of dimension 6, Map with following data -Domain: -======= -Hermitian space of dimension 3 -Codomain: -========= -Hermitian space of dimension 6], AbstractSpaceMor[Map with following data -Domain: -======= -Hermitian space of dimension 6 -Codomain: -========= -Hermitian space of dimension 3, Map with following data -Domain: -======= -Hermitian space of dimension 6 -Codomain: -========= -Hermitian space of dimension 3])
julia> is_one(matrix(compose(inj[1], proj[1])))true
julia> is_zero(matrix(compose(inj[1], proj[2])))true

Orthogonality operations

orthogonal_complementMethod
orthogonal_complement(V::AbstractSpace, M::T) where T <: MatElem -> T

Given a space V and a subspace W with basis matrix M, return a basis matrix of the orthogonal complement of W inside V.

orthogonal_projectionMethod
orthogonal_projection(V::AbstractSpace, M::T) where T <: MatElem -> AbstractSpaceMor

Given a space V and a non-degenerate subspace W with basis matrix M, return the endomorphism of V corresponding to the projection onto the complement of W in V.

Example


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> Q = quadratic_space(K, K[0 1; 1 0]);
julia> orthogonal_complement(Q, matrix(K, 1, 2, [1 0]))[1 0]

Isotropic spaces

Let $(V, \Phi)$ be a space over $E/K$ and let $\mathfrak p$ be a place in $K$. $V$ is said to be isotropic locally at $\mathfrak p$ if there exists an element $x \in V_{\mathfrak p}$ such that $\Phi_{\mathfrak p}(x,x) = 0$, where $\Phi_{\mathfrak p}$ is the continuous extension of $\Phi$ to $V_{\mathfrak p} \times V_{\mathfrak p}$.

is_isotropicMethod
is_isotropic(V::AbstractSpace, p::Union{NfOrdIdl, InfPlc}) -> Bool

Given a space V and a place p in the fixed field K of V, return whether the completion of V at p is isotropic.

Example


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2-a*t+1, "b");
julia> H = hermitian_space(E, 3);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> is_isotropic(H, p)true

Hyperbolic spaces

Let $(V, \Phi)$ be a space over $E/K$ and let $\mathfrak p$ be a prime ideal of $\mathcal O_K$. $V$ is said to be hyperbolic locally at $\mathfrak p$ if the completion $V_{\mathfrak p}$ of $V$ can be decomposed as an orthogonal sum of hyperbolic planes. The hyperbolic plane is the space $(H, \Psi)$ of rank 2 over $E/K$ such that there exists a basis $e_1, e_2$ of $H$ such that $\Psi(e_1, e_1) = \Psi(e_2, e_2) = 0$ and $\Psi(e_1, e_2) = 1$.

is_locally_hyperbolicMethod
is_locally_hyperbolic(V::Hermspace, p::NfOrdIdl) -> Bool

Return whether the completion of the hermitian space V over $E/K$ at the prime ideal p of $\mathcal O_K$ is hyperbolic.

Example


julia> K, a = CyclotomicRealSubfield(7);
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2-a*t+1, "b");
julia> H = hermitian_space(E, 3);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> is_locally_hyperbolic(H, p)false
diff --git a/previews/PR2578/Hecke/quad_forms/discriminant_group/index.html b/previews/PR2578/Hecke/quad_forms/discriminant_group/index.html deleted file mode 100644 index 91d4083fd55d..000000000000 --- a/previews/PR2578/Hecke/quad_forms/discriminant_group/index.html +++ /dev/null @@ -1,228 +0,0 @@ - -Discriminant Groups · Oscar.jl

Discriminant Groups

Torsion Quadratic Modules

A torsion quadratic module is the quotient $M/N$ of two quadratic integer lattices $N \subseteq M$ in the quadratic space $(V,\Phi)$. It inherits a bilinear form

\[b: M/N \times M/N \to \mathbb{Q} / n \mathbb{Z}\]

as well as a quadratic form

\[q: M/N \to \mathbb{Q} / m \mathbb{Z}.\]

where $n \mathbb{Z} = \Phi(M,N)$ and $m \mathbb{Z} = 2n\mathbb{Z} + \sum_{x \in N} \mathbb{Z} \Phi (x,x)$.

torsion_quadratic_moduleMethod
torsion_quadratic_module(M::ZZLat, N::ZZLat; gens::Union{Nothing, Vector{<:Vector}} = nothing,
-                                                snf::Bool = true,
-                                                modulus::QQFieldElem = QQFieldElem(0),
-                                                check::Bool = true) -> TorQuadModule

Given a Z-lattice $M$ and a sublattice $N$ of $M$, return the torsion quadratic module $M/N$.

If gens is set, the images of gens will be used as the generators of the abelian group $M/N$.

If snf is true, the underlying abelian group will be in Smith normal form. Otherwise, the images of the basis of $M$ will be used as the generators.

The underlying Type

TorQuadModuleType
TorQuadModule

Examples

julia> A = matrix(ZZ, [[2,0,0,-1],[0,2,0,-1],[0,0,2,-1],[-1,-1,-1,2]]);
-
-julia> L = integer_lattice(gram = A);
-
-julia> T = Hecke.discriminant_group(L)
-Finite quadratic module
-  over integer ring
-Abelian group: (Z/2)^2
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form:
-[   1   1//2]
-[1//2      1]

We represent torsion quadratic modules as quotients of $\mathbb{Z}$-lattices by a full rank sublattice.

We store them as a $\mathbb{Z}$-lattice M together with a projection p : M -> A onto an abelian group A. The bilinear structure of A is induced via p, that is <a, b> = <p^-1(a), p^-1(a)> with values in $\mathbb{Q}/n\mathbb{Z}$, where $n$ is the modulus and depends on the kernel of p.

Elements of A are basically just elements of the underlying abelian group. To move between M and A, we use the lift function lift : M -> A and coercion A(m).

Examples

julia> R = rescale(root_lattice(:D,4),2);
-
-julia> D = discriminant_group(R);
-
-julia> A = abelian_group(D)
-GrpAb: (Z/2)^2 x (Z/4)^2
-
-julia> d = D[1]
-Element
-  of finite quadratic module: (Z/2)^2 x (Z/4)^2 -> Q/2Z
-with components [1 0 0 0]
-
-julia> d == D(A(d))
-true
-
-julia> lift(d)
-4-element Vector{QQFieldElem}:
- 1
- 1
- 3//2
- 1

N.B. Since there are no elements of $\mathbb{Z}$-lattices, we think of elements of M as elements of the ambient vector space. Thus if v::Vector is such an element then the coordinates with respec to the basis of M are given by solve_left(basis_matrix(M), v).

Most of the functionality mirrors that of AbGrp its elements and homomorphisms. Here we display the part that is specific to elements of torsion quadratic modules.

Attributes

abelian_groupMethod
abelian_group(T::TorQuadModule) -> GrpAbFinGen

Return the underlying abelian group of T.

coverMethod
cover(T::TorQuadModule) -> ZZLat

For $T=M/N$ this returns $M$.

relationsMethod
relations(T::TorQuadModule) -> ZZLat

For $T=M/N$ this returns $N$.

value_moduleMethod
value_module(T::TorQuadModule) -> QmodnZ

Return the value module Q/nZ of the bilinear form of T.

value_module_quadratic_formMethod
value_module_quadratic_form(T::TorQuadModule) -> QmodnZ

Return the value module Q/mZ of the quadratic form of T.

gram_matrix_bilinearMethod
gram_matrix_bilinear(T::TorQuadModule) -> QQMatrix

Return the gram matrix of the bilinear form of T.

gram_matrix_quadraticMethod
gram_matrix_quadratic(T::TorQuadModule) -> QQMatrix

Return the 'gram matrix' of the quadratic form of T.

The off diagonal entries are given by the bilinear form whereas the diagonal entries are given by the quadratic form.

modulus_bilinear_formMethod
modulus_bilinear_form(T::TorQuadModule) -> QQFieldElem

Return the modulus of the value module of the bilinear form ofT.

modulus_quadratic_formMethod
modulus_quadratic_form(T::TorQuadModule) -> QQFieldElem

Return the modulus of the value module of the quadratic form of T.

Elements

quadratic_productMethod
quadratic_product(a::TorQuadModuleElem) -> QmodnZElem

Return the quadratic product of a.

It is defined in terms of a representative: for $b + M \in M/N=T$, this returns $\Phi(b,b) + n \mathbb{Z}$.

inner_productMethod
inner_product(a::TorQuadModuleElem, b::TorQuadModuleElem) -> QmodnZElem

Return the inner product of a and b.

Lift to the cover

liftMethod
lift(a::TorQuadModuleElem) -> Vector{QQFieldElem}

Lift a to the ambient space of cover(parent(a)).

For $a + N \in M/N$ this returns the representative $a$.

representativeMethod
representative(a::TorQuadModuleElem) -> Vector{QQFieldElem}

For $a + N \in M/N$ this returns the representative $a$. An alias for lift(a).

Orthogonal submodules

orthogonal_submoduleMethod
orthogonal_submodule(T::TorQuadModule, S::TorQuadModule)-> TorQuadModule

Return the orthogonal submodule to the submodule S of T.

Isometry

is_isometric_with_isometryMethod
is_isometric_with_isometry(T::TorQuadModule, U::TorQuadModule)
-                                               -> Bool, TorQuadModuleMor

Return whether the torsion quadratic modules T and U are isometric. If yes, it also returns an isometry $T \to U$.

If T and U are not semi-regular it requires that they both split into a direct sum of their respective quadratic radical (see radical_quadratic).

It requires that both T and U have modulus 1: in case one of them do not, they should be rescaled (see rescale).

Examples

julia> T = torsion_quadratic_module(QQ[2//3 2//3    0    0    0;
-                                       2//3 2//3 2//3    0 2//3;
-                                          0 2//3 2//3 2//3    0;
-                                          0    0 2//3 2//3    0;
-                                          0 2//3    0    0 2//3])
-Finite quadratic module
-  over integer ring
-Abelian group: (Z/3)^5
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form:
-[2//3   2//3      0      0      0]
-[2//3   2//3   2//3      0   2//3]
-[   0   2//3   2//3   2//3      0]
-[   0      0   2//3   2//3      0]
-[   0   2//3      0      0   2//3]
-
-julia> U = torsion_quadratic_module(QQ[4//3    0    0    0    0;
-                                          0 4//3    0    0    0;
-                                          0    0 4//3    0    0;
-                                          0    0    0 4//3    0;
-                                          0    0    0    0 4//3])
-Finite quadratic module
-  over integer ring
-Abelian group: (Z/3)^5
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form:
-[4//3      0      0      0      0]
-[   0   4//3      0      0      0]
-[   0      0   4//3      0      0]
-[   0      0      0   4//3      0]
-[   0      0      0      0   4//3]
-
-julia> bool, phi = is_isometric_with_isometry(T,U)
-(true, Map with following data
-Domain:
-=======
-Finite quadratic module: (Z/3)^5 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: (Z/3)^5 -> Q/2Z)
-
-julia> is_bijective(phi)
-true
-
-julia> T2, _ = sub(T, [-T[4], T[2]+T[3]+T[5]])
-(Finite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data
-Domain:
-=======
-Finite quadratic module: (Z/3)^2 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: (Z/3)^5 -> Q/2Z)
-
-julia> U2, _ = sub(T, [T[4], T[2]+T[3]+T[5]])
-(Finite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data
-Domain:
-=======
-Finite quadratic module: (Z/3)^2 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: (Z/3)^5 -> Q/2Z)
-
-julia> bool, phi = is_isometric_with_isometry(U2, T2)
-(true, Map with following data
-Domain:
-=======
-Finite quadratic module: (Z/3)^2 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: (Z/3)^2 -> Q/2Z)
-
-julia> is_bijective(phi)
-true
is_anti_isometric_with_anti_isometryMethod
is_anti_isometric_with_anti_isometry(T::TorQuadModule, U::TorQuadModule)
-                                                 -> Bool, TorQuadModuleMor

Return whether there exists an anti-isometry between the torsion quadratic modules T and U. If yes, it returns such an anti-isometry $T \to U$.

If T and U are not semi-regular it requires that they both split into a direct sum of their respective quadratic radical (see radical_quadratic).

It requires that both T and U have modulus 1: in case one of them do not, they should be rescaled (see rescale).

Examples

julia> T = torsion_quadratic_module(QQ[4//5;])
-Finite quadratic module
-  over integer ring
-Abelian group: Z/5
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form:
-[4//5]
-
-julia> bool, phi = is_anti_isometric_with_anti_isometry(T, T)
-(true, Map with following data
-Domain:
-=======
-Finite quadratic module: Z/5 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: Z/5 -> Q/2Z)
-
-julia> a = gens(T)[1];
-
-julia> a*a == -phi(a)*phi(a)
-true
-
-julia> G = matrix(FlintQQ, 6, 6 , [3 3 0 0 0  0;
-                                   3 3 3 0 3  0;
-                                   0 3 3 3 0  0;
-                                   0 0 3 3 0  0;
-                                   0 3 0 0 3  0;
-                                   0 0 0 0 0 10]);
-
-julia> V = quadratic_space(QQ, G);
-
-julia> B = matrix(QQ, 6, 6 , [1    0    0    0    0    0;
-                              0 1//3 1//3 2//3 1//3    0;
-                              0    0    1    0    0    0;
-                              0    0    0    1    0    0;
-                              0    0    0    0    1    0;
-                              0    0    0    0    0 1//5]);
-
-
-julia> M = lattice(V, B);
-
-julia> B2 = matrix(FlintQQ, 6, 6 , [ 1  0 -1  1  0 0;
-                                     0  0  1 -1  0 0;
-                                    -1  1  1 -1 -1 0;
-                                     1 -1 -1  2  1 0;
-                                     0  0 -1  1  1 0;
-                                     0  0  0  0  0 1]);
-
-julia> N = lattice(V, B2);
-
-julia> T = torsion_quadratic_module(M, N)
-Finite quadratic module
-  over integer ring
-Abelian group: Z/15
-Bilinear value module: Q/Z
-Quadratic value module: Q/Z
-Gram matrix quadratic form:
-[3//5]
-
-julia> bool, phi = is_anti_isometric_with_anti_isometry(T,T)
-(true, Map with following data
-Domain:
-=======
-Finite quadratic module: Z/15 -> Q/Z
-Codomain:
-=========
-Finite quadratic module: Z/15 -> Q/Z)
-
-julia> a = gens(T)[1];
-
-julia> a*a == -phi(a)*phi(a)
-true

Primary and elementary modules

is_primary_with_primeMethod
is_primary_with_prime(T::TorQuadModule) -> Bool, ZZRingElem

Given a torsion quadratic module T, return whether the underlying (finite) abelian group of T (see abelian_group) is a p-group for some prime number p. In case it is, p is also returned as second output.

Note that in the case of trivial groups, this function returns (true, 1). If T is not primary, the second return value is -1 by default.

is_primaryMethod
is_primary(T::TorQuadModule, p::Union{Integer, ZZRingElem}) -> Bool

Given a torsion quadratic module T and a prime number p, return whether the underlying (finite) abelian group of T (see abelian_group) is a p-group.

is_elementary_with_primeMethod
is_elementary_with_prime(T::TorQuadModule) -> Bool, ZZRingElem

Given a torsion quadratic module T, return whether the underlying (finite) abelian group of T (see abelian_group) is an elementary p-group, for some prime number p. In case it is, p is also returned as second output.

Note that in the case of trivial groups, this function returns (true, 1). If T is not elementary, the second return value is -1 by default.

is_elementaryMethod
is_elementary(T::TorQuadModule, p::Union{Integer, ZZRingElem}) -> Bool

Given a torsion quadratic module T and a prime number p, return whether the underlying (finite) abelian group of T (see abelian_group) is an elementary p-group.

Smith normal form

snfMethod
snf(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMor

Given a torsion quadratic module T, return a torsion quadratic module S, isometric to T, such that the underlying abelian group of S is in canonical Smith normal form. It comes with an isometry $f : S \to T$.

is_snfMethod
is_snf(T::TorQuadModule) -> Bool

Given a torsion quadratic module T, return whether its underlying abelian group is in Smith normal form.

Discriminant Groups

See V. V. Nikulin (1979) for the general theory of discriminant groups. They are particularly useful to work with primitive embeddings of integral integer quadratic lattices.

From a lattice

discriminant_groupMethod
discriminant_group(L::ZZLat) -> TorQuadModule

Return the discriminant group of L.

The discriminant group of an integral lattice L is the finite abelian group D = dual(L)/L.

It comes equipped with the discriminant bilinear form

\[D \times D \to \mathbb{Q} / \mathbb{Z} \qquad (x,y) \mapsto \Phi(x,y) + \mathbb{Z}.\]

If L is even, then the discriminant group is equipped with the discriminant quadratic form $D \to \mathbb{Q} / 2 \mathbb{Z}, x \mapsto \Phi(x,x) + 2\mathbb{Z}$.

From a matrix

torsion_quadratic_moduleMethod
torsion_quadratic_module(q::QQMatrix) -> TorQuadModule

Return a torsion quadratic module with gram matrix given by q and value module Q/Z. If all the diagonal entries of q have: either even numerator or even denominator, then the value module of the quadratic form is Q/2Z

Example

julia> torsion_quadratic_module(QQ[1//6;])
-Finite quadratic module
-  over integer ring
-Abelian group: Z/6
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form:
-[1//6]
-
-julia> torsion_quadratic_module(QQ[1//2;])
-Finite quadratic module
-  over integer ring
-Abelian group: Z/2
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form:
-[1//2]
-
-julia> torsion_quadratic_module(QQ[3//2;])
-Finite quadratic module
-  over integer ring
-Abelian group: Z/2
-Bilinear value module: Q/Z
-Quadratic value module: Q/2Z
-Gram matrix quadratic form:
-[3//2]
-
-julia> torsion_quadratic_module(QQ[1//3;])
-Finite quadratic module
-  over integer ring
-Abelian group: Z/3
-Bilinear value module: Q/Z
-Quadratic value module: Q/Z
-Gram matrix quadratic form:
-[1//3]

Rescaling the form

rescaleMethod
rescale(T::TorQuadModule, k::RingElement) -> TorQuadModule

Return the torsion quadratic module with quadratic form scaled by $k$, where k is a non-zero rational number. If the old form was defined modulo n, then the new form is defined modulo n k.

Invariants

is_degenerateMethod
is_degenerate(T::TorQuadModule) -> Bool

Return true if the underlying bilinear form is degenerate.

is_semi_regularMethod
is_semi_regular(T::TorQuadModule) -> Bool

Return whether T is semi-regular, that is its quadratic radical is trivial (see radical_quadratic).

radical_bilinearMethod
radical_bilinear(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMor

Return the radical \{x \in T | b(x,T) = 0\} of the bilinear form b on T.

radical_quadraticMethod
radical_quadratic(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMor

Return the radical \{x \in T | b(x,T) = 0 and q(x)=0\} of the quadratic form q on T.

normal_formMethod
normal_form(T::TorQuadModule; partial=false) -> TorQuadModule, TorQuadModuleMor

Return the normal form N of the given torsion quadratic module T along with the projection T -> N.

Let K be the radical of the quadratic form of T. Then N = T/K is half-regular. Two half-regular torsion quadratic modules are isometric if and only if they have equal normal forms.

Genus

genusMethod
genus(T::TorQuadModule, signature_pair::Tuple{Int, Int}) -> ZZGenus

Return the genus of an integer lattice with discriminant group T and the given signature_pair. If no such genus exists, raise an error.

Reference

V. V. Nikulin (1979) Corollary 1.9.4 and 1.16.3.

brown_invariantMethod
brown_invariant(self::TorQuadModule) -> Nemo.zzModRingElem

Return the Brown invariant of this torsion quadratic form.

Let (D,q) be a torsion quadratic module with values in Q / 2Z. The Brown invariant Br(D,q) in Z/8Z is defined by the equation

\[\exp \left( \frac{2 \pi i }{8} Br(q)\right) = - \frac{1}{\sqrt{D}} \sum_{x \in D} \exp(i \pi q(x)).\]

The Brown invariant is additive with respect to direct sums of torsion quadratic modules.

Examples

julia> L = integer_lattice(gram=matrix(ZZ, [[2,-1,0,0],[-1,2,-1,-1],[0,-1,2,0],[0,-1,0,2]]));
-
-julia> T = Hecke.discriminant_group(L);
-
-julia> brown_invariant(T)
-4
is_genusMethod
is_genus(T::TorQuadModule, signature_pair::Tuple{Int, Int}) -> Bool

Return if there is an integral lattice with this signature and discriminant form.

Categorical constructions

direct_sumMethod
direct_sum(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}
-direct_sum(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}

Given a collection of torsion quadratic modules $T_1, \ldots, T_n$, return their direct sum $T := T_1\oplus \ldots \oplus T_n$, together with the injections $T_i \to T$.

For objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct product with the projections $T \to T_i$, one should call direct_product(x). If one wants to obtain T as a biproduct with the injections $T_i \to T$ and the projections $T \to T_i$, one should call biproduct(x).

direct_productMethod
direct_product(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}
-direct_product(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}

Given a collection of torsion quadratic modules $T_1, \ldots, T_n$, return their direct product $T := T_1\times \ldots \times T_n$, together with the projections $T \to T_i$.

For objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct sum with the inctions $T_i \to T$, one should call direct_sum(x). If one wants to obtain T as a biproduct with the injections $T_i \to T$ and the projections $T \to T_i$, one should call biproduct(x).

biproductMethod
biproduct(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}, Vector{TorQuadModuleMor}
-biproduct(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}, Vector{TorQuadModuleMor}

Given a collection of torsion quadratic modules $T_1, \ldots, T_n$, return their biproduct $T := T_1\oplus \ldots \oplus T_n$, together with the injections $T_i \to T$ and the projections $T \to T_i$.

For objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct sum with the inctions $T_i \to T$, one should call direct_sum(x). If one wants to obtain T as a direct product with the projections $T \to T_i$, one should call direct_product(x).

Submodules

submodulesMethod
submodules(T::TorQuadMod; kw...)

Return the submodules of T as an iterator. Possible keyword arguments to restrict the submodules:

  • order::Int: only submodules of order order,
  • index::Int: only submodules of index index,
  • subtype::Vector{Int}: only submodules which are isomorphic as an abelian group to abelian_group(subtype),
  • quotype::Vector{Int}: only submodules whose quotient are isomorphic as an abelian to abelian_group(quotype).
stable_submodulesMethod
stable_submodules(T::TorQuadMod, act::Vector{TorQuadModuleMor}; kw...)

Return the submodules of T stable under the endomorphisms in act as an iterator. Possible keyword arguments to restrict the submodules:

  • quotype::Vector{Int}: only submodules whose quotient are isomorphic as an abelian group to abelian_group(quotype).
diff --git a/previews/PR2578/Hecke/quad_forms/genusherm/index.html b/previews/PR2578/Hecke/quad_forms/genusherm/index.html deleted file mode 100644 index b0b0aab70afb..000000000000 --- a/previews/PR2578/Hecke/quad_forms/genusherm/index.html +++ /dev/null @@ -1,139 +0,0 @@ - -Genera for hermitian lattices · Oscar.jl

Genera for hermitian lattices

Local genus symbols

Definition 8.3.1 ([Kir16]) Let $L$ be a hermitian lattice over $E/K$ and let $\mathfrak p$ be a prime ideal of $\mathcal O_K$. Let $\mathfrak P$ be the largest ideal of $\mathcal O_E$ over $\mathfrak p$ being invariant under the involution of $E$. We suppose that we are given a Jordan decomposition

\[ L_{\mathfrak p} = \perp_{i=1}^tL_i\]

where the Jordan block $L_i$ is $\mathfrak P^{s_i}$-modular for $1 \leq i \leq t$, for a strictly increasing sequence of integers $s_1 < \ldots < s_t$. In particular, $\mathfrak s(L_i) = \mathfrak P^{s_i}$. Then, the local genus symbol $g(L, \mathfrak p)$ of $L_{\mathfrak p}$ is defined to be:

  • if $\mathfrak p$ is good, i.e. non ramified and non dyadic,

\[ g(L, \mathfrak p) := [(s_1, r_1, d_1), \ldots, (s_t, r_t, d_t)]\]

where $d_i = 1$ if the determinant (resp. discriminant) of $L_i$ is a norm in $K_{\mathfrak p}^{\times}$, and $d_i = -1$ otherwise, and $r_i := \text{rank}(L_i)$ for all i;

  • if $\mathfrak p$ is bad,

\[ g(L, \mathfrak p) := [(s_1, r_1, d_1, n_1), \ldots, (s_t, r_t, d_t, n_t)]\]

where for all i, $n_i := \text{ord}_{\mathfrak p}(\mathfrak n(L_i))$

Note that we define the scale and the norm of the lattice $L_i$ ($1 \leq i \leq n$) defined over the extension of local fields $E_{\mathfrak P}/K_{\mathfrak p}$ similarly to the ones of $L$, by extending by continuity the sesquilinear form of the ambient space of $L$ to the completion. Regarding the determinant (resp. discriminant), it is defined as the determinant of the Gram matrix associated to a basis of $L_i$ relatively to the extension of the sesquilinear form (resp. $(-1)^{(m(m-1)/2}$ times the determinant, where $m$ is the rank of $L_i$).

We call any tuple in $g := g(L, \mathfrak p) = [g_1, \ldots, g_t]$ a Jordan block of $g$ since it corresponds to invariants of a Jordan block of the completion of the lattice $L$ at $\mathfrak p$. For any such block $g_i$, we call respectively $s_i, r_i, d_i, n_i$ the scale, the rank, the determinant class (resp. discriminant class) and the norm of $g_i$. Note that the norm is necessary only when the prime ideal is bad.

We say that two hermitian lattices $L$ and $L'$ over $E/K$ are in the same local genus at $\mathfrak p$ if $g(L, \mathfrak p) = g(L', \mathfrak p)$.

Creation of local genus symbols

There are two ways of creating a local genus symbol for hermitian lattices:

  • either abstractly, by choosing the extension $E/K$, the prime ideal $\mathfrak p$ of $\mathcal O_K$, the Jordan blocks data and the type of the $d_i$'s (either determinant class :det or discriminant class :disc);
   genus(HermLat, E::NumField, p::NfOrdIdl, data::Vector; type::Symbol = :det,
-                                                          check::Bool = false)
-                                                             -> HermLocalGenus
  • or by constructing the local genus symbol of the completion of a hermitian lattice $L$ over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$.
   genus(L::HermLat, p::NfOrdIdl) -> HermLocalGenus

Examples

We will construct two examples for the rest of this section. Note that the prime chosen here is bad.


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det)Local genus symbol for hermitian lattices - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b, 1//1 * <1, 1>) -Prime ideal: <2, a> -Jordan blocks (scale, rank, det, norm): - (0, 1, +, 0) - (2, 2, -, 1)
julia> D = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];
julia> L = hermitian_lattice(E, gens, gram = D);
julia> g2 = genus(L, p)Local genus symbol for hermitian lattices - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b, 1//1 * <1, 1>) -Prime ideal: <2, a> -Jordan blocks (scale, rank, det, norm): - (-2, 1, +, -1) - (2, 2, +, 1)

Attributes

lengthMethod
length(g::HermLocalGenus) -> Int

Given a local genus symbol g for hermitian lattices, return the number of Jordan blocks of g.

base_fieldMethod
base_field(g::HermLocalGenus) -> NumField

Given a local genus symbol g for hermitian lattices over $E/K$, return E.

primeMethod
prime(g::HermLocalGenus) -> NfOrdIdl

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return $\mathfrak p$.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);
julia> length(g1)2
julia> base_field(g1)Relative number field with defining polynomial t^2 - a - over number field with defining polynomial x^2 - 2 - over rational field
julia> prime(g1)<2, a> -Norm: 2 -Minimum: 2 -basis_matrix -[2 0; 0 1] -two normal wrt: 2

Invariants

scaleMethod
scale(g::HermLocalGenus, i::Int) -> Int

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime $\mathfrak p$ of $\mathcal O_K$, return the $\mathfrak P$-valuation of the scale of the ith Jordan block of g, where $\mathfrak P$ is a prime ideal of $\mathcal O_E$ lying over $\mathfrak p$.

scaleMethod
scale(g::HermLocalGenus) -> NfOrdFracIdl

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime $\mathfrak p$ of $\mathcal O_K$, return the scale of the Jordan block of minimum $\mathfrak P$-valuation, where $\mathfrak{P}$ is a prime ideal of $\mathcal O_E$ lying over $\mathfrak p$.

scalesMethod
scales(g::HermLocalGenus) -> Vector{Int}

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime $\mathfrak p$ of $\mathcal O_K$, return the $\mathfrak P$-valuation of the scales of the Jordan blocks of g, where $\mathfrak P$ is a prime ideal of $\mathcal O_E$ lying over $\mathfrak p$.

rankMethod
rank(g::HermLocalGenus, i::Int) -> Int

Given a local genus symbol g for hermitian lattices, return the rank of the ith Jordan block of g.

rankMethod
rank(g::HermLocalGenus) -> Int

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return the rank of any hermitian lattice whose $\mathfrak p$-adic completion has local genus symbol g.

ranksMethod
ranks(g::HermLocalGenus) -> Vector{Int}

Given a local genus symbol g for hermitian lattices, return the ranks of the Jordan blocks of g.

detMethod
det(g::HermLocalGenus, i::Int) -> Int

Given a local genus symbol g for hermitian lattices over $E/K$, return the determinant of the ith Jordan block of g.

The returned value is $1$ or $-1$ depending on whether the determinant is a local norm in K.

detMethod
det(g::HermLocalGenus) -> Int

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return the determinant of a hermitian lattice whose $\mathfrak p$-adic completion has local genus symbol g.

The returned value is $1$ or $-1$ depending on whether the determinant is a local norm in K.

detsMethod
dets(g::HermLocalGenus) -> Vector{Int}

Given a local genus symbol g for hermitian lattices over $E/K$, return the determinants of the Jordan blocks of g.

The returned values are $1$ or $-1$ depending on whether the respective determinants are are local norms in K.

discriminantMethod
discriminant(g::HermLocalGenus, i::Int) -> Int

Given a local genus symbol g for hermitian lattices over $E/K$, return the discriminant of the ith Jordan block of g.

The returned value is $1$ or $-1$ depending on whether the discriminant is a local norm in K.

discriminantMethod
discriminant(g::HermLocalGenus) -> Int

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return the discriminant of a hermitian lattice whose $\mathfrak p$-adic completion has local genus symbol g.

The returned value is $1$ or $-1$ depending on whether the discriminant is a local norm in K.

normMethod
norm(g::HermLocalGenus, i::Int) -> Int

Given a ramified dyadic local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return the $\mathfrak p$-valuation of the norm of the ith Jordan block of g.

normsMethod
norms(g::HermLocalGenus) -> Vector{Int}

Given a ramified dyadic local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return the $\mathfrak p$-valuations of the norms of the Jordan blocks of g.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> D = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];
julia> L = hermitian_lattice(E, gens, gram = D);
julia> g2 = genus(L, p);
julia> scales(g2)2-element Vector{Int64}: - -2 - 2
julia> ranks(g2)2-element Vector{Int64}: - 1 - 2
julia> dets(g2)2-element Vector{Int64}: - 1 - 1
julia> norms(g2)2-element Vector{Int64}: - -1 - 1
julia> rank(g2), det(g2), discriminant(g2)(3, 1, -1)

Predicates

is_ramifiedMethod
is_ramified(g::HermLocalGenus) -> Bool

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return whether $\mathfrak p$ is ramified in $\mathcal O_E$.

is_splitMethod
is_split(g::HermLocalGenus) -> Bool

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return whether $\mathfrak p$ is split in $\mathcal O_E$.

is_inertMethod
is_inert(g::HermLocalGenus) -> Bool

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return whether $\mathfrak p$ is inert in $\mathcal O_E$.

is_dyadicMethod
is_dyadic(g::HermLocalGenus) -> Bool

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return whether $\mathfrak p$ is dyadic.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);
julia> is_ramified(g1), is_split(g1), is_inert(g1), is_dyadic(g1)(true, false, false, true)

Local uniformizer

uniformizerMethod
uniformizer(g::HermLocalGenus) -> NumFieldElem

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return a generator for the largest ideal of $\mathcal O_E$ containing $\mathfrak p$ and invariant under the action of the non-trivial involution of E.

Example


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);
julia> uniformizer(g1)-a

Determinant representatives

Let $g$ be a local genus symbol for hermitian lattices. Its determinant class, or the determinant class of its Jordan blocks, are given by $\pm 1$, depending on whether the determinants are local norms or not. It is possible to get a representative of this determinant class in terms of powers of the uniformizer of $g$.

det_representativeMethod
det_representative(g::HermLocalGenus, i::Int) -> NumFieldElem

Given a local genus symbol g for hermitian lattices over $E/K$, return a representative of the norm class of the determinant of the ith Jordan block of g in $K^{\times}$.

det_representativeMethod
det_representative(g::HermLocalGenus) -> NumFieldElem

Given a local genus symbol g for hermitian lattices over $E/K$, return a representative of the norm class of the determinant of g in $K^{\times}$.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);
julia> det_representative(g1)-8*a - 6
julia> det_representative(g1,2)-8*a - 6

Gram matrices

gram_matrixMethod
gram_matrix(g::HermLocalGenus, i::Int) -> MatElem

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return a Gram matrix M of the ith Jordan block of g, with coefficients in E. M is such that any hermitian lattice over $E/K$ with Gram matrix M satisfies that the local genus symbol of its completion at $\mathfrak p$ is equal to the ith Jordan block of g.

gram_matrixMethod
gram_matrix(g::HermLocalGenus) -> MatElem

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return a Gram matrix M of g, with coefficients in E.M is such that any hermitian lattice over $E/K$ with Gram matrix M satisfies that the local genus symbol of its completion at $\mathfrak p$ is g.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> D = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];
julia> L = hermitian_lattice(E, gens, gram = D);
julia> g2 = genus(L, p);
julia> gram_matrix(g2)[-3//2*a 0 0] -[ 0 a a] -[ 0 a 4*a]
julia> gram_matrix(g2,1)[-3//2*a]


Global genus symbols

Let $L$ be a hermitian lattice over $E/K$. Let $P(L)$ be the set of all prime ideals of $\mathcal O_K$ which are bad (ramified or dyadic), which are dividing the scale of $L$ or which are dividing the volume of $L$. Let $S(E/K)$ be the set of real infinite places of $K$ which split into complex places in $E$. We define the global genus symbol $G(L)$ of $L$ to be the datum consisting of the local genus symbols of $L$ at each prime of $P(L)$ and the signatures (i.e. the negative index of inertia) of the Gram matrix of the rational span of $L$ at each place in $S(E/K)$.

Note that prime ideals in $P(L)$ which don't ramify correspond to those for which the corresponding completions of $L$ are not unimodular.

We say that two lattice $L$ and $L'$ over $E/K$ are in the same genus, if $G(L) = G(L')$.

Creation of global genus symbols

Similarly, there are two ways of constructing a global genus symbol for hermitian lattices:

  • either abstractly, by choosing the extension $E/K$, the set of local genus symbols S and the signatures signatures at the places in $S(E/K)$. Note that this requires the given invariants to satisfy the product formula for Hilbert symbols.
   genus(S::Vector{HermLocalGenus}, signatures) -> HermGenus

Here signatures can be a dictionary with keys the infinite places and values the corresponding signatures, or a collection of tuples of the type (::InfPlc, ::Int);

  • or by constructing the global genus symbol of a given hermitian lattice $L$.
   genus(L::HermLat) -> HermGenus

Examples

As before, we will construct two different global genus symbols for hermitian lattices, which we will use for the rest of this section.


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);
julia> infp = infinite_places(E)3-element Vector{InfPlc{Hecke.NfRel{nf_elem}, Hecke.NumFieldEmbNfRel{Hecke.NumFieldEmbNfAbs, Hecke.NfRel{nf_elem}}}}: - Infinite place corresponding to (Complex embedding corresponding to root -1.19 of relative number field) - Infinite place corresponding to (Complex embedding corresponding to root 1.19 of relative number field) - Infinite place corresponding to (Complex embedding corresponding to root 0.00 + 1.19 * i of relative number field)
julia> SEK = unique([r.base_field_place for r in infp if isreal(r.base_field_place) && !isreal(r)]);ERROR: type InfPlc has no field base_field_place
julia> length(SEK)ERROR: UndefVarError: `SEK` not defined
julia> G1 = genus([g1], [(SEK[1], 1)])ERROR: UndefVarError: `SEK` not defined
julia> D = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];
julia> L = hermitian_lattice(E, gens, gram = D);
julia> G2 = genus(L)Genus symbol for hermitian lattices - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b, 1//1 * <1, 1>) -Signature: - infinite place corresponding to (Complex embedding of number field) => 2 -Local symbols: - <2, a> => (-2, 1, +, -1)(2, 2, +, 1) - <7, a + 4> => (0, 1, +)(1, 2, +)

Attributes

base_fieldMethod
base_field(G::HermGenus) -> NumField

Given a global genus symbol G for hermitian lattices over $E/K$, return E.

primesMethod
primes(G::HermGenus) -> Vector{NfOrdIdl}

Given a global genus symbol G for hermitian lattices over $E/K$, return the list of prime ideals of $\mathcal O_K$ at which G has a local genus symbol.

signaturesMethod
signatures(G::HermGenus) -> Dict{InfPlc, Int}

Given a global genus symbol G for hermitian lattices over $E/K$, return the signatures at the infinite places of K. For each real place, it is given by the negative index of inertia of the Gram matrix of the rational span of a hermitian lattice whose global genus symbol is G.

The output is given as a dictionary with keys the infinite places of K and value the corresponding signatures.

rankMethod
rank(G::HermGenus) -> Int

Return the rank of any hermitian lattice with global genus symbol G.

is_integralMethod
is_integral(G::HermGenus) -> Bool

Return whether G defines a genus of integral hermitian lattices.

local_symbolsMethod
local_symbols(G::HermGenus) -> Vector{HermLocalGenus}

Given a global genus symbol of hermitian lattices, return its associated local genus symbols.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> D = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];
julia> L = hermitian_lattice(E, gens, gram = D);
julia> G2 = genus(L);
julia> base_field(G2)Relative number field with defining polynomial t^2 - a - over number field with defining polynomial x^2 - 2 - over rational field
julia> primes(G2)2-element Vector{NfOrdIdl}: - <2, a> -Norm: 2 -Minimum: 2 -basis_matrix -[2 0; 0 1] -two normal wrt: 2 - <7, a + 4> -Norm: 7 -Minimum: 7 -basis_matrix -[7 0; 4 1] -two normal wrt: 7
julia> signatures(G2)Dict{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}, Int64} with 1 entry: - Infinite place corresponding to (Complex embedding corresponding to -1.4… => 2
julia> rank(G2)3

Mass

Definition 4.2.1 [Kir16] Let $L$ be a hermitian lattice over $E/K$, and suppose that $L$ is definite. In particular, the automorphism group of $L$ is finite. Let $L_1, \ldots, L_n$ be a set of representatives of isometry classes in the genus of $L$. This means that if $L'$ is a lattice over $E/K$ in the genus of $L$ (i.e. they are in the same genus), then $L'$ is isometric to one of the $L_i$'s, and these representatives are pairwise non-isometric. Then we define the mass of the genus $G(L)$ of $L$ to be

\[ \text{mass}(G(L)) := \sum_{i=1}^n\frac{1}{\#\text{Aut}(L_i)}.\]

Note that since $L$ is definite, any lattice in the genus of $L$ is also definite, and the definition makes sense.

massMethod
mass(L::HermLat) -> QQFieldElem

Given a definite hermitian lattice L, return the mass of its genus.

Example


julia> Qx, x = polynomial_ring(FlintQQ, "x");
julia> f = x^2 - 2;
julia> K, a = number_field(f, "a", cached = false);
julia> Kt, t = polynomial_ring(K, "t");
julia> g = t^2 + 1;
julia> E, b = number_field(g, "b", cached = false);
julia> D = matrix(E, 3, 3, [1, 0, 0, 0, 1, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [(-3*a + 7)*b + 3*a, (5//2*a - 1)*b - 3//2*a + 4, 0]), map(E, [(3004*a - 4197)*b - 3088*a + 4348, (-1047//2*a + 765)*b + 5313//2*a - 3780, (-a - 1)*b + 3*a - 1]), map(E, [(728381*a - 998259)*b + 3345554*a - 4653462, (-1507194*a + 2168244)*b - 1507194*a + 2168244, (-5917//2*a - 915)*b - 4331//2*a - 488])];
julia> L = hermitian_lattice(E, gens, gram = D);
julia> mass(L)1//1024


Representatives of a genus

representativeMethod
representative(g::HermLocalGenus) -> HermLat

Given a local genus symbol g for hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, return a hermitian lattice over $E/K$ whose completion at $\mathfrak p$ admits g as local genus symbol.

inMethod
in(L::HermLat, g::HermLocalGenus) -> Bool

Return whether g and the local genus symbol of the completion of the hermitian lattice L at prime(g) agree. Note that L being in g requires both L and g to be defined over the same extension $E/K$.

representativeMethod
representative(G::HermGenus) -> HermLat

Given a global genus symbol G for hermitian lattices over $E/K$, return a hermitian lattice over $E/K$ which admits G as global genus symbol.

inMethod
in(L::HermLat, G::HermGenus) -> Bool

Return whether G and the global genus symbol of the hermitian lattice L agree.

representativesMethod
representatives(G::HermGenus) -> Vector{HermLat}

Given a global genus symbol G for hermitian lattices, return representatives for the isometry classes of hermitian lattices in G.

genus_representativesMethod
genus_representatives(L::HermLat; max = inf, use_auto = true,
-                                             use_mass = false)
-                                                      -> Vector{HermLat}

Return representatives for the isometry classes in the genus of the hermitian lattice L. At most max representatives are returned.

If L is definite, the use of the automorphism group of L is enabled by default. It can be disabled by use_auto = false. In the case where L is indefinite, the entry use_auto has no effect. The computation of the mass can be enabled by use_mass = true.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);
julia> SEK = unique([restrict(r, K) for r in infinite_places(E) if isreal(restrict(r, K)) && !isreal(r)]);
julia> G1 = genus([g1], [(SEK[1], 1)]);
julia> L1 = representative(g1)Hermitian lattice of rank 3 and degree 3 - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b, 1//1 * <1, 1>)
julia> L1 in g1true
julia> L2 = representative(G1)Hermitian lattice of rank 3 and degree 3 - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b, 1//1 * <1, 1>)
julia> L2 in G1, L2 in g1(true, true)
julia> length(genus_representatives(L1))1
julia> length(representatives(G1))1

Sum of genera

direct_sumMethod
direct_sum(g1::HermLocalGenus, g2::HermLocalGenus) -> HermLocalGenus

Given two local genus symbols g1 and g2 for hermitian lattices over $E/K$ at the same prime ideal $\mathfrak p$ of $\mathcal O_K$, return their direct sum. It corresponds to the local genus symbol of the $\mathfrak p$-adic completion of the direct sum of respective representatives of g1 and g2.

direct_sumMethod
direct_sum(G1::HermGenus, G2::HermGenus) -> HermGenus

Given two global genus symbols G1 and G2 for hermitian lattices over $E/K$, return their direct sum. It corresponds to the global genus symbol of the direct sum of respective representatives of G1 and G2.

Examples


julia> Qx, x = QQ["x"];
julia> K, a = number_field(x^2 - 2, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a, "b");
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 2)[1][1];
julia> g1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);
julia> SEK = unique([restrict(r, K) for r in infinite_places(E) if isreal(restrict(r, K)) && !isreal(r)]);
julia> G1 = genus([g1], [(SEK[1], 1)]);
julia> D = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];
julia> L = hermitian_lattice(E, gens, gram = D);
julia> g2 = genus(L, p);
julia> G2 = genus(L);
julia> direct_sum(g1, g2)Local genus symbol for hermitian lattices - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b, 1//1 * <1, 1>) -Prime ideal: <2, a> -Jordan blocks (scale, rank, det, norm): - (-2, 1, +, -1) - (0, 1, +, 0) - (2, 4, -, 1)
julia> direct_sum(G1, G2)Genus symbol for hermitian lattices - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b, 1//1 * <1, 1>) -Signature: - infinite place corresponding to (Complex embedding of number field) => 3 -Local symbols: - <2, a> => (-2, 1, +, -1)(0, 1, +, 0)(2, 4, -, 1) - <7, a + 4> => (0, 4, +)(1, 2, +)

Enumeration of genera

hermitian_local_generaMethod
hermitian_local_genera(E::NumField, p::NfOrdIdl, rank::Int,
-                       det_val::Int, min_scale::Int, max_scale::Int)
-                                                  -> Vector{HermLocalGenus}

Return all local genus symbols for hermitian lattices over the algebra E, with base field $K$, at the prime idealp of $\mathcal O_K$. Each of them has rank equal to rank, scale $\mathfrak P$-valuations bounded between min_scale and max_scale and determinant p-valuations equal to det_val, where $\mathfrak P$ is a prime ideal of $\mathcal O_E$ lying above p.

hermitian_generaMethod
hermitian_genera(E::NumField, rank::Int,
-                              signatures::Dict{InfPlc, Int},
-                              determinant::Union{Hecke.NfRelOrdIdl, Hecke.NfRelOrdFracIdl};
-                              min_scale::Union{Hecke.NfRelOrdIdl, Hecke.NfRelOrdFracIdl} = is_integral(determinant) ? inv(1*order(determinant)) : determinant,
-                              max_scale::Union{Hecke.NfRelOrdIdl, Hecke.NfRelOrdFracIdl} = is_integral(determinant) ? determinant : inv(1*order(determinant)))
-                                                                                                             -> Vector{HermGenus}

Return all global genus symbols for hermitian lattices over the algebraE with rank rank, signatures given by signatures, scale bounded by max_scale and determinant class equal to determinant.

If max_scale == nothing, it is set to be equal to determinant.

Examples


julia> K, a = CyclotomicRealSubfield(8, "a");
julia> Kt, t = K["t"];
julia> E, b = number_field(t^2 - a * t + 1);
julia> p = prime_decomposition(maximal_order(K), 2)[1][1];
julia> hermitian_local_genera(E, p, 4, 2, 0, 4)15-element Vector{HermLocalGenus{Hecke.NfRel{nf_elem}, NfOrdIdl}}: - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers - Local genus symbol for hermitian lattices over the 2-adic integers
julia> SEK = unique([restrict(r, K) for r in infinite_places(E) if isreal(restrict(r, K)) && !isreal(r)]);
julia> hermitian_genera(E, 3, Dict(SEK[1] => 1, SEK[2] => 1), 30 * maximal_order(E))6-element Vector{HermGenus{Hecke.NfRel{nf_elem}, NfOrdIdl, HermLocalGenus{Hecke.NfRel{nf_elem}, NfOrdIdl}, Dict{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}, Int64}}}: - Genus symbol for hermitian lattices of rank 3 over relative maximal order of Relative number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(_$, 1//1 * <1, 1>) - Genus symbol for hermitian lattices of rank 3 over relative maximal order of Relative number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(_$, 1//1 * <1, 1>) - Genus symbol for hermitian lattices of rank 3 over relative maximal order of Relative number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(_$, 1//1 * <1, 1>) - Genus symbol for hermitian lattices of rank 3 over relative maximal order of Relative number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(_$, 1//1 * <1, 1>) - Genus symbol for hermitian lattices of rank 3 over relative maximal order of Relative number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(_$, 1//1 * <1, 1>) - Genus symbol for hermitian lattices of rank 3 over relative maximal order of Relative number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(_$, 1//1 * <1, 1>)

Rescaling

rescaleMethod
rescale(g::HermLocalGenus, a::Union{FieldElem, RationalUnion})
-                                                          -> HermLocalGenus

Given a local genus symbol G of hermitian lattices and an element a lying in the base field E of g, return the local genus symbol at the prime ideal p associated to g of any representative of g rescaled by a.

rescaleMethod
rescale(G::HermGenus, a::Union{FieldElem, RationalUnion}) -> HermGenus

Given a global genus symbol G of hermitian lattices and an element a lying in the base field E of G, return the global genus symbol of any representative of G rescaled by a.

diff --git a/previews/PR2578/Hecke/quad_forms/integer_lattices/index.html b/previews/PR2578/Hecke/quad_forms/integer_lattices/index.html deleted file mode 100644 index 36ed1c02268a..000000000000 --- a/previews/PR2578/Hecke/quad_forms/integer_lattices/index.html +++ /dev/null @@ -1,341 +0,0 @@ - -Integer Lattices · Oscar.jl

Integer Lattices

An integer lattice $L$ is a finitely generated $\mathbb{Z}$-submodule of a quadratic vector space $V = \mathbb{Q}^n$ over the rational numbers. Integer lattices are also known as quadratic forms over the integers. We will refer to them as $\mathbb{Z}$-lattices.

A $\mathbb{Z}$-lattice $L$ has the type ZZLat. It is given in terms of its ambient quadratic space $V$ together with a basis matrix $B$ whose rows span $L$, i.e. $L = \mathbb{Z}^r B$ where $r$ is the ($\mathbb{Z}$-module) rank of $L$.

To access $V$ and $B$ see ambient_space(L::ZZLat) and basis_matrix(L::ZZLat).

Creation of integer lattices

From a gram matrix

integer_latticeMethod
integer_lattice([B::MatElem]; gram) -> ZZLat

Return the Z-lattice with basis matrix $B$ inside the quadratic space with Gram matrix gram.

If the keyword gram is not specified, the Gram matrix is the identity matrix. If $B$ is not specified, the basis matrix is the identity matrix.

Examples

julia> L = integer_lattice(matrix(QQ, 2, 2, [1//2, 0, 0, 2]));
-
-julia> gram_matrix(L) == matrix(QQ, 2, 2, [1//4, 0, 0, 4])
-true
-
-julia> L = integer_lattice(gram = matrix(ZZ, [2 -1; -1 2]));
-
-julia> gram_matrix(L) == matrix(ZZ, [2 -1; -1 2])
-true

In a quadratic space

latticeMethod
lattice(V::AbstractSpace, basis::MatElem ; check::Bool = true) -> AbstractLat

Given an ambient space V and a matrix basis, return the lattice spanned by the rows of basis inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

By default, basis is checked to be of full rank. This test can be disabled by setting check to false.

Special lattices

root_latticeMethod
root_lattice(R::Symbol, n::Int) -> ZZLat

Return the root lattice of type R given by :A, :D or :E with parameter n.

hyperbolic_plane_latticeMethod
hyperbolic_plane_lattice(n::RationalUnion = 1) -> ZZLat

Return the hyperbolic plane with intersection form of scale n, that is, the unique (up to isometry) even unimodular hyperbolic $\mathbb Z$-lattice of rank 2, rescaled by n.

Examples

julia> L = hyperbolic_plane_lattice(6);
-
-julia> gram_matrix(L)
-[0   6]
-[6   0]
-
-julia> L = hyperbolic_plane_lattice(ZZ(-13));
-
-julia> gram_matrix(L)
-[  0   -13]
-[-13     0]
integer_latticeMethod
integer_lattice(S::Symbol, n::RationalUnion = 1) -> ZZlat

Given S = :H or S = :U, return a $\mathbb Z$-lattice admitting $n*J_2$ as Gram matrix in some basis, where $J_2$ is the 2-by-2 matrix with 0's on the main diagonal and 1's elsewhere.

leech_latticeFunction
leech_lattice() -> ZZLat

Return the Leech lattice.

leech_lattice(niemeier_lattice::ZZLat) -> ZZLat, QQMatrix, Int

Return a triple L, v, h where L is the Leech lattice.

L is an h-neighbor of the Niemeier lattice N with respect to v. This means that L / L ∩ N ≅ ℤ / h ℤ. Here h is the Coxeter number of the Niemeier lattice.

This implements the 23 holy constructions of the Leech lattice in J. H. Conway, N. J. A. Sloane (1999).

Examples

julia> R = integer_lattice(gram=2 * identity_matrix(ZZ, 24));
-
-julia> N = maximal_even_lattice(R) # Some Niemeier lattice
-Integer lattice of rank 24 and degree 24
-with gram matrix
-[2   1   1   1   0   0   0   0   0   0   0   0   0   0   0   0   1   0   1   1   0   0   0   0]
-[1   2   1   1   0   0   0   0   0   0   0   0   0   0   0   0   1   1   0   1   0   0   0   0]
-[1   1   2   1   0   0   0   0   0   0   0   0   0   0   0   0   1   1   1   0   0   0   0   0]
-[1   1   1   2   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
-[0   0   0   0   2   1   1   1   0   0   0   0   1   0   1   1   0   0   0   0   0   0   0   0]
-[0   0   0   0   1   2   1   1   0   0   0   0   1   1   0   1   0   0   0   0   0   0   0   0]
-[0   0   0   0   1   1   2   1   0   0   0   0   1   1   1   0   0   0   0   0   0   0   0   0]
-[0   0   0   0   1   1   1   2   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
-[0   0   0   0   0   0   0   0   2   1   1   1   0   0   0   0   0   0   0   0   1   1   1   0]
-[0   0   0   0   0   0   0   0   1   2   1   1   0   0   0   0   0   0   0   0   1   0   1   1]
-[0   0   0   0   0   0   0   0   1   1   2   1   0   0   0   0   0   0   0   0   1   1   0   1]
-[0   0   0   0   0   0   0   0   1   1   1   2   0   0   0   0   0   0   0   0   0   0   0   0]
-[0   0   0   0   1   1   1   0   0   0   0   0   2   1   1   1   0   0   0   0   0   0   0   0]
-[0   0   0   0   0   1   1   0   0   0   0   0   1   2   0   0   0   0   0   0   0   0   0   0]
-[0   0   0   0   1   0   1   0   0   0   0   0   1   0   2   0   0   0   0   0   0   0   0   0]
-[0   0   0   0   1   1   0   0   0   0   0   0   1   0   0   2   0   0   0   0   0   0   0   0]
-[1   1   1   0   0   0   0   0   0   0   0   0   0   0   0   0   2   1   1   1   0   0   0   0]
-[0   1   1   0   0   0   0   0   0   0   0   0   0   0   0   0   1   2   0   0   0   0   0   0]
-[1   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   1   0   2   0   0   0   0   0]
-[1   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1   0   0   2   0   0   0   0]
-[0   0   0   0   0   0   0   0   1   1   1   0   0   0   0   0   0   0   0   0   2   1   1   1]
-[0   0   0   0   0   0   0   0   1   0   1   0   0   0   0   0   0   0   0   0   1   2   0   0]
-[0   0   0   0   0   0   0   0   1   1   0   0   0   0   0   0   0   0   0   0   1   0   2   0]
-[0   0   0   0   0   0   0   0   0   1   1   0   0   0   0   0   0   0   0   0   1   0   0   2]
-
-julia> minimum(N)
-2
-
-julia> det(N)
-1
-
-julia> L, v, h = leech_lattice(N);
-
-julia> minimum(L)
-4
-
-julia> det(L)
-1
-
-julia> h == index(L, intersect(L, N))
-true
-

We illustrate how the Leech lattice is constructed from N, h and v.

julia> Zmodh = residue_ring(ZZ, h);
-
-julia> V = ambient_space(N);
-
-julia> vG = map_entries(x->Zmodh(ZZ(x)), inner_product(V, v, basis_matrix(N)));
-
-julia> LN = transpose(lift(kernel(vG)[2]))*basis_matrix(N); # vectors whose inner product with `v` is divisible by `h`.
-
-julia> lattice(V, LN) == intersect(L, N)
-true
-
-julia> gensL = vcat(LN, 1//h * v);
-
-julia> lattice(V, gensL, isbasis=false) == L
-true
-

From a genus

Integer lattices can be created as representatives of a genus. See (representative(L::ZZGenus))

Rescaling the Quadratic Form

rescaleMethod
rescale(L::ZZLat, r::RationalUnion) -> ZZLat

Return the lattice L in the quadratic space with form r \Phi.

Examples

This can be useful to apply methods intended for positive definite lattices.

julia> L = integer_lattice(gram=ZZ[-1 0; 0 -1])
-Integer lattice of rank 2 and degree 2
-with gram matrix
-[-1    0]
-[ 0   -1]
-
-julia> shortest_vectors(rescale(L, -1))
-2-element Vector{Vector{ZZRingElem}}:
- [0, 1]
- [1, 0]

Attributes

ambient_spaceMethod
ambient_space(L::AbstractLat) -> AbstractSpace

Return the ambient space of the lattice L. If the ambient space is not known, an error is raised.

basis_matrixMethod
basis_matrix(L::ZZLat) -> QQMatrix

Return the basis matrix $B$ of the integer lattice $L$.

The lattice is given by the row span of $B$ seen inside of the ambient quadratic space of $L$.

gram_matrixMethod
gram_matrix(L::ZZLat) -> QQMatrix

Return the gram matrix of $L$.

Examples

julia> L = integer_lattice(matrix(ZZ, [2 0; -1 2]));
-
-julia> gram_matrix(L)
-[ 4   -2]
-[-2    5]
rational_spanMethod
rational_span(L::ZZLat) -> QuadSpace

Return the rational span of $L$, which is the quadratic space with Gram matrix equal to gram_matrix(L).

Examples

julia> L = integer_lattice(matrix(ZZ, [2 0; -1 2]));
-
-julia> rational_span(L)
-Quadratic space of dimension 2
-  over rational field
-with gram matrix
-[ 4   -2]
-[-2    5]

Invariants

rankMethod
rank(L::AbstractLat) -> Int

Return the rank of the underlying module of the lattice L.

detMethod
det(L::ZZLat) -> QQFieldElem

Return the determinant of the gram matrix of L.

scaleMethod
scale(L::ZZLat) -> QQFieldElem

Return the scale of L.

The scale of L is defined as the positive generator of the $\mathbb Z$-ideal generated by $\{\Phi(x, y) : x, y \in L\}$.

normMethod
norm(L::ZZLat) -> QQFieldElem

Return the norm of L.

The norm of L is defined as the positive generator of the $\mathbb Z$- ideal generated by $\{\Phi(x,x) : x \in L\}$.

isevenMethod
iseven(L::ZZLat) -> Bool

Return whether L is even.

An integer lattice L in the rational quadratic space $(V,\Phi)$ is called even if $\Phi(x,x) \in 2\mathbb{Z}$ for all $x in L$.

is_integralMethod
is_integral(L::AbstractLat) -> Bool

Return whether the lattice L is integral.

is_primary_with_primeMethod
is_primary_with_prime(L::ZZLat) -> Bool, ZZRingElem

Given a $\mathbb Z$-lattice L, return whether L is primary, that is whether L is integral and its discriminant group (see discriminant_group) is a p-group for some prime number p. In case it is, p is also returned as second output.

Note that for unimodular lattices, this function returns (true, 1). If the lattice is not primary, the second return value is -1 by default.

is_primaryMethod
is_primary(L::ZZLat, p::Union{Integer, ZZRingElem}) -> Bool

Given an integral $\mathbb Z$-lattice L and a prime number p, return whether L is p-primary, that is whether its discriminant group (see discriminant_group) is a p-group.

is_elementary_with_primeMethod
is_elementary_with_prime(L::ZZLat) -> Bool, ZZRingElem

Given a $\mathbb Z$-lattice L, return whether L is elementary, that is whether L is integral and its discriminant group (see discriminant_group) is an elemenentary p-group for some prime number p. In case it is, p is also returned as second output.

Note that for unimodular lattices, this function returns (true, 1). If the lattice is not elementary, the second return value is -1 by default.

is_elementaryMethod
is_elementary(L::ZZLat, p::Union{Integer, ZZRingElem}) -> Bool

Given an integral $\mathbb Z$-lattice L and a prime number p, return whether L is p-elementary, that is whether its discriminant group (see discriminant_group) is an elementary p-group.

The Genus

For an integral lattice The genus of an integer lattice collects its local invariants. genus(::ZZLat)

massMethod
mass(L::ZZLat) -> QQFieldElem

Return the mass of the genus of L.

genus_representativesMethod
genus_representatives(L::ZZLat) -> Vector{ZZLat}

Return representatives for the isometry classes in the genus of L.

Real invariants

signature_tupleMethod
signature_tuple(L::ZZLat) -> Tuple{Int,Int,Int}

Return the number of (positive, zero, negative) inertia of L.

is_positive_definiteMethod
is_positive_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is positive definite.

is_negative_definiteMethod
is_negative_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is negative definite.

is_definiteMethod
is_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is definite.

Isometries

automorphism_group_generatorsMethod
automorphism_group_generators(E::EllCrv) -> Vector{EllCrvIso}

Return generators of the automorphism group of $E$.

automorphism_group_generators(L::AbstractLat; ambient_representation::Bool = true)
-                                                      -> Vector{MatElem}

Given a definite lattice L, return generators for the automorphism group of L. If ambient_representation == true (the default), the transformations are represented with respect to the ambient space of L. Otherwise, the transformations are represented with respect to the (pseudo-)basis of L.

automorphism_group_orderMethod
automorphism_group_order(L::AbstractLat) -> Int

Given a definite lattice L, return the order of the automorphism group of L.

is_isometricMethod
is_isometric(L::AbstractLat, M::AbstractLat) -> Bool

Return whether the lattices L and M are isometric.

is_locally_isometricMethod
is_locally_isometric(L::ZZLat, M::ZZLat, p::Int) -> Bool

Return whether L and M are isometric over the p-adic integers.

i.e. whether $L \otimes \mathbb{Z}_p \cong M\otimes \mathbb{Z}_p$.

Root lattices

root_lattice_recognitionMethod
root_lattice_recognition(L::ZZLat)

Return the ADE type of the root sublattice of L.

Input:

L – a definite and integral $\mathbb{Z}$-lattice.

Output:

Two lists, the first one containing the ADE types and the second one the irreducible root sublattices.

For more recognizable gram matrices use root_lattice_recognition_fundamental.

Examples

julia> L = integer_lattice(gram=ZZ[4  0 0  0 3  0 3  0;
-                            0 16 8 12 2 12 6 10;
-                            0  8 8  6 2  8 4  5;
-                            0 12 6 10 2  9 5  8;
-                            3  2 2  2 4  2 4  2;
-                            0 12 8  9 2 12 6  9;
-                            3  6 4  5 4  6 6  5;
-                            0 10 5  8 2  9 5  8])
-Integer lattice of rank 8 and degree 8
-with gram matrix
-[4    0   0    0   3    0   3    0]
-[0   16   8   12   2   12   6   10]
-[0    8   8    6   2    8   4    5]
-[0   12   6   10   2    9   5    8]
-[3    2   2    2   4    2   4    2]
-[0   12   8    9   2   12   6    9]
-[3    6   4    5   4    6   6    5]
-[0   10   5    8   2    9   5    8]
-
-julia> R = root_lattice_recognition(L)
-([(:A, 1), (:D, 6)], ZZLat[Integer lattice of rank 1 and degree 8, Integer lattice of rank 6 and degree 8])
root_lattice_recognition_fundamentalMethod
root_lattice_recognition_fundamental(L::ZZLat)

Return the ADE type of the root sublattice of L as well as the corresponding irreducible root sublattices with basis given by a fundamental root system.

Input:

L – a definite and integral $\mathbb Z$-lattice.

Output:

  • the root sublattice, with basis given by a fundamental root system
  • the ADE types
  • a Vector consisting of the irreducible root sublattices.

Examples

julia> L = integer_lattice(gram=ZZ[4  0 0  0 3  0 3  0;
-                            0 16 8 12 2 12 6 10;
-                            0  8 8  6 2  8 4  5;
-                            0 12 6 10 2  9 5  8;
-                            3  2 2  2 4  2 4  2;
-                            0 12 8  9 2 12 6  9;
-                            3  6 4  5 4  6 6  5;
-                            0 10 5  8 2  9 5  8])
-Integer lattice of rank 8 and degree 8
-with gram matrix
-[4    0   0    0   3    0   3    0]
-[0   16   8   12   2   12   6   10]
-[0    8   8    6   2    8   4    5]
-[0   12   6   10   2    9   5    8]
-[3    2   2    2   4    2   4    2]
-[0   12   8    9   2   12   6    9]
-[3    6   4    5   4    6   6    5]
-[0   10   5    8   2    9   5    8]
-
-julia> R = root_lattice_recognition_fundamental(L);
-
-julia> gram_matrix(R[1])
-[2    0    0    0    0    0    0]
-[0    2    0   -1    0    0    0]
-[0    0    2   -1    0    0    0]
-[0   -1   -1    2   -1    0    0]
-[0    0    0   -1    2   -1    0]
-[0    0    0    0   -1    2   -1]
-[0    0    0    0    0   -1    2]
-
ADE_typeMethod
ADE_type(G::MatrixElem) -> Tuple{Symbol,Int64}

Return the type of the irreducible root lattice with gram matrix G.

See also root_lattice_recognition.

Examples

julia> Hecke.ADE_type(gram_matrix(root_lattice(:A,3)))
-(:A, 3)
coxeter_numberMethod
coxeter_number(ADE::Symbol, n) -> Int

Return the Coxeter number of the corresponding ADE root lattice.

If $L$ is a root lattice and $R$ its set of roots, then the Coxeter number $h$ is $|R|/n$ where n is the rank of $L$.

Examples

julia> coxeter_number(:D, 4)
-6
-
highest_rootMethod
highest_root(ADE::Symbol, n) -> ZZMatrix

Return coordinates of the highest root of root_lattice(ADE, n).

Examples

julia> highest_root(:E, 6)
-[1   2   3   2   1   2]

Module operations

Most module operations assume that the lattices live in the same ambient space. For instance only lattices in the same ambient space compare.

==Method

Return true if both lattices have the same ambient quadratic space and the same underlying module.

is_sublatticeMethod
is_sublattice(L::AbstractLat, M::AbstractLat) -> Bool

Return whether M is a sublattice of the lattice L.

is_sublattice_with_relationsMethod
is_sublattice_with_relations(M::ZZLat, N::ZZLat) -> Bool, QQMatrix

Returns whether $N$ is a sublattice of $M$. In this case, the second return value is a matrix $B$ such that $B B_M = B_N$, where $B_M$ and $B_N$ are the basis matrices of $M$ and $N$ respectively.

+Method
+(L::AbstractLat, M::AbstractLat) -> AbstractLat

Return the sum of the lattices L and M.

The lattices L and M must have the same ambient space.

*Method
*(a::RationalUnion, L::ZZLat) -> ZZLat

Return the lattice $aM$ inside the ambient space of $M$.

intersectMethod
intersect(L::AbstractLat, M::AbstractLat) -> AbstractLat

Return the intersection of the lattices L and M.

The lattices L and M must have the same ambient space.

inMethod
Base.in(v::Vector, L::ZZLat) -> Bool

Return whether the vector v lies in the lattice L.

inMethod
Base.in(v::QQMatrix, L::ZZLat) -> Bool

Return whether the row span of v lies in the lattice L.

primitive_closureMethod
primitive_closure(M::ZZLat, N::ZZLat) -> ZZLat

Given two $\mathbb Z$-lattices M and N with $N \subseteq \mathbb{Q} M$, return the primitive closure $M \cap \mathbb{Q} N$ of N in M.

Examples

julia> M = root_lattice(:D, 6);
-
-julia> N = lattice_in_same_ambient_space(M, 3*basis_matrix(M)[1,:]);
-
-julia> basis_matrix(N)
-[3   0   0   0   0   0]
-
-julia> N2 = primitive_closure(M, N)
-Integer lattice of rank 1 and degree 6
-with gram matrix
-[2]
-
-julia> basis_matrix(N2)
-[1   0   0   0   0   0]
-
-julia> M2 = primitive_closure(dual(M), M);
-
-julia> is_integral(M2)
-false
-
is_primitiveMethod
is_primitive(M::ZZLat, N::ZZLat) -> Bool

Given two $\mathbb Z$-lattices $N \subseteq M$, return whether N is a primitive sublattice of M.

Examples

julia> U = hyperbolic_plane_lattice(3);
-
-julia> bU = basis_matrix(U);
-
-julia> e1, e2 = bU[1,:], bU[2,:]
-([1 0], [0 1])
-
-julia> N = lattice_in_same_ambient_space(U, e1 + e2)
-Integer lattice of rank 1 and degree 2
-with gram matrix
-[6]
-
-julia> is_primitive(U, N)
-true
-
-julia> M = root_lattice(:A, 3);
-
-julia> f = matrix(QQ, 3, 3, [0 1 1; -1 -1 -1; 1 1 0]);
-
-julia> N = kernel_lattice(M, f+1)
-Integer lattice of rank 1 and degree 3
-with gram matrix
-[4]
-
-julia> is_primitive(M, N)
-true
is_primitiveMethod
is_primitive(L::ZZLat, v::Union{Vector, QQMatrix}) -> Bool

Return whether the vector v is primitive in L.

A vector v in a $\mathbb Z$-lattice L is called primitive if for all w in L such that $v = dw$ for some integer d, then $d = \pm 1$.

divisibilityMethod
divisibility(L::ZZLat, v::Union{Vector, QQMatrix}) -> QQFieldElem

Return the divisibility of v with respect to L.

For a vector v in the ambient quadratic space $(V, \Phi)$ of L, we call the divisibility of v with the respect to L the non-negative generator of the fractional $\mathbb Z$-ideal $\Phi(v, L)$.

Embeddings

Categorical constructions

direct_sumMethod
direct_sum(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}
-direct_sum(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}

Given a collection of $\mathbb Z$-lattices $L_1, \ldots, L_n$, return their direct sum $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$. (seen as maps between the corresponding ambient spaces).

For objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

direct_productMethod
direct_product(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}
-direct_product(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}

Given a collection of $\mathbb Z$-lattices $L_1, \ldots, L_n$, return their direct product $L := L_1 \times \ldots \times L_n$, together with the projections $L \to L_i$. (seen as maps between the corresponding ambient spaces).

For objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections $L_i \to L$, one should call direct_sum(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

biproductMethod
biproduct(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
-biproduct(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}

Given a collection of $\mathbb Z$-lattices $L_1, \ldots, L_n$, return their biproduct $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$ and the projections $L \to L_i$. (seen as maps between the corresponding ambient spaces).

For objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections $L_i \to L$, one should call direct_sum(x). If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x).

Orthogonal sublattices

orthogonal_submoduleMethod
orthogonal_submodule(L::ZZLat, S::ZZLat) -> ZZLat

Return the largest submodule of $L$ orthogonal to $S$.

irreducible_componentsMethod
irreducible_components(L::ZZLat) -> Vector{ZZLat}

Return the irreducible components $L_i$ of the positive definite lattice $L$.

This yields a maximal orthogonal splitting of L as

\[L = \bigoplus_i L_i.\]

Dual lattice

dualMethod
dual(L::AbstractLat) -> AbstractLat

Return the dual lattice of the lattice L.

Discriminant group

See discriminant_group(L::ZZLat).

Overlattices

glue_mapMethod
glue_map(L::ZZLat, S::ZZLat, R::ZZLat; check=true)
-                       -> Tuple{TorQuadModuleMor, TorQuadModuleMor, TorQuadModuleMor}

Given three integral $\mathbb Z$-lattices L, S and R, with S and R primitive sublattices of L and such that the sum of the ranks of S and R is equal to the rank of L, return the glue map $\gamma$ of the primitive extension $S+R \subseteq L$, as well as the inclusion maps of the domain and codomain of $\gamma$ into the respective discriminant groups of S and R.

Example

julia> M = root_lattice(:E,8);
-
-julia> f = matrix(QQ, 8, 8, [-1 -1  0  0  0  0  0  0;
-                              1  0  0  0  0  0  0  0;
-                              0  1  1  0  0  0  0  0;
-                              0  0  0  1  0  0  0  0;
-                              0  0  0  0  1  0  0  0;
-                              0  0  0  0  0  1  1  0;
-                             -2 -4 -6 -5 -4 -3 -2 -3;
-                              0  0  0  0  0  0  0  1]);
-
-julia> S = kernel_lattice(M ,f-1)
-Integer lattice of rank 4 and degree 8
-with gram matrix
-[12   -3    0   -3]
-[-3    2   -1    0]
-[ 0   -1    2    0]
-[-3    0    0    2]
-
-julia> R = kernel_lattice(M , f^2+f+1)
-Integer lattice of rank 4 and degree 8
-with gram matrix
-[ 2   -1    0    0]
-[-1    2   -6    0]
-[ 0   -6   30   -3]
-[ 0    0   -3    2]
-
-julia> glue, iS, iR = glue_map(M, S, R)
-(Map with following data
-Domain:
-=======
-Finite quadratic module: (Z/3)^2 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data
-Domain:
-=======
-Finite quadratic module: (Z/3)^2 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data
-Domain:
-=======
-Finite quadratic module: (Z/3)^2 -> Q/2Z
-Codomain:
-=========
-Finite quadratic module: (Z/3)^2 -> Q/2Z)
-
-julia> is_bijective(glue)
-true
overlatticeMethod
overlattice(glue_map::TorQuadModuleMor) -> ZZLat

Given the glue map of a primitive extension of $\mathbb Z$-lattices $S+R \subseteq L$, return L.

Example

julia> M = root_lattice(:E,8);
-
-julia> f = matrix(QQ, 8, 8, [ 1  0  0  0  0  0  0  0;
-                              0  1  0  0  0  0  0  0;
-                              1  2  4  4  3  2  1  2;
-                             -2 -4 -6 -5 -4 -3 -2 -3;
-                              2  4  6  4  3  2  1  3;
-                             -1 -2 -3 -2 -1  0  0 -2;
-                              0  0  0  0  0 -1  0  0;
-                             -1 -2 -3 -3 -2 -1  0 -1]);
-
-julia> S = kernel_lattice(M ,f-1)
-Integer lattice of rank 4 and degree 8
-with gram matrix
-[ 2   -1     0     0]
-[-1    2    -1     0]
-[ 0   -1    12   -15]
-[ 0    0   -15    20]
-
-julia> R = kernel_lattice(M , f^4+f^3+f^2+f+1)
-Integer lattice of rank 4 and degree 8
-with gram matrix
-[10   -4    0    1]
-[-4    2   -1    0]
-[ 0   -1    4   -3]
-[ 1    0   -3    4]
-
-julia> glue, iS, iR = glue_map(M, S, R);
-
-julia> overlattice(glue) == M
-true
local_modificationMethod
local_modification(M::ZZLat, L::ZZLat, p)

Return a local modification of M that matches L at p.

INPUT:

  • $M$ – a \mathbb{Z}_p-maximal lattice
  • $L$ – the a lattice isomorphic to M over \QQ_p
  • $p$ – a prime number

OUTPUT:

an integral lattice M' in the ambient space of M such that M and M' are locally equal at all completions except at p where M' is locally isometric to the lattice L.

maximal_integral_latticeMethod
maximal_integral_lattice(L::AbstractLat) -> AbstractLat

Given a lattice L, return a lattice M in the ambient space of L which is maximal integral and which contains L.

Sublattices defined by endomorphisms

kernel_latticeMethod
kernel_lattice(L::ZZLat, f::MatElem;
-               ambient_representation::Bool = true) -> ZZLat

Given a $\mathbf{Z}$-lattice $L$ and a matrix $f$ inducing an endomorphism of $L$, return $\ker(f)$ is a sublattice of $L$.

If ambient_representation is true (the default), the endomorphism is represented with respect to the ambient space of $L$. Otherwise, the endomorphism is represented with respect to the basis of $L$.

invariant_latticeMethod
invariant_lattice(L::ZZLat, G::Vector{MatElem};
-                  ambient_representation::Bool = true) -> ZZLat
-invariant_lattice(L::ZZLat, G::MatElem;
-                  ambient_representation::Bool = true) -> ZZLat

Given a $\mathbf{Z}$-lattice $L$ and a list of matrices $G$ inducing endomorphisms of $L$ (or just one matrix $G$), return the lattice $L^G$, consisting on elements fixed by $G$.

If ambient_representation is true (the default), the endomorphism is represented with respect to the ambient space of $L$. Otherwise, the endomorphism is represented with respect to the basis of $L$.

coinvariant_latticeMethod
coinvariant_lattice(L::ZZLat, G::Vector{MatElem};
-                    ambient_representation::Bool = true) -> ZZLat
-coinvariant_lattice(L::ZZLat, G::MatElem;
-                    ambient_representation::Bool = true) -> ZZLat

Given a $\mathbf{Z}$-lattice $L$ and a list of matrices $G$ inducing endomorphisms of $L$ (or just one matrix $G$), return the orthogonal complement $L_G$ in $L$ of the fixed lattice $L^G$ (see invariant_lattice).

If ambient_representation is true (the default), the endomorphism is represented with respect to the ambient space of $L$. Otherwise, the endomorphism is represented with respect to the basis of $L$.

Computing embeddings

embedMethod
embed(S::ZZLat, G::Genus, primitive::Bool=true) -> Bool, embedding

Return a (primitive) embedding of the integral lattice S into some lattice in the genus of G.

julia> G = integer_genera((8,0), 1, even=true)[1];
-
-julia> L, S, i = embed(root_lattice(:A,5), G);
-
embed_in_unimodularMethod
embed_in_unimodular(S::ZZLat, pos::Int, neg::Int, primitive=true, even=true) -> Bool, L, S', iS, iR

Return a (primitive) embedding of the integral lattice S into some (even) unimodular lattice of signature (pos, neg).

For now this works only for even lattices.

julia> NS = direct_sum(integer_lattice(:U), rescale(root_lattice(:A, 16), -1))[1];
-
-julia> LK3, iNS, i = embed_in_unimodular(NS, 3, 19);
-
-julia> genus(LK3)
-Genus symbol for integer lattices
-Signatures: (3, 0, 19)
-Local symbol:
-  Local genus symbol at 2: 1^22
-
-julia> iNS
-Integer lattice of rank 18 and degree 22
-with gram matrix
-[0   1    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0]
-[1   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0]
-[0   0   -2    1    0    0    0    0    0    0    0    0    0    0    0    0    0    0]
-[0   0    1   -2    1    0    0    0    0    0    0    0    0    0    0    0    0    0]
-[0   0    0    1   -2    1    0    0    0    0    0    0    0    0    0    0    0    0]
-[0   0    0    0    1   -2    1    0    0    0    0    0    0    0    0    0    0    0]
-[0   0    0    0    0    1   -2    1    0    0    0    0    0    0    0    0    0    0]
-[0   0    0    0    0    0    1   -2    1    0    0    0    0    0    0    0    0    0]
-[0   0    0    0    0    0    0    1   -2    1    0    0    0    0    0    0    0    0]
-[0   0    0    0    0    0    0    0    1   -2    1    0    0    0    0    0    0    0]
-[0   0    0    0    0    0    0    0    0    1   -2    1    0    0    0    0    0    0]
-[0   0    0    0    0    0    0    0    0    0    1   -2    1    0    0    0    0    0]
-[0   0    0    0    0    0    0    0    0    0    0    1   -2    1    0    0    0    0]
-[0   0    0    0    0    0    0    0    0    0    0    0    1   -2    1    0    0    0]
-[0   0    0    0    0    0    0    0    0    0    0    0    0    1   -2    1    0    0]
-[0   0    0    0    0    0    0    0    0    0    0    0    0    0    1   -2    1    0]
-[0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    1   -2    1]
-[0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    1   -2]
-
-julia> is_primitive(LK3, iNS)
-true

LLL, Short and Close Vectors

LLL and indefinite LLL

lllMethod
lll(L::ZZLat, same_ambient::Bool = true) -> ZZLat

Given an integral $\mathbb Z$-lattice L with basis matrix B, compute a basis C of L such that the gram matrix $G_C$ of L with respect to C is LLL-reduced.

By default, it creates the lattice in the same ambient space as L. This can be disabled by setting same_ambient = false. Works with both definite and indefinite lattices.

Short Vectors

short_vectorsFunction
short_vectors(L::ZZLat, [lb = 0], ub, [elem_type = ZZRingElem]; check::Bool = true)
-                                   -> Vector{Tuple{Vector{elem_type}, QQFieldElem}}

Returns all tuples (v, n) such that n = v G v^t satisfies lb <= n <= ub, where G is the Gram matrix of L and v is non-zero.

Note that the vectors are computed up to sign (so only one of v and -v appears).

It is assumed and checked that L is positive definite.

See also short_vectors_iterator for an iterator version.

shortest_vectorsFunction
shortest_vectors(L::ZZLat, [elem_type = ZZRingElem]; check::Bool = true)
-                                           -> QQFieldElem, Vector{elem_type}, QQFieldElem}

Returns the list of shortest non-zero vectors. Note that the vectors are computed up to sign (so only one of v and -v appears).

It is assumed and checked that L is positive definite.

See also minimum.

short_vectors_iteratorFunction
short_vectors_iterator(L::ZZLat, [lb = 0], ub,
-                       [elem_type = ZZRingElem]; check::Bool = true)
-                                -> Tuple{Vector{elem_type}, QQFieldElem} (iterator)

Returns an iterator for all tuples (v, n) such that n = v G v^t satisfies lb <= n <= ub, where G is the Gram matrix of L and v is non-zero.

Note that the vectors are computed up to sign (so only one of v and -v appears).

It is assumed and checked that L is positive definite.

See also short_vectors.

minimumMethod
minimum(L::ZZLat) -> QQFieldElem

Return the minimum squared length among the non-zero vectors in L.

kissing_numberMethod
kissing_number(L::ZZLat) -> Int

Return the Kissing number of the sphere packing defined by L.

This is the number of non-overlapping spheres touching any other given sphere.

Close Vectors

close_vectorsMethod
close_vectors(L:ZZLat, v:Vector, [lb,], ub; check::Bool = false)
-                                        -> Vector{Tuple{Vector{Int}}, QQFieldElem}

Return all tuples (x, d) where x is an element of L such that d = b(v - x, v - x) <= ub. If lb is provided, then also lb <= d.

If filter is not nothing, then only those x with filter(x) evaluating to true are returned.

By default, it will be checked whether L is positive definite. This can be disabled setting check = false.

Both input and output are with respect to the basis matrix of L.

Examples

julia> L = integer_lattice(matrix(QQ, 2, 2, [1, 0, 0, 2]));
-
-julia> close_vectors(L, [1, 1], 1)
-3-element Vector{Tuple{Vector{ZZRingElem}, QQFieldElem}}:
- ([2, 1], 1)
- ([0, 1], 1)
- ([1, 1], 0)
-
-julia> close_vectors(L, [1, 1], 1, 1)
-2-element Vector{Tuple{Vector{ZZRingElem}, QQFieldElem}}:
- ([2, 1], 1)
- ([0, 1], 1)

diff --git a/previews/PR2578/Hecke/quad_forms/introduction/index.html b/previews/PR2578/Hecke/quad_forms/introduction/index.html deleted file mode 100644 index 1ca4265273ca..000000000000 --- a/previews/PR2578/Hecke/quad_forms/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This chapter deals with quadratic and hermitian spaces, and lattices there of. Note that even though quadratic spaces/lattices are theoretically a special case of hermitian spaces/lattices, a particular distinction is made here. As a note for knowledgeable users, only methods regarding hermitian spaces/lattices over degree 1 and degree 2 extensions of number fields are implemented up to now.

Definitions and vocabulary

We begin by collecting the necessary definitions and vocabulary. The terminology follows mainly [Kir16]

Quadratic and hermitian spaces

Let $K$ be a number field and let $E$ be a finitely generated etale algebra over $K$ of dimension 1 or 2, i.e. $E=K$ or $E$ is a separable extension of $K$ of degree 2. In both cases, $E/K$ is endowed with an $K$-linear involution $\overline{\phantom{x}} \colon E \to E$ for which $K$ is the fixed field (in the case $E=K$, this is simply the identity of $K$).

A hermitian space $V$ over $E/K$ is a finite-dimensional $E$-vector space, together with a sesquilinear (with respect to the involution of $E/K$) morphism $\Phi \colon V \times V \to E$. In the trivial case $E=K$, $\Phi$ is therefore a $K$-bilinear morphism and we called $(V, \Phi)$ a quadratic hermitian space over $K$.

We will always work with an implicit canonical basis $e_1, \ldots, e_n$ of $V$. In view of this, hermitian spaces over $E/K$ are in bijection with hermitian matrices with entries in $E$, with respect to the involution $\overline{\phantom{x}}$. In particular, there is a bijection between quadratic hermitian spaces over $K$ and symmetric matrices with entries in $K$. For any basis $B = (v_1, \ldots, v_n)$ of $(V, \Phi)$, we call the matrix $G_B = (\Phi(v_i, v_j))_{1 \leq i, j \leq n} \in E^{n \times n}$ the Gram matrix of $(V, \Phi)$ associated to $B$. If $B$ is the implicit fixed canonical basis of $(V, \Phi)$, we simply talk about the Gram matrix of $(V, \Phi)$.

For a hermitian space $V$, we refer to the field $E$ as the base ring of $V$ and to $\overline{\phantom{x}}$ as the involution of $V$. Meanwhile, the field $K$ is referred to as the fixed field of $V$.

By abuse of language, non-quadratic hermitian spaces are sometimes simply called hermitian spaces and, in contrast, quadratic hermitian spaces are called quadratic spaces. In a general context, an arbitrary space (quadratic or hermitian) is referred to as a space throughout this chapter.

Quadratic and hermitian lattices

Let $V$ be a space over $E/K$. A finitely generated $\mathcal O_E$-submodule $L$ of $V$ is called a hermitian lattice. By extension of vocabulary if $V$ is quadratic (i.e. $E=K$), $L$ is called a quadratic hermitian lattice. We call $V$ the ambient space of $L$ and $L\otimes_{\mathcal O_E} E$ the rational span of $L$.

For a hermitian lattice $L$, we refer to $E$ as the base field of $L$ and to the ring $\mathcal O_E$ as the base ring of $L$. We also call $\overline{\phantom{x}} \colon E \to E$ the involution of $L$. Finally, we refer to the field $K$ fixed by this involution as the fixed field of $L$ and to $\mathcal O_K$ as the fixed ring of $L$.

Once again by abuse of language, non-quadratic hermitian lattices are sometimes simply called hermitian lattices and quadratic lattices refer to quadratic hermitian lattices. Therefore, in a general context, an arbitrary lattice is referred to as a lattice in this chapter.

References

Many of the implemented algorithms for computing with quadratic and hermitian lattices over number fields are based on the Magma implementation of Markus Kirschmer, which can be found here.

Most of the definitions and results are taken from:

[Kir16] : Definite quadratic and hermitian forms with small class number. Habilitationsschrift. RWTH Aachen University, 2016. pdf

[Kir19] : Determinant groups of hermitian lattices over local fields, Archiv der Mathematik, 113 (2019), no. 4, 337–347. pdf

diff --git a/previews/PR2578/Hecke/quad_forms/lattices/index.html b/previews/PR2578/Hecke/quad_forms/lattices/index.html deleted file mode 100644 index 496a095f2a09..000000000000 --- a/previews/PR2578/Hecke/quad_forms/lattices/index.html +++ /dev/null @@ -1,262 +0,0 @@ - -Lattices · Oscar.jl

Lattices

Creation of lattices

Inside a given ambient space

latticeMethod
lattice(V::AbstractSpace) -> AbstractLat

Given an ambient space V, return the lattice with the standard basis matrix. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

latticeMethod
lattice(V::AbstractSpace, B::PMat ; check::Bool = true) -> AbstractLat

Given an ambient space V and a pseudo-matrix B, return the lattice spanned by the pseudo-matrix B inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

By default, B is checked to be of full rank. This test can be disabled by setting check to false.

latticeMethod
lattice(V::AbstractSpace, basis::MatElem ; check::Bool = true) -> AbstractLat

Given an ambient space V and a matrix basis, return the lattice spanned by the rows of basis inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

By default, basis is checked to be of full rank. This test can be disabled by setting check to false.

latticeMethod
lattice(V::AbstractSpace, gens::Vector) -> AbstractLat

Given an ambient space V and a list of generators gens, return the lattice spanned by gens in V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

If gens is empty, the function returns the zero lattice in V.

Quadratic lattice over a number field

quadratic_latticeMethod
quadratic_lattice(K::Field ; gram::MatElem) -> Union{ZZLat, QuadLat}

Given a matrix gram and a field K, return the free quadratic lattice inside the quadratic space over K with Gram matrix gram.

If $K = \mathbb{Q}$, then the output lattice is of type ZZLat, seen as a lattice over the ring $\mathbb{Z}$.

quadratic_latticeMethod
quadratic_lattice(K::Field, B::PMat ; gram = nothing,
-                                      check:::Bool = true) -> QuadLat

Given a pseudo-matrix B with entries in a field K return the quadratic lattice spanned by the pseudo-matrix B inside the quadratic space over K with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the number of columns of B.

By default, B is checked to be of full rank. This test can be disabled by setting check to false.

quadratic_latticeMethod
quadratic_lattice(K::Field, basis::MatElem ; gram = nothing,
-                                             check::Bool = true)
-                                                      -> Union{ZZLat, QuadLat}

Given a matrix basis and a field K, return the quadratic lattice spanned by the rows of basis inside the quadratic space over K with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the number of columns of basis.

By default, basis is checked to be of full rank. This test can be disabled by setting check to false.

If $K = \mathbb{Q}$, then the output lattice is of type ZZLat, seen as a lattice over the ring $\mathbb{Z}$.

quadratic_latticeMethod
quadratic_lattice(K::Field, gens::Vector ; gram = nothing) -> Union{ZZLat, QuadLat}

Given a list of vectors gens and a field K, return the quadratic lattice spanned by the elements of gens inside the quadratic space over K with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the length of the elements of gens.

If gens is empty, gram must be supplied and the function returns the zero lattice in the quadratic space over K with gram matrix gram.

If $K = \mathbb{Q}$, then the output lattice is of type ZZLat, seen as a lattice over the ring $\mathbb{Z}$.

Hermitian lattice over a degree 2 extension

hermitian_latticeMethod
hermitian_lattice(E::NumField; gram::MatElem) -> HermLat

Given a matrix gram and a number field E of degree 2, return the free hermitian lattice inside the hermitian space over E with Gram matrix gram.

hermitian_latticeMethod
hermitian_lattice(E::NumField, B::PMat; gram = nothing,
-			             check::Bool = true) -> HermLat

Given a pseudo-matrix B with entries in a number field E of degree 2, return the hermitian lattice spanned by the pseudo-matrix B inside the hermitian space over E with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the number of columns of B.

By default, B is checked to be of full rank. This test can be disabled by setting check to false.

hermitian_latticeMethod
hermitian_lattice(E::NumField, basis::MatElem; gram = nothing,
-			                    check::Bool = true) -> HermLat

Given a matrix basis and a number field E of degree 2, return the hermitian lattice spanned by the rows of basis inside the hermitian space over E with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the number of columns of basis.

By default, basis is checked to be of full rank. This test can be disabled by setting check to false.

hermitian_latticeMethod
hermitian_lattice(E::NumField, gens::Vector ; gram = nothing) -> HermLat

Given a list of vectors gens and a number field E of degree 2, return the hermitian lattice spanned by the elements of gens inside the hermitian space over E with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the length of the elements of gens.

If gens is empty, gram must be supplied and the function returns the zero lattice in the hermitan space over E with Gram matrix gram.

Examples

The two following examples will be used all along this section:


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];
julia> Lquad = quadratic_lattice(K, gens, gram = D)Quadratic lattice of rank 3 and degree 3 - over maximal order of Number field of degree 1 over QQ - with basis nf_elem[1]
julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];
julia> Lherm = hermitian_lattice(E, gens, gram = D)Hermitian lattice of rank 4 and degree 4 - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b + 1, 1//2 * <1, 1>)

Note that the format used here is the one given by the internal function Hecke.to_hecke() which prints REPL commands to get back the input lattice.


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];
julia> Lherm = hermitian_lattice(E, gens, gram = D);
julia> Hecke.to_hecke(Lherm)Qx, x = polynomial_ring(FlintQQ, "x") -f = x - 1 -K, a = number_field(f, "a", cached = false) -Kt, t = polynomial_ring(K, "t") -g = t^2 + 7 -E, b = number_field(g, "b", cached = false) -D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) -gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])] -L = hermitian_lattice(E, gens, gram = D)

Finally, one can access some databases in which are stored several quadratic and hermitian lattices. Up to now, these are not automatically available while running Hecke. It can nonethelss be used in the following way:


julia> qld = Hecke.quadratic_lattice_database()Quadratic lattices of rank >= 3 with class number 1 or 2 -Author: Markus Kirschmer -Source: http://www.math.rwth-aachen.de/~Markus.Kirschmer/forms/ -Version: 0.0.1 -Number of lattices: 30250
julia> lattice(qld, 1)Quadratic lattice of rank 3 and degree 3 - over maximal order of Number field of degree 1 over QQ - with basis nf_elem[1]
julia> hlb = Hecke.hermitian_lattice_database()Hermitian lattices of rank >= 3 with class number 1 or 2 -Author: Markus Kirschmer -Source: http://www.math.rwth-aachen.de/~Markus.Kirschmer/forms/ -Version: 0.0.1 -Number of lattices: 570
julia> lattice(hlb, 426)Hermitian lattice of rank 4 and degree 4 - over relative maximal order of Relative number field of degree 2 over number field - with pseudo-basis - (1, 1//1 * <1, 1>) - (b + 1, 1//2 * <1, 1>)

Ambient space and rational span

ambient_spaceMethod
ambient_space(L::AbstractLat) -> AbstractSpace

Return the ambient space of the lattice L. If the ambient space is not known, an error is raised.

rational_spanMethod
rational_span(L::AbstractLat) -> AbstractSpace

Return the rational span of the lattice L.

basis_matrix_of_rational_spanMethod
basis_matrix_of_rational_span(L::AbstractLat) -> MatElem

Return a basis matrix of the rational span of the lattice L.

gram_matrix_of_rational_spanMethod
gram_matrix_of_rational_span(L::AbstractLat) -> MatElem

Return the Gram matrix of the rational span of the lattice L.

diagonal_of_rational_spanMethod
diagonal_of_rational_span(L::AbstractLat) -> Vector

Return the diagonal of the rational span of the lattice L.

Examples


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];
julia> Lquad = quadratic_lattice(K, gens, gram = D);
julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];
julia> Lherm = hermitian_lattice(E, gens, gram = D);
julia> ambient_space(Lherm)Hermitian space of dimension 4 - over relative number field with defining polynomial t^2 + 7 - over number field with defining polynomial x - 1 - over rational field -with gram matrix -[1 0 0 0] -[0 1 0 0] -[0 0 1 0] -[0 0 0 1]
julia> rational_span(Lquad)Quadratic space of dimension 3 - over number field of degree 1 over QQ -with gram matrix -[2 2 2] -[2 4 2] -[2 2 4]
julia> basis_matrix_of_rational_span(Lherm)[1 0 0 0] -[5 1 0 0] -[3 0 1 0] -[0 0 0 1]
julia> gram_matrix_of_rational_span(Lherm)[1 5 3 0] -[5 26 15 0] -[3 15 10 0] -[0 0 0 1]
julia> diagonal_of_rational_span(Lquad)3-element Vector{nf_elem}: - 2 - 2 - 2

Rational equivalence

hasse_invariantMethod
hasse_invariant(L::AbstractLat, p::Union{InfPlc, NfOrdIdl}) -> Int

Return the Hasse invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.

witt_invariantMethod
witt_invariant(L::AbstractLat, p::Union{InfPlc, NfOrdIdl}) -> Int

Return the Witt invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.

is_rationally_isometricMethod
is_rationally_isometric(L::AbstractLat, M::AbstractLat, p::Union{InfPlc, NfAbsOrdIdl})
-                                                                     -> Bool

Return whether the rational spans of the lattices L and M are isometric over the completion at the place p.

is_rationally_isometricMethod
is_rationally_isometric(L::AbstractLat, M::AbstractLat) -> Bool

Return whether the rational spans of the lattices L and M are isometric.

Examples

For now and for the rest of this section, the examples will include the new lattice Lquad2 which is quadratic. Moreover, all the completions are going to be done at the prime ideal $p = 7*\mathcal O_K$.


julia> K, a = rationals_as_number_field();
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];
julia> Lquad = quadratic_lattice(K, gens, gram = D);
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];
julia> Lquad2 = quadratic_lattice(K, gens, gram = D)Quadratic lattice of rank 3 and degree 3 - over maximal order of Number field of degree 1 over QQ - with basis nf_elem[1]
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1]<7, 7> -Norm: 7 -Minimum: 7 -principal generator 7 -two normal wrt: 7
julia> hasse_invariant(Lquad, p), witt_invariant(Lquad, p)(1, 1)
julia> is_rationally_isometric(Lquad, Lquad2, p)true
julia> is_rationally_isometric(Lquad, Lquad2)true

Attributes

Let $L$ be a lattice over $E/K$. We call a pseudo-basis of $L$ any sequence of pairs $(\mathfrak A_i, x_i)_{1 \leq i \leq n}$ where the $\mathfrak A_i$'s are fractional (left) ideals of $\mathcal O_E$ and $(x_i)_{1 \leq i \leq n}$ is a basis of the rational span of $L$, and such that

\[ L = \bigoplus_{i = 1}^n \mathfrak A_ix_i.\]

Note that a pseudo-basis is not unique. Given a pseudo-basis $(\mathfrak A_i, x_i)_{1 \leq i \leq n}$ of $L$, we define the corresponding pseudo-matrix of $L$ to be the datum consisting of a list of coefficient ideals corresponding to the ideals $\mathfrak A_i$'s and a matrix whose rows are the coordinates of the $x_i$'s in the canonical basis of the ambient space of $L$ (conversely, given any such pseudo-matrix, one can define the corresponding pseudo-basis).

rankMethod
rank(L::AbstractLat) -> Int

Return the rank of the underlying module of the lattice L.

degreeMethod
degree(L::AbstractLat) -> Int

Return the dimension of the ambient space of the lattice L.

discriminantMethod
discriminant(L::AbstractLat) -> NfOrdFracIdl

Return the discriminant of the lattice L, that is, the generalized index ideal $[L^\# : L]$.

base_fieldMethod
base_field(L::AbstractLat) -> Field

Return the algebra over which the rational span of the lattice L is defined.

base_ringMethod
base_ring(L::AbstractLat) -> Ring

Return the order over which the lattice L is defined.

fixed_fieldMethod
fixed_field(L::AbstractLat) -> Field

Returns the fixed field of the involution of the lattice L.

fixed_ringMethod
fixed_ring(L::AbstractLat) -> Ring

Return the maximal order in the fixed field of the lattice L.

involutionMethod
involution(L::AbstractLat) -> Map

Return the involution of the rational span of the lattice L.

pseudo_matrixMethod
pseudo_matrix(L::AbstractLat) -> PMat

Return a basis pseudo-matrix of the lattice L.

pseudo_basisMethod
pseudo_basis(L::AbstractLat) -> Vector{Tuple{Vector, Ideal}}

Return a pseudo-basis of the lattice L.

coefficient_idealsMethod
coefficient_ideals(L::AbstractLat) -> Vector{NfOrdIdl}

Return the coefficient ideals of a pseudo-basis of the lattice L.

absolute_basis_matrixMethod
absolute_basis_matrix(L::AbstractLat) -> MatElem

Return a $\mathbf{Z}$-basis matrix of the lattice L.

absolute_basisMethod
absolute_basis(L::AbstractLat) -> Vector

Return a $\mathbf{Z}$-basis of the lattice L.

generatorsMethod
generators(L::AbstractLat; minimal = false) -> Vector{Vector}

Return a set of generators of the lattice L over the base ring of L.

If minimal == true, the number of generators is minimal. Note that computing minimal generators is expensive.

gram_matrix_of_generatorsMethod
gram_matrix_of_generators(L::AbstractLat; minimal::Bool = false) -> MatElem

Return the Gram matrix of a generating set of the lattice L.

If minimal == true, then a minimal generating set is used. Note that computing minimal generators is expensive.

Examples


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];
julia> Lherm = hermitian_lattice(E, gens, gram = D);
julia> rank(Lherm), degree(Lherm)(4, 4)
julia> discriminant(Lherm)Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <7, 7>) * [1 0] -(1//2 * <7, 7>) * [0 1]
julia> base_field(Lherm)Relative number field with defining polynomial t^2 + 7 - over number field with defining polynomial x - 1 - over rational field
julia> base_ring(Lherm)Relative maximal order of Relative number field of degree 2 over number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(b + 1, 1//2 * <1, 1>)
julia> fixed_field(Lherm)Number field with defining polynomial x - 1 - over rational field
julia> fixed_ring(Lherm)Maximal order of Number field of degree 1 over QQ -with basis nf_elem[1]
julia> involution(Lherm)Map with following data -Domain: -======= -Relative number field of degree 2 over number field -Codomain: -========= -Relative number field of degree 2 over number field
julia> pseudo_matrix(Lherm)Pseudo-matrix over Relative maximal order of Relative number field of degree 2 over number field -with pseudo-basis -(1, 1//1 * <1, 1>) -(b + 1, 1//2 * <1, 1>) -Fractional ideal with row [1 0 0 0] -Fractional ideal with row [5 1 0 0] -Fractional ideal with row [3 0 1 0] -Fractional ideal with row [0 0 0 1]
julia> pseudo_basis(Lherm)4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}: - ([1, 0, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <7, 28>) * [1 0] -(1//2 * <1, 1>) * [6 1]) - ([5, 1, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([3, 0, 1, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([0, 0, 0, 1], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1])
julia> coefficient_ideals(Lherm)4-element Vector{Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}: - Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <7, 28>) * [1 0] -(1//2 * <1, 1>) * [6 1] - Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1] - Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1] - Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]
julia> absolute_basis_matrix(Lherm)[ 7 0 0 0] -[1//2*b + 7//2 0 0 0] -[ 5 1 0 0] -[5//2*b + 5//2 1//2*b + 1//2 0 0] -[ 3 0 1 0] -[3//2*b + 3//2 0 1//2*b + 1//2 0] -[ 0 0 0 1] -[ 0 0 0 1//2*b + 1//2]
julia> absolute_basis(Lherm)8-element Vector{Vector{Hecke.NfRelElem{nf_elem}}}: - [7, 0, 0, 0] - [1//2*b + 7//2, 0, 0, 0] - [5, 1, 0, 0] - [5//2*b + 5//2, 1//2*b + 1//2, 0, 0] - [3, 0, 1, 0] - [3//2*b + 3//2, 0, 1//2*b + 1//2, 0] - [0, 0, 0, 1] - [0, 0, 0, 1//2*b + 1//2]
julia> generators(Lherm)4-element Vector{Vector{Hecke.NfRelElem{nf_elem}}}: - [2, -1, 0, 0] - [-3, 0, -1, 0] - [0, 0, 0, -1] - [b, 0, 0, 0]
julia> gram_matrix_of_generators(Lherm)[ 5 -6 0 -2*b] -[ -6 10 0 3*b] -[ 0 0 1 0] -[2*b -3*b 0 7]

Module operations

Let $L$ be a lattice over $E/K$ inside the space $(V, \Phi)$. The dual lattice of $L$ is defined to be the following lattice over $E/K$ in $(V, \Phi)$:

\[ L^{\#} = \left\{ x \in V \mid \Phi(x,L) \subseteq \mathcal O_E \right\}.\]

For any fractional (left) ideal $\mathfrak a$ of $\mathcal O_E$, one can define the lattice $\mathfrak aL$ to be the lattice over $E/K$, in the same space $(V, \Phi)$, obtained by rescaling the coefficient ideals of a pseudo-basis of $L$ by $\mathfrak a$. In another flavour, for any non-zero element $a \in K$, one defines the rescaled lattice $L^a$ to be the lattice over $E/K$ with the same underlying module as $L$ (i.e. the same pseudo-bases) but in space $(V, a\Phi)$.

+Method
+(L::AbstractLat, M::AbstractLat) -> AbstractLat

Return the sum of the lattices L and M.

The lattices L and M must have the same ambient space.

*Method
*(a::NumFieldElem, L::AbstractLat) -> AbstractLat

Return the lattice $aL$ inside the ambient space of the lattice L.

*Method
*(a::NumFieldOrdIdl, L::AbstractLat) -> AbstractLat

Return the lattice $aL$ inside the ambient space of the lattice L.

*Method
*(a::NumFieldOrdFracIdl, L::AbstractLat) -> AbstractLat

Return the lattice $aL$ inside the ambient space of the lattice L.

rescaleMethod
rescale(L::AbstractLat, a::NumFieldElem) -> AbstractLat

Return the rescaled lattice $L^a$. Note that this has a different ambient space than the lattice L.

dualMethod
dual(L::AbstractLat) -> AbstractLat

Return the dual lattice of the lattice L.

intersectMethod
intersect(L::AbstractLat, M::AbstractLat) -> AbstractLat

Return the intersection of the lattices L and M.

The lattices L and M must have the same ambient space.

primitive_closureMethod
primitive_closure(M::AbstractLat, N::AbstractLat) -> AbstractLat

Given two lattices M and N defined over a number field E, with $N \subseteq E\otimes M$, return the primitive closure $M \cap E\otimes N$ of N in M.

One can also use the alias saturate(L, M).

orthogonal_submoduleMethod
orthogonal_submodule(L::AbstractLat, M::AbstractLat) -> AbstractLat

Return the largest submodule of L orthogonal to M.

Examples


julia> K, a = rationals_as_number_field();
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];
julia> Lquad = quadratic_lattice(K, gens, gram = D);
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];
julia> Lquad2 = quadratic_lattice(K, gens, gram = D);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> pseudo_matrix(Lquad + Lquad2)Pseudo-matrix over Maximal order of Number field of degree 1 over QQ -with basis nf_elem[1] -1//1 * <2, 2> with row [1 0 0] -1//1 * <1, 1> with row [1 1 0] -1//1 * <1, 1> with row [1 0 1]
julia> pseudo_matrix(intersect(Lquad, Lquad2))Pseudo-matrix over Maximal order of Number field of degree 1 over QQ -with basis nf_elem[1] -1//1 * <10, 10> with row [1 0 0] -1//1 * <25, 25> with row [1//5 1 0] -1//1 * <5, 5> with row [0 3 1]
julia> pseudo_matrix(p*Lquad)Pseudo-matrix over Maximal order of Number field of degree 1 over QQ -with basis nf_elem[1] -1//1 * <14, 126> with row [1 0 0] -1//1 * <7, 7> with row [1 1 0] -1//1 * <7, 7> with row [1 0 1]
julia> ambient_space(rescale(Lquad,3*a))Quadratic space of dimension 3 - over number field of degree 1 over QQ -with gram matrix -[6 0 0] -[0 6 0] -[0 0 6]
julia> pseudo_matrix(Lquad)Pseudo-matrix over Maximal order of Number field of degree 1 over QQ -with basis nf_elem[1] -1//1 * <2, 2> with row [1 0 0] -1//1 * <1, 1> with row [1 1 0] -1//1 * <1, 1> with row [1 0 1]

Categorical constructions

Given finite collections of lattices, one can construct their direct sums, which are also direct products in this context. They are also sometimes called biproducts. Depending on the user usage, it is possible to call one of the following functions.

direct_sumMethod
direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T

Given modules $M_1\dots M_n$, say, return the direct sum $\bigoplus_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical injections $M_i\to\bigoplus_{i=1}^n M_i$ if task = :sum (default),
  • a vector containing the canonical projections $\bigoplus_{i=1}^n M_i\to M_i$ if task = :prod,
  • two vectors containing the canonical injections and projections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_sum(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
-direct_sum(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian lattices $L_1, \ldots, L_n$, return their direct sum $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$ (seen as maps between the corresponding ambient spaces).

For objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

direct_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls

Return the isometry class of the direct sum of two representatives.

direct_productMethod
direct_product(F::FreeMod{T}...; task::Symbol = :prod) where T

Given free modules $F_1\dots F_n$, say, return the direct product $\prod_{i=1}^n F_i$.

Additionally, return

  • a vector containing the canonical projections $\prod_{i=1}^n F_i\to F_i$ if task = :prod (default),
  • a vector containing the canonical injections $F_i\to\prod_{i=1}^n F_i$ if task = :sum,
  • two vectors containing the canonical projections and injections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T

Given modules $M_1\dots M_n$, say, return the direct product $\prod_{i=1}^n M_i$.

Additionally, return

  • a vector containing the canonical projections $\prod_{i=1}^n M_i\to M_i$ if task = :prod (default),
  • a vector containing the canonical injections $M_i\to\prod_{i=1}^n M_i$ if task = :sum,
  • two vectors containing the canonical projections and injections, respectively, if task = :both,
  • none of the above maps if task = :none.
source
direct_product(algebras::AlgAss...; task::Symbol = :sum)
-  -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
-direct_product(algebras::Vector{AlgAss}; task::Symbol = :sum)
-  -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}

Returns the algebra $A = A_1 \times \cdots \times A_k$. task can be ":sum", ":prod", ":both" or ":none" and determines which canonical maps are computed as well: ":sum" for the injections, ":prod" for the projections.

direct_product(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
-direct_product(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian lattices $L_1, \ldots, L_n$, return their direct product $L := L_1 \times \ldots \times L_n$, together with the projections $L \to L_i$ (seen as maps between the corresponding ambient spaces).

For objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections $L_i \to L$, one should call direct_sum(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

biproductMethod
biproduct(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
-biproduct(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian lattices $L_1, \ldots, L_n$, return their biproduct $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$ and the projections $L \to L_i$ (seen as maps between the corresponding ambient spaces).

For objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections $L_i \to L$, one should call direct_sum(x). If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x).


Invariants

Let $L$ be a lattice over $E/K$, in the space $(V, \Phi)$. We define:

  • the norm $\mathfrak n(L)$ of $L$ to be the ideal of $\mathcal O_K$ generated by the squares $\left\{\Phi(x,x) \mid x \in L \right\}$;
  • the scale $\mathfrak s(L)$ of $L$ to be the set $\Phi(L,L) = \left\{\Phi(x,y) \mid x,y \in L \right\}$;
  • the volume $\mathfrak v(L)$ of $L$ to be the index ideal

\[ \lbrack L^{\#} \colon L \rbrack_{\mathcal O_E} := \langle \left\{ \sigma \mid \sigma \in \text{Hom}_{\mathcal O_E}(L^{\#}, L) \right\} \rangle_{\mathcal O_E}.\]

normMethod
norm(L::AbstractLat) -> NfAbsOrdFracIdl

Return the norm of the lattice L. This is a fractional ideal of the fixed field of L.

scaleMethod
scale(L::AbstractLat) -> NfOrdFracIdl

Return the scale of the lattice L.

volumeMethod
volume(L::AbstractLat) -> NfOrdFracIdl

Return the volume of the lattice L.

Examples


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];
julia> Lherm = hermitian_lattice(E, gens, gram = D);
julia> norm(Lherm)1//1 * <1, 1> -Norm: 1 -Minimum: 1 -principal generator 1 -basis_matrix -[1] -two normal wrt: 2
julia> scale(Lherm)Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]
julia> volume(Lherm)Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <7, 7>) * [1 0] -(1//2 * <7, 7>) * [0 1]

Predicates

Let $L$ be a lattice over $E/K$. It is said to be integral if its scale is an integral ideal, i.e. it is contained in $\mathcal O_E$. Moreover, if $\mathfrak p$ is a prime ideal in $\mathcal O_K$, then $L$ is said to be modular (resp. locally modular at $\mathfrak p$) if there exists a fractional ideal $\mathfrak a$ of $\mathcal O_E$ (resp. an integer $v$) such that $\mathfrak aL^{\#} = L$ (resp. $\mathfrak p^vL_{\mathfrak p}^{\#} = L_{\mathfrak p}$).

is_integralMethod
is_integral(L::AbstractLat) -> Bool

Return whether the lattice L is integral.

is_modularMethod
is_modular(L::AbstractLat) -> Bool, NfOrdFracIdl

Return whether the lattice L is modular. In this case, the second returned value is a fractional ideal $\mathfrak a$ of the base algebra of L such that $\mathfrak a L^\# = L$, where $L^\#$ is the dual of L.

is_modularMethod
is_modular(L::AbstractLat, p) -> Bool, Int

Return whether the completion $L_{p}$ of the lattice L at the prime ideal or integer p is modular. If it is the case the second returned value is an integer v such that $L_{p}$ is $p^v$-modular.

is_positive_definiteMethod
is_positive_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is positive definite.

is_negative_definiteMethod
is_negative_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is negative definite.

is_definiteMethod
is_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is definite.

can_scale_totally_positiveMethod
can_scale_totally_positive(L::AbstractLat) -> Bool, NumFieldElem

Return whether there is a totally positive rescaled lattice of the lattice L. If so, the second returned value is an element $a$ such that $L^a$ is totally positive.

Examples


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];
julia> Lherm = hermitian_lattice(E, gens, gram = D);
julia> OK = maximal_order(K);
julia> is_integral(Lherm)true
julia> is_modular(Lherm)[1]false
julia> p = prime_decomposition(OK, 7)[1][1];
julia> is_modular(Lherm, p)(false, 0)
julia> is_positive_definite(Lherm)true
julia> can_scale_totally_positive(Lherm)(true, 1)

Local properties

local_basis_matrixMethod
local_basis_matrix(L::AbstractLat, p::NfOrdIdl; type = :any) -> MatElem

Given a prime ideal p and a lattice L, return a basis matrix of a lattice M such that $M_{p} = L_{p}$. Note that if p is an ideal in the base ring of L, the completions are taken at the minimum of p (which is an ideal in the base ring of the order of p).

  • If type == :submodule, the lattice M will be a sublattice of L.
  • If type == :supermodule, the lattice M will be a superlattice of L.
  • If type == :any, there may not be any containment relation between M and L.
jordan_decompositionMethod
jordan_decomposition(L::AbstractLat, p::NfOrdIdl)
-                            -> Vector{MatElem}, Vector{MatElem}, Vector{Int}

Return a Jordan decomposition of the completion of the lattice L at a prime ideal p.

The returned value consists of three lists $(M_i)_i$, $(G_i)_i$ and $(s_i)_i$ of the same length $r$. The completions of the row spans of the matrices $M_i$ yield a Jordan decomposition of $L_{p}$ into modular sublattices $L_i$ with Gram matrices $G_i$ and scale of $p$-adic valuation $s_i$.

is_isotropicMethod
is_isotropic(L::AbstractLat, p::Union{NfOrdIdl, InfPlc}) -> Bool

Return whether the completion of the lattice L at the place p is isotropic.

Examples


julia> K, a = rationals_as_number_field();
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];
julia> Lquad = quadratic_lattice(K, gens, gram = D);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> local_basis_matrix(Lquad, p)[1 0 0] -[1 1 0] -[1 0 1]
julia> jordan_decomposition(Lquad, p)(AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[1 0 0; 0 1 0; 0 0 1]], AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[2 0 0; 0 2 0; 0 0 2]], [0])
julia> is_isotropic(Lquad, p)true

Automorphisms for definite lattices

Let $L$ and $L'$ be two lattices over the same extension $E/K$, inside their respective ambient spaces $(V, \Phi)$ and $(V', \Phi')$. Similarly to homomorphisms of spaces, we define a homomorphism of lattices from $L$ to $L'$ to be an $\mathcal{O}_E$-module$ homomorphism $f \colon L \to L'$ such that for all $x,y \in L$, one has

\[ \Phi'(f(x), f(y)) = \Phi(x,y).\]

Again, any automorphism of lattices is called an isometry and any monomorphism is called an embedding. We refer to the set of isometries from a lattice $L$ to itself as the automorphism group of $L$.

automorphism_group_orderMethod
automorphism_group_order(L::AbstractLat) -> Int

Given a definite lattice L, return the order of the automorphism group of L.

automorphism_group_generatorsMethod
automorphism_group_generators(L::AbstractLat; ambient_representation::Bool = true)
-                                                      -> Vector{MatElem}

Given a definite lattice L, return generators for the automorphism group of L. If ambient_representation == true (the default), the transformations are represented with respect to the ambient space of L. Otherwise, the transformations are represented with respect to the (pseudo-)basis of L.

Examples


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];
julia> Lquad = quadratic_lattice(K, gens, gram = D);
julia> is_definite(Lquad)true
julia> automorphism_group_order(Lquad)48
julia> automorphism_group_generators(Lquad)6-element Vector{AbstractAlgebra.Generic.MatSpaceElem{nf_elem}}: - [-1 0 0; 0 -1 0; 0 0 -1] - [1 0 0; 0 -1 0; 0 0 -1] - [1 0 0; 0 0 -1; 0 -1 0] - [0 -1 0; 0 0 -1; 1 0 0] - [1 0 0; 0 1 0; 0 0 -1] - [0 1 0; 1 0 0; 0 0 1]

Isometry

is_isometricMethod
is_isometric(L::AbstractLat, M::AbstractLat) -> Bool

Return whether the lattices L and M are isometric.

is_isometric_with_isometryMethod
is_isometric_with_isometry(L::AbstractLat, M::AbstractLat; ambient_representation::Bool = true)
-                                                          -> (Bool, MatElem)

Return whether the lattices L and M are isometric. If this is the case, the second returned value is an isometry T from L to M.

By default, that isometry is represented with respect to the bases of the ambient spaces, that is, $T V_M T^t = V_L$ where $V_L$ and $V_M$ are the Gram matrices of the ambient spaces of L and M respectively. If ambient_representation == false, then the isometry is represented with respect to the (pseudo-)bases of L and M, that is, $T G_M T^t = G_L$ where $G_M$ and $G_L$ are the Gram matrices of the (pseudo-)bases of L and M respectively.

is_locally_isometricMethod
is_locally_isometric(L::AbstractLat, M::AbstractLat, p::NfOrdIdl) -> Bool

Return whether the completions of the lattices L and M at the prime ideal p are isometric.

Examples


julia> K, a = rationals_as_number_field();
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];
julia> Lquad = quadratic_lattice(K, gens, gram = D);
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];
julia> Lquad2 = quadratic_lattice(K, gens, gram = D);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> is_isometric(Lquad, Lquad2)false
julia> is_locally_isometric(Lquad, Lquad2, p)true

Maximal integral lattices

is_maximal_integralMethod
is_maximal_integral(L::AbstractLat, p::NfOrdIdl) -> Bool, AbstractLat

Given a lattice L and a prime ideal p of the fixed ring $\mathcal O_K$ of L, return whether the completion of L at p is maximal integral. If it is not the case, the second returned value is a lattice in the ambient space of L whose completion at p is a minimal overlattice of $L_p$.

is_maximal_integralMethod
is_maximal_integral(L::AbstractLat) -> Bool, AbstractLat

Given a lattice L, return whether L is maximal integral. If it is not, the second returned value is a minimal overlattice of L with integral norm.

is_maximalMethod
is_maximal(L::AbstractLat, p::NfOrdIdl) -> Bool, AbstractLat

Given a lattice L and a prime ideal p in the fixed ring $\mathcal O_K$ of L, check whether the norm of $L_p$ is integral and return whether L is maximal at p. If it is locally integral but not locally maximal, the second returned value is a lattice in the same ambient space of L whose completion at p has integral norm and is a proper overlattice of $L_p$.

maximal_integral_latticeMethod
maximal_integral_lattice(L::AbstractLat, p::NfOrdIdl) -> AbstractLat

Given a lattice L and a prime ideal p of the fixed ring $\mathcal O_K$ of L, return a lattice M in the ambient space of L which is maximal integral at p and which agrees with L locally at all the places different from p.

maximal_integral_latticeMethod
maximal_integral_lattice(L::AbstractLat) -> AbstractLat

Given a lattice L, return a lattice M in the ambient space of L which is maximal integral and which contains L.

maximal_integral_latticeMethod
maximal_integral_lattice(V::AbstractSpace) -> AbstractLat

Given a space V, return a lattice in V with integral norm and which is maximal in V satisfying this property.

Examples


julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];
julia> Lherm = hermitian_lattice(E, gens, gram = D);
julia> OK = maximal_order(K);
julia> p = prime_decomposition(OK, 7)[1][1];
julia> is_maximal_integral(Lherm, p)(false, Hermitian lattice of rank 4 and degree 4)
julia> is_maximal_integral(Lherm)(false, Hermitian lattice of rank 4 and degree 4)
julia> is_maximal(Lherm, p)(false, Hermitian lattice of rank 4 and degree 4)
julia> pseudo_basis(maximal_integral_lattice(Lherm, p))4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}: - ([1, 0, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([0, 1, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([2, 4, 1, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//14 * <1, 1>) * [6 1]) - ([3, 2, 0, 1], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//14 * <1, 1>) * [6 1])
julia> pseudo_basis(maximal_integral_lattice(Lherm))4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}: - ([1, 0, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([0, 1, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([2, 4, 1, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//14 * <1, 1>) * [6 1]) - ([3, 2, 0, 1], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//14 * <1, 1>) * [6 1])
julia> pseudo_basis(maximal_integral_lattice(ambient_space(Lherm)))4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}: - ([1, 0, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([0, 1, 0, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//2 * <1, 1>) * [0 1]) - ([2, 4, 1, 0], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//14 * <1, 1>) * [6 1]) - ([4, 5, 0, 1], Fractional ideal of -Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1> -with basis pseudo-matrix -(1//1 * <1, 1>) * [1 0] -(1//14 * <1, 1>) * [6 1])
diff --git a/previews/PR2578/Hecke/sparse/intro/index.html b/previews/PR2578/Hecke/sparse/intro/index.html deleted file mode 100644 index b3c408ccc9f0..000000000000 --- a/previews/PR2578/Hecke/sparse/intro/index.html +++ /dev/null @@ -1,5 +0,0 @@ - -Sparse linear algebra · Oscar.jl

Sparse linear algebra

Introduction

This chapter deals with sparse linear algebra over commutative rings and fields.

Sparse linear algebra, that is, linear algebra with sparse matrices, plays an important role in various algorithms in algebraic number theory. For example, it is one of the key ingredients in the computation of class groups and discrete logarithms using index calculus methods.

Sparse rows

Building blocks for sparse matrices are sparse rows, which are modelled by objects of type SRow. More precisely, the type is of parametrized form SRow{T}, where T is the element type of the base ring $R$. For example, SRow{ZZRingElem} is the type for sparse rows over the integers.

It is important to note that sparse rows do not have a fixed number of columns, that is, they represent elements of $\{ (x_i)_i \in R^{\mathbb{N}} \mid x_i = 0 \text{ for almost all }i\}$. In particular any two sparse rows over the same base ring can be added.

Creation

sparse_rowMethod
sparse_row(R::Ring, J::Vector{Tuple{Int, T}}) -> SRow{T}

Constructs the sparse row $(a_i)_i$ with $a_{i_j} = x_j$, where $J = (i_j, x_j)_j$. The elements $x_i$ must belong to the ring $R$.

sparse_rowMethod
sparse_row(R::Ring, J::Vector{Tuple{Int, T}}) -> SRow{T}

Constructs the sparse row $(a_i)_i$ with $a_{i_j} = x_j$, where $J = (i_j, x_j)_j$. The elements $x_i$ must belong to the ring $R$.

sparse_row(R::Ring, J::Vector{Tuple{Int, Int}}) -> SRow

Constructs the sparse row $(a_i)_i$ over $R$ with $a_{i_j} = x_j$, where $J = (i_j, x_j)_j$.

sparse_rowMethod
sparse_row(R::Ring, J::Vector{Int}, V::Vector{T}) -> SRow{T}

Constructs the sparse row $(a_i)_i$ over $R$ with $a_{i_j} = x_j$, where $J = (i_j)_j$ and $V = (x_j)_j$.

Basic operations

Rows support the usual operations:

  • +, -, ==
  • multiplication by scalars
  • div, divexact
getindexMethod
getindex(A::SRow, j::Int) -> RingElem

Given a sparse row $(a_i)_{i}$ and an index $j$ return $a_j$.

add_scaled_rowMethod
add_scaled_row(A::SRow{T}, B::SRow{T}, c::T) -> SRow{T}

Returns the row $c A + B$.

add_scaled_rowMethod
add_scaled_row(A::SRow{T}, B::SRow{T}, c::T) -> SRow{T}

Returns the row $c A + B$.

transform_rowMethod
transform_row(A::SRow{T}, B::SRow{T}, i::Int, j::Int, a::T, b::T, c::T, d::T)

Returns the tuple $(aA + bB, cA + dB)$.

lengthMethod
length(A::SRow)

Returns the number of nonzero entries of $A$.

Change of base ring

change_base_ringMethod
change_base_ring(R::Ring, A::SRow) -> SRow

Create a new sparse row by coercing all elements into the ring $R$.

Maximum, minimum and 2-norm

maximumMethod
maximum(A::SRow{T}) -> T

Returns the largest entry of $A$.

maximumMethod
maximum(A::SRow{T}) -> T

Returns the largest entry of $A$.

minimumMethod
minimum(A::SRow{T}) -> T

Returns the smallest entry of $A$.

  minimum(A::NfRelOrdIdl) -> NfOrdIdl
-  minimum(A::NfRelOrdIdl) -> NfRelOrdIdl

Returns the ideal $A \cap O$ where $O$ is the maximal order of the coefficient ideals of $A$.

minimumMethod
minimum(A::SRow{T}) -> T

Returns the smallest entry of $A$.

norm2Method
norm2(A::SRow{T} -> T

Returns $A \cdot A^t$.

Functionality for integral sparse rows

liftMethod
lift(A::SRow{zzModRingElem}) -> SRow{ZZRingElem}

Return the sparse row obtained by lifting all entries in $A$.

mod!Method
mod!(A::SRow{ZZRingElem}, n::ZZRingElem) -> SRow{ZZRingElem}

Inplace reduction of all entries of $A$ modulo $n$ to the positive residue system.

mod_sym!Method
mod_sym!(A::SRow{ZZRingElem}, n::ZZRingElem) -> SRow{ZZRingElem}

Inplace reduction of all entries of $A$ modulo $n$ to the symmetric residue system.

mod_sym!Method
mod_sym!(A::SRow{ZZRingElem}, n::Integer) -> SRow{ZZRingElem}

Inplace reduction of all entries of $A$ modulo $n$ to the symmetric residue system.

maximumMethod
maximum(abs, A::SRow{ZZRingElem}) -> ZZRingElem

Returns the largest, in absolute value, entry of $A$.

Sparse matrices

Let $R$ be a commutative ring. Sparse matrices with base ring $R$ are modelled by objects of type SMat. More precisely, the type is of parametrized form SRow{T}, where T is the element type of the base ring. For example, SMat{ZZRingElem} is the type for sparse matrices over the integers.

In contrast to sparse rows, sparse matrices have a fixed number of rows and columns, that is, they represent elements of the matrices space $\mathrm{Mat}_{n\times m}(R)$. Internally, sparse matrices are implemented as an array of sparse rows. As a consequence, unlike their dense counterparts, sparse matrices have a mutable number of rows and it is very performant to add additional rows.

Construction

sparse_matrixMethod
sparse_matrix(R::Ring) -> SMat

Return an empty sparse matrix with base ring $R$.

sparse_matrixMethod
sparse_matrix(R::Ring, n::Int, m::Int) -> SMat

Return a sparse $n$ times $m$ zero matrix over $R$.

Sparse matrices can also be created from dense matrices as well as from julia arrays:

sparse_matrixMethod
sparse_matrix(A::MatElem; keepzrows::Bool = true)

Constructs the sparse matrix corresponding to the dense matrix $A$. If keepzrows is false, then the constructor will drop any zero row of $A$.

sparse_matrixMethod
sparse_matrix(R::Ring, A::Matrix{T}) -> SMat

Constructs the sparse matrix over $R$ corresponding to $A$.

sparse_matrixMethod
sparse_matrix(R::Ring, A::Matrix{T}) -> SMat

Constructs the sparse matrix over $R$ corresponding to $A$.

The normal way however, is to add rows:

push!Method
push!(A::SMat{T}, B::SRow{T}) where T

Appends the sparse row B to A.

Sparse matrices can also be concatenated to form larger ones:

vcat!Method
vcat!(A::SMat, B::SMat) -> SMat

Vertically joins $A$ and $B$ inplace, that is, the rows of $B$ are appended to $A$.

vcatMethod
vcat(A::SMat, B::SMat) -> SMat

Vertically joins $A$ and $B$.

hcat!Method
hcat!(A::SMat, B::SMat) -> SMat

Horizontally concatenates $A$ and $B$, inplace, changing $A$.

hcatMethod
hcat(A::SMat, B::SMat) -> SMat

Horizontally concatenates $A$ and $B$.

(Normal julia $cat$ is also supported)

There are special constructors:

identity_matrixMethod
identity_matrix(::Type{SMat}, R::Ring, n::Int)

Return a sparse $n$ times $n$ identity matrix over $R$.

zero_matrixMethod
zero_matrix(::Type{SMat}, R::Ring, n::Int)

Return a sparse $n$ times $n$ zero matrix over $R$.

zero_matrixMethod
zero_matrix(::Type{SMat}, R::Ring, n::Int, m::Int)

Return a sparse $n$ times $m$ zero matrix over $R$.

Slices:

subMethod
sub(A::SMat, r::AbstractUnitRange, c::AbstractUnitRange) -> SMat

Return the submatrix of $A$, where the rows correspond to $r$ and the columns correspond to $c$.

Transpose:

transposeMethod
transpose(A::SMat) -> SMat

Returns the transpose of $A$.

Elementary Properties

sparsityMethod
sparsity(A::SMat) -> Float64

Return the sparsity of A, that is, the number of zero-valued elements divided by the number of all elements.

densityMethod
density(A::SMat) -> Float64

Return the density of A, that is, the number of nonzero-valued elements divided by the number of all elements.

nnzMethod
nnz(A::SMat) -> Int

Return the number of non-zero entries of $A$.

nrowsMethod
nrows(A::SMat) -> Int

Return the number of rows of $A$.

ncolsMethod
ncols(A::SMat) -> Int

Return the number of columns of $A$.

isoneMethod
isone(A::SMat)

Tests if $A$ is an identity matrix.

iszeroMethod
iszero(A::SMat)

Tests if $A$ is a zero matrix.

isupper_triangularMethod
isupper_triangular(A::SMat)

Returns true if and only if $A$ is upper (right) triangular.

maximumMethod
maximum(A::SMat{T}) -> T

Finds the largest entry of $A$.

minimumMethod
minimum(A::SMat{T}) -> T

Finds the smallest entry of $A$.

maximumMethod
maximum(abs, A::SMat{ZZRingElem}) -> ZZRingElem

Finds the largest, in absolute value, entry of $A$.

elementary_divisorsMethod
elementary_divisors(A::SMat{ZZRingElem}) -> Vector{ZZRingElem}

The elementary divisors of $A$, i.e. the diagonal elements of the Smith normal form of $A$.

solve_dixon_sfMethod
solve_dixon_sf(A::SMat{ZZRingElem}, b::SRow{ZZRingElem}, is_int::Bool = false) -> SRow{ZZRingElem}, ZZRingElem
-solve_dixon_sf(A::SMat{ZZRingElem}, B::SMat{ZZRingElem}, is_int::Bool = false) -> SMat{ZZRingElem}, ZZRingElem

For a sparse square matrix $A$ of full rank and a sparse matrix (row), find a sparse matrix (row) $x$ and an integer $d$ s.th. $x A = bd$ holds. The algorithm is a Dixon-based linear p-adic lifting method. If \code{is_int} is given, then $d$ is assumed to be $1$. In this case rational reconstruction is avoided.

hadamard_bound2Method
hadamard_bound2(A::SMat{T}) -> T

The square of the product of the norms of the rows of $A$.

echelon_with_transformMethod
echelon_with_transform(A::SMat{zzModRingElem}) -> SMat, SMat

Find a unimodular matrix $T$ and an upper-triangular $E$ s.th. $TA = E$ holds.

reduce_fullMethod
reduce_full(A::SMat{ZZRingElem}, g::SRow{ZZRingElem},
-                      trafo = Val{false}) -> SRow{ZZRingElem}, Vector{Int}

Reduces $g$ modulo $A$ and assumes that $A$ is upper triangular.

The second return value is the array of pivot elements of $A$ that changed.

If trafo is set to Val{true}, then additionally an array of transformations is returned.

hnf!Method
hnf!(A::SMat{ZZRingElem})

Inplace transform of $A$ into upper right Hermite normal form.

hnfMethod
hnf(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}

Return the upper right Hermite normal form of $A$.

snfMethod
snf(A::SMat{ZZRingElem})

The Smith normal form (snf) of $A$.

hnf_extend!Method
hnf_extend!(A::SMat{ZZRingElem}, b::SMat{ZZRingElem}, offset::Int = 0) -> SMat{ZZRingElem}

Given a matrix $A$ in HNF, extend this to get the HNF of the concatenation with $b$.

is_diagonalMethod
is_diagonal(A::SMat) -> Bool

True iff only the i-th entry in the i-th row is non-zero.

detMethod
det(A::SMat{ZZRingElem})

The determinant of $A$ using a modular algorithm. Uses the dense (zzModMatrix) determinant on $A$ for various primes $p$.

det_mcMethod
det_mc(A::SMat{ZZRingElem})

Computes the determinant of $A$ using a LasVegas style algorithm, i.e. the result is not proven to be correct. Uses the dense (zzModMatrix) determinant on $A$ for various primes $p$.

valence_mcMethod
valence_mc{T}(A::SMat{T}; extra_prime = 2, trans = Vector{SMatSLP_add_row{T}}()) -> T

Uses a Monte-Carlo algorithm to compute the valence of $A$. The valence is the valence of the minimal polynomial $f$ of $transpose(A)*A$, thus the last non-zero coefficient, typically $f(0)$.

The valence is computed modulo various primes until the computation stabilises for extra_prime many.

trans, if given, is a SLP (straight-line-program) in GL(n, Z). Then the valence of trans * $A$ is computed instead.

saturateMethod
saturate(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}

Computes the saturation of $A$, that is, a basis for $\mathbf{Q}\otimes M \meet \mathbf{Z}^n$, where $M$ is the row span of $A$ and $n$ the number of rows of $A$.

Equivalently, return $TA$ for an invertible rational matrix $T$, such that $TA$ is integral and the elementary divisors of $TA$ are all trivial.

hnf_kannan_bachemMethod
hnf_kannan_bachem(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}

Compute the Hermite normal form of $A$ using the Kannan-Bachem algorithm.

diagonal_formMethod
diagonal_form(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}

A matrix $D$ that is diagonal and obtained via unimodular row and column operations. Like a snf without the divisibility condition.

Manipulation/ Access

getindexMethod
getindex(A::SMat, i::Int, j::Int)

Given a sparse matrix $A = (a_{ij})_{i, j}$, return the entry $a_{ij}$.

getindexMethod
getindex(A::SMat, i::Int) -> SRow

Given a sparse matrix $A$ and an index $i$, return the $i$-th row of $A$.

setindex!Method
setindex!(A::SMat, b::SRow, i::Int)

Given a sparse matrix $A$, a sparse row $b$ and an index $i$, set the $i$-th row of $A$ equal to $b$.

swap_rows!Method
swap_rows!(A::SMat{T}, i::Int, j::Int)

Swap the $i$-th and $j$-th row of $A$ inplace.

swap_cols!Method
swap_cols!(A::SMat, i::Int, j::Int)

Swap the $i$-th and $j$-th column of $A$ inplace.

scale_row!Method
scale_row!(A::SMat{T}, i::Int, c::T)

Multiply the $i$-th row of $A$ by $c$ inplace.

add_scaled_col!Method
add_scaled_col!(A::SMat{T}, i::Int, j::Int, c::T)

Add $c$ times the $i$-th column to the $j$-th column of $A$ inplace, that is, $A_j \rightarrow A_j + c \cdot A_i$, where $(A_i)_i$ denote the columns of $A$.

add_scaled_row!Method
add_scaled_row!(A::SMat{T}, i::Int, j::Int, c::T)

Add $c$ times the $i$-th row to the $j$-th row of $A$ inplace, that is, $A_j \rightarrow A_j + c \cdot A_i$, where $(A_i)_i$ denote the rows of $A$.

transform_row!Method
transform_row!(A::SMat{T}, i::Int, j::Int, a::T, b::T, c::T, d::T)

Applies the transformation $(A_i, A_j) \rightarrow (aA_i + bA_j, cA_i + dA_j)$ to $A$, where $(A_i)_i$ are the rows of $A$.

diagonalMethod
diagonal(A::SMat) -> ZZRingElem[]

The diagonal elements of $A$ in an array.

reverse_rows!Method
reverse_rows!(A::SMat)

Inplace inversion of the rows of $A$.

mod_sym!Method
mod_sym!(A::SMat{ZZRingElem}, n::ZZRingElem)

Inplace reduction of all entries of $A$ modulo $n$ to the symmetric residue system.

find_row_starting_withMethod
find_row_starting_with(A::SMat, p::Int) -> Int

Tries to find the index $i$ such that $A_{i,p} \neq 0$ and $A_{i, p-j} = 0$ for all $j > 1$. It is assumed that $A$ is upper triangular. If such an index does not exist, find the smallest index larger.

reduceMethod
reduce(A::SMat{ZZRingElem}, g::SRow{ZZRingElem}, m::ZZRingElem) -> SRow{ZZRingElem}

Given an upper triangular matrix $A$ over the integers, a sparse row $g$ and an integer $m$, this function reduces $g$ modulo $A$ and returns $g$ modulo $m$ with respect to the symmetric residue system.

reduceMethod
reduce(A::SMat{ZZRingElem}, g::SRow{ZZRingElem}) -> SRow{ZZRingElem}

Given an upper triangular matrix $A$ over a field and a sparse row $g$, this function reduces $g$ modulo $A$.

reduceMethod
reduce(A::SMat{T}, g::SRow{T}) -> SRow{T}

Given an upper triangular matrix $A$ over a field and a sparse row $g$, this function reduces $g$ modulo $A$.

rand_rowMethod
rand_row(A::SMat) -> SRow

Return a random row of the sparse matrix $A$.

Changing of the ring:

map_entriesMethod
map_entries(f, A::SMat) -> SMat

Given a sparse matrix $A$ and a callable object $f$, this function will construct a new sparse matrix by applying $f$ to all elements of $A$.

change_base_ringMethod
change_base_ring(R::Ring, A::SMat)

Create a new sparse matrix by coercing all elements into the ring $R$.

Arithmetic

Matrices support the usual operations as well

  • +, -, ==
  • div, divexact by scalars
  • multiplication by scalars

Various products:

mulMethod
mul(A::SMat{T}, b::AbstractVector{T}) -> Vector{T}

Return the product $A \cdot b$ as a dense vector.

mulMethod
mul(A::SMat{T}, b::AbstractMatrix{T}) -> Matrix{T}

Return the product $A \cdot b$ as a dense array.

mulMethod
mul(A::SMat{T}, b::MatElem{T}) -> MatElem

Return the product $A \cdot b$ as a dense matrix.

mulMethod
mul(A::SRow, B::SMat) -> SRow

Return the product $A\cdot B$ as a sparse row.

Other:

sparseMethod
sparse(A::SMat) -> SparseMatrixCSC

The same matrix, but as a sparse matrix of julia type SparseMatrixCSC.

ZZMatrixMethod
ZZMatrix(A::SMat{ZZRingElem})

The same matrix $A$, but as an ZZMatrix.

ZZMatrixMethod
ZZMatrix(A::SMat{T}) where {T <: Integer}

The same matrix $A$, but as an ZZMatrix. Requires a conversion from the base ring of $A$ to $\mathbb ZZ$.

ArrayMethod
Array(A::SMat{T}) -> Matrix{T}

The same matrix, but as a two-dimensional julia array.

diff --git a/previews/PR2578/InvariantTheory/finite_groups/index.html b/previews/PR2578/InvariantTheory/finite_groups/index.html deleted file mode 100644 index 2ebae75b65ea..000000000000 --- a/previews/PR2578/InvariantTheory/finite_groups/index.html +++ /dev/null @@ -1,534 +0,0 @@ - -Invariants of Finite Groups · Oscar.jl

Invariants of Finite Groups

In this section, with notation as in the introduction to this chapter, $G$ will be a finite group.

Note

The ssumption that $G$ is finite implies:

  • By a result of Emmy Noether, $K[V]$ is integral over $K[V]^G$. In particular,

    $\; \; \; \; \; \dim K[V]^G = \dim K[V] = n.$

    Moreover, $K[V]^G$ is finitely generated as a $K$-algebra.

  • If the group order $|G|$ is invertible in $K$, then we have the explicit Reynolds operator

    $\; \; \; \; \; \mathcal R: K[V] \to K[V], f\mapsto \frac{1}{|G|}\sum_{\pi\in G}(f \;\! . \;\! \pi).$

Note

We speak of non-modular invariant theory if $|G|$ is invertible in $K$, and of modular invariant theory otherwise.

Note

In the non-modular case, using Emmy Noether's result and the Reynolds operator, it is not too difficult to show that $K[V]^G$ is a free module over any of its graded Noether normalizations. That is, $K[V]^G$ is Cohen-Macaulay. In the modular case, $K[V]^G$ may not be Cohen-Macaulay.

Note

In the non-modular case, the Hilbert series of $K[V]^G$ can be precomputed as its Molien series. See Harm Derksen, Gregor Kemper (2015) and Wolfram Decker, Theo de Jong (1998) for explicit formulas.

Knowing the Hilbert series means to know the dimension of each graded piece $K[V]^G_d$. This information can often be used to speed up algorithms for finding invariants. The most basic task here is to compute the invariants of some given degree $d$, that is, to find an explicit $K$-basis of $K[V]^G_d$. There are two different approaches:

  • The Reynolds Operator Method, available in the non-modular case, applies the Reynolds operator to sufficiently many monomials in $K[x_1, \dots, x_n]_d\cong K[V]_d$, and extracts a $K$-basis from the resulting generating set.
  • The Linear Algebra Method, available in the non-modular and the modular case, finds the elements of a $K$-basis all at once by setting up and solving an appropriate $K$-linear system of equations.

These methods are, in particular, crucial to the computation of primary and secondary invariants. Primary invariants and irreducible secondary invariants together generate $K[V]^G$ as a $K$-algebra. Omitting redundant generators yields a system of fundamental invariants. In the non-modular case, an alternative and typically more effective way to compute generators of $K[V]^G$ is King's algorithm which finds a system of fundamental invariants directly, without computing primary and secondary invariants. See Simon King (2013).

We discuss the relevant OSCAR functionality below.

Creating Invariant Rings

How Groups are Given

The invariant theory part of OSCAR distinguishes two ways of how finite groups and their actions on $K[x_1, \dots, x_n]\cong K[V]$ are specified:

Matrix Groups

Here, $G$ will be explicitly given as a matrix group $G\subset \text{GL}_n(K)\cong \text{GL}(V) $ by (finitely many) generating matrices, acting on $K[x_1, \dots, x_n]\cong K[V]$ by linear substitution:

\[(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f((x_1, \dots, x_n) \cdot \rho(\pi)) \text{ for all } \pi\in G.\]

Permutation Groups

Here, $G$ will be given as a permutation group, acting on $K[x_1, \dots, x_n]\cong K[V]$ by permuting the variables.

Constructors for Invariant Rings

invariant_ringMethod
invariant_ring(G::MatrixGroup)
-invariant_ring(K::Field = QQ, G::PermGroup)

Return the invariant ring of the finite matrix group or permutation group G.

In the latter case, use the specified field K as the coefficient field. The default value for K is QQ.

Note

The creation of invariant rings is lazy in the sense that no explicit computations are done until specifically invoked (for example, by the primary_invariants function).

Examples

julia> K, a = CyclotomicField(3, "a");
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);
-
-julia> G = matrix_group(M1, M2);
-
-julia> IRm = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over K
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> IRp = invariant_ring(symmetric_group(3))
-Invariant ring of
-Sym( [ 1 .. 3 ] )
-with generators
-PermGroupElem[(1,2,3), (1,2)]
-
-julia> coefficient_ring(IRp)
-Rational field
source

Basic Data Associated to Invariant Rings

If IR is the invariant ring $K[x_1,..., x_n]^G$ of a finite matrix group $G$, then

  • group(IR) refers to $G$,
  • coefficient_ring(IR) to $K$, and
  • polynomial_ring(IR) to $K[x_1,..., x_n]$.

Moreover, is_modular(IR) returns true in the modular case, and false otherwise.

Examples
julia> K, a = CyclotomicField(3, "a")
-(Cyclotomic field of order 3, a)
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])
-[0   0   1]
-[1   0   0]
-[0   1   0]
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])
-[1   0        0]
-[0   a        0]
-[0   0   -a - 1]
-
-julia> G = matrix_group(M1, M2)
-Matrix group of degree 3 over K
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over K
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> group(IR)
-Matrix group of degree 3 over K
-
-julia> coefficient_ring(IR)
-Number field with defining polynomial _$^2 + _$ + 1
-  over rational field
-
-julia> R = polynomial_ring(IR)
-Multivariate polynomial ring in 3 variables over cyclotomic field of order 3 graded by
-  x[1] -> [1]
-  x[2] -> [1]
-  x[3] -> [1]
-
-julia> x = gens(R)
-3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]
- x[2]
- x[3]
-
-julia> is_modular(IR)
-false
-

The Reynolds Operator

reynolds_operatorMethod
 reynolds_operator(IR::InvRing{FldT, GrpT, T}, f::T) where {FldT, GrpT, T <: MPolyRingElem}

In the non-modular case, return the image of f under the Reynolds operator projecting onto IR.

Examples

julia> K, a = CyclotomicField(3, "a")
-(Cyclotomic field of order 3, a)
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])
-[0   0   1]
-[1   0   0]
-[0   1   0]
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])
-[1   0        0]
-[0   a        0]
-[0   0   -a - 1]
-
-julia> G = matrix_group(M1, M2)
-Matrix group of degree 3 over K
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over K
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> R = polynomial_ring(IR)
-Multivariate polynomial ring in 3 variables over cyclotomic field of order 3 graded by
-  x[1] -> [1]
-  x[2] -> [1]
-  x[3] -> [1]
-
-julia> x = gens(R)
-3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]
- x[2]
- x[3]
-
-julia> f = x[1]^3
-x[1]^3
-
-julia> reynolds_operator(IR, f)
-1//3*x[1]^3 + 1//3*x[2]^3 + 1//3*x[3]^3
-
-julia> M = matrix(GF(3), [0 1 0; -1 0 0; 0 0 -1])
-[0   1   0]
-[2   0   0]
-[0   0   2]
-
-julia> G = matrix_group(M)
-Matrix group of degree 3 over Finite field of characteristic 3
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over Finite field of characteristic 3
-with generators
-fpMatrix[[0 1 0; 2 0 0; 0 0 2]]
-
-julia> R = polynomial_ring(IR)
-Multivariate polynomial ring in 3 variables over GF(3) graded by
-  x[1] -> [1]
-  x[2] -> [1]
-  x[3] -> [1]
-
-julia> x = gens(R)
-3-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:
- x[1]
- x[2]
- x[3]
-
-julia> f = x[1]^2
-x[1]^2
-
-julia> reynolds_operator(IR, f)
-2*x[1]^2 + 2*x[2]^2
-
-julia> f = x[1]^3
-x[1]^3
-
-julia> reynolds_operator(IR, f)
-0
source
reynolds_operatorMethod
 reynolds_operator(IR::InvRing{FldT, GrpT, T}, f::T, chi::GAPGroupClassFunction)
-   where {FldT, GrpT, T <: MPolyRingElem}

In the case of characteristic zero, return the image of f under the twisted Reynolds operator projecting onto the isotypic component of the polynomial ring with respect to chi, that is, the semi-invariants (or relative invariants) with respect to chi, see Richard P. Stanley (1979). It is assumed that chi is an irreducible character.

In case chi is a linear character, the returned polynomial, say h, fulfils h^g = chi(g)h for all g in group(IR) (possibly h is zero).

Note

If coefficient_ring(IR) does not contain all character values of chi, an error is raised.

Examples

julia> K, a = CyclotomicField(3, "a");
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);
-
-julia> G = matrix_group(M1, M2);
-
-julia> IR = invariant_ring(G);
-
-julia> R = polynomial_ring(IR);
-
-julia> x = gens(R);
-
-julia> f = x[1]^3
-x[1]^3
-
-julia> reynolds_operator(IR, f, trivial_character(G))
-1//3*x[1]^3 + 1//3*x[2]^3 + 1//3*x[3]^3
-
-julia> S2 = symmetric_group(2);
-
-julia> IR = invariant_ring(QQ, S2);
-
-julia> R = polynomial_ring(IR);
-
-julia> x = gens(R);
-
-julia> F = abelian_closure(QQ)[1];
-
-julia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])
-class_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])
-
-julia> reynolds_operator(IR, x[1], chi)
-1//2*x[1] - 1//2*x[2]
source

Invariants of a Given Degree

basisFunction
 basis(IR::InvRing, d::Int, algorithm::Symbol = :default)

Given an invariant ring IR and an integer d, return a basis for the invariants in degree d.

The optional argument algorithm specifies the algorithm to be used. If algorithm = :reynolds, the Reynolds operator is utilized (this method is only available in the non-modular case). Setting algorithm = :linear_algebra means that plain linear algebra is used. The default option algorithm = :default asks to select the heuristically best algorithm.

See also iterate_basis.

Examples

julia> K, a = CyclotomicField(3, "a")
-(Cyclotomic field of order 3, a)
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])
-[0   0   1]
-[1   0   0]
-[0   1   0]
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])
-[1   0        0]
-[0   a        0]
-[0   0   -a - 1]
-
-julia> G = matrix_group(M1, M2)
-Matrix group of degree 3 over K
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over K
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> basis(IR, 6)
-4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]^2*x[2]^2*x[3]^2
- x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4
- x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3
- x[1]^6 + x[2]^6 + x[3]^6
-
-julia> M = matrix(GF(3), [0 1 0; -1 0 0; 0 0 -1])
-[0   1   0]
-[2   0   0]
-[0   0   2]
-
-julia> G = matrix_group(M)
-Matrix group of degree 3 over Finite field of characteristic 3
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over Finite field of characteristic 3
-with generators
-fpMatrix[[0 1 0; 2 0 0; 0 0 2]]
-
-julia> basis(IR, 2)
-2-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:
- x[1]^2 + x[2]^2
- x[3]^2
-
-julia> basis(IR, 3)
-2-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:
- x[1]*x[2]*x[3]
- x[1]^2*x[3] + 2*x[2]^2*x[3]
source
basisMethod
basis(IR::InvRing, d::Int, chi::GAPGroupClassFunction)

Given an invariant ring IR, an integer d and an irreducible character chi, return a basis for the semi-invariants (or relative invariants) in degree d with respect to chi.

This function is only implemented in the case of characteristic zero.

Note

If coefficient_ring(IR) does not contain all character values of chi, an error is raised.

See also iterate_basis.

Examples

julia> K, a = CyclotomicField(3, "a");
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);
-
-julia> G = matrix_group(M1, M2);
-
-julia> IR = invariant_ring(G);
-
-julia> basis(IR, 6, trivial_character(G))
-4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]^6 + x[2]^6 + x[3]^6
- x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4
- x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3
- x[1]^2*x[2]^2*x[3]^2
-
-julia> S2 = symmetric_group(2);
-
-julia> R = invariant_ring(QQ, S2);
-
-julia> F = abelian_closure(QQ)[1];
-
-julia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])
-class_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])
-
-julia> basis(R, 3, chi)
-2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x[1]^3 - x[2]^3
- x[1]^2*x[2] - x[1]*x[2]^2
-
source
iterate_basisFunction
 iterate_basis(IR::InvRing, d::Int, algorithm::Symbol = :default)

Given an invariant ring IR and an integer d, return an iterator over a basis for the invariants in degree d.

The optional argument algorithm specifies the algorithm to be used. If algorithm = :reynolds, the Reynolds operator is utilized (this method is only available in the non-modular case). Setting algorithm = :linear_algebra means that plain linear algebra is used. The default option algorithm = :default asks to select the heuristically best algorithm.

When using the Reynolds operator, the basis is constructed element-by-element. With linear algebra, this is not possible and the basis will be constructed all at once when calling the function.

See also basis.

Examples

julia> K, a = CyclotomicField(3, "a")
-(Cyclotomic field of order 3, a)
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])
-[0   0   1]
-[1   0   0]
-[0   1   0]
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])
-[1   0        0]
-[0   a        0]
-[0   0   -a - 1]
-
-julia> G = matrix_group(M1, M2)
-Matrix group of degree 3 over Cyclotomic field of order 3
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over Cyclotomic field of order 3
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> B = iterate_basis(IR, 6)
-Iterator over a basis of the component of degree 6 of
-Invariant ring of
-Matrix group of degree 3 over Cyclotomic field of order 3
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> collect(B)
-4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]^2*x[2]^2*x[3]^2
- x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4
- x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3
- x[1]^6 + x[2]^6 + x[3]^6
-
-julia> M = matrix(GF(3), [0 1 0; -1 0 0; 0 0 -1])
-[0   1   0]
-[2   0   0]
-[0   0   2]
-
-julia> G = matrix_group(M)
-Matrix group of degree 3 over Galois field with characteristic 3
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over Galois field with characteristic 3
-with generators
-fpMatrix[[0 1 0; 2 0 0; 0 0 2]]
-
-julia> B = iterate_basis(IR, 2)
-Iterator over a basis of the component of degree 2 of
-Invariant ring of
-Matrix group of degree 3 over Galois field with characteristic 3
-with generators
-fpMatrix[[0 1 0; 2 0 0; 0 0 2]]
-
-julia> collect(B)
-2-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:
- x[1]^2 + x[2]^2
- x[3]^2
source
iterate_basisMethod
iterate_basis(IR::InvRing, d::Int, chi::GAPGroupClassFunction)

Given an invariant ring IR, an integer d and an irreducible character chi, return an iterator over a basis for the semi-invariants (or relative invariants) in degree d with respect to chi.

This function is only implemented in the case of characteristic zero.

Note

If coefficient_ring(IR) does not contain all character values of chi, an error is raised.

See also basis.

Examples

julia> K, a = CyclotomicField(3, "a");
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);
-
-julia> G = matrix_group(M1, M2);
-
-julia> IR = invariant_ring(G);
-
-julia> B = iterate_basis(IR, 6, trivial_character(G))
-Iterator over a basis of the component of degree 6 of
-Invariant ring of
-Matrix group of degree 3 over Cyclotomic field of order 3
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-relative to a character
-
-julia> collect(B)
-4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]^6 + x[2]^6 + x[3]^6
- x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4
- x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3
- x[1]^2*x[2]^2*x[3]^2
-
-julia> S2 = symmetric_group(2);
-
-julia> R = invariant_ring(QQ, S2);
-
-julia> F = abelian_closure(QQ)[1];
-
-julia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])
-class_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])
-
-julia> B = iterate_basis(R, 3, chi)
-Iterator over a basis of the component of degree 3 of
-Invariant ring of
-Sym( [ 1 .. 2 ] )
-with generators
-PermGroupElem[(1,2)]
-relative to a character
-
-julia> collect(B)
-2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x[1]^3 - x[2]^3
- x[1]^2*x[2] - x[1]*x[2]^2
-
source

The Molien Series

molien_seriesMethod
molien_series([S::PolyRing], I::InvRing, [chi::GAPGroupClassFunction])

In the non-modular case, return the Molien series of I as a rational function.

If a univariate polynomial ring with rational coefficients is specified by the optional argument S::PolyRing, then return the Molien series as an element of the fraction field of that ring.

If a character chi is specified, the series relative to chi is returned. This is the Molien series of the module of semi-invariants (or relative invariants) with respect to chi, see Richard P. Stanley (1979).

Examples

julia> K, a = CyclotomicField(3, "a");
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);
-
-julia> G = matrix_group(M1, M2);
-
-julia> IR = invariant_ring(G);
-
-julia> MS = molien_series(IR)
-(-t^6 + t^3 - 1)//(t^9 - 3*t^6 + 3*t^3 - 1)
-
-julia> parent(MS)
-Fraction field
-  of univariate polynomial ring in t over QQ
-
-julia> expand(MS, 10)
-1 + 2*t^3 + 4*t^6 + 7*t^9 + O(t^11)
julia> S2 = symmetric_group(2);
-
-julia> IR = invariant_ring(QQ, S2);
-
-julia> F = abelian_closure(QQ)[1];
-
-julia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])
-class_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])
-
-julia> molien_series(IR)
-1//(t^3 - t^2 - t + 1)
-
-julia> molien_series(IR, chi)
-t//(t^3 - t^2 - t + 1)
source

Primary Invariants

primary_invariantsMethod
primary_invariants(IR::InvRing;
-  ensure_minimality::Int = 0, degree_bound::Int = 1,
-  primary_degrees::Vector{Int} = Int[])

Return a system of primary invariants for IR as a Vector sorted by increasing degree. The result is cached, so calling this function again with argument IR will be fast and give the same result.

The primary invariants are computed using the algorithm in Gregor Kemper (1999).

The product of the degrees $d_1,\dots, d_n$ of the returned primary invariants is guaranteed to be minimal among all possible sets of primary invariants.

Expert users (or users happy to experiment) may enter the following keyword arguments to speed up the computation. Note that all of these options are ignored if there are already primary invariants cached. If admissible degrees $d_1,\dots, d_n$ for a system of primary invariants are known a priori, these degrees can be specified by primary_degrees = [d_1, ..., d_n]. Note that an error is raised if in fact no primary invariants of the given degrees exist. An a priori known number $k \geq 1$ with $d_1\cdots d_n \geq k \cdot |G|$, where $G$ is the underlying group, can be specified by degree_bound = k. The default value is degree_bound = 1. In some situations, the runtime of the algorithm might be improved by assigning a positive integer to ensure_minimality. This leads to an early cancellation of loops in the algorithm and the described minimality of the degrees is not guaranteed anymore. A smaller (positive) value of ensure_minimality corresponds to an earlier cancellation. However, the default value ensure_minimality = 0 corresponds to no cancellation.

Examples

julia> K, a = CyclotomicField(3, "a");
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);
-
-julia> G = matrix_group(M1, M2);
-
-julia> IR = invariant_ring(G);
-
-julia> primary_invariants(IR)
-3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]*x[2]*x[3]
- x[1]^3 + x[2]^3 + x[3]^3
- x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3
-
-julia> IR = invariant_ring(G); # "New" ring to avoid caching
-
-julia> primary_invariants(IR, primary_degrees = [ 3, 6, 6 ])
-3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]*x[2]*x[3]
- x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3
- x[1]^6 + x[2]^6 + x[3]^6
-
source

Secondary Invariants

secondary_invariantsMethod
secondary_invariants(IR::InvRing)

Return a system of secondary invariants for IR as a Vector sorted by increasing degree. The result is cached, so calling this function again with argument IR will be fast and give the same result. Note that the secondary invariants are defined with respect to the currently cached system of primary invariants for IR (if no system of primary invariants for IR is cached, such a system is computed and cached first).

Implemented Algorithms

For the non-modular case, the function relies on Algorithm 3.7.2 in Harm Derksen, Gregor Kemper (2015), enhanced by ideas from Simon King (2007). In the modular case, Algorithm 3.7.5 in Harm Derksen, Gregor Kemper (2015) is used.

Examples

julia> K, a = CyclotomicField(3, "a");
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);
-
-julia> G = matrix_group(M1, M2);
-
-julia> IR = invariant_ring(G);
-
-julia> secondary_invariants(IR)
-2-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- 1
- x[1]^3*x[2]^6 + x[1]^6*x[3]^3 + x[2]^3*x[3]^6
source
irreducible_secondary_invariantsMethod
irreducible_secondary_invariants(IR::InvRing)

Return a system of irreducible secondary invariants for IR as a Vector sorted by increasing degree. The result is cached, so calling this function again will be fast and give the same result. Here, a secondary invariant is called irreducible, if it cannot be written as a polynomial expression in the primary invariants and the other secondary invariants.

Note that the secondary invariants and hence the irreducible secondary invariants are defined with respect to the currently cached system of primary invariants for IR (if no system of primary invariants for IR is cached, such a system is computed and cached first).

Examples

julia> M = matrix(QQ, [0 -1 0 0 0; 1 -1 0 0 0; 0 0 0 0 1; 0 0 1 0 0; 0 0 0 1 0]);
-
-julia> G = matrix_group(M);
-
-julia> IR = invariant_ring(G);
-
-julia> secondary_invariants(IR)
-12-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- 1
- x[1]*x[3] - x[2]*x[3] + x[2]*x[4] - x[1]*x[5]
- x[3]^2 + x[4]^2 + x[5]^2
- x[1]^3 - 3*x[1]*x[2]^2 + x[2]^3
- x[1]^2*x[3] - x[1]*x[2]*x[3] - x[1]*x[2]*x[4] + x[2]^2*x[4] + x[1]*x[2]*x[5]
- x[1]*x[3]^2 - x[2]*x[3]^2 + x[2]*x[4]^2 - x[1]*x[5]^2
- x[1]^2*x[3] + x[1]^2*x[4] - 2*x[1]*x[2]*x[4] + x[2]^2*x[4] + x[2]^2*x[5]
- x[1]*x[3]*x[4] - x[2]*x[3]*x[4] - x[1]*x[3]*x[5] + x[2]*x[4]*x[5]
- x[3]*x[4]^2 + x[3]^2*x[5] + x[4]*x[5]^2
- x[1]*x[3]^3 - x[2]*x[3]^3 + x[2]*x[3]^2*x[4] + x[1]*x[3]*x[4]^2 - x[2]*x[3]*x[4]^2 + x[2]*x[4]^3 - x[1]*x[3]^2*x[5] - x[1]*x[4]^2*x[5] + x[1]*x[3]*x[5]^2 - x[2]*x[3]*x[5]^2 + x[2]*x[4]*x[5]^2 - x[1]*x[5]^3
- x[3]^4 + 2*x[3]^2*x[4]^2 + x[4]^4 + 2*x[3]^2*x[5]^2 + 2*x[4]^2*x[5]^2 + x[5]^4
- x[1]*x[3]^5 - x[2]*x[3]^5 + x[2]*x[3]^4*x[4] + 2*x[1]*x[3]^3*x[4]^2 - 2*x[2]*x[3]^3*x[4]^2 + 2*x[2]*x[3]^2*x[4]^3 + x[1]*x[3]*x[4]^4 - x[2]*x[3]*x[4]^4 + x[2]*x[4]^5 - x[1]*x[3]^4*x[5] - 2*x[1]*x[3]^2*x[4]^2*x[5] - x[1]*x[4]^4*x[5] + 2*x[1]*x[3]^3*x[5]^2 - 2*x[2]*x[3]^3*x[5]^2 + 2*x[2]*x[3]^2*x[4]*x[5]^2 + 2*x[1]*x[3]*x[4]^2*x[5]^2 - 2*x[2]*x[3]*x[4]^2*x[5]^2 + 2*x[2]*x[4]^3*x[5]^2 - 2*x[1]*x[3]^2*x[5]^3 - 2*x[1]*x[4]^2*x[5]^3 + x[1]*x[3]*x[5]^4 - x[2]*x[3]*x[5]^4 + x[2]*x[4]*x[5]^4 - x[1]*x[5]^5
-
-julia> irreducible_secondary_invariants(IR)
-8-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x[1]*x[3] - x[2]*x[3] + x[2]*x[4] - x[1]*x[5]
- x[3]^2 + x[4]^2 + x[5]^2
- x[1]^3 - 3*x[1]*x[2]^2 + x[2]^3
- x[1]^2*x[3] - x[1]*x[2]*x[3] - x[1]*x[2]*x[4] + x[2]^2*x[4] + x[1]*x[2]*x[5]
- x[1]*x[3]^2 - x[2]*x[3]^2 + x[2]*x[4]^2 - x[1]*x[5]^2
- x[1]^2*x[3] + x[1]^2*x[4] - 2*x[1]*x[2]*x[4] + x[2]^2*x[4] + x[2]^2*x[5]
- x[1]*x[3]*x[4] - x[2]*x[3]*x[4] - x[1]*x[3]*x[5] + x[2]*x[4]*x[5]
- x[3]*x[4]^2 + x[3]^2*x[5] + x[4]*x[5]^2
source

Fundamental Systems of Invariants

fundamental_invariantsFunction
fundamental_invariants(IR::InvRing, algorithm::Symbol = :default; beta::Int = 0)

Return a system of fundamental invariants for IR.

The result is cached, so calling this function again with argument IR will be fast and give the same result.

Implemented Algorithms

In the non-modular case the function relies on King's algorithm Simon King (2013) which finds a system of fundamental invariants directly, without computing primary and secondary invariants. If an upper bound for the degrees of fundamental invariants is known, this can be supplied by the keyword argument beta and might result in an earlier termination of the algorithm. By default, the algorithm uses the bounds from Mátyás Domokos, Pál Hegedűs (2000) and Müfit Sezer (2002).

Alternatively, if specified by algorithm = :primary_and_secondary, the function computes fundamental invariants from a collection of primary and irreducible secondary invariants. The optional keyword argument beta is ignored for this algorithm.

In the modular case, only the second method is available for theoretical reasons.

Examples

julia> K, a = CyclotomicField(3, "a")
-(Cyclotomic field of order 3, a)
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])
-[0   0   1]
-[1   0   0]
-[0   1   0]
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])
-[1   0        0]
-[0   a        0]
-[0   0   -a - 1]
-
-julia> G = matrix_group(M1, M2)
-Matrix group of degree 3 over K
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over K
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> fundamental_invariants(IR)
-4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:
- x[1]^3 + x[2]^3 + x[3]^3
- x[1]*x[2]*x[3]
- x[1]^6 + x[2]^6 + x[3]^6
- x[1]^3*x[2]^6 + x[1]^6*x[3]^3 + x[2]^3*x[3]^6
source

Invariant Rings as Affine Algebras

affine_algebraMethod
affine_algebra(IR::InvRing;
-  algo_gens::Symbol = :default, algo_rels::Symbol = :groebner_basis)

Given an invariant ring IR with underlying graded polynomial ring, say R, return a graded affine algebra, say A, together with a graded algebra homomorphism A $\to$ R which maps A isomorphically onto IR.

Note

If a system of fundamental invariants for IR is already cached, the function makes use of that system. Otherwise, such a system is computed and cached first. The algebra A is graded according to the degrees of the fundamental invariants, the modulus of A is generated by the algebra relations on these invariants, and the algebra homomorphism A $\to$ R is defined by sending the i-th generator of A to the i-th fundamental invariant.

Optional arguments

Using the arguments :king or :primary_and_secondary for algo_gens selects the algorithm for the computation of the fundamental invariants (see fundamental_invariants for details). The argument :groebner_basis or :linear_algebra for algo_rels controls which algorithm for the computation of the relations between the fundamental invariants is used. With :groebner_basis, the relations are computed via the standard computation of a kernel of a morphism between multivariate polynomial rings. The option :linear_algebra uses an algorithm by Kemper and Steel Gregor Kemper, Allan Steel (1999), Section 17.5.5, to compute the relations without the use of Groebner bases. Note that this option is only available, if the fundamental invariants are computed via primary and secondary invariants (i.e. algo_gens = :primary_and_secondary).

Note

If a presentation of IR is already computed (and hence cached), this cached presentation will be returned and the values of algo_gens and algo_rels will be ignored. Further, if fundamental invariants are already computed and cached, the value of algo_gens might be ignored, as the cached system is used.

Examples

julia> K, a = CyclotomicField(3, "a")
-(Cyclotomic field of order 3, a)
-
-julia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])
-[0   0   1]
-[1   0   0]
-[0   1   0]
-
-julia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])
-[1   0        0]
-[0   a        0]
-[0   0   -a - 1]
-
-julia> G = matrix_group(M1, M2)
-Matrix group of degree 3 over K
-
-julia> IR = invariant_ring(G)
-Invariant ring of
-Matrix group of degree 3 over K
-with generators
-AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]
-
-julia> affine_algebra(IR)
-(Quotient of multivariate polynomial ring by ideal with 1 generator, Map with following data
-Domain:
-=======
-Quotient of multivariate polynomial ring by ideal with 1 generator
-Codomain:
-=========
-Graded multivariate polynomial ring in 3 variables over cyclotomic field of order 3)
source

Semi-invariants / relative invariants

semi_invariantsMethod
semi_invariants(IR::InvRing, chi::GAPGroupClassFunction)
-relative_invariants(IR::InvRing, chi::GAPGroupClassFunction)

Given an irreducible character chi of the underlying group, return a system of semi-invariants (or relative invariants) with respect to chi. By this, we mean a set of free generators of the isotypic component of the of the polynomial ring with respect to chi as a module over the algebra generated by primary invariants for IR. See also Karin Gatermann (1996) and Richard P. Stanley (1979).

Note

If coefficient_ring(IR) does not contain all character values of chi, an error is raised.

This function is so far only implemented in the case of characteristic zero.

Examples

julia> S2 = symmetric_group(2);
-
-julia> RS2 = invariant_ring(S2);
-
-julia> F = abelian_closure(QQ)[1];
-
-julia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])
-class_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])
-
-julia> semi_invariants(RS2, chi)
-1-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x[1] - x[2]
-
source
diff --git a/previews/PR2578/InvariantTheory/intro/index.html b/previews/PR2578/InvariantTheory/intro/index.html deleted file mode 100644 index 4b2874e0b3ce..000000000000 --- a/previews/PR2578/InvariantTheory/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The invariant theory part of OSCAR provides functionality for computing polynomial invariants of group actions, focusing on finite and linearly reductive groups, respectively.

The basic setting in this context consists of a group $G$, a field $K$, a vector space $V$ over $K$ of finite dimension $n,$ and a representation $\rho: G \to \text{GL}(V)$ of $G$ on $V$. The induced action on the dual vector space $V^\ast$,

\[V^\ast \times G \to V^\ast, (f, \pi)\mapsto f \;\! . \;\! \pi := f\circ \rho(\pi),\]

extends to an action of $G$ on the graded symmetric algebra

\[K[V]:=S(V^*)=\bigoplus_{d\geq 0} S^d V^*\]

which preserves the grading.

The invariants of $G$ are the fixed points of this action, its invariant ring is the graded subalgebra

\[K[V]^G:=\{f\in K[V] \mid f \;\! . \;\! \pi =f {\text { for any }} \pi\in G\} \subset K[V].\]

Explicitly, the choice of a basis of $V$ and its dual basis, say, $\{x_1, \dots, x_n\}$ of $V^*$ gives rise to isomorphisms $\text{GL}(V) \cong \text{GL}_n(K)$ and $K[V]\cong K[x_1, \dots, x_n]$. After identifying $\text{GL}(V)$ with $\text{GL}_n(K)$ and $K[V]$ with $K[x_1, \dots, x_n]$ by means of these isomorphisms, the action of $G$ on $K[V]$ is given as follows:

\[(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f((x_1, \dots, x_n) \cdot \rho(\pi)).\]

Accordingly, $K[V]^G$ may be regarded as a graded subalgebra of $K[x_1, \dots, x_n]$:

\[K[V]^G \cong K[x_1, \dots, x_n]^G :=\{f\in K[x_1, \dots, x_n] \mid f \;\! . \;\! \pi =f {\text { for any }} \pi\in G\}.\]

The main objective of invariant theory in OSCAR is the computation of $K$-algebra generators for invariant rings.

Note

If $K[V]^G$ is finitely generated as a $K$-algebra, then any minimal system of homogeneous generators is called a fundamental system of invariants for $K[V]^G$. By Nakayama's lemma, the number of elements in such a system is uniquely determined as the embedding dimension of $K[V]^G$. Similarly, the degrees of these elements are uniquely determined.

Note

If $K[V]^G$ is finitely generated as a $K$-algebra, then $K[V]^G$ admits a graded Noether normalization, that is, a Noether normalization $K[p_1, \dots, p_m] \subset K[V]^G$ with $p_1, \dots, p_m$ homogeneous. Given any such Noether normalization, $p_1, \dots, p_m$ is called a homogeneous system of parameters or a system of primary invariants for $K[V]^G$, and any minimal system $s_0=1, s_1,\dots, s_l$ of homogeneous generators of $K[V]^G$ as a $K[p_1, \dots, p_m]$-module is called a system of secondary invariants for $K[V]^G$ with respect to $p_1, \dots, p_m$. A secondary invariant $s_i\neq 1$ is called irreducible if it cannot be written as a polynomial expression in the primary invariants and the other secondary invariants. The irreducible secondary invariants form a minimal system of homogeneous generators for $K[V]^G$ as a $K[p_1, \dots, p_m]$-algebra. Somewhat abusing notation, we call every minimal system of homogeneous generators for $K[V]^G$ as a $K[p_1, \dots, p_m]$-algebra a system of irreducible secondary invariants.

Note

For the invariant rings handled by OSCAR, the assumption that $K[V]^G$ is finitely generated as a $K$-algebra will be guaranteed by theoretical results. In addition, where not mentioned otherwise, the following will hold:

  • There exists a Reynolds operator $\mathcal R: K[V] \to K[V]$. That is, $\mathcal R$ is a $K$-linear graded map which projects $K[V]$ onto $K[V]^G$, and which is a $K[V]^G$-module homomorphism.
  • The ring $K[V]^G$ is Cohen-Macaulay. Equivalently, $K[V]^G$ is a free module (of finite rank) over any of its graded Noether normalizations.

The textbook

and the survey article

provide details on theory and algorithms as well as references.

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/InvariantTheory/reductive_groups/index.html b/previews/PR2578/InvariantTheory/reductive_groups/index.html deleted file mode 100644 index 4c132e4f9026..000000000000 --- a/previews/PR2578/InvariantTheory/reductive_groups/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Invariants of Linearly Reductive Groups · Oscar.jl

Invariants of Linearly Reductive Groups

In this section, with notation as in the introduction to this chapter, $G$ will be a linearly algebraic group over an algebraically closed field $K$, and $\rho: G \to \text{GL}(V)\cong \text{GL}_n(K)$ will be a rational representation of $G$. As in the previous sections, $G$ will act on $K[V]\cong K[x_1, \dots, x_n]$ by linear substitution:

\[(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f((x_1, \dots, x_n) \cdot \rho(\pi)) \text{ for all } \pi\in G.\]

Note
  • The definition of linear reductivity guarantees the existence of a Reynolds operator $\mathcal R: K[V] \to K[V]$.
  • By Hilbert's celebrated finiteness theorem, $K[V]^G$ is finitely generated as a $K$-algebra.
  • By a result of Hochster and Roberts, $K[V]^G$ is Cohen-Macaulay.

In cases where the Reynold's operator can be explicitly handled, generators of invariant rings of linearly reductive groups can be found in two steps using Derksen's algorithm, see Harm Derksen (1999) :

  • First, compute generators of Hilbert's null-cone ideal.
  • Then, apply the Reynold's operator to these generators.

See also Harm Derksen, Gregor Kemper (2015) and Wolfram Decker, Theo de Jong (1998).

Creating Invariant Rings

There are no exact means to handle algebraically closed fields on the computer. For the computation of invariant rings in the above setting, on the other hand, there is no need to deal with explicit elements of $G$ or with its group structure. The implementation of Derksen's algorithm in OSCAR can handle situations where both $G$ and the representation $\rho$ are defined over an exact subfield $k$ of $K$ which is supported by OSCAR:

  • $G$ is specified as an affine algebraic variety by polynomials with coefficients in $k$;
  • $\rho: G \to \text{GL}(V) \cong \text{GL}_n(K)$ is specified by an $n\times n$ matrix whose entries are polynomials in the same variables as those specifying $G$, with coefficients in $k$.

All computations are then performed over $k$.

Warning

OSCAR does neither check whether the affine variety defined by the given equations carries a group structure which makes it a linearly reductive group nor does it check whether the given $n\times n$ matrix really defines a representation.

Basic Data Associated to Invariant Rings

The Reynolds Operator

Omega-process

Generators of Hilbert's Null-Cone Ideal

Generators of the Invariant Ring

Fundamental Systems of Invariants

Invariant Rings as Affine Algebras

diff --git a/previews/PR2578/LinearAlgebra/intro/index.html b/previews/PR2578/LinearAlgebra/intro/index.html deleted file mode 100644 index 3e07ea9d134a..000000000000 --- a/previews/PR2578/LinearAlgebra/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The linear algebra part of OSCAR provides functionality for handling

  • vectors and matrices
  • modules and vector spaces,
  • vector spaces over fields
  • matrix spaces and matrix algebras

General textbooks offering details on theory and algorithms include:

  • ...

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/Nemo/about/index.html b/previews/PR2578/Nemo/about/index.html deleted file mode 100644 index 7a8f2d2610bd..000000000000 --- a/previews/PR2578/Nemo/about/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -About Nemo · Oscar.jl

About Nemo

Nemo is a library for fast basic arithmetic in various commonly used rings, for the Julia programming language. Our aim is to provide a highly performant package covering

  • Commutative Algebra
  • Number Theory
  • Group Theory

Nemo consists of wrappers of specialised C/C++ libraries:

Nemo also uses AbstractAlgebra.jl to provide generic constructions over the basic rings provided by the above packages.

Why Julia?

Julia is a sophisticated, modern programming language which is designed to be both performant and flexible. It was written by mathematicians, for mathematicians.

The benefits of Julia include

  • Familiar imperative syntax
  • JIT compilation (provides near native performance, even for highly generic code)
  • REPL console (cuts down on development time)
  • Parametric types (allows for fast generic constructions over other data types)
  • Powerful metaprogramming facilities
  • Operator overloading
  • Multiple dispatch (dispatch on every argument of a function)
  • Efficient native C interface (little or no wrapper overhead)
  • Experimental C++ interface
  • Dynamic type inference
  • Built-in bignums
  • Able to be embedded in C programs
  • High performance collection types (dictionaries, iterators, arrays, etc.)
  • Jupyter support (for web based notebooks)

The main benefits for Nemo are the parametric type system and JIT compilation. The former allows us to model many mathematical types, e.g. generic polynomial rings over an arbitrary base ring. The latter speeds up the runtime performance, even of highly generic mathematical procedures.

diff --git a/previews/PR2578/Nemo/acb/index.html b/previews/PR2578/Nemo/acb/index.html deleted file mode 100644 index 151694beae55..000000000000 --- a/previews/PR2578/Nemo/acb/index.html +++ /dev/null @@ -1,184 +0,0 @@ - -Fixed precisioncomplex balls · Oscar.jl

Fixed precisioncomplex balls

Arbitrary precision complex ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Complex numbers are represented in rectangular form $a+bi$ where $a,b$ are arb balls.

The Arb complex field is constructed using the AcbField constructor. This constructs the parent object for the Arb complex field.

The types of complex boxes in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Arb$\mathbb{C}$ (boxes)acbAcbField

All the complex field types belong to the Field abstract type and the types of elements in this field, i.e. complex boxes in this case, belong to the FieldElem abstract type.

Complex ball functionality

The complex balls in Nemo provide all the field functionality defined by AbstractAlgebra:.

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document the additional functionality provided for complex balls.

Complex field constructors

In order to construct complex boxes in Nemo, one must first construct the Arb complex field itself. This is accomplished with the following constructor.

AcbField(prec::Int)

Return the Arb complex field with precision in bits prec used for operations on interval midpoints. The precision used for interval radii is a fixed implementation-defined constant (30 bits).

Here is an example of creating an Arb complex field and using the resulting parent object to coerce values into the resulting field.

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> a = CC("0.25")
-0.25000000000000000000
-
-julia> b = CC("0.1")
-[0.100000000000000000 +/- 1.22e-20]
-
-julia> c = CC(0.5)
-0.50000000000000000000
-
-julia> d = CC(12)
-12.000000000000000000

Note that whilst one can coerce double precision floating point values into an Arb complex field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.

If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb complex field.

If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.

Constructors

oneiMethod
onei(r::AcbField)

Return exact one times $i$ in the given Arb complex field.

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> c = onei(CC)
-1.0000000000000000000*im

Basic functionality

The following basic functionality is provided by the default Arb complex field implementation in Nemo, to support construction of generic rings over complex fields. Any custom complex field implementation in Nemo should provide analogues of these functions along with the usual arithmetic operations.

parent_type(::Type{acb})

Gives the type of the parent object of an Arb complex field element.

elem_type(R::AcbField)

Given the parent object for an Arb complex field, return the type of elements of the field.

mul!(c::acb, a::acb, b::acb)

Multiply $a$ by $b$ and set the existing Arb complex field element $c$ to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.

addeq!(c::acb, a::acb)

In-place addition adds $a$ to $c$ and sets $c$ to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.

deepcopy(a::acb)

Return a copy of the Arb complex field element $a$, recursively copying the internal data. Arb complex field elements are mutable in Nemo so a shallow copy is not sufficient.

Given the parent object R for an Arb complex field, the following coercion functions are provided to coerce various elements into the Arb complex field. Developers provide these by overloading the call operator for the complex field parent objects.

R()

Coerce zero into the Arb complex field.

R(n::Integer)
-R(f::ZZRingElem)
-R(q::QQFieldElem)

Coerce an integer or rational value into the Arb complex field.

R(f::Float64)
-R(f::BigFloat)

Coerce the given floating point number into the Arb complex field.

R(f::AbstractString)
-R(f::AbstractString, g::AbstractString)

Coerce the decimal number, given as a string, into the Arb complex field. In each case $f$ is the real part and $g$ is the imaginary part.

R(f::arb)

Coerce the given Arb real ball into the Arb complex field.

R(f::acb)

Take an Arb complex field element that is already in an Arb field and simply return it. A copy of the original is not made.

Here are some examples of coercing elements into the Arb complex field.

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> a = CC(3)
-3.0000000000000000000
-
-julia> b = CC(QQ(2,3))
-[0.6666666666666666666 +/- 8.48e-20]
-
-julia> c = CC("3 +/- 0.0001")
-[3.000 +/- 1.01e-4]
-
-julia> d = CC("-1.24e+12345")
-[-1.240000000000000000e+12345 +/- 1.16e+12326]
-
-julia> f = CC("nan +/- inf")
-nan
-
-julia> g = CC(RR(3))
-3.0000000000000000000

In addition to the above, developers of custom complex field types must ensure that they provide the equivalent of the function base_ring(R::AcbField) which should return Union{}. In addition to this they should ensure that each complex field element contains a field parent specifying the parent object of the complex field element, or at least supply the equivalent of the function parent(a::acb) to return the parent object of a complex field element.

Basic manipulation

isfiniteMethod
isfinite(x::acb)

Return true if $x$ is finite, i.e. its real and imaginary parts have finite midpoint and radius, otherwise return false.

is_exactMethod
is_exact(x::acb)

Return true if $x$ is exact, i.e. has its real and imaginary parts have zero radius, otherwise return false.

isintegerMethod
isinteger(x::acb)

Return true if $x$ is an exact integer, otherwise return false.

accuracy_bitsMethod
accuracy_bits(x::acb)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> a = CC("1.2 +/- 0.001")
-[1.20 +/- 1.01e-3]
-
-julia> b = CC(3)
-3.0000000000000000000
-
-julia> isreal(a)
-true
-
-julia> isfinite(b)
-true
-
-julia> isinteger(b)
-true
-
-julia> c = real(a)
-[1.20 +/- 1.01e-3]
-
-julia> d = imag(b)
-0
-
-julia> f = accuracy_bits(a)
-9
-

Containment

It is often necessary to determine whether a given exact value or box is contained in a given complex box or whether two boxes overlap. The following functions are provided for this purpose.

overlapsMethod
overlaps(x::acb, y::acb)

Returns true if any part of the box $x$ overlaps any part of the box $y$, otherwise return false.

containsMethod
contains(x::acb, y::acb)

Returns true if the box $x$ contains the box $y$, otherwise return false.

containsMethod
contains(x::acb, y::Integer)

Returns true if the box $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::acb, y::ZZRingElem)

Returns true if the box $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::acb, y::QQFieldElem)

Returns true if the box $x$ contains the given rational value, otherwise return false.

The following functions are also provided for determining if a box intersects a certain part of the complex number plane.

contains_zeroMethod
contains_zero(x::acb)

Returns true if the box $x$ contains zero, otherwise return false.

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> x = CC("1 +/- 0.001")
-[1.00 +/- 1.01e-3]
-
-julia> y = CC("3")
-3.0000000000000000000
-
-julia> overlaps(x, y)
-false
-
-julia> contains(x, y)
-false
-
-julia> contains(y, 3)
-true
-
-julia> contains(x, ZZ(1)//2)
-false
-
-julia> contains_zero(x)
-false

Comparison

Nemo provides a full range of comparison operations for Arb complex boxes.

In addition to the standard comparisons, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.

isequalMethod
isequal(x::acb, y::acb)

Return true if the boxes $x$ and $y$ are precisely equal, i.e. their real and imaginary parts have the same midpoints and radii.

A full range of ad hoc comparison operators is provided. These are implemented directly in Julia, but we document them as though only == were provided.

Function
==(x::acb, y::Integer)
==(x::Integer, y::acb)
==(x::acb, y::ZZRingElem)
==(x::ZZRingElem, y::acb)
==(x::arb, y::ZZRingElem)
==(x::ZZRingElem, y::arb)
==(x::acb, y::Float64)
==(x::Float64, y::acb)

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> x = CC("1 +/- 0.001")
-[1.00 +/- 1.01e-3]
-
-julia> y = CC("3")
-3.0000000000000000000
-
-julia> z = CC("4")
-4.0000000000000000000
-
-julia> isequal(x, deepcopy(x))
-true
-
-julia> x == 3
-false
-
-julia> ZZ(3) == z
-false
-
-julia> x != 1.23
-true

Absolute value

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> x = CC("-1 +/- 0.001")
-[-1.00 +/- 1.01e-3]
-
-julia> a = abs(x)
-[1.00 +/- 1.01e-3]

Shifting

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> x = CC("-3 +/- 0.001")
-[-3.00 +/- 1.01e-3]
-
-julia> a = ldexp(x, 23)
-[-2.52e+7 +/- 4.26e+4]
-
-julia> b = ldexp(x, -ZZ(15))
-[-9.16e-5 +/- 7.78e-8]

Miscellaneous operations

trimMethod
trim(x::acb)

Return an acb box containing $x$ but which may be more economical, by rounding off insignificant bits from midpoints.

unique_integerMethod
unique_integer(x::acb)

Return a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the box $x$ contains a unique integer. If this is the case, the second return value is set to this unique integer.

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> x = CC("-3 +/- 0.001", "0.1")
-[-3.00 +/- 1.01e-3] + [0.100000000000000000 +/- 1.22e-20]*im
-
-julia> a = trim(x)
-[-3.00 +/- 1.01e-3] + [0.100000000000000000 +/- 1.22e-20]*im
-
-julia> b, c = unique_integer(x)
-(false, 0)
-
-julia> d = conj(x)
-[-3.00 +/- 1.01e-3] + [-0.100000000000000000 +/- 1.22e-20]*im
-
-julia> f = angle(x)
-[3.1083 +/- 3.95e-5]

Constants

const_piMethod
const_pi(r::AcbField)

Return $\pi = 3.14159\ldots$ as an element of $r$.

Examples

julia> CC = AcbField(200)
-Complex Field with 200 bits of precision and error bounds
-
-julia> a = const_pi(CC)
-[3.14159265358979323846264338327950288419716939937510582097494 +/- 5.73e-60]

Mathematical and special functions

rsqrtMethod
rsqrt(x::acb)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

cispiMethod
cispi(x::acb)

Return the exponential of $\pi i x$.

root_of_unityMethod
root_of_unity(C::AcbField, k::Int)

Return $\exp(2\pi i/k)$.

log_sinpiMethod
log_sinpi(x::acb)

Return $\log\sin(\pi x)$, constructed without branch cuts off the real line.

gammaMethod
gamma(x::acb)

Return the Gamma function evaluated at $x$.

lgammaMethod
lgamma(x::acb)

Return the logarithm of the Gamma function evaluated at $x$.

rgammaMethod
rgamma(x::acb)

Return the reciprocal of the Gamma function evaluated at $x$.

digammaMethod
digamma(x::acb)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

zetaMethod
zeta(x::acb)

Return the Riemann zeta function evaluated at $x$.

barnes_gMethod
barnes_g(x::acb)

Return the Barnes $G$-function, evaluated at $x$.

log_barnes_gMethod
log_barnes_g(x::acb)

Return the logarithm of the Barnes $G$-function, evaluated at $x$.

erfMethod
erf(x::acb)

Return the error function evaluated at $x$.

erfiMethod
erfi(x::acb)

Return the imaginary error function evaluated at $x$.

exp_integral_eiMethod
exp_integral_ei(x::acb)

Return the exponential integral evaluated at $x$.

sin_integralMethod
sin_integral(x::acb)

Return the sine integral evaluated at $x$.

cos_integralMethod
cos_integral(x::acb)

Return the exponential cosine integral evaluated at $x$.

sinh_integralMethod
sinh_integral(x::acb)

Return the hyperbolic sine integral evaluated at $x$.

cosh_integralMethod
cosh_integral(x::acb)

Return the hyperbolic cosine integral evaluated at $x$.

dedekind_etaMethod
dedekind_eta(x::acb)

Return the Dedekind eta function $\eta(\tau)$ at $\tau = x$.

modular_weber_fMethod
modular_weber_f(x::acb)

Return the modular Weber function $\mathfrak{f}(\tau) = \frac{\eta^2(\tau)}{\eta(\tau/2)\eta(2\tau)},$ at $x$ in the complex upper half plane.

modular_weber_f1Method
modular_weber_f1(x::acb)

Return the modular Weber function $\mathfrak{f}_1(\tau) = \frac{\eta(\tau/2)}{\eta(\tau)},$ at $x$ in the complex upper half plane.

modular_weber_f2Method
modular_weber_f2(x::acb)

Return the modular Weber function $\mathfrak{f}_2(\tau) = \frac{\sqrt{2}\eta(2\tau)}{\eta(\tau)}$ at $x$ in the complex upper half plane.

j_invariantMethod
j_invariant(x::acb)

Return the $j$-invariant $j(\tau)$ at $\tau = x$.

modular_lambdaMethod
modular_lambda(x::acb)

Return the modular lambda function $\lambda(\tau)$ at $\tau = x$.

modular_deltaMethod
modular_delta(x::acb)

Return the modular delta function $\Delta(\tau)$ at $\tau = x$.

eisenstein_gMethod
eisenstein_g(k::Int, x::acb)

Return the non-normalized Eisenstein series $G_k(\tau)$ of $\mathrm{SL}_2(\mathbb{Z})$. Also defined for $\tau = i \infty$.

elliptic_kMethod
elliptic_k(x::acb)

Return the complete elliptic integral $K(x)$.

elliptic_eMethod
elliptic_e(x::acb)

Return the complete elliptic integral $E(x)$.

agmMethod
agm(x::acb)

Return the arithmetic-geometric mean of $1$ and $x$.

agmMethod
agm(x::acb, y::acb)

Return the arithmetic-geometric mean of $x$ and $y$.

polygammaMethod
polygamma(s::acb, a::acb)

Return the generalised polygamma function $\psi(s,z)$.

zetaMethod
zeta(s::acb, a::acb)

Return the Hurwitz zeta function $\zeta(s,a)$.

rising_factorialMethod
rising_factorial(x::acb, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Acb.

rising_factorial2Method
rising_factorial2(x::acb, n::Int)

Return a tuple containing the rising factorial $x(x + 1)\ldots (x + n - 1)$ and its derivative.

polylogMethod
polylog(s::Union{acb,Int}, a::acb)

Return the polylogarithm Li$_s(a)$.

log_integralMethod
log_integral(x::acb)

Return the logarithmic integral, evaluated at $x$.

log_integral_offsetMethod
log_integral_offset(x::acb)

Return the offset logarithmic integral, evaluated at $x$.

exp_integral_eMethod
exp_integral_e(s::acb, x::acb)

Return the generalised exponential integral $E_s(x)$.

gammaMethod
gamma(s::acb, x::acb)

Return the upper incomplete gamma function $\Gamma(s,x)$.

gamma_regularizedMethod
gamma_regularized(s::acb, x::acb)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

gamma_lowerMethod
gamma_lower(s::acb, x::acb)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

gamma_lower_regularizedMethod
gamma_lower_regularized(s::acb, x::acb)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

airy_aiMethod
airy_ai(x::acb)

Return the Airy function $\operatorname{Ai}(x)$.

airy_ai_primeMethod
airy_ai_prime(x::acb)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

airy_biMethod
airy_bi(x::acb)

Return the Airy function $\operatorname{Bi}(x)$.

airy_bi_primeMethod
airy_bi_prime(x::acb)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

bessel_jMethod
bessel_j(nu::acb, x::acb)

Return the Bessel function $J_{\nu}(x)$.

bessel_yMethod
bessel_y(nu::acb, x::acb)

Return the Bessel function $Y_{\nu}(x)$.

bessel_iMethod
bessel_i(nu::acb, x::acb)

Return the Bessel function $I_{\nu}(x)$.

bessel_kMethod
bessel_k(nu::acb, x::acb)

Return the Bessel function $K_{\nu}(x)$.

hypergeometric_1f1Method
hypergeometric_1f1(a::acb, b::acb, x::acb)

Return the confluent hypergeometric function ${}_1F_1(a,b,x)$.

hypergeometric_1f1_regularizedMethod
hypergeometric_1f1_regularized(a::acb, b::acb, x::acb)

Return the regularized confluent hypergeometric function ${}_1F_1(a,b,x) / \Gamma(b)$.

hypergeometric_uMethod
hypergeometric_u(a::acb, b::acb, x::acb)

Return the confluent hypergeometric function $U(a,b,x)$.

hypergeometric_2f1Method
hypergeometric_2f1(a::acb, b::acb, c::acb, x::acb; flags=0)

Return the Gauss hypergeometric function ${}_2F_1(a,b,c,x)$.

jacobi_thetaMethod
jacobi_theta(z::acb, tau::acb)

Return a tuple of four elements containing the Jacobi theta function values $\theta_1, \theta_2, \theta_3, \theta_4$ evaluated at $z, \tau$.

weierstrass_pMethod
weierstrass_p(z::acb, tau::acb)

Return the Weierstrass elliptic function $\wp(z,\tau)$.

Examples

julia> CC = AcbField(64)
-Complex Field with 64 bits of precision and error bounds
-
-julia> s = CC(1, 2)
-1.0000000000000000000 + 2.0000000000000000000*im
-
-julia> z = CC("1.23", "3.45")
-[1.230000000000000000 +/- 2.00e-19] + [3.450000000000000000 +/- 3.91e-19]*im
-
-julia> a = sin(z)^2 + cos(z)^2
-[1.000000000000000 +/- 4.92e-16] + [+/- 4.12e-16]*im
-
-julia> b = zeta(z)
-[0.685803329024164062 +/- 6.30e-19] + [-0.038574782404586856 +/- 7.54e-19]*im
-
-julia> c = bessel_j(s, z)
-[0.63189634741402481 +/- 4.85e-18] + [0.00970090757446076 +/- 4.66e-18]*im
-
-julia> d = hypergeometric_1f1(s, s+1, z)
-[-1.3355297330012291 +/- 5.83e-17] + [-0.1715020340928697 +/- 4.97e-17]*im

Linear dependence

lindepMethod
lindep(A::Vector{acb}, bits::Int)

Find a small linear combination of the entries of the array $A$ that is small (using LLL). The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find linear dependence between a list of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.

lindepMethod
lindep(A::Matrix{acb}, bits::Int)

Find a (common) small linear combination of the entries in each row of the array $A$, that is small (using LLL). It is assumed that the complex numbers in each row of the array share the same linear combination. The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find a common linear dependence shared across a number of lists of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the common linear combination.

Examples

CC = AcbField(128)
-
-# These are two of the roots of x^5 + 3x + 1
-a = CC(1.0050669478588622428791051888364775253, - 0.93725915669289182697903585868761513585)
-b = CC(-0.33198902958450931620250069492231652319)
-
-# We recover the polynomial from one root....
-V1 = [CC(1), a, a^2, a^3, a^4, a^5];
-W = lindep(V1, 20)
-
-# ...or from two
-V2 = [CC(1), b, b^2, b^3, b^4, b^5];
-Vs = [V1 V2]
-X = lindep(Vs, 20)
diff --git a/previews/PR2578/Nemo/algebraic/index.html b/previews/PR2578/Nemo/algebraic/index.html deleted file mode 100644 index c606f0b7682e..000000000000 --- a/previews/PR2578/Nemo/algebraic/index.html +++ /dev/null @@ -1,92 +0,0 @@ - -Algebraic numbers · Oscar.jl

Algebraic numbers

Nemo allows working with exact real and complex algebraic numbers.

The default algebraic number type in Nemo is provided by Calcium. The associated field of algebraic numbers is represented by the constant parent object called CalciumQQBar.

For convenience we define

QQBar = CalciumQQBar

so that algebraic numbers can be constructed using QQBar instead of CalciumQQBar. Note that this is the name of a specific parent object, not the name of its type.

LibraryElement typeParent type
CalciumqqbarCalciumQQBarField

Important note on performance

The default algebraic number type represents algebraic numbers in canonical form using minimal polynomials. This works well for representing individual algebraic numbers, but it does not provide the best performance for field arithmetic. For fast calculation in $\overline{\mathbb{Q}}$, CalciumField should typically be used instead (see the section on Exact real and complex numbers). Alternatively, to compute in a fixed subfield of $\overline{\mathbb{Q}}$, you may fix a generator $a$ and construct an Antic number field to represent $\mathbb{Q}(a)$.

Algebraic number functionality

Constructing algebraic numbers

Methods to construct algebraic numbers include:

  • Conversion from other numbers and through arithmetic operations
  • Computing the roots of a given polynomial
  • Computing the eigenvalues of a given matrix
  • Random generation
  • Exact trigonometric functions (see later section)
  • Guessing (see later section)

Examples

Arithmetic:

julia> ZZRingElem(QQBar(3))
-3
-
-julia> QQFieldElem(QQBar(3) // 2)
-3//2
-
-julia> QQBar(-1) ^ (QQBar(1) // 3)
-Root 0.500000 + 0.866025*im of x^2 - x + 1

Solving the quintic equation:

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over QQ, x)
-
-julia> v = roots(QQBar, x^5-x-1)
-5-element Vector{qqbar}:
- Root 1.16730 of x^5 - x - 1
- Root 0.181232 + 1.08395*im of x^5 - x - 1
- Root 0.181232 - 1.08395*im of x^5 - x - 1
- Root -0.764884 + 0.352472*im of x^5 - x - 1
- Root -0.764884 - 0.352472*im of x^5 - x - 1
-
-julia> v[1]^5 - v[1] - 1 == 0
-true

Computing exact eigenvalues of a matrix:

julia> eigenvalues(ZZ[1 1 0; 0 1 1; 1 0 1], QQBar)
-3-element Vector{qqbar}:
- Root 2.00000 of x - 2
- Root 0.500000 + 0.866025*im of x^2 - x + 1
- Root 0.500000 - 0.866025*im of x^2 - x + 1

Interface

rootsMethod
roots(R::CalciumQQBarField, f::ZZPolyRingElem)

Return all the roots of the polynomial f in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Roots of multiplicity higher than one are repeated according to their multiplicity.

rootsMethod
roots(R::CalciumQQBarField, f::QQPolyRingElem)

Return all the roots of the polynomial f in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Roots of multiplicity higher than one are repeated according to their multiplicity.

eigenvaluesMethod
eigenvalues(A::ZZMatrix, R::CalciumQQBarField)

Return all the eigenvalues of the matrix A in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Eigenvalues of multiplicity higher than one are repeated according to their multiplicity.

eigenvaluesMethod
eigenvalues(A::QQMatrix, R::CalciumQQBarField)

Return all the eigenvalues of the matrix A in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Eigenvalues of multiplicity higher than one are repeated according to their multiplicity.

randMethod
rand(R::CalciumQQBarField; degree::Int, bits::Int, randtype::Symbol=:null)

Return a random algebraic number with degree up to degree and coefficients up to bits in size. By default, both real and complex numbers are generated. Set the optional randtype to :real or :nonreal to generate a specific type of number. Note that nonreal numbers require degree at least 2.

Numerical evaluation

Examples

Algebraic numbers can be evaluated numerically to arbitrary precision by converting to real or complex Arb fields:

julia> RR = ArbField(64); RR(sqrt(QQBar(2)))
-[1.414213562373095049 +/- 3.45e-19]
-
-julia> CC = AcbField(32); CC(QQBar(-1) ^ (QQBar(1) // 4))
-[0.707106781 +/- 2.74e-10] + [0.707106781 +/- 2.74e-10]*im

Minimal polynomials, conjugates, and properties

Examples

Retrieving the minimal polynomial and algebraic conjugates of a given algebraic number:

julia> minpoly(polynomial_ring(ZZ, "x")[1], QQBar(1+2im))
-x^2 - 2*x + 5
-
-julia> conjugates(QQBar(1+2im))
-2-element Vector{qqbar}:
- Root 1.00000 + 2.00000*im of x^2 - 2x + 5
- Root 1.00000 - 2.00000*im of x^2 - 2x + 5

Interface

iszeroMethod
iszero(x::qqbar)

Return whether x is the number 0.

isoneMethod
isone(x::qqbar)

Return whether x is the number 1.

isintegerMethod
isinteger(x::qqbar)

Return whether x is an integer.

is_rationalMethod
is_rational(x::qqbar)

Return whether x is a rational number.

isrealMethod
isreal(x::qqbar)

Return whether x is a real number.

degreeMethod
degree(x::qqbar)

Return the degree of the minimal polynomial of x.

is_algebraic_integerMethod
is_algebraic_integer(x::qqbar)

Return whether x is an algebraic integer.

minpolyMethod
minpoly(R::ZZPolyRing, x::qqbar)

Return the minimal polynomial of x as an element of the polynomial ring R.

minpolyMethod
minpoly(R::ZZPolyRing, x::qqbar)

Return the minimal polynomial of x as an element of the polynomial ring R.

conjugatesMethod
conjugates(a::qqbar)

Return all the roots of the polynomial f in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers.

denominatorMethod
denominator(x::qqbar)

Return the denominator of x, defined as the leading coefficient of the minimal polynomial of x. The result is returned as an ZZRingElem.

numeratorMethod
numerator(x::qqbar)

Return the numerator of x, defined as x multiplied by its denominator. The result is an algebraic integer.

heightMethod
height(x::qqbar)

Return the height of the algebraic number x. The result is an ZZRingElem integer.

height_bitsMethod
height_bits(x::qqbar)

Return the height of the algebraic number x measured in bits. The result is a Julia integer.

Complex parts

Examples

julia> real(sqrt(QQBar(1im)))
-Root 0.707107 of 2x^2 - 1
-
-julia> abs(sqrt(QQBar(1im)))
-Root 1.00000 of x - 1
-
-julia> floor(sqrt(QQBar(1000)))
-Root 31.0000 of x - 31
-
-julia> sign(QQBar(-10-20im))
-Root -0.447214 - 0.894427*im of 5x^4 + 6x^2 + 5

Interface

realMethod
real(a::qqbar)

Return the real part of a.

imagMethod
imag(a::qqbar)

Return the imaginary part of a.

absMethod
abs(a::qqbar)

Return the absolute value of a.

abs2Method
abs2(a::qqbar)

Return the squared absolute value of a.

conjMethod
conj(a::qqbar)

Return the complex conjugate of a.

signMethod
sign(a::qqbar)

Return the complex sign of a, defined as zero if a is zero and as $a / |a|$ otherwise.

csgnMethod
csgn(a::qqbar)

Return the extension of the real sign function taking the value 1 strictly in the right half plane, -1 strictly in the left half plane, and the sign of the imaginary part when on the imaginary axis. Equivalently, $\operatorname{csgn}(x) = x / \sqrt{x^2}$ except that the value is 0 at zero. The value is returned as a Julia integer.

sign_realMethod
sign_real(a::qqbar)

Return the sign of the real part of a as a Julia integer.

sign_imagMethod
sign_imag(a::qqbar)

Return the sign of the imaginary part of a as a Julia integer.

floorMethod
floor(a::qqbar)

Return the floor function of a as an algebraic number. Use ZZRingElem(floor(a)) to construct a Nemo integer instead.

ceilMethod
ceil(a::qqbar)

Return the ceiling function of b as an algebraic number. Use ZZRingElem(ceil(a)) to construct a Nemo integer instead.

Comparing algebraic numbers

The operators == and != check exactly for equality.

We provide various comparison functions for ordering algebraic numbers:

  • Standard comparison for real numbers (<, isless)
  • Real parts
  • Imaginary parts
  • Absolute values
  • Absolute values of real or imaginary parts
  • Root sort order

The standard comparison will throw if either argument is nonreal.

The various comparisons for complex parts are provided as separate operations since these functions are far more efficient than explicitly computing the complex parts and then doing real comparisons.

The root sort order is a total order for complex algebraic numbers used to order the output of roots and conjugates canonically. We define this order as follows: real roots come first, in descending order. Nonreal roots are subsequently ordered first by real part in descending order, then in ascending order by the absolute value of the imaginary part, and then in descending order of the sign of the imaginary part. This implies that complex conjugate roots are adjacent, with the root in the upper half plane first.

Examples

julia> 1 < sqrt(QQBar(2)) < QQBar(3)//2
-true
-
-julia> x = QQBar(3+4im)
-Root 3.00000 + 4.00000*im of x^2 - 6x + 25
-
-julia> is_equal_abs(x, -x)
-true
-
-julia> is_equal_abs_imag(x, 2-x)
-true
-
-julia> is_less_real(x, x // 2)
-false

Interface

is_equal_realMethod
is_equal_real(a::qqbar, b::qqbar)

Compares the real parts of a and b.

is_equal_imagMethod
is_equal_imag(a::qqbar, b::qqbar)

Compares the imaginary parts of a and b.

is_equal_absMethod
is_equal_abs(a::qqbar, b::qqbar)

Compares the absolute values of a and b.

is_equal_abs_realMethod
is_equal_abs_real(a::qqbar, b::qqbar)

Compares the absolute values of the real parts of a and b.

is_equal_abs_imagMethod
is_equal_abs_imag(a::qqbar, b::qqbar)

Compares the absolute values of the imaginary parts of a and b.

is_less_realMethod
is_less_real(a::qqbar, b::qqbar)

Compares the real parts of a and b.

is_less_imagMethod
is_less_imag(a::qqbar, b::qqbar)

Compares the imaginary parts of a and b.

is_less_absMethod
is_less_abs(a::qqbar, b::qqbar)

Compares the absolute values of a and b.

is_less_abs_realMethod
is_less_abs_real(a::qqbar, b::qqbar)

Compares the absolute values of the real parts of a and b.

is_less_abs_imagMethod
is_less_abs_imag(a::qqbar, b::qqbar)

Compares the absolute values of the imaginary parts of a and b.

is_less_root_orderMethod
is_less_root_order(a::qqbar, b::qqbar)

Compares the a and b in root sort order.

Roots and trigonometric functions

Examples

julia> root(QQBar(2), 5)
-Root 1.14870 of x^5 - 2
-
-julia> sinpi(QQBar(7) // 13)
-Root 0.992709 of 4096x^12 - 13312x^10 + 16640x^8 - 9984x^6 + 2912x^4 - 364x^2 + 13
-
-julia> tanpi(atanpi(sqrt(QQBar(2)) + 1))
-Root 2.41421 of x^2 - 2x - 1
-
-julia> root_of_unity(QQBar, 5)
-Root 0.309017 + 0.951057*im of x^4 + x^3 + x^2 + x + 1
-
-julia> root_of_unity(QQBar, 5, 4)
-Root 0.309017 - 0.951057*im of x^4 + x^3 + x^2 + x + 1
-
-julia> w = (1 - sqrt(QQBar(-3)))//2
-Root 0.500000 - 0.866025*im of x^2 - x + 1
-
-julia> is_root_of_unity(w)
-true
-
-julia> is_root_of_unity(w + 1)
-false
-
-julia> root_of_unity_as_args(w)
-(6, 5)

Interface

sqrtMethod
sqrt(a::qqbar; check::Bool=true)

Return the principal square root of a.

rootMethod
root(a::qqbar, n::Int)

Return the principal n-th root of a. Requires positive n.

root_of_unityMethod
root_of_unity(C::CalciumQQBarField, n::Int)

Return the root of unity $e^{2 \pi i / n}$ as an element of the field of algebraic numbers C.

root_of_unityMethod
root_of_unity(C::CalciumQQBarField, n::Int, k::Int)

Return the root of unity $e^{2 \pi i k / n}$ as an element of the field of algebraic numbers C.

is_root_of_unityMethod
is_root_of_unity(a::qqbar)

Return whether the given algebraic number is a root of unity.

root_of_unity_as_argsMethod
root_of_unity_as_args(a::qqbar)

Return a pair of integers (q, p) such that the given a equals $e^{2 \pi i p / q}$. The denominator q will be minimal, with $0 \le p < q$. Throws if a is not a root of unity.

exp_pi_iMethod
exp_pi_i(a::qqbar)

Return $e^{\pi i a}$ as an algebraic number. Throws if this value is transcendental.

log_pi_iMethod
log_pi_i(a::qqbar)

Return $\log(a) / (\pi i)$ as an algebraic number. Throws if this value is transcendental or undefined.

sinpiMethod
sinpi(a::qqbar)

Return $\sin(\pi a)$ as an algebraic number. Throws if this value is transcendental.

cospiMethod
cospi(a::qqbar)

Return $\cos(\pi a)$ as an algebraic number. Throws if this value is transcendental.

tanpiMethod
tanpi(a::qqbar)

Return $\tan(\pi a)$ as an algebraic number. Throws if this value is transcendental or undefined.

asinpiMethod
asinpi(a::qqbar)

Return $\operatorname{asin}(a) / \pi$ as an algebraic number. Throws if this value is transcendental.

acospiMethod
acospi(a::qqbar)

Return $\operatorname{acos}(a) / \pi$ as an algebraic number. Throws if this value is transcendental.

atanpiMethod
atanpi(a::qqbar)

Return $\operatorname{atan}(a) / \pi$ as an algebraic number. Throws if this value is transcendental or undefined.

Guessing

Examples

An algebraic number can be recovered from a numerical value:

julia> RR = ArbField(53); guess(QQBar, RR("1.41421356 +/- 1e-6"), 2)
-Root 1.41421 of x^2 - 2

Warning: the input should be an enclosure. If you have a floating-point approximation, you should add an error estimate; otherwise, the only algebraic number that can be guessed is the binary floating-point number itself.

julia> RR = ArbField(128);
-
-julia> x = RR(0.1);       # note: 53-bit binary approximation of 1//10 without radius
-
-julia> guess(QQBar, x, 1)
-Root 0.100000 of 36028797018963968x - 3602879701896397
-
-julia> guess(QQBar, x + RR("+/- 1e-10"), 1)
-Root 0.100000 of 10x - 1

Interface

guessFunction
guess(R::CalciumQQBarField, x::acb, maxdeg::Int, maxbits::Int=0)

Try to reconstruct an algebraic number from a given numerical enclosure x. The algorithm looks for candidates up to degree maxdeg and with coefficients up to size maxbits (which defaults to the precision of x if not given). Throws if no suitable algebraic number can be found.

Guessing typically requires high precision to succeed, and it does not make much sense to call this function with input precision smaller than $O(maxdeg \cdot maxbits)$. If this function succeeds, then the output is guaranteed to be contained in the enclosure x, but failure does not prove that such an algebraic number with the specified parameters does not exist.

This function does a single iteration with the target parameters. For best performance, one should invoke this function repeatedly with successively larger parameters when the size of the intended solution is unknown or may be much smaller than a worst-case bound.

guessFunction
guess(R::CalciumQQBarField, x::acb, maxdeg::Int, maxbits::Int=0)

Try to reconstruct an algebraic number from a given numerical enclosure x. The algorithm looks for candidates up to degree maxdeg and with coefficients up to size maxbits (which defaults to the precision of x if not given). Throws if no suitable algebraic number can be found.

Guessing typically requires high precision to succeed, and it does not make much sense to call this function with input precision smaller than $O(maxdeg \cdot maxbits)$. If this function succeeds, then the output is guaranteed to be contained in the enclosure x, but failure does not prove that such an algebraic number with the specified parameters does not exist.

This function does a single iteration with the target parameters. For best performance, one should invoke this function repeatedly with successively larger parameters when the size of the intended solution is unknown or may be much smaller than a worst-case bound.

diff --git a/previews/PR2578/Nemo/arb/index.html b/previews/PR2578/Nemo/arb/index.html deleted file mode 100644 index c9659d8007cf..000000000000 --- a/previews/PR2578/Nemo/arb/index.html +++ /dev/null @@ -1,115 +0,0 @@ - -Fixed precision real balls · Oscar.jl

Fixed precision real balls

Fixed precision real ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Real numbers are represented in mid-rad interval form $[m \pm r] = [m-r, m+r]$.

The Arb real field is constructed using the ArbField constructor. This constructs the parent object for the Arb real field.

The types of real balls in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Arb$\mathbb{R}$ (balls)arbArbField

All the real field types belong to the Field abstract type and the types of elements in this field, i.e. balls in this case, belong to the FieldElem abstract type.

Real ball functionality

Real balls in Nemo provide all the field functionality described in AbstractAlgebra:

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document the additional functionality provided for real balls.

Constructors

In order to construct real balls in Nemo, one must first construct the Arb real field itself. This is accomplished with the following constructor.

ArbField(prec::Int)

Return the Arb field with precision in bits prec used for operations on interval midpoints. The precision used for interval radii is a fixed implementation-defined constant (30 bits).

Here is an example of creating an Arb real field and using the resulting parent object to coerce values into the resulting field.

Examples

RR = ArbField(64)
-
-a = RR("0.25")
-b = RR("0.1 +/- 0.001")
-c = RR(0.5)
-d = RR(12)

Note that whilst one can coerce double precision floating point values into an Arb real field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.

If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb field.

If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.

Real ball constructors

ballMethod
ball(x::arb, y::arb)

Constructs an Arb ball enclosing $x_m \pm (|x_r| + |y_m| + |y_r|)$, given the pair $(x, y) = (x_m \pm x_r, y_m \pm y_r)$.

Examples

RR = ArbField(64)
-
-c = ball(RR(3), RR("0.0001"))

Conversions

RR = ArbField(64)
-
-convert(Float64, RR(1//3))

Basic manipulation

is_nonzeroMethod
is_nonzero(x::arb)

Return true if $x$ is certainly not equal to zero, otherwise return false.

isfiniteMethod
isfinite(x::arb)

Return true if $x$ is finite, i.e. having finite midpoint and radius, otherwise return false.

is_exactMethod
is_exact(x::arb)

Return true if $x$ is exact, i.e. has zero radius, otherwise return false.

isintegerMethod
isinteger(x::arb)

Return true if $x$ is an exact integer, otherwise return false.

is_positiveMethod
is_positive(x::arb)

Return true if $x$ is certainly positive, otherwise return false.

is_nonnegativeMethod
is_nonnegative(x::arb)

Return true if $x$ is certainly nonnegative, otherwise return false.

is_negativeMethod
is_negative(x::arb)

Return true if $x$ is certainly negative, otherwise return false.

is_nonpositiveMethod
is_nonpositive(x::arb)

Return true if $x$ is certainly nonpositive, otherwise return false.

midpointMethod
midpoint(x::arb)

Return the midpoint of the ball $x$ as an Arb ball.

radiusMethod
radius(x::arb)

Return the radius of the ball $x$ as an Arb ball.

accuracy_bitsMethod
accuracy_bits(x::arb)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

Examples

RR = ArbField(64)
-
-a = RR("1.2 +/- 0.001")
-b = RR(3)
-
-is_positive(a)
-isfinite(b)
-isinteger(b)
-is_negative(a)
-c = radius(a)
-d = midpoint(b)
-f = accuracy_bits(a)

Printing

Printing real balls can at first sight be confusing. Lets look at the following example:

RR = ArbField(64)
-
-a = RR(1)
-b = RR(2)
-c = RR(12)
-
-x = ball(a, b)
-y = ball(c, b)
-
-mid = midpoint(x)
-rad = radius(x)
-
-print(x, "\n", y, "\n", mid, "\n", rad)

which generates

[+/- 3.01]
-[1e+1 +/- 4.01]
-1.0000000000000000000
-[2.0000000037252902985 +/- 3.81e-20]

The first reason that c is not printed as [1 +/- 2] is that the midpoint does not have a greater exponent than the radius in its scientific notation. For similar reasons y is not printed as [12 +/- 2].

The second reason is that we get an additional error term after our addition. As we see, radius(c) is not equal to $2$, which when printed rounds it up to a reasonable decimal place. This is because real balls keep track of rounding errors of basic arithmetic.

Containment

It is often necessary to determine whether a given exact value or ball is contained in a given real ball or whether two balls overlap. The following functions are provided for this purpose.

overlapsMethod
overlaps(x::arb, y::arb)

Returns true if any part of the ball $x$ overlaps any part of the ball $y$, otherwise return false.

containsMethod
contains(x::arb, y::arb)

Returns true if the ball $x$ contains the ball $y$, otherwise return false.

containsMethod
contains(x::arb, y::Integer)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::arb, y::ZZRingElem)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::arb, y::QQFieldElem)

Returns true if the ball $x$ contains the given rational value, otherwise return false.

containsMethod
contains(x::arb, y::Rational{T}) where {T <: Integer}

Returns true if the ball $x$ contains the given rational value, otherwise return false.

containsMethod
contains(x::arb, y::BigFloat)

Returns true if the ball $x$ contains the given floating point value, otherwise return false.

The following functions are also provided for determining if a ball intersects a certain part of the real number line.

contains_zeroMethod
contains_zero(x::arb)

Returns true if the ball $x$ contains zero, otherwise return false.

contains_negativeMethod
contains_negative(x::arb)

Returns true if the ball $x$ contains any negative value, otherwise return false.

contains_positiveMethod
contains_positive(x::arb)

Returns true if the ball $x$ contains any positive value, otherwise return false.

contains_nonnegativeMethod
contains_nonnegative(x::arb)

Returns true if the ball $x$ contains any nonnegative value, otherwise return false.

contains_nonpositiveMethod
contains_nonpositive(x::arb)

Returns true if the ball $x$ contains any nonpositive value, otherwise return false.

Examples

RR = ArbField(64)
-x = RR("1 +/- 0.001")
-y = RR("3")
-
-overlaps(x, y)
-contains(x, y)
-contains(y, 3)
-contains(x, ZZ(1)//2)
-contains_zero(x)
-contains_positive(y)

Comparison

Nemo provides a full range of comparison operations for Arb balls. Note that a ball is considered less than another ball if every value in the first ball is less than every value in the second ball, etc.

In addition to the standard comparison operators, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.

isequalMethod
isequal(x::arb, y::arb)

Return true if the balls $x$ and $y$ are precisely equal, i.e. have the same midpoints and radii.

We also provide a full range of ad hoc comparison operators. These are implemented directly in Julia, but we document them as though isless and == were provided.

Function
==(x::arb, y::Integer)
==(x::Integer, y::arb)
==(x::arb, y::ZZRingElem)
==(x::ZZRingElem, y::arb)
==(x::arb, y::Float64)
==(x::Float64, y::arb)
isless(x::arb, y::Integer)
isless(x::Integer, y::arb)
isless(x::arb, y::ZZRingElem)
isless(x::ZZRingElem, y::arb)
isless(x::arb, y::Float64)
isless(x::Float64, y::arb)
isless(x::arb, y::BigFloat)
isless(x::BigFloat, y::arb)
isless(x::arb, y::QQFieldElem)
isless(x::QQFieldElem, y::arb)

Examples

RR = ArbField(64)
-x = RR("1 +/- 0.001")
-y = RR("3")
-z = RR("4")
-
-isequal(x, deepcopy(x))
-x == 3
-ZZ(3) < z
-x != 1.23

Absolute value

Examples

RR = ArbField(64)
-x = RR("-1 +/- 0.001")
-
-a = abs(x)

Shifting

Examples

RR = ArbField(64)
-x = RR("-3 +/- 0.001")
-
-a = ldexp(x, 23)
-b = ldexp(x, -ZZ(15))

Miscellaneous operations

add_error!Method
add_error!(x::arb, y::arb)

Adds the absolute values of the midpoint and radius of $y$ to the radius of $x$.

trimMethod
trim(x::arb)

Return an arb interval containing $x$ but which may be more economical, by rounding off insignificant bits from the midpoint.

unique_integerMethod
unique_integer(x::arb)

Return a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the interval $x$ contains a unique integer. If this is the case, the second return value is set to this unique integer.

setunionMethod
setunion(x::arb, y::arb)

Return an arb containing the union of the intervals represented by $x$ and $y$.

Examples

RR = ArbField(64)
-x = RR("-3 +/- 0.001")
-y = RR("2 +/- 0.5")
-
-a = trim(x)
-b, c = unique_integer(x)
-d = setunion(x, y)

Constants

const_piMethod
const_pi(r::ArbField)

Return $\pi = 3.14159\ldots$ as an element of $r$.

const_eMethod
const_e(r::ArbField)

Return $e = 2.71828\ldots$ as an element of $r$.

const_log2Method
const_log2(r::ArbField)

Return $\log(2) = 0.69314\ldots$ as an element of $r$.

const_log10Method
const_log10(r::ArbField)

Return $\log(10) = 2.302585\ldots$ as an element of $r$.

const_eulerMethod
const_euler(r::ArbField)

Return Euler's constant $\gamma = 0.577215\ldots$ as an element of $r$.

const_catalanMethod
const_catalan(r::ArbField)

Return Catalan's constant $C = 0.915965\ldots$ as an element of $r$.

const_khinchinMethod
const_khinchin(r::ArbField)

Return Khinchin's constant $K = 2.685452\ldots$ as an element of $r$.

const_glaisherMethod
const_glaisher(r::ArbField)

Return Glaisher's constant $A = 1.282427\ldots$ as an element of $r$.

Examples

RR = ArbField(200)
-
-a = const_pi(RR)
-b = const_e(RR)
-c = const_euler(RR)
-d = const_glaisher(RR)

Mathematical and special functions

rsqrtMethod
rsqrt(x::arb)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

sqrt1pm1Method
sqrt1pm1(x::arb)

Return $\sqrt{1+x}-1$, evaluated accurately for small $x$.

sqrtposMethod
sqrtpos(x::arb)

Return the sqrt root of $x$, assuming that $x$ represents a nonnegative number. Thus any negative number in the input interval is discarded.

gammaMethod
gamma(x::arb)

Return the Gamma function evaluated at $x$.

lgammaMethod
lgamma(x::arb)

Return the logarithm of the Gamma function evaluated at $x$.

rgammaMethod
rgamma(x::arb)

Return the reciprocal of the Gamma function evaluated at $x$.

digammaMethod
digamma(x::arb)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

gammaMethod
gamma(s::arb, x::arb)

Return the upper incomplete gamma function $\Gamma(s,x)$.

gamma_regularizedMethod
gamma_regularized(s::arb, x::arb)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

gamma_lowerMethod
gamma_lower(s::arb, x::arb)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

gamma_lower_regularizedMethod
gamma_lower_regularized(s::arb, x::arb)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

zetaMethod
zeta(x::arb)

Return the Riemann zeta function evaluated at $x$.

atan2Method
atan2(y::arb, x::arb)

Return $\operatorname{atan2}(y,x) = \arg(x+yi)$. Same as atan(y, x).

agmMethod
agm(x::arb, y::arb)

Return the arithmetic-geometric mean of $x$ and $y$

zetaMethod
zeta(s::arb, a::arb)

Return the Hurwitz zeta function $\zeta(s,a)$.

rootMethod
root(x::arb, n::Int)

Return the $n$-th root of $x$. We require $x \geq 0$.

factorialMethod
factorial(x::arb)

Return the factorial of $x$.

factorialMethod
factorial(n::Int, r::ArbField)

Return the factorial of $n$ in the given Arb field.

binomialMethod
binomial(x::arb, n::UInt)

Return the binomial coefficient ${x \choose n}$.

binomialMethod
binomial(n::UInt, k::UInt, r::ArbField)

Return the binomial coefficient ${n \choose k}$ in the given Arb field.

fibonacciMethod
fibonacci(n::ZZRingElem, r::ArbField)

Return the $n$-th Fibonacci number in the given Arb field.

fibonacciMethod
fibonacci(n::Int, r::ArbField)

Return the $n$-th Fibonacci number in the given Arb field.

gammaMethod
gamma(x::ZZRingElem, r::ArbField)

Return the Gamma function evaluated at $x$ in the given Arb field.

gammaMethod
gamma(x::QQFieldElem, r::ArbField)

Return the Gamma function evaluated at $x$ in the given Arb field.

zetaMethod
zeta(n::Int, r::ArbField)

Return the Riemann zeta function $\zeta(n)$ as an element of the given Arb field.

bernoulliMethod
bernoulli(n::Int, r::ArbField)

Return the $n$-th Bernoulli number as an element of the given Arb field.

rising_factorialMethod
rising_factorial(x::arb, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Arb.

rising_factorialMethod
rising_factorial(x::QQFieldElem, n::Int, r::ArbField)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an element of the given Arb field.

rising_factorial2Method
rising_factorial2(x::arb, n::Int)

Return a tuple containing the rising factorial $x(x + 1)\ldots (x + n - 1)$ and its derivative.

polylogMethod
polylog(s::Union{arb,Int}, a::arb)

Return the polylogarithm Li$_s(a)$.

chebyshev_tMethod
chebyshev_t(n::Int, x::arb)

Return the value of the Chebyshev polynomial $T_n(x)$.

chebyshev_uMethod
chebyshev_u(n::Int, x::arb)

Return the value of the Chebyshev polynomial $U_n(x)$.

chebyshev_t2Method
chebyshev_t2(n::Int, x::arb)

Return the tuple $(T_{n}(x), T_{n-1}(x))$.

chebyshev_u2Method
chebyshev_u2(n::Int, x::arb)

Return the tuple $(U_{n}(x), U_{n-1}(x))$

bellMethod
bell(n::ZZRingElem, r::ArbField)

Return the Bell number $B_n$ as an element of $r$.

bellMethod
bell(n::Int, r::ArbField)

Return the Bell number $B_n$ as an element of $r$.

numpartMethod
numpart(n::ZZRingElem, r::ArbField)

Return the number of partitions $p(n)$ as an element of $r$.

numpartMethod
numpart(n::Int, r::ArbField)

Return the number of partitions $p(n)$ as an element of $r$.

airy_aiMethod
airy_ai(x::arb)

Return the Airy function $\operatorname{Ai}(x)$.

airy_ai_primeMethod
airy_ai_prime(x::arb)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

airy_biMethod
airy_bi(x::arb)

Return the Airy function $\operatorname{Bi}(x)$.

airy_bi_primeMethod
airy_bi_prime(x::arb)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

Examples

RR = ArbField(64)
-
-a = floor(exp(RR(1)))
-b = sinpi(QQ(5,6), RR)
-c = gamma(QQ(1,3), ArbField(256))
-d = bernoulli(1000, ArbField(53))
-f = polylog(3, RR(-10))

Linear dependence

lindepMethod
lindep(A::Vector{arb}, bits::Int)

Find a small linear combination of the entries of the array $A$ that is small (using LLL). The entries are first scaled by the given number of bits before truncating to integers for use in LLL. This function can be used to find linear dependence between a list of real numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> a = RR(-0.33198902958450931620250069492231652319)
-[-0.33198902958450932088 +/- 4.15e-22]
-
-julia> V = [RR(1), a, a^2, a^3, a^4, a^5]
-6-element Vector{arb}:
- 1.0000000000000000000
- [-0.33198902958450932088 +/- 4.15e-22]
- [0.11021671576446420510 +/- 7.87e-21]
- [-0.03659074051063616184 +/- 4.17e-21]
- [0.012147724433904692427 +/- 4.99e-22]
- [-0.004032911246472051677 +/- 6.25e-22]
-
-julia> W = lindep(V, 20)
-6-element Vector{ZZRingElem}:
- 1
- 3
- 0
- 0
- 0
- 1

Examples

RR = ArbField(128)
-
-a = RR(-0.33198902958450931620250069492231652319)
-
-V = [RR(1), a, a^2, a^3, a^4, a^5]
-W = lindep(V, 20)
simplest_rational_insideMethod
  simplest_rational_inside(x::arb)

Return the simplest fraction inside the ball $x$. A canonical fraction $a_1/b_1$ is defined to be simpler than $a_2/b_2$ iff $b_1 < b_2$ or $b_1 = b_2$ and $a_1 < a_2$.

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> simplest_rational_inside(const_pi(RR))
-8717442233//2774848045

Examples

RR = ArbField(64)
-simplest_rational_inside(const_pi(RR))

Random generation

randMethod
rand(r::ArbField; randtype::Symbol=:urandom)

Return a random element in given Arb field.

The randtype default is :urandom which return an arb contained in $[0,1]$.

The rest of the methods return non-uniformly distributed values in order to exercise corner cases. The option :randtest will return a finite number, and :randtest_exact the same but with a zero radius. The option :randtest_precise return an arb with a radius around $2^{-\mathrm{prec}}$ the magnitude of the midpoint, while :randtest_wide return a radius that might be big relative to its midpoint. The :randtest_special-option might return a midpoint and radius whose values are NaN or inf.

Examples

RR = ArbField(100)
-
-a = rand(RR)
-b = rand(RR; randtype = :null_exact)
-c = rand(RR; randtype = :exact)
-d = rand(RR; randtype = :special)
diff --git a/previews/PR2578/Nemo/complex/index.html b/previews/PR2578/Nemo/complex/index.html deleted file mode 100644 index 804bb13ea930..000000000000 --- a/previews/PR2578/Nemo/complex/index.html +++ /dev/null @@ -1,83 +0,0 @@ - -Arbitrary precision complex balls · Oscar.jl

Arbitrary precision complex balls

Arbitrary precision complex ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Complex numbers are represented in rectangular form $a+bi$ where $a,b$ are arb balls.

The corresponding field is constructed using the ComplexField constructor. This constructs the parent object for the Arb complex field.

The types of complex boxes in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Arb$\mathbb{C}$ (boxes)ComplexFieldElemComplexField

All the complex field types belong to the Field abstract type and the types of elements in this field, i.e. complex boxes in this case, belong to the FieldElem abstract type.

Complex ball functionality

The complex balls in Nemo provide all the field functionality defined by AbstractAlgebra:.

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document the additional functionality provided for complex balls.

Precision management

See Precision management.

Complex field constructors

In order to construct complex boxes in Nemo, one must first construct the Arb complex field itself. This is accomplished with the following constructor.

ComplexField(prec::Int)

Here is an example of creating an Arb complex field and using the resulting parent object to coerce values into the resulting field.

Examples

CC = ComplexField(64)
-
-a = CC("0.25")
-b = CC("0.1")
-c = CC(0.5)
-d = CC(12)

Note that whilst one can coerce double precision floating point values into an Arb complex field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.

If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb complex field.

If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.

Constructors

oneiMethod
onei(r::ComplexField)

Return exact one times $i$ in the given Arb complex field.

Examples

CC = ComplexField(64)
-
-c = onei(CC)

Basic functionality

The following basic functionality is provided by the default Arb complex field implementation in Nemo, to support construction of generic rings over complex fields. Any custom complex field implementation in Nemo should provide analogues of these functions along with the usual arithmetic operations.

parent_type(::Type{ComplexFieldElem})

Gives the type of the parent object of an Arb complex field element.

elem_type(R::ComplexField)

Given the parent object for an Arb complex field, return the type of elements of the field.

mul!(c::ComplexFieldElem, a::ComplexFieldElem, b::ComplexFieldElem)

Multiply $a$ by $b$ and set the existing Arb complex field element $c$ to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.

addeq!(c::ComplexFieldElem, a::ComplexFieldElem)

In-place addition adds $a$ to $c$ and sets $c$ to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.

deepcopy(a::ComplexFieldElem)

Return a copy of the Arb complex field element $a$, recursively copying the internal data. Arb complex field elements are mutable in Nemo so a shallow copy is not sufficient.

Given the parent object R for an Arb complex field, the following coercion functions are provided to coerce various elements into the Arb complex field. Developers provide these by overloading the call operator for the complex field parent objects.

R()

Coerce zero into the Arb complex field.

R(n::Integer)
-R(f::ZZRingElem)
-R(q::QQFieldElem)

Coerce an integer or rational value into the Arb complex field.

R(f::Float64)
-R(f::BigFloat)

Coerce the given floating point number into the Arb complex field.

R(f::AbstractString)
-R(f::AbstractString, g::AbstractString)

Coerce the decimal number, given as a string, into the Arb complex field. In each case $f$ is the real part and $g$ is the imaginary part.

R(f::arb)

Coerce the given Arb real ball into the Arb complex field.

R(f::ComplexFieldElem)

Take an Arb complex field element that is already in an Arb field and simply return it. A copy of the original is not made.

Here are some examples of coercing elements into the Arb complex field.

RR = RealField(64)
-CC = ComplexField(64)
-
-a = CC(3)
-b = CC(QQ(2,3))
-c = CC("3 +/- 0.0001")
-d = CC("-1.24e+12345")
-f = CC("nan +/- inf")
-g = CC(RR(3))

In addition to the above, developers of custom complex field types must ensure that they provide the equivalent of the function base_ring(R::ComplexField) which should return Union{}. In addition to this they should ensure that each complex field element contains a field parent specifying the parent object of the complex field element, or at least supply the equivalent of the function parent(a::ComplexFieldElem) to return the parent object of a complex field element.

Basic manipulation

isfiniteMethod
isfinite(x::ComplexFieldElem)

Return true if $x$ is finite, i.e. its real and imaginary parts have finite midpoint and radius, otherwise return false.

is_exactMethod
is_exact(x::ComplexFieldElem)

Return true if $x$ is exact, i.e. has its real and imaginary parts have zero radius, otherwise return false.

isintegerMethod
isinteger(x::ComplexFieldElem)

Return true if $x$ is an exact integer, otherwise return false.

accuracy_bitsMethod
accuracy_bits(x::ComplexFieldElem)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

Examples

CC = ComplexField(64)
-
-a = CC("1.2 +/- 0.001")
-b = CC(3)
-
-isreal(a)
-isfinite(b)
-isinteger(b)
-c = real(a)
-d = imag(b)
-f = accuracy_bits(a)

Containment

It is often necessary to determine whether a given exact value or box is contained in a given complex box or whether two boxes overlap. The following functions are provided for this purpose.

overlapsMethod
overlaps(x::ComplexFieldElem, y::ComplexFieldElem)

Returns true if any part of the box $x$ overlaps any part of the box $y$, otherwise return false.

containsMethod
contains(x::ComplexFieldElem, y::ComplexFieldElem)

Returns true if the box $x$ contains the box $y$, otherwise return false.

containsMethod
contains(x::ComplexFieldElem, y::Integer)

Returns true if the box $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::ComplexFieldElem, y::ZZRingElem)

Returns true if the box $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::ComplexFieldElem, y::QQFieldElem)

Returns true if the box $x$ contains the given rational value, otherwise return false.

The following functions are also provided for determining if a box intersects a certain part of the complex number plane.

contains_zeroMethod
contains_zero(x::ComplexFieldElem)

Returns true if the box $x$ contains zero, otherwise return false.

Examples

CC = ComplexField(64)
-x = CC("1 +/- 0.001")
-y = CC("3")
-
-overlaps(x, y)
-contains(x, y)
-contains(y, 3)
-contains(x, ZZ(1)//2)
-contains_zero(x)

Comparison

Nemo provides a full range of comparison operations for Arb complex boxes.

In addition to the standard comparisons, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.

isequalMethod
isequal(x::ComplexFieldElem, y::ComplexFieldElem)

Return true if the boxes $x$ and $y$ are precisely equal, i.e. their real and imaginary parts have the same midpoints and radii.

A full range of ad hoc comparison operators is provided. These are implemented directly in Julia, but we document them as though only == were provided.

Function
==(x::ComplexFieldElem, y::Integer)
==(x::Integer, y::ComplexFieldElem)
==(x::ComplexFieldElem, y::ZZRingElem)
==(x::ZZRingElem, y::ComplexFieldElem)
==(x::arb, y::ZZRingElem)
==(x::ZZRingElem, y::arb)
==(x::ComplexFieldElem, y::Float64)
==(x::Float64, y::ComplexFieldElem)

Examples

CC = ComplexField(64)
-x = CC("1 +/- 0.001")
-y = CC("3")
-z = CC("4")
-
-isequal(x, deepcopy(x))
-x == 3
-ZZ(3) == z
-x != 1.23

Absolute value

Examples

CC = ComplexField(64)
-x = CC("-1 +/- 0.001")
-
-a = abs(x)

Shifting

Examples

CC = ComplexField(64)
-x = CC("-3 +/- 0.001")
-
-a = ldexp(x, 23)
-b = ldexp(x, -ZZ(15))

Miscellaneous operations

trimMethod
trim(x::ComplexFieldElem)

Return an acb box containing $x$ but which may be more economical, by rounding off insignificant bits from midpoints.

unique_integerMethod
unique_integer(x::ComplexFieldElem)

Return a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the box $x$ contains a unique integer. If this is the case, the second return value is set to this unique integer.

Examples

CC = ComplexField(64)
-x = CC("-3 +/- 0.001", "0.1")
-
-a = trim(x)
-b, c = unique_integer(x)
-d = conj(x)
-f = angle(x)

Constants

const_piMethod
const_pi(r::ComplexField)

Return $\pi = 3.14159\ldots$ as an element of $r$.

Examples

CC = ComplexField(200)
-
-a = const_pi(CC)

Mathematical and special functions

rsqrtMethod
rsqrt(x::ComplexFieldElem)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

cispiMethod
cispi(x::ComplexFieldElem)

Return the exponential of $\pi i x$.

root_of_unityMethod
root_of_unity(C::ComplexField, k::Int)

Return $\exp(2\pi i/k)$.

log_sinpiMethod
log_sinpi(x::ComplexFieldElem)

Return $\log\sin(\pi x)$, constructed without branch cuts off the real line.

gammaMethod
gamma(x::ComplexFieldElem)

Return the Gamma function evaluated at $x$.

lgammaMethod
lgamma(x::ComplexFieldElem)

Return the logarithm of the Gamma function evaluated at $x$.

rgammaMethod
rgamma(x::ComplexFieldElem)

Return the reciprocal of the Gamma function evaluated at $x$.

digammaMethod
digamma(x::ComplexFieldElem)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

zetaMethod
zeta(x::ComplexFieldElem)

Return the Riemann zeta function evaluated at $x$.

barnes_gMethod
barnes_g(x::ComplexFieldElem)

Return the Barnes $G$-function, evaluated at $x$.

log_barnes_gMethod
log_barnes_g(x::ComplexFieldElem)

Return the logarithm of the Barnes $G$-function, evaluated at $x$.

erfMethod
erf(x::ComplexFieldElem)

Return the error function evaluated at $x$.

erfiMethod
erfi(x::ComplexFieldElem)

Return the imaginary error function evaluated at $x$.

exp_integral_eiMethod
exp_integral_ei(x::ComplexFieldElem)

Return the exponential integral evaluated at $x$.

sin_integralMethod
sin_integral(x::ComplexFieldElem)

Return the sine integral evaluated at $x$.

cos_integralMethod
cos_integral(x::ComplexFieldElem)

Return the exponential cosine integral evaluated at $x$.

sinh_integralMethod
sinh_integral(x::ComplexFieldElem)

Return the hyperbolic sine integral evaluated at $x$.

cosh_integralMethod
cosh_integral(x::ComplexFieldElem)

Return the hyperbolic cosine integral evaluated at $x$.

dedekind_etaMethod
dedekind_eta(x::ComplexFieldElem)

Return the Dedekind eta function $\eta(\tau)$ at $\tau = x$.

modular_weber_fMethod
modular_weber_f(x::ComplexFieldElem)

Return the modular Weber function $\mathfrak{f}(\tau) = \frac{\eta^2(\tau)}{\eta(\tau/2)\eta(2\tau)},$ at $x$ in the complex upper half plane.

modular_weber_f1Method
modular_weber_f1(x::ComplexFieldElem)

Return the modular Weber function $\mathfrak{f}_1(\tau) = \frac{\eta(\tau/2)}{\eta(\tau)},$ at $x$ in the complex upper half plane.

modular_weber_f2Method
modular_weber_f2(x::ComplexFieldElem)

Return the modular Weber function $\mathfrak{f}_2(\tau) = \frac{\sqrt{2}\eta(2\tau)}{\eta(\tau)}$ at $x$ in the complex upper half plane.

j_invariantMethod
j_invariant(x::ComplexFieldElem)

Return the $j$-invariant $j(\tau)$ at $\tau = x$.

j_invariant(E::ProjEllipticCurve{S}) where S <: FieldElem

Return the j-invariant of the projective elliptic curve E.

source
j_invariant(E::EllCrv) -> FieldElem

Compute the j-invariant of $E$.

modular_lambdaMethod
modular_lambda(x::ComplexFieldElem)

Return the modular lambda function $\lambda(\tau)$ at $\tau = x$.

modular_deltaMethod
modular_delta(x::ComplexFieldElem)

Return the modular delta function $\Delta(\tau)$ at $\tau = x$.

eisenstein_gMethod
eisenstein_g(k::Int, x::ComplexFieldElem)

Return the non-normalized Eisenstein series $G_k(\tau)$ of $\mathrm{SL}_2(\mathbb{Z})$. Also defined for $\tau = i \infty$.

hilbert_class_polynomialMethod
hilbert_class_polynomial(D::Int, R::ZZPolyRing)

Return in the ring $R$ the Hilbert class polynomial of discriminant $D$, which is only defined for $D < 0$ and $D \equiv 0, 1 \pmod 4$.

elliptic_kMethod
elliptic_k(x::ComplexFieldElem)

Return the complete elliptic integral $K(x)$.

elliptic_eMethod
elliptic_e(x::ComplexFieldElem)

Return the complete elliptic integral $E(x)$.

agmMethod
agm(x::ComplexFieldElem)

Return the arithmetic-geometric mean of $1$ and $x$.

agmMethod
agm(x::ComplexFieldElem, y::ComplexFieldElem)

Return the arithmetic-geometric mean of $x$ and $y$.

polygammaMethod
polygamma(s::ComplexFieldElem, a::ComplexFieldElem)

Return the generalised polygamma function $\psi(s,z)$.

zetaMethod
zeta(s::ComplexFieldElem, a::ComplexFieldElem)

Return the Hurwitz zeta function $\zeta(s,a)$.

rising_factorialMethod
rising_factorial(x::ComplexFieldElem, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Acb.

rising_factorial2Method
rising_factorial2(x::ComplexFieldElem, n::Int)

Return a tuple containing the rising factorial $x(x + 1)\ldots (x + n - 1)$ and its derivative.

polylogMethod
polylog(s::Union{ComplexFieldElem,Int}, a::ComplexFieldElem)

Return the polylogarithm Li$_s(a)$.

log_integralMethod
log_integral(x::ComplexFieldElem)

Return the logarithmic integral, evaluated at $x$.

log_integral_offsetMethod
log_integral_offset(x::ComplexFieldElem)

Return the offset logarithmic integral, evaluated at $x$.

exp_integral_eMethod
exp_integral_e(s::ComplexFieldElem, x::ComplexFieldElem)

Return the generalised exponential integral $E_s(x)$.

gammaMethod
gamma(s::ComplexFieldElem, x::ComplexFieldElem)

Return the upper incomplete gamma function $\Gamma(s,x)$.

gamma_regularizedMethod
gamma_regularized(s::ComplexFieldElem, x::ComplexFieldElem)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

gamma_lowerMethod
gamma_lower(s::ComplexFieldElem, x::ComplexFieldElem)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

gamma_lower_regularizedMethod
gamma_lower_regularized(s::ComplexFieldElem, x::ComplexFieldElem)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

airy_aiMethod
airy_ai(x::ComplexFieldElem)

Return the Airy function $\operatorname{Ai}(x)$.

airy_ai_primeMethod
airy_ai_prime(x::ComplexFieldElem)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

airy_biMethod
airy_bi(x::ComplexFieldElem)

Return the Airy function $\operatorname{Bi}(x)$.

airy_bi_primeMethod
airy_bi_prime(x::ComplexFieldElem)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

bessel_jMethod
bessel_j(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $J_{\nu}(x)$.

bessel_yMethod
bessel_y(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $Y_{\nu}(x)$.

bessel_iMethod
bessel_i(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $I_{\nu}(x)$.

bessel_kMethod
bessel_k(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $K_{\nu}(x)$.

hypergeometric_1f1Method
hypergeometric_1f1(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)

Return the confluent hypergeometric function ${}_1F_1(a,b,x)$.

hypergeometric_1f1_regularizedMethod
hypergeometric_1f1_regularized(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)

Return the regularized confluent hypergeometric function ${}_1F_1(a,b,x) / \Gamma(b)$.

hypergeometric_uMethod
hypergeometric_u(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)

Return the confluent hypergeometric function $U(a,b,x)$.

hypergeometric_2f1Method
hypergeometric_2f1(a::ComplexFieldElem, b::ComplexFieldElem, c::ComplexFieldElem, x::ComplexFieldElem; flags=0)

Return the Gauss hypergeometric function ${}_2F_1(a,b,c,x)$.

jacobi_thetaMethod
jacobi_theta(z::ComplexFieldElem, tau::ComplexFieldElem)

Return a tuple of four elements containing the Jacobi theta function values $\theta_1, \theta_2, \theta_3, \theta_4$ evaluated at $z, \tau$.

weierstrass_pMethod
weierstrass_p(z::ComplexFieldElem, tau::ComplexFieldElem)

Return the Weierstrass elliptic function $\wp(z,\tau)$.

Examples

CC = ComplexField(64)
-
-s = CC(1, 2)
-z = CC("1.23", "3.45")
-
-a = sin(z)^2 + cos(z)^2
-b = zeta(z)
-c = bessel_j(s, z)
-d = hypergeometric_1f1(s, s+1, z)

Linear dependence

lindepMethod
lindep(A::Vector{ComplexFieldElem}, bits::Int)

Find a small linear combination of the entries of the array $A$ that is small (using LLL). The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find linear dependence between a list of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.

lindepMethod
lindep(A::Matrix{ComplexFieldElem}, bits::Int)

Find a (common) small linear combination of the entries in each row of the array $A$, that is small (using LLL). It is assumed that the complex numbers in each row of the array share the same linear combination. The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find a common linear dependence shared across a number of lists of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the common linear combination.

Examples

CC = ComplexField(128)
-
-# These are two of the roots of x^5 + 3x + 1
-a = CC(1.0050669478588622428791051888364775253, - 0.93725915669289182697903585868761513585)
-b = CC(-0.33198902958450931620250069492231652319)
-
-# We recover the polynomial from one root....
-V1 = [CC(1), a, a^2, a^3, a^4, a^5];
-W = lindep(V1, 20)
-
-# ...or from two
-V2 = [CC(1), b, b^2, b^3, b^4, b^5];
-Vs = [V1 V2]
-X = lindep(Vs, 20)
diff --git a/previews/PR2578/Nemo/constructors/index.html b/previews/PR2578/Nemo/constructors/index.html deleted file mode 100644 index 80d104e29785..000000000000 --- a/previews/PR2578/Nemo/constructors/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Constructing mathematical objects in Nemo · Oscar.jl

Constructing mathematical objects in Nemo

Constructing objects in Julia

In Julia, one constructs objects of a given type by calling a type constructor. This is simply a function with the same name as the type itself. For example, to construct a BigInt object in Julia, we simply call the BigInt constructor:

n = BigInt("1234567898765434567898765434567876543456787654567890")

Julia also uses constructors to convert between types. For example, to convert an Int to a BigInt:

m = BigInt(123)

How we construct objects in Nemo

Julia types don't contain enough information to properly model groups, rings and fields, especially if they are parameterised by values. For example, the ring of integers modulo $n$ for a multiprecision modulus $n$ cannot be modeled using types alone.

Instead of using types to construct objects in Nemo, we use special objects that we refer to as parent objects. They behave a lot like Julia types.

Consider the following simple example, to create a Flint multiprecision integer:

n = ZZ("12345678765456787654567890987654567898765678909876567890")

Here ZZ is not a Julia type, but a callable object. However, for most purposes one can think of such a parent object ZZ as though it were a type.

Constructing parent objects

For more complicated groups, rings, fields, etc., one first needs to construct the parent object before one can use it to construct element objects.

Nemo provides a set of functions for constructing such parent objects. For example, to create a parent object for polynomials over the integers, we use the polynomial_ring parent object constructor.

R, x = polynomial_ring(ZZ, "x")
-f = x^3 + 3x + 1
-g = R(12)

In this example, $R$ is the parent object and we use it to convert the Int value $12$ to an element of the polynomial ring $\mathbb{Z}[x]$.

List of parent object constructors

For convenience, we provide a list of all the parent object constructors in Nemo and explain what domains they represent.

MathematicsNemo constructor
$R = \mathbb{Z}$R = ZZ
$R = \mathbb{Q}$R = QQ
$R = \mathbb{F}_{p^n}$R, a = FiniteField(p, n, "a")
$R = \mathbb{Z}/n\mathbb{Z}$R = residue_ring(ZZ, n)
$S = R[x]$S, x = polynomial_ring(R, "x")
$S = R[x, y]$S, (x, y) = polynomial_ring(R, ["x", "y"])
$S = R[[x]]$ (to precision $n$)S, x = power_series_ring(R, n, "x")
$S = R((x))$ (to precision $n$)S, x = laurent_series_ring(R, n, "x")
$S = \mathrm{Frac}_R$S = fraction_field(R)
$S = R/(f)$S = residue_ring(R, f)
$S = \mathrm{Mat}_{m\times n}(R)$S = matrix_space(R, m, n)
$S = \mathbb{Q}[x]/(f)$S, a = number_field(f, "a")
$S = \mathbb{Q}_p$ (to precision $N$)S = PadicField(p, n)
$S = \mathbb{R}$ (to precision $n$)S = RealField(n)
$S = \mathbb{C}$ (to precision $n$)S = ComplexField(n)
diff --git a/previews/PR2578/Nemo/developer/conventions/index.html b/previews/PR2578/Nemo/developer/conventions/index.html deleted file mode 100644 index 9ec7efd54948..000000000000 --- a/previews/PR2578/Nemo/developer/conventions/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Conventions · Oscar.jl

Conventions

AbstractAlgebra and Nemo have adopted a number of conventions to help maintain a uniform codebase.

Code conventions

Function and type names

Names of types in Julia follow the convention of CamelCase where the first letter of each word is capitalised, e.g. Int64 and AbstractString.

Function/method names in Julia use all lowercase with underscores between the words, e.g. zip and jacobi_symbol.

We follow these conventions in Nemo with some exceptions:

  • When interfacing C libraries the types use the same spelling and capitalisation in Nemo as they do in C, e.g. the Flint library's ZZPolyRingElem remains uncapitalised in Nemo.

  • Types such as fpPolyRingElem which don't exist under that name on the C side also use the lowercase convention as they wrap an actual C type which must be split into more than one type on the Julia side. For example zzModPolyRingElem and fpPolyRingElem on the Julia side both represent Flint zzModPolyRingElem's on the C side.

  • Types of rings and fields, modules, maps, etc. are capitalised whether they correspond to a C type or not, e.g. fqPolyRepField for the type of an object representing the field that fqPolyRepFieldElem's belong to.

.

  • We omit an underscore if the first word of a method is "is" or "has", e.g. iseven.

  • Underscores are omitted if the method name is already well established without an underscore in Julia itself, e.g. setindex.

  • Constructors with the same name as a type use the same spelling and capitalisation as that type, e.g. ZZRingElem(1).

  • Functions for creating rings, fields, modules, maps, etc. (rather than the elements thereof) use CamelCase, e.g. polynomial_ring. We refer to these functions as parent constructors. Note that we do not follow the Julia convention here, e.g. polynomial_ring is a function and not a type constructor (in fact we often return a tuple consisting of a parent object and other objects such as generators with this type of function) yet we capitalise it.

  • We prefer words to not be abbreviated, e.g. denominator instead of den.

  • Exceptions always exist where the result would be offensive in any major spoken language (example omitted).

It is easy to find counterexamples to virtually all these rules. However we have been making efforts to remove the most egregious cases from our codebase over time. As perfect consistency is not possible, work on this has to at times take a back seat.

Use of ASCII characters

All code and printed output in Nemo should use ASCII characters only. This is because we have developers who are using versions of the WSL that cannot correctly display non-ASCII characters.

This extends to function and operator names, which saves people having to learn how to enter them to use the system.

Spacing and tabs

All function bodies and control blocks should be indented using spaces.

A survey of existing code shows 2, 3 or 4 space indenting commonly used in our files. Values outside this range should not be used.

When contributing to an existing file, follow the majority convention in that file. Consistency within a file is valued highly.

If you are new to Nemo development and do not already have a very strong preference, new files should be started with 3 space indenting. This maximises the likelihood that copy and paste between files will be straightforward, though modern editors ease this to some degree.

Function signatures in docstrings should have four spaces before them.

Where possible, line lengths should not exceed 80 characters.

We use a term/factor convention for spacing. This means that all (additive) terms have spaces before and after them, (multiplicative) factors usually do not.

In practice this means that +, -, =, ==, !=, <, >, <=, >= all have spaces before and after them. The operators *, /, ^ and unary minus do not.

As per English, commas are followed by a single space in expressions. This applies for example to function arguments and tuples.

We do not put spaces immediately inside or before parentheses.

Colons used for ranges do not have spaces before or after them.

Logical operators, &, |, &&, etc. usually have spaces before and after them.

Comments

Despite appearances to the contrary, we now prefer code comments explaining the algorithm as it proceeds.

The hash when used for a comment should always be followed by a space. Full sentences are preferred.

We do not generally use comments in Nemo for questions, complaints or proposals for future improvement. These are better off in a ticket on GitHub with a discussion that will be brought to the attention of all relevant parties.

Any (necessary) limitations of the implementation should be noted in docstrings.

Layout of files

In Nemo, all types are places in special files with the word "Types" in their name, e.g. FlintTypes.jl. This is because Julia must be aware of all types before they are used. Separation of types from implementations makes it easy to ensure this happens.

Abstract types should be put in the file called AbstractTypes.jl at the top level of the src directory.

Most implementation files present functions in a particular order, which is as follows:

  • A header stating what the file is for, and if needed, any copyright notices

  • Functions applying to any "types" used in the file, e.g. parent_type, elem_type, base_ring, parent, check_parent.

  • Basic manipulation, including hashes, predicates, getters/setters, functions for creating special values (e.g. one, zero and the like), deepcopy_internal. These are usually fairly short functions, often a single line.

  • Indexing (getindex, setindex), iteration, views.

  • String I/O (expressify and file access, etc.)

  • Arithmetic operations, usually in multiple sections, such as unary operations, binary operations, ad hoc binary operations (e.g. multiplication of a complex object by a scalar), comparisons, ad hoc comparisons, division, etc.

  • More complex functionality separated into sections based on functionality provided, e.g. gcd, interpolation, special functions, solving, etc.

  • Functions for mapping between different types, coercion, changing base ring, etc.

  • Unsafe operators, e.g. mul!, add!, addeq! etc.

  • Random generation

  • Promotion rules

  • Parent object call overload (e.g. for implementing R(2) where R is an object representing a ring or field, etc.)

  • Additional constructors, e.g. matrix, which might be used instead of a parent object to construct elements.

  • Parent object constructors, e.g. polynomial_ring, etc.

The exact order within the file is less important than generally following something like the above. This aids in finding functions in a file since all files are more or less set out the same way.

For an example to follow, see the src/Poly.jl and src/generic/Poly.jl files in AbstractAlgebra which form the oldest and most canonical example.

Headings for sections should be 80 characters wide and formed of hashes in the style that can be seen in each Nemo file.

diff --git a/previews/PR2578/Nemo/developer/future/index.html b/previews/PR2578/Nemo/developer/future/index.html deleted file mode 100644 index 2f910485c70c..000000000000 --- a/previews/PR2578/Nemo/developer/future/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Future plans · Oscar.jl

Future plans

Ring and CommRing

Currently all commutative ring types belong to Ring and their elements to RingElem (and RingElement) and we have separate types for noncommutative rings and elements thereof, i.e. NCRing and NCRingElem etc.

However, it would be more logical to use Ring for not necessarily commutative rings and CommRing, CRing or CommutativeRing (the name has not been decided on yet) for commutative rings.

This is a big change and should happen with plenty of warning for the community. It would be convenient if a script could be made available to automate this.

Mono repository

There is currently a proposal to place all Oscar related repositories, or some subset of them in a single repository called OscarMono.jl. The details are not finalised and it is not known what impact this will have on Nemo. However, Nemo developers should be aware that this may happen at some point in the fairly near future.

Users of Nemo should be unaffected, as Nemo will continue to exist as a separate package in the OscarMono.jl repository, even if it does become part of this repository. Julia supports multiple packages in the same repository nowadays.

The possibility will always exist to separate the repositories again if the experiment is unsuccessful or serves its purpose and is no longer needed.

Moving implementations from Hecke

In the Hecke.jl project there are a vast number of implementations that were intended for AbstractAlgebra.jl and Nemo.jl. They exist in the src/Misc directory of that project.

These implementations will eventually all be moved over to the correct repositories. Code, documentation and performance improvements will be added.

A number of things must be taken into account when making such moves:

  • Substantial chunks of code should be moved at a time. The code can be initially placed in a src/Misc directory in AbstractAlgebra or Nemo until it can finally be integrated fully into the correct place in those projects.

  • Some of the code calls full parent object constructors in generic code. Such calls should be removed where possible.

  • Some functions such as exp and the like require Base to be prepended, as we do not import these functions from Base into Generic.

  • Some of the code calls back into convenience functions found only in Hecke. These have to be rewritten in terms of AbstractAlgebra/Nemo functions.

  • Some of the code relies on ZZRingElem being available, but would otherwise be suitable for AbstractAlgebra. This code can hopefully be rewritten to be agnostic about the integer type.

  • Todos, questions and so on should be moved to tickets.

  • Sometimes exception types differ between Hecke and Nemo, meaning that tests will fail due to the wrong type of exception being raised. Either the tests will have to be adjusted, or the Nemo exception types changed.

  • RingElem is often used where RingElement is intended, etc. Also types are often unconstrained where Nemo would constrain them to RingElement.

  • Some Hecke functions try to support generic types and specific concrete Nemo types in the same implementation. These will unfortunately have to either be split between AbstractAlgebra and Nemo or a completely generic implementation for abstract types will have to be made.

  • Some Hecke implementations assume sub! and friends are available in generic code. These will have to be rewritten, usually by adding a single unary minus outside of a loop and switching to add! and friends inside the loops.

  • Test code, docstrings and documentation will have to be added where they do not already exist.

  • Exports of the new functionality will have to be added.

  • Some functions should be accompanied by similar functions that don't yet exist. For example if there is a blah_rows there probably should be a blah_cols function as well, etc.

diff --git a/previews/PR2578/Nemo/developer/img/types.svg b/previews/PR2578/Nemo/developer/img/types.svg deleted file mode 100644 index 2c498e168b13..000000000000 --- a/previews/PR2578/Nemo/developer/img/types.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
RingElem
RingElem
NCRingElem
NCRingElem
MPolyRingElem{T}
MPolyRingElem{T}
ResElem{T}
ResElem{T}
FracElem{T}
FracElem{T}
SeriesElem{T}
SeriesElem{T}
FieldElem
FieldElem
MatAlgElem{T}
MatAlgElem{T}
RelPowerSeriesRingElem{T}
RelPowerSeriesRingElem{T}
AbsPowerSeriesRingElem{T}
AbsPowerSeriesRingElem{T}
MatElem{T}
MatElem{T}
MatrixElem{T}
MatrixElem{...
ResFieldElem{T}
ResFieldElem{T}
PolyRingElem{T}
PolyRingElem{T}
LaurentPolyRingElem{T}
LaurentPolyRingElem{T}
NCPolyRingElem{T}
NCPolyRingElem{T}
PolynomialElem{T}
Polynom...
NumFieldElem{T}
NumFieldElem{T}
FinFieldElem
FinFieldElem
SimpleNumFieldElem{T}
SimpleNumFieldEl...
GroupElem
GroupElem
AdditiveGroupElem
AdditiveGroupElem
ModuleElem{T}
ModuleElem{T}
FPModuleElem{T}
FPModuleElem{T}
AbstractPerm
AbstractPerm
IdealElem{T}
IdealElem{T}
SetMap
SetMap
IdentityMap
IdentityMap
FunctionalMap
FunctionalMap
FPModuleHomomorphism
FPModuleHomomorp...
Map{D, C, S, T}
Map{D, C, S, T}
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/previews/PR2578/Nemo/developer/img/types2.svg b/previews/PR2578/Nemo/developer/img/types2.svg deleted file mode 100644 index 39e647e5e93a..000000000000 --- a/previews/PR2578/Nemo/developer/img/types2.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
Ring
Ring
NCRing
NCRing
MPolyRing{T}
MPolyRing{T}
ResidueRing{T}
ResidueRing{T}
FracField{T}
FracField{T}
SeriesRing{T}
SeriesRing{T}
Field
Field
MatAlgebra{T}
MatAlgebra{T}
MatSpace{T}
MatSpace{T}
ResidueField{T}
ResidueField{T}
PolyRing{T}
PolyRing{T}
LaurentPolyRing{T}
LaurentPolyRing{T}
NCPolyRing{T}
NCPolyRing{T}
NumField{T}
NumField{T}
FinField
FinField
SimpleNumField{T}
SimpleNumField{T}
Group
Group
AdditiveGroup
AdditiveGroup
Module{T}
Module{T}
FPModule{T}
FPModule{T}
AbstractPermutationGroup
AbstractPermutat...
Ideal{T}
Ideal{T}
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/previews/PR2578/Nemo/developer/interfaces/index.html b/previews/PR2578/Nemo/developer/interfaces/index.html deleted file mode 100644 index b285498cdefd..000000000000 --- a/previews/PR2578/Nemo/developer/interfaces/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Interfaces · Oscar.jl

Interfaces

Functionality for Generic and Abstract Types

As previously mentioned, Nemo provides various generic types, e.g. Poly{T} for generic univariate polynomials and Mat{T} for generic matrices over a base ring. These and other polynomial and matrix types belong in turn to abstract types or unions thereof, e.g. PolyRingElem{T} is an abstract type representing all univariate polynomial types and MatrixElem{T} is a union of all Nemo matrix types.

When implementing generic functionality, one should usually implement it for the abstract types and unions thereof, since the new functionality will then work for all types of the specified kind, instead of just the generic types.

In order for this to work in practice, such implementations can only use functions in the relevant official interface. These are the functions required to be implemented by all types of that kind. For example, matrix implementations make heavy use of addeq! and mul! to accumulate entries, but they cannot make use of functions such as subeq! as it is not part of the official interface.

In addition to implementations for abstract types and their unions, one may also like to provide specialised implementations for the generic types e.g. Poly{T} and Mat{T} as one would for other specialised types. The generic types are based on Julia arrays internally, and so it makes perfect sense to implement lower level functionality for these types specifically, as this may lead to performance gains. Such specialised implementations can make use of any functions provided for the generic types, whether in the interface or not.

For convenience we list the most important abstract types and their unions for which one should usually prefer to write generic implementations.

  • PolyRingElem{T} : all univariate polynomial types
  • MPolyRingElem{T} : all multivariate polynomial types (see note below)
  • MatrixElem{T} : union of all matrix types including matrix algebras
  • MatElem{T} : all matrix types not including matrix algebras
  • AbsPowerSeriesRingElem{T} : all abstract series types
  • RelPowerSeriesRingElem{T} : all relative series types
  • LaurentSeriesElem{T} : union of all Laurent series over rings and fields
  • PuiseuxSeriesElem{T} : union of all Puiseux series over rings and fields
  • FPModule{T} : all finitely presented modules over a Euclidean domain
  • FPModuleElem{T} : all elems of fin. presented modules over a Euc. domain
  • FracElem{T} : all fractions
  • ResElem{T} : all elements of a residue ring
  • ResFieldElem{T} : all elements of a residue field
  • Map{D, C} : all maps (see Maps developer docs for a description)

N.B: inside the Generic submodule of AbstractAlgebra some abstract types Blah are only accessible by writing AbstractAlgebra.Blah. The unions are directly accessible. There may be generic types and abstract types with the same name, so this is more than just a convention.

Note that multivariate polynomials tend to require very specialised implementations depending heavily on implementation details of the specific multivariate type. Therefore it is rare to write implementations for the abstract type MPolyRingElem{T}. Instead, implementations tend to be done for each concrete multivariate type separately.

Generic interfaces

As mentioned above, the generic implementations in Nemo depend on carefully written interfaces for each of the abstract types provided by the system.

These interfaces are spelled out in the AbstractAlgebra documentation. Note that a generic implementation may depend on functions in both the required and optional interfaces as the optional functions are all implemented with generic fallbacks in terms of the required functions.

For convenience we provide here a list of interfaces that can be relied on in generic implementations, along with a description.

  • Ring : all commutative rings in the system
  • Field : all fields in the system
  • NCRing : all rings in the system (not necessarily commutative)
  • Euclidean Ring : Euclidean rings (see notes below)
  • Univariate Polynomial Ring : all dense univariate polynomials
  • Multivariate Polynomial Ring : all sparse distributed multivariate polys.
  • Series Ring : all series, relative and absolute
  • Residue Ring : all quotients of gcd domains with gcdx by a principal ideal
  • Fraction Field : all fractions over a gcd domain with gcdx
  • Module : all finitely presented modules over a Euclidean domain
  • Matrix : all matrices over a commutative ring
  • Map : all (set) maps in the system

Although we allow Z/nZ in our definition of Euclidean ring, much of the functionality in Nemo can be expected to misbehave (impossible inverses, etc.) when working with Euclidean rings that are not domains. In some cases the algorithms just don't exist, and in other cases we simply haven't implemented the required functionality to support all Euclidean rings for which computations can be done.

Whether a ring is a Euclidean domain or not cannot be encoded in the type. Thus there is no abstract type for Euclidean domains or their elements. Instead, generic functions rely on the existence of certain functions such as gcdx to implement functionality for Euclidean domains.

There is also currently no way to define a Euclidean function for a given ring (which is known to be Euclidean) and have the system recognise the ring as such. This kind of Euclidean interface may be provided in a future version of Nemo.

Julia interfaces we support

Many Julia interfaces rely on being able to create zero and one elements given the type only. As we use the parent/element model (see developer notes on this topic) we cannot support all Julia interfaces fully.

We do however partially implement some Julia interfaces.

  • Iteration : iterators are currently provided for multivariate polynomials to iterate over the coefficients, terms and monomials. Nemo matrices can also be iterated over. Iteration proceeds down each column in turn. One can also iterate over all permutations and partitions. Finally, all finite field types can be iterated over.

  • Views : because C libraries cannot be expected to implement the full range of Julia view types, views of matrices in Nemo can only be constructed for submatrices consisting of contiguous blocks in the original matrix.

  • map and similar : we implement the map and similar interfaces with the caveat that we generally use parent objects where Julia would use types. See the specific documentation for the module of interest to see details.

  • zero and one : these are implemented for parent types, which is not what Julia typically expects. Exceptions include the Flint ZZRingElem and QQFieldElem types, as their parents are not parameterised, which makes it possible to implement these functions for the types as well as the parents.

  • rand : we have a Nemo specific rand interface, which passes the tail of a given rand invocation to the rand function for the base ring, e.g. to create random matrix elements or polynomial coefficients and so on. In addition to this custom rand interface, we also support much of the Julia rand interface, with the usual caveat that we use parent objects instead of types where necessary.

  • serialisation : unfortunately this is currently NOT implemented by Nemo, but we would certainly like to see that done in the future. It's not automatic because of the C objects that underly many of our constructions.

  • Number : Nemo number types do NOT belong to Julia's Number hierarchy, as we must make all our ring element types belong to our RingElem abstract type. To make some Julia Number types cooperate with Nemo, we define the unions RingElement and FieldElement which include some Julia types, such as BigInt and Rational{BigInt}, etc. Note that fixed precision integer types cannot be expected to be well-behaved when they overflow. We recommend using Nemo integer types if one wants good performance for small machine word sized integers, but no overflow when the integer becomes large (Nemo integers are based on Flint's multiprecision ZZRingElem type).

  • hash : we implement hash functions for all major element types in Nemo.

  • getindex/setindex!/typed_hvcat : we implement these to access elements of Nemo matrices, however see the note below on row major representation. In addition, we allow creation of matrices using the notation R[a b; c d] etc. This is done by overloading typed_hvcat for the parent object R instead of a type as Julia would normally expect. This produces a Nemo matrix rather than a Julia one. Note that when passed a type, Julia's typed_hvcat can only construct Julia matrices for Nemo types such as ZZRingElem and QQFieldElem where elements can be constructed from types alone.

Many other Julia interfaces are either not yet implemented or only very partially implemented.

Column major vs row major matrices

Whereas Julia uses column major representation for its matrices, Nemo follows the convention of the C libraries it wraps and uses row major representation. Although Julia 2-D arrays are used internally in Nemo's generic matrix type, the interface from the perspective of the user is still the Nemo row major convention, not the Julia column major convention.

In row major representation, some row operations may be able to be performed more cheaply than similar column operations. In column major representation the converse is true. This may mean that some Julia matrix implementations may perform more slowly if naively ported to Nemo matrices, unless suitably modified.

diff --git a/previews/PR2578/Nemo/developer/introduction/index.html b/previews/PR2578/Nemo/developer/introduction/index.html deleted file mode 100644 index 1397df2bd37a..000000000000 --- a/previews/PR2578/Nemo/developer/introduction/index.html +++ /dev/null @@ -1,7 +0,0 @@ - -Introduction to Nemo development · Oscar.jl

Introduction to Nemo development

Relationship to AbstractAlgebra.jl

Some time in the past, Nemo was split into two packages called Nemo.jl and AbstractAlgebra.jl. The purpose was to provide a Julia only package which did some subset of what Nemo could do, albeit slower. This was requested by people in the Julia community.

Unfortunately this hasn't been terribly successful. Most Julia developers expect that AbstractAlgebra and Nemo functionality will work for Julia matrices over AbstractAlgebra/Nemo rings. This would be possible for functions that do not conflict with Base or LinearAlgebra at least when working with non-empty matrices. However, for reasons that we explain in both the Appendix to the AbstractAlgebra package and in the parent object section of the developer documentation, this is not possible even in theory for functions that would conflict with Julia's standard library or for empty matrices (except in a limited number of special cases).

Unfortunately the Julia standard library functions do not work with matrices of Nemo objects and there is little we can do about this. Moreover, some Julia functionality isn't supported by the underlying C libraries in Nemo and would be difficult or impossible to provide on the C side.

Nowadays we see AbstractAlgebra to provide three things to Nemo:

  • An abstract type hierarchy
  • Generic ring constructions, e.g. generic polynomials and matrices
  • Generic implementations that should work for any ring implementing the required interfaces. These interfaces are documented in the AbstractAlgebra documentation.

Nemo itself is now more or less just a wrapper of four C libraries:

  • Flint : polynomials and matrices over Z, Q, Z/nZ, Qp, Fq
  • Arb : polynomials, matrices and special functions over balls over R and C
  • Antic : algebraic number field element arithmetic
  • Calcium : exact real and complex numbers, including algebraic numbers

Each ring implemented in those C libraries is wrapped in such a way as to implement the interfaces described by AbstractAlgebra.

Most of the time an AbstractAlgebra implementation will work just as well using Nemo, but the latter will usually be faster, due to the extremely performant C code (around half a million lines of it).

Layout of files

In the src directory of Nemo are four directories flint, arb, antic and calcium, each containing the wrappers for the relevant C libraries. The test directory is similarly organised.

Within each of these directories is a set of files, one per module within the C libraries, e.g. the fmpz.jl file wraps the Flint fmpz module for multiple precision integers. The fmpz_poly.jl file wraps the Flint univariate polynomials over fmpz integers, and so on.

The QQFieldElem prefix is for Flint rationals, FqPolyRepFieldElem for Flint finite fields with multiprecision characteristic, fqPolyRepFieldElem is the same but for single word characteristic. The padic prefix is for the field of p-adic numbers for a given p. The zzModRingElem prefix is for Z/nZ for a given n. The gfp prefix is the same as Z/nZ but where n is prime, so that we are dealing with a field.

The FlintTypes.jl file contains the implementation of all the Flint types.

In the antic directory, nf_elem is for elements of a number field.

The AnticTypes.jl file contains the Antic types.

In the arb directory the arb prefix is for arbitrary precision ball arithmetic over the reals. The acb prefix is similar but for complex numbers.

The ArbTypes.jl file contains the Arb types.

In the calcium directory the ca prefix is for Calcium's type. There is also a qqbar file for the field of algebraic numbers.

In the AbstractAlgebra.jl package the src directory contains a directory called generic. This is where the implementations of generic types, such as matrices, polynomials, series, etc. reside. Each file such as Matrix.jl corresponds to a generic group/ring/field or other algebraic construction (typically over a base ring). The files in this directory exist inside a submodule of AbstractAlgebra called Generic.

The file GenericTypes.jl is where all the generic types are implemented.

At the top level of the src directory is a file Generic.jl which is where the Generic submodule of AbstractAlgebra begins and where imports are made from AbstractAlgebra into Generic.

In the src directory we have implementations that work for every type belonging to a given abstract type, e.g. Matrix.jl has implementations that will work for any matrix type, whether from AbstractAlgebra's Generic module or even matrix types from Nemo, and so on. So long as they are implemented to provide the Matrix interface all the functions there will work for them. The same applies for Poly.jl for polynomial types, AbsSeries.jl for absolute series types, RelSeries.jl for relative series types, etc.

In the src directory is AbstractTypes.jl where all the AbstractAlgebra abstract types are defined.

Also in the src directory is a subdirectory called Julia. This is where we give our own implementations of functionality for Julia Integers and Rationals and various other basic rings implemented in terms of Julia types. These are provided so that the package will work as a pure Julia package, replacing many of the rings and fields that would be available in Flint and the other C libraries with Julia equivalents.

Note that some of the implementations we give there would conflict with Base and so are only available inside AbstractAlgebra and are not exported!

We try to keep the test directory at the top level of the source tree organised in the same manner as the other directories just discussed, though there is currently no split between tests for Generic and for the implementations in src. All tests are currently combined in test/generic..

Git, GitHub and project workflows

The official repositories for AbstractAlgebra and Nemo are:

https://github.com/Nemocas/AbstractAlgebra.jl

https://github.com/Nemocas/Nemo.jl

If you wish to contribute to these projects, the first step is to fork them on GitHub. The button for this is in the upper right of the main project page. You will need to sign up for a free GitHub account to do this.

Once you have your own GitHub copy of our repository you can push changes to it from your local machine and this will make them visible to the world.

Before sinking a huge amount of time into a contribution, please open a ticket on the official project page on GitHub explaining what you intend to do and discussing it with the other developers.

The easiest way to get going with development on your local machine is to dev AbstractAlgebra and/or Nemo. To do this, press the ] key in Julia to enter the special package mode and type:

dev Nemo

Now you will find a local copy on your machine of the Nemo repository in

.julia/dev/Nemo

However, this will be set up to push to the official repository instead of your own, so you will need to change this. For example, if your GitHub account name is myname, edit the .git/config file in your local Nemo directory to say:

        url = https://github.com/Nemocas/Nemo.jl.git
-        pushurl = https://github.com/myname/Nemo.jl

instead of just the first line which will already be there.

It is highly recommended that you do not work in the master branch, but create a new branch for each thing you want to contribute to Nemo.

git checkout -b mynewbranch

If your contribution is small and does not take a long time to implement, everything will likely be fine if you simply commit the changes locally, then push them to your GitHub account online:

git commit -a
-git push --all

However, if you are working on a much larger project it is highly recommended that you frequently pull from the official master branch and rebase your new branch on top of any changes that have been made there:

git checkout master
-git pull
-git checkout mynewbranch
-git rebase master

Note that rebasing will try to rewrite each of your commits over the top of the branch you are rebasing on (master in this case). This process will have many steps if there are many commits and lots of conflicts. Simply follow the instructions until the process is finished.

The longer you leave it before rebasing on master the longer the rebase process will take. It can eventually become overwhelming as it is not replaying the latest state of your repository over master, but each commit that you made in order. You may have completely forgotten what those older commits were about, so this can become very difficult if not done regularly.

Once you have pushed your changes to your GitHub account, go to the official project GitHub page and you should see your branch mentioned near the top of the page. Open a pull request.

Someone will review your code and suggest changes they'd like made. Simply add more commits to your branch and push again. They will automatically get added to your pull request.

Note that we don't accept code without tests and documentation. We use Documenter.jl for our documentation, in Markdown format. See our existing code for examples of docstrings above functions in the source code and look in the docs/src directory to see how these docstrings are merged into our online documentation.

Development list

All developers of AbstractAlgebra and Nemo are welcome to write to our development list to ask questions and discuss development:

https://groups.google.com/g/nemo-devel

Reporting bugs

Bugs should be reported by opening an issue (ticket) on the official GitHub page for the relevant project. Please state the Julia version being used, the machine you are using and the version of AbstractAlgebra/Nemo you are using. The version can be found in the Project.toml file at the top level of the source tree.

Development roadmap

AbstractAlgebra has a special roadmap ticket which lists the most important tickets that have been opened. If you want to contribute something high value this is the place to start:

https://github.com/Nemocas/AbstractAlgebra.jl/issues/492

This ticket is updated every so often.

Binaries

Binaries of C libraries for Nemo are currently made in a separate repository:

https://github.com/JuliaPackaging/Yggdrasil

If code is added to any of the C libraries used by Nemo, this jll package must be updated first and the version updated in Nemo.jl before the new functionality can be used. Ask the core developers for help with this as various other tasks must be completed at the same time.

Relationship to Oscar

Nemo and AbstractAlgebra are heavily used by the Oscar computer algebra system being developed in Germany by a number of universities involved in a large project known as TRR 195, funded by the DFG.

Oscar is the number one customer for Nemo. Many bugs in Nemo are found and fixed by Oscar developers and most of the key Nemo developers are part of the Oscar project.

See the Oscar website for further details:

https://www.oscar-system.org/

diff --git a/previews/PR2578/Nemo/developer/parents/index.html b/previews/PR2578/Nemo/developer/parents/index.html deleted file mode 100644 index 688dc26d2b96..000000000000 --- a/previews/PR2578/Nemo/developer/parents/index.html +++ /dev/null @@ -1,12 +0,0 @@ - -Parent objects · Oscar.jl

Parent objects

The use of parent objects in Nemo

The parent/element model

As for other major computer algebra projects such as Sage and Magma, Nemo uses the parent/element model to manage its mathematical objects.

As explained in the appendix to the AbstractAlgebra documentation, the standard type/object model used in most programming languages is insufficient for much of mathematics which often requires mathematical structures parameterised by other objects.

For example a quotient ring by an ideal would be parameterised by the ideal. The ideal is an object in the system and not a type and so parameterised types are not sufficient to represent such quotient rings.

This means that each mathematical "domain" in the system (set, group, ring, field, module, etc.) must be represented by an object in the system, rather than a type. Such objects are called parent objects.

Just as one would write typeof(a) to get the type of an object a in an object/type system of a standard programming language, we write parent(a) to return the parent of the object a.

When talked about with reference to a parent in this way, the object a is referred to as an element of the parent. Thus the system is divided into elements and parents. For example a polynomial would be an element of a polynomial ring, the latter being the parent of the former.

Naturally the parent/element system leads to some issues in a programming language not built around this model. We discuss some of these issues below.

Types in the parent/element model

As all elements and parents in Nemo are objects, those objects have types which we refer to as the element type and parent type respectively.

For example, Flint integers have type ZZRingElem and the parent object they all belong to, FlintZZ has type ZZRing.

More complex parents and elements are parameterised. For example, generic univariate polynomials over a base ring R are parameterised by R. The base ring of a ring S can be obtained by the call base_ring(S).

We have found it extremely useful to parameterise the type of both the parent and element objects of such a ring by the type of the elements of the base ring. Thus for example, a generic polynomial with Flint integer coefficients would have type Poly{ZZRingElem}.

In practice Flint already implements univariate polynomials over Flint integers, and these have type ZZPolyRingElem. But both ZZPolyRingElem and the generic polynomials Poly{ZZRingElem} belong to the abstract type PolyRingElem{ZZRingElem} making it possible to write functions for all univariate polynomials over Flint integers.

Given a specific element type or parent type it is possible to compute one from the other with the functions elem_type and parent_type. For example parent_type(ZZPolyRingElem) returns ZZPolyRing and elem_type(ZZPolyRing) returns ZZPolyRingElem. Similarly parent_type(Generic.Poly{ZZRingElem}) returns Generic.PolyRing{ZZRingElem} and so on.

These functions are especially useful when writing type assertions or constructing arrays of elements insides function where only the parent object was passed.

Other functions for computing types

Sometimes one needs to know the type of a polynomial or matrix one would obtain if it were constructed over a given ring or with coefficients/entries of a given element type.

This is especially important in generic code where it may not even be known which Julia package is being used. The user may be expecting an AbstractAlgebra object, a Nemo object or even some other kind of object to be constructed, depending on which package they are using.

The function for returning the correct type for a dense matrix is dense_matrix_type to which one can pass either a base ring or an element type. For example, if AbstractAlgebra is being used, dense_matrix_type(ZZ) will return Mat{BigInt} whereas if Nemo is being used it will return ZZMatrix.

We also have dense_poly_type for univariate polynomials, abs_series_type for absolute series and rel_series_type for relative series.

In theory such functions should exist for all major object types, however they have in most cases not been implemented yet.

Functions for creating objects of a similar type

A slightly more consistent interface for creating objects of a type that is suitable for the package currently in use is the similar interface.

For example, given a matrix M one can create one with the same dimensions but over a different ring R by calling similar(M, R). Likewise one can create one over the same ring with different dimensions r x c by calling similar(M, r, c).

The similar system is sophisticated enough to know that there is no native type provided by Flint/Antic for matrices and polynomials over a number field. The system knows that in such cases it must create a generic matrix or polynomial over the given number field.

A great deal of thought went into the design of the similar system so that developers would not be required to implement similar for every pair of types in the package.

Again this interface should exist for all major Nemo domains, but the functionality is still being implemented in some cases.

Changing base rings and map

Given a polynomial, matrix or other composite object over a base ring, it is often convenient to create a similar object but with all the entries or coefficients coerced into a different ring.

For this purpose the function change_base_ring is provided.

Similarly it may be useful to create the matrix or polynomial that results by applying a given map/function/lambda to each of the entries or coefficients.

For this purpose Julia's map function is overloaded. There are also functions specific to polynomials and matrices called map_coefficients and map_entries respectively, which essentially do the same thing.

Note that the implementation of such functions must make use of the functions discussed above to ensure that a matrix/polynomial of the right type is output.

Parent checking

When applying binary operations to a pair of elements of a given ring, it is useful to check that they are in fact elements of the same ring. This is not possible by checking the types alone. For example elements of $Z/7Z$ and $Z/3Z$ would have the same type but different parents (one parameterised by the integer 7, the other by the integer 3).

In order to perform such a check in a function one uses check_parent(a, b) where a and b are the objects one wishes to assert must have the same parent. If not, an exception is raised by check_parent.

Parent object constructors

Various functions are provided for constructing parent objects. For example a polynomial ring is constructed by calling a polynomial_ring function. Such functions are called parent object constructors.

In general parent object constructors are intended for the user and should not be used in library code. There are a number of reasons for this.

Firstly, inside the Generic submodule of AbstractAlgebra the only parent object constructors that are directly accessible are the ones inside Generic. Thus if a Nemo function calls a function inside Generic and it creates a parent object using one of the parent object constructors, it will create a parent object for a generic ring rather than a Nemo one.

One can work around this by calling AbstractAlgebra.polynomial_ring instead of simply polynomial_ring inside Generic, but even safer would be to find another way to construct the polynomials required.

A second issue is that parent objects are allowed to be as large as one likes and they are cached by the system. They can also perform arbitrary precomputations for the ring/field/module etc. that is being constructed. Over time they tend to accumulate such precomputations, slowing down all generic code which made use of them. Both memory usage and performance may blow out in previously working code.

Thirdly, parent objects must be unique across the system for a given set of parameters. This means they must be cached globally. This is problematic for any future attempts to parallelise library code and in the worst case memory usage can balloon due to swelling caches.

Most parent object constructors take a cached keyword which specifies whether the parent object should be cached or not, but again it is better overall to simply eschew the use of parent object constructors in library code.

Instead, it is recommended to use functions such as similar, zero, zero_matrix, identity_matrix, change_base_ring, map, etc. for constructing polynomials and matrices directly.

There are also functions that provide alternative ways of constructing objects, e.g. matrix provides a means of creating a matrix over a given ring with given dimensions. The constructor polynomial allows creation of a polynomial over a given base ring with given coefficients and abs_series and rel_series do similar things for absolute and relative series. These should be used in preference to parent object constructors where possible. Additional functions of this type should be added in future.

However even when using these functions in library code, it is important to remember to pass cached=false so that the cache is not filled up by calls to the library code. But this creates an additional problem, namely that if one uses polynomial say, to construct two polynomials over the same base ring, they will not be compatible in the sense that they will have different parents.

When one wishes to construct multiple elements in the same group/ring/field, it is convenient to be able to construct a parent just as a user would. For this purpose various light-weight and very safe parent constructors are provided for use in library code.

For example there are the constructors PolyRing, AbsPowerSeriesRing and RelPowerSeriesRing. These functions return the parent ring $R$ only and no generator (it can be obtained by calling gen(R)). They also set the variable for printing to a default (usually x). Moreover, these parents are not cached, so they are completely safe to use in library code. They can be thousands of times faster than the full parent constructors intended for users.

Here is an example of their use:

julia> R = PolyRing(ZZ)
-Univariate polynomial ring in x over ZZ
-
-julia> p = R([1, 2, 3])
-3*x^2 + 2*x + 1
-
-julia> q = R([2, 3, 4])
-4*x^2 + 3*x + 2
-
-julia> s = p + q
-7*x^2 + 5*x + 3

Naturally functions like polynomial and matrix and the light-weight parent constructors are missing for other modules in Nemo at present and it is hoped that developers will fill in such infrastructure rather than simply push the can down the road for someone else to fix. Forcing the creating of full parent objects into as few bottlenecks as possible will make it much easier for developers to remove problems associated with such calls when they arise in future.

diff --git a/previews/PR2578/Nemo/developer/topics/index.html b/previews/PR2578/Nemo/developer/topics/index.html deleted file mode 100644 index 87b539855628..000000000000 --- a/previews/PR2578/Nemo/developer/topics/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Specific topics · Oscar.jl

Specific topics

Julia arithmetic

At the console, Julia arithmetic is often defined in a way that a numerical person would expect. For example, 3/1 returns a floating point number 3.0, sqrt(4) returns the floating point number 2.0 and exp(0) returns the floating point number 1.0.

In each case the ring is changed from the input to the output of the function. Whilst this is often what one expects to happen in a computer algebra system, these are not the definitions one would want for algebraic operations.

In this section we describe the alternatives we have implemented to allow algebraic computations, particularly for rings and fields.

divexact and divides

Nemo implements numerous kinds of division:

  • floating point division using the / operator as per Julia
  • exact division in a ring using divexact and divides
  • quotient field element construction using // as per Julia
  • Euclidean division using div, rem, divrem, mod and %

The expression divexact(a, b) for a and b in a ring R returns a value c in R such that a = bc. If such an element of R does not exist, an exception is raised.

To instead test whether such an element exists, divides(a, b) returns a tuple (flag, q) where flag is a boolean saying whether such an exact quotient exists in the ring and if so q is such a quotient.

Euclidean division

Nemo must provide Euclidean division, i.e. given a and b in a Euclidean ring R it must be able to find q and r such that a = bq + r with r smaller than a with respect to some fixed Euclidean function on R. There are some restrictions imposed by Julia however.

Firstly, % is a constant alias of rem in Julia, so these are not actually two independent functions but the same function.

Julia defines div, rem and divrem for integers as a triple of functions that return Euclidean quotient and remainder, where the remainder has the same sign as the dividend, e.g. rem(1, 3) == 1 but rem(-2, 3) == -2. In other words, this triple of functions gives Euclidean division, but without a consistent set of representatives.

When using Nemo at the console (or indeed inside any other package without importing the internal Nemo definitions) div, rem and divrem return the same values as Julia and these functions follows the Julia convention of making the sign of the remainder the same as the dividend over ZZ, e.g. rem(ZZ(1), ZZ(3)) == 1 but rem(ZZ(-2), ZZ(3)) == -2.

Internally to Nemo however, this is not convenient. For example, Hermite normal form over ZZ will only return a unique result if there is a consistent choice of representatives for the Euclidean division. This applies to the generic HNF code in AbstractAlgebra, but similar problems exist for the generic finitely presented module code in AbstractAlgebra, even when used over Nemo integers. Thus the Julia definition of rem will not suffice.

Furthermore, as Nemo wraps Flint, it is convenient that Euclidean division inside Nemo should operate the way Flint operates. This is critical if for example one wants the result of a Hermite normal form coming from Flint to be reduced using the same definition of Euclidean remainder as used elsewhere throughout the Nemo module and to return the same answers as the generic HNF code in AbstractAlgebra for example.

In particular, Flint defines Euclidean remainder over the integers in line with the Julia function mod, namely by returning the smallest remainder with the same sign as the divisor, i.e. mod(1, 3) == 1 but mod(1, -3) == -2.

Therefore internally, Nemo chooses div, mod and divrem to be a consistent triple of functions for Euclidean division, with mod defined as per Julia. Thus in particular, div and divrem behave differently to Julia inside of Nemo itself, viz. Nemo.divrem(-1, 3) == (-1, 2).

The same definitions for div, mod and divrem are used internally to AbstractAlgebra as well, even for Julia integers, so that AbstractAlgebra and Nemo are both consistent internally. However, both AbstractAlgebra and Nemo export definitions in line with Julia so that behaviour at the console is consistent.

The Nemo developers have given considerable thought to this compromise and the current situation has evolved over many iterations to the current state. We do not consider this to be a situation that needs 'fixing', though we are acutely aware that many tickets will be opened complaining about some inconsistency.

When reflecting on the choice we have made, one must consider the following:

  • Nemo must internally behave as Flint does for consistency
  • There are also functions such as powmod, invmod that reduce as per mod
  • HNF requires a consistent set of representatives for uniqueness over ZZ

Also note that Julia's rem does not provide symmetric mod, a misconception that often arises. The issues here are independent of the decision to use positive remainder (for positive modulus) in Flint, rather than symmetric mod.

We are aware that the conventions we have chosen have inconsistencies with Julia and do not have the nice property that div, rem and divrem are a triple of Euclidean functions inside Nemo. However, we are sure that the convention we have chosen is one of only two sensible possibilities, and switching to the other convention (apart from being a huge amount of effort) would only succeed in replacing one kind of inconsistency with another.

As a consequence of these choices, div, mod and divrem are a triple of functions for all Euclidean division across Nemo, not just for the integers. As generic code must use a consistent set of functions, we ask that developers respect this choice by using these three functions in all generic code. The functions rem and % should only be used for Julia integers, and only when one specifically wants the Julia definition.

sqrt, inv and exp

As mentioned above, Julia does not perform computations within a given ring, but often returns a numerical result when given an exact input.

Whilst this is often what a user expects, it makes operations such as power series square root, inversion or exponentiation more tricky over an exact ring.

Therefore, AbstractAlgebra defines sqrt, inv and exp internally in a strictly algebraic way, returning a result only if it exists in the ring of the input and otherwise raising an exception.

For example, AbstractAlgebra.sqrt(4) == 2, AbstractAlgebra.inv(-1) == -1 and AbstractAlgebra.exp(0) == 1.

Naturally these definitions are not so terribly useful to a user and are only needed for internal consistency. Therefore, of course these definitions are not exported by AbstractAlgebra so that the behaviour at the console is not affected by these definitions.

There is currently some inconsistency in that Nemo follows the Julia numerical definitions internally rather than following the algebraic definitions provided internally in AbstractAlgebra. This may or may not change in future.

It is worth recalling that Julia provides isqrt for integer square root. This is not sufficient to solve our problem as we require square root for all rings, not just integers. We don't feel that developers will want to type isqrt rather than sqrt internally for all rings.

A number of changes are expected to be made with regard to the behaviour of root taking and division functions, including the ability to specify high performance alternatives that do not check the exactness of the computation. These changes are being discussed on the Nemo ticket https://github.com/Nemocas/Nemo.jl/issues/862 In particular, the table given there by thofma represents the current consensus on the changes that will be made in the future.

Note that many of the above issues with exact computations in rings exist for all the Julia transcendental functions, sin, cos, log, etc., of which there are many. If we ever add some kind of generic power series functions for these, we may extend the internal definitions to include exact algebraic versions of all these functions. At least for now this is not a pressing issue.

The way that AbstractAlgebra deals with functions which must have a different definition inside the module than what it exports is as follows. Firstly, we do not import the functions from Base or export the functions at all. Internally we make our definitions as we want them, but then we overload the Base version explicitly to do what the console version of the function should do. This is done by explicitly defining Base.sqrt(::ZZRingElem) for example without explicitly importing sqrt from Base, etc.

In the Generic module discussed below, we import the definitions from AbstractAlgebra rather than Base.

Determinant

Another function which Nemo handles differently to Julia is det for determinant of matrices. If the input is an integer matrix, Nemo outputs an integer rather than a floating point number for the determinant.

However, this is not such an acute problem as Julia's det has now been placed in LinearAlgebra rather than Base. Moreover, Nemo has its own matrices and so does not conflict with the definition of det for Julia matrices.

It is important for developers to understand this difference however. It is not generally wise to use the Julia linear algebra functionality on the Julia matrices underlying generic Nemo matrices for this reason.

The Generic submodule

In AbstractAlgebra we define a submodule called Generic. The purpose of this module is to allow generic constructions over a given base ring. For example in Nemo, R, x = Generic.polynomial_ring(ZZ, "x") will construct a generic polynomial ring over Nemo integers instead of constructing a Flint polynomial ring.

In other words x will have the type Generic.Poly{ZZRingElem} instead of the usual ZZPolyRingElem.

The ability to construct generic polynomials and matrices and the like is useful for test code and for tracking down bugs in basic arithmetic. It is also useful for performance comparison of arithmetic defined for generic ring constructions vs the specialised implementations provided by C libraries like Flint.

Whilst most developers will not need to use the Generic module specifically, unless they have such needs, all Nemo developers need to understand how to define new generic ring constructions and functions for them. They also need to understand some subtleties that arise because of this mechanism.

Firstly, a generic construction like polynomial_ring must be defined inside the Generic submodule of AbstractAlgebra. All files inside the src/generic directory of AbstractAlgebra exist for this purpose. However, exporting from that submodule will not export the functionality to the Nemo user.

To do this, one must add a function polynomial_ring for example, in src/Poly.jl, say, which calls Generic.polynomial_ring. Then one needs to export polynomial_ring from AbstractAlgebra (also in that file).

Similarly, all functions provided for generic polynomial rings are not automatically available, even when exported from the Generic submodule. Two additional things are required, namely an import from Generic into AbstractAlgebra and then an export from AbstractAlgebra to the user.

An exception to this is if there is a function with the same name in AbstractAlgebra (i.e. in the top level src directory). In this case it is sufficient to simply import that function into Generic in the file src/Generic.jl.

In the former case, two large lists exist in src/AbstractAlgebra.jl with these imports and exports. These are kept in alphabetical order to prevent duplicate imports/exports being added over time.

If one wishes to extend a definition provided by Base, one can simply overload Base.blah inside the Generic submodule directly. Exceptions to this include the div, mod, divrem, sqrt, inv and exp functions mentioned above.

For AbstractAlgebra types, one still defines these exceptions blah by overloading Base.blah directly inside Generic. However, for the versions that would conflict with the Julia definition (e.g. the definition for Int), we instead define AbstractAlgebra.blah for that specific type and a fallback AbstractAlgebra.blah(a) = Base.blah(a) which calls the Base version of the function for all other types. Of course we do not export blah from AbstractAlgebra.

In order to make the AbstractAlgebra version available in Generic (rather than the Base version), we do not import blah from Base inside Generic, but instead import it from AbstractAlgebra. One can see these imports for the exceptional functions blah in the file src/Generic.jl.

Unsafe operations and aliasing

As with most object oriented languages that overload arithmetic operators, Julia creates new objects when doing an arithmetic operation. For example, BigInt(3) + BigInt(5) creates a new BigInt object to return the value BigInt(8). This can be problematic when accumulating many such operations in a single coefficient of a polynomial or entry of a matrix due to the large number of temporary objects the garbage collector must allocate and clean up.

To speed up such accumulations, Nemo provides numerous unsafe operators, which mutate the existing elements of the polynomial, matrix, etc. These include functions such as add!, addeq!, mul!, zero! and addmul!.

These functions take as their first argument the object that should be modified with the return value.

Note that functions such as sub!, submul! and subeq! are not in the official interface and not provided consistently, thus generic code cannot rely on them existing. So far it has always been the case that when doing accumulation where subtraction is needed rather than addition, that a single negation can be performed outside the accumulation loop and then the additive versions of the functions can be called inside the loop where the performance matters.

If we encounter cases in future where this is not the case, it may be necessary to add the versions that do subtraction to the interface. However, this can only be done if all rings in Nemo support it. One cannot define a fallback which turns a subtraction into a negation and an addition, as then the old performance characteristics of a new object being created per operation will result, meaning that the developer will not be able to reason about the likely performance of unsafe operators.

Interaction of unsafe operators and immutable types

Because not all objects in Nemo are mutable, the unsafe operators somehow have to support immutable objects. This is done by also returning the "modified" return value from the unsafe operators. Naturally, this return value is not a mutated version of the original value, as that is not possible. However, it does allow the unsafe operators to accept immutable values in their first argument. Instead of modifying this value, the old value is replaced with the return value of the unsafe operator.

In order to make this work correctly, every single call to an unsafe operator must assign the return value to the original location. This requires discipline on the part of the developer using unsafe operators.

For example, to set the existing value a to a + b one must write

a = addeq!(a, b)

i.e. one must have an explicit assignment to the left of the addeq! call and indeed all the unsafe operator calls.

In the case of a mutable type, addeq! will simply modify the original a. The modified object will be returned and assigned to the exact same variable, which has no effect.

In the case of an immutable type, addeq! does not modify the original object a as this is impossible, but it still returns the new value and assigns it to a which is what one wants.

Aliasing rules and mutation

One must be incredibly careful when mutating an existing value that one owns the value. If the user passes an object to a generic function for example and it changes the object without the user knowing, this can result in incorrect results in user code due to the value of their objects changing from under them.

In the first instance, functions should never modify their inputs. But further problems can also occur if the output of an unsafe operator happens to alias one of the other inputs. Such cases need to be handled exceptionally carefully.

A second issue arises as Nemo is based on Flint, which has its own aliasing rules which are distinct from the default expectation in Julia. This leads to some interesting corner cases.

In particularly, Flint always allows aliasing of inputs and outputs in its polynomial functions but expects matrix functions to have output matrices that are distinct from their inputs, except in a handful of functions that are specially documented to be inplace operations.

Moreover, when assigning an element to a coefficient of a polynomial or entry of a matrix Flint always makes a copy of the element being assigned to that location. In Julia however, if one assigns an element to some index of an array, the existing object at that location is replaced with the new object. This means that inplace modification of Julia array elements is not safe as it would modify the original object that was assigned to that location, whereas in Flint inplace modification is highly desirable for performance reasons and is completely safe due to the fact that a copy was made when the value was assigned to that location.

We have developed over a period of many years a set of rules that maximise the performance benefit we get from our unsafe operators, whilst keeping the burden imposed on the programmer to a minimum. It has been a very difficult task to arrive at the set of rules we have whilst respecting correctness of our code, and it would be extremely hard to change any of them.

Arithmetic operations return a new object

In order to make it easy for the Nemo developer to create a completely new object when one is needed, e.g. for accumulating values using unsafe operators, we developed the following rules.

Whenever an arithmetic operation is used, i.e. +, -, *, unary minus and ^, Nemo always returns a new object, in line with Julia. Naturally, deepcopy also makes a copy of an object which can be used in unsafe functions.

Note that if R is a type and an element a of that type is passed to it, e.g. R(a) then, the Julia convention is that the original object a will be returned rather than a copy of a. This convention ensures there is not an additional cost when coercing values that are already of the right type, e.g in generic code where coercion may or may not be needed depending on the type.

We extend this convention to parent objects R and elements a of that parent. In particular, R(a) cannot be used to make a copy of a for use in an unsafe function if R is the parent of a.

All other functions may also return the input object if they wish. In other words, the return value of all other functions is not suitable for use in an unsafe function. Only return values of arithmetic operations and deepcopy or objects freshly created using inner constructors will be suitable for such use.

This convention has been chosen to maximise performance of Nemo. Low level operations (where performance matters) make a new object, even if the result is the same arithmetically as one of the inputs. But higher level functions will not necessarily make a new object, meaning that they cannot be used with unsafe functions.

Aliasing rules

We now summarise the aliasing rules used by Nemo and AbstractAlgebra. We are relatively confident by now that following these rules will result in correct code given the constraints mentioned above.

  • matrices are viewed as containers which may contain elements that alias one another. Other objects, e.g. polynomials, series, etc., are constructed from objects that do not alias one another, even in part

  • standard unsafe operators, addeq!, mul!, addmul!, zero!, add! which mutate their outputs are allow to be used iff that output is entirely under the control of the caller, i.e. it was created for the purpose of accumulation, but otherwise must not be used

  • all arithmetic functions i.e. unary minus, +, -, *, ^, and deepcopy must return new objects and cannot return one of their inputs

  • all other functions are allowed to return their inputs as outputs

  • matrix functions with an exclamation mark should not mutate the objects that occur as entries of the output matrix, though should be allowed to arbitrarily replace/swap the entries that appear in the matrix. In other words, these functions should be interpreted as inplace operations, rather than operations that are allowed to mutate the actual entries themselves

  • R(a) where R is the parent of a, always just returns a and not a copy

  • setcoeff! and setindex! and getcoeff and getindex should not make copies. Note that this implies that setcoeff! should not be passed an element that aliases another somewhere else, even in part

  • Constructors for polynomials, series and similar ring element objects (that are not matrices) that take an array as input, must ensure that the coefficients being placed into the object do not alias, even in part

The SparsePoly module

The SparsePoly module in AbstractAlgebra is a generic module for sparse univariate polynomials over a given base ring.

This module is used internally, e.g. in the generic multivariate gcd code, however it is not particularly suitable for general use.

Firstly, whilst the representation is sparse (recursive) the algorithms used generally are not. This is because the amount of time taken by the Jit in Julia is simply too large (upwards of 6s for the first multivariate gcd).

Secondly, the order of terms in that representation is not the one which a developer would expect for a sparse univariate format.

If the Julia Jit is ever made orders of magnitude faster, it may be worth cleaning up this module and making it generally available. But for now, it should be considered internal and heavily incomplete.

Parent object caching

Parent objects in Nemo must be unique given the data that is used to create them. For this purpose most parent objects are cached globally and looked up upon creation. If a parent object with that data already exists, it is returned from the cache instead of creating a new one.

There are two situations where this can be problematic however.

The first situation is if one is doing some parallel programming. Here global objects are a blight and it may be necessary to turn off caching and simply ensure that that same data is only ever used once when creating parent objects.

The second situation is when doing multimodular algorithms, where many similar parent objects with different moduli are created. The cache can become overwhelmed slowing the code down or even grinding to a halt.

In both these situations one can pass false as an additional argument to a parent constructor to avoid caching the parent object it creates. This parameter normally has a default value of true and under normal circumstances doesn't need to be supplied.

Note that special light-weight parent constructors, PolyRing, AbsPowerSeriesRing, RelPowerSeriesRing, etc. are also provided which do not cache.

Throw/nothrow for check_parent

By default the check_parent functions throw an exception if parents do not match. However sometimes one would like to know if they match without throwing.

For this purpose one can pass an additional false argument to check_parent. This suppresses the exception that would be thrown if the parent objects didn't match. Instead the function simply returns true or false to indicate whether they matched or not.

Delayed reduction

When working in residue rings, various functions will perform an arithmetic operation followed by a reduction modulo the modulus of the residue ring.

Some accumulations, e.g. in linear algebra or polynomial arithmetic, can be dramatically sped up if one can delay the reductions that would happen after each operation in the accumulation.

Some of the Generic code in Nemo is designed to allow such delayed reduction if the ring supports it and to simply use fallbacks that do the reduction after every intermediate operation if they don't.

To support delayed reduction, a ring must support the delayed reduction interface which we describe here.

Two additional functions must be supplied for the element type. We give examples for the Nemo nf_elem type:

mul_red!(z::nf_elem, x::nf_elem, y::nf_elem, red::Bool)

This function behaves as per mul! but only performs reduction if the additional boolean argument red is set to true. This function can assume that both the inputs are reduced.

reduce!(x::nf_elem)

This function must perform reduction on an unreduced element (mutating it). Note that it must return the mutated value as per all unsafe operators.

Finally, the add! and addeq! operators must be able to add nonreduced values.

If one wishes to speed up generic code for rings that provide delayed reduction, one makes use of the function addmul_delayed_reduction! in the accumulation loop. Here is an example for accumulation into a two dimensional matrix element in Generic in a matrix multiplication routine:

A[i, j] = base_ring(X)()
-for k = 1:ncols(X)
-    A[i, j] = addmul_delayed_reduction!(A[i, j], x[i, k], y[k, j], C)
-end
-A[i, j] = reduce!(A[i, j])

Here C is a temporary element of the same type as the other inputs which is used internally in addmul_delayed_reduction! if needed.

Notice the final call to reduce! to reduce the accumulated value after the accumulation loop has finished.

Note that mul_red! is never called directly but is called inside the generic implementation of addmul_delayed_reduction! for rings that support delayed reduction. That generic code falls back to a call to addmul! which in turn falls back to mul! and addeq! where delayed reduction or addmul! are not available.

diff --git a/previews/PR2578/Nemo/developer/typesystem/index.html b/previews/PR2578/Nemo/developer/typesystem/index.html deleted file mode 100644 index 4b28ba72bd30..000000000000 --- a/previews/PR2578/Nemo/developer/typesystem/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -The type system · Oscar.jl

The type system

Use of Julia types in Nemo

Concrete and abstract types

Julia does not provide a traditional class/inheritance approach to programming. Instead, the basic unit of its object oriented approach is the type definition (struct and mutable struct) and inheritance exists only on the function side of the language rather than data side. Julia provides a rich system of abstract types and unions on the data side and multimethods on the function side to effect this.

For example Julia's Number type is an abstract type containing all concrete types that behave like numbers, e.g. Int64, Float64, and so on.

Abstract types can also belong to other abstract types, forming a tree of abstract types.

In Nemo the most important abstract types are Ring and Field, with the latter belonging to the former so that all fields are rings, and the abstract types RingElem and FieldElem for the objects that represent elements of rings and fields, again with the latter abstract type belonging to the former.

Because this hierarchy of abstract types must form a tree, Julia is strictly speaking single inheritance, as each concrete and abstract type can belong to at most one other abstract type. For example, one could not have a diamond of abstract types with ExactField belonging to both Field and ExactRing.

Recovering aspects of multiple inheritance in Nemo

Various possibilities exist to get around the limitation that abstract types must form a 'tree' in Nemo and AbstractAlgebra.

One such possibility is union types. If a function should accept one of a number of concrete or abstract types that can't all be made to belong to a single abstract type due to this limitation then one can use a union type.

For example, Nemo defines RingElement to be a union of RingElem and all the Julia standard types which behave like ring elements, e.g. all Integer types and types of rationals with Integer components.

Other union types are defined in src/AbstractAlgebra.jl in AbstractAlgebra.

A second feature we make use of in Nemo is parameterised types. Each concrete and abstract type can take one or more parameters. These parameter can be any other type, either concrete or abstract. For example, in Julia Rational{T} is for rationals with numerator and denominator of type T.

A great deal of control over parameterised types is possible, e.g. one can restrict the type parameter T using a where clause, e.g. to write a function that accepts all rational types with integer components of the same type one can use the type Rational{T} where T <: Integer.

Nemo makes use of such parameterised types for generic ring constructions such as generic polynomial rings and matrices over a given base ring. The type of the elements of the base ring is substituted for the parameter T in any concrete instantiation of the types Poly{T} and Mat{T}, which are defined in AbstractAlgebra in src/generic/GenericTypes.jl.

The totality of all univariate polynomial types, including those of generic Poly{T} types and those coming from C libraries (such as ZZPolyRingElem), is represented by the abstract type PolyRingElem{T} which in turn belongs to RingElem, both defined in AbstractAlgebra in src/AbstractTypes.jl.

Similarly, the totality of all matrix types, including explicit C types like ZZMatrix and the generic Mat{T} types is given by the abstract type MatElem{T}, again defined in AbstractAlgebra in src/AbstractTypes.jl.

This hierarchy of types allows one to write functions at any level, e.g. for all univariate polynomial types, just those with a given base type T, or for a specific concrete type corresponding to just one kind of univariate polynomial.

A third possibility to get around the single inheritance limitation of Julia is type traits. There is currently no explicit compiler/language support for traits, however various implementations exist that make use of type parameters in tricky ways. This allows one to add 'traits' to types, so long as those traits can be expressed as types. In this way, types can have multiple 'properties' at the same time, instead of belonging to just a single abstract type.

Nemo does not currently use type traits, though the map types in Nemo do make use of a custom analogue of this.

Note that unlike class based systems that dispatch on the type of a (sometimes implicit) this or self parameter, Julia methods dispatch on the type of all arguments. This is a natural fit for mathematics where all sorts of ad hoc left and right operations may be required.

Encapsulation, maps and runtime flags

One limitation of the Julia approach is that the type of an object cannot be changed at runtime. For example one might like to insist that a given ring is in fact a field. There are three standard ways to handle this in Julia.

The first approach is to encapsulate the object in another object which does have the desired type. The second approach is to map the object to a different one of the required type (e.g. by applying a morphism). The third approach is to introduce data fields in the original type which can be changed at runtime, unlike its type. All three approaches come with downsides.

Encapsulation can be time consuming for the developer as methods which applied to the original object do not automatically apply to the encapsulated object. One can write methods which do, but this is not automatic.

Application of a map may come with a performance penalty and may be difficult for the user to navigate. Moreover, mutation of the resulting object does not result in mutation of the original object.

The third option of adding runtime data fields essentially takes one back to writing a (possibly bug ridden) interpreter. It relies on the developer implementing outer methods that make use of hand written control statements to determine which of a range of inner methods should be applied to the object. This misses the benefits of one of the main defining features of Julia, namely its multimethod system and can also make introspection more difficult.

Nemo does not apply any of these three approaches widely at present, though information which can only be known at runtime such as whether a ring is Euclidean will eventually have to be encoded using one of these three methods.

Nemo's custom map types

It makes sense that map types in Nemo should be parameterised by the element types of both the domain and codomain of the map, and of course all maps in the system should somehow belong to an abstract type Map.

This leads one to consider a two parameter system of types Map{D, C} where D and C are the domain and codomain types respectively.

One may also wish to implement various types of map, e.g. linear maps (where the map contains a matrix representing the map) or functional maps (where the map is implemented by a Julia function) and so on. Notionally one imagines doing this with a hierarchy of two parameter abstract types all ultimately belonging to Map{D, C} as the root of the tree.

This approach begins to break down when constructions from homological algebra begin to be applied to maps. In such cases, the maps themselves are the object of study and functions may be applied to maps to produce other maps.

The simplest such function is composition. In a system where composition of maps always results in a map of the same type, no problem arises with the straightforward approach outlined above.

However, for various reasons (including performance) it may not be desirable or even possible to construct a composition of two given maps using the same representation as the original maps. This means that the result of composing two maps of the same type may be a map of a different type, e.g. in the worst case a general composition type.

This problem makes many homological and category theoretic operations on maps difficult or impossible to implement.

Other operations which may be desirable to implement are caching of maps (e.g. where the map is extremely time consuming to compute, such as discrete logarithms) and attaching category theoretic information to maps. Such operations can be effected by encapsulating existing maps in objects containing the extra information, e.g. a cache or a category. However all the methods that applied to the original map objects now no longer apply to the encapsulated objects.

To work around these limitations Nemo implements a four parameter Map type, Map{D, C, T, U}.

The first two parameters are the domain and codomain types as discussed above.

The parameter T is a "map class" which is itself an abstract type existing in a hierarchy of abstract types. This parameter is best thought of as a trait, independent of the hierarchy of abstract types belonging to Map, giving additional flexibility to the map types in the system.

For example, T may be set to LinearMap or FunctionalMap. This may be useful if one wishes to distinguish maps in other ways, e.g. whether they are homomorphisms, isomorphisms, maps with section or retraction etc. As usual, offering traits partially gets around the single inheritance problem.

The final parameter U is used to allow maps of a given type U to be composed and still result in a map of type U, even though the concrete type of the composition is different to that of the original maps. Methods can be written for all maps of type U by matching this parameter, rather than matching on the concrete type U of the original maps.

For example, two maps with concrete type MyRingHomomorphism would belong to Map{D, C, T, MyRingHomomorphism} as would any composition of such maps, even if the concrete type of the composition was not a MyRingHomomorphism.

Naturally four parameter types are rather unwieldy and so various helper functions are provided to compute four parameter map types. In the first instance one still has the type Map{D, C} which will give the union of all map types whose first two parameters are D and C, and where the remaining two parameters are arbitrary.

However one can also pass a map class or a concrete type U to a Map function to compute the class of all maps of the given map class or type.

For example, to write a function which accepts all maps of "type" MyRingHomomorphism, including all compositions of such maps, one inserts Map(MyRingHomomorphism) in place of the type, e.g.

function myfun(f::Map(MyRingHomomorphism))

Note the parentheses here, rather than curly braces; it's a function to compute a type! Now the function myfun will accept any map type whose fourth parameter U is set to MyRingHomomorphism.

This four parameter system is flexible, but may need to be expanded in the future. For example it may be useful to have more than one trait T. This could be achieved either by making T a tuple of traits or by introducing a parameterised MapTrait type which can be placed at that location. Naturally the Map functions for computing the four parameter types will have to be similarly expanded to make it easier for the user.

The map type system is currently considered experimental and our observation so far is that it is not intuitive for developers.

Type hierarchy diagram

The most important abstract types in the system are the element types. Their hierarchy is shown in the following diagram.

alt text

Most of the element types have a corresponding parent abstract type. These are shown in the following diagram.

alt text

diff --git a/previews/PR2578/Nemo/exact/index.html b/previews/PR2578/Nemo/exact/index.html deleted file mode 100644 index eb6c6a33b3d3..000000000000 --- a/previews/PR2578/Nemo/exact/index.html +++ /dev/null @@ -1,172 +0,0 @@ - -Exact real and complex numbers · Oscar.jl

Exact real and complex numbers

Exact real and complex numbers are provided by Calcium. Internally, a number $z$ is represented as an element of an extension field of the rational numbers. That is,

\[z \in \mathbb{Q}(a_1,\ldots,a_n)\]

where $a_1, \ldots, a_n$ are symbolically defined algebraic or transcendental real or complex numbers such as $\pi$, $\sqrt{2}$ or $e^{\sqrt{2} \pi i}$. The user does not normally need to worry about the details of the internal representation; Calcium constructs extension numbers and fields automatically as needed to perform operations.

The user must create a CalciumField instance which represents the mathematical domain $\mathbb{C}$. This parent object holds a cache of extension numbers and fields used to represent individual elements. It also stores various options for evaluation (documented further below).

LibraryElement typeParent type
CalciumcaCalciumField

Please note the following:

  • It is in the nature of exact complex arithmetic that some operations must be implemented using incomplete heuristics. For example, testing whether an element is zero will not always succeed. When Calcium is unable to perform a task, Nemo will throw an exception. This ensures that Calcium fields behave exactly and never silently return wrong results.

  • Calcium elements can optionally hold special non-numerical values:

    • Unsigned infinity $\hat \infty$

    • Signed infinities ($\pm \infty$, $\pm i \infty$, and more generally $e^{i \theta} \cdot \infty$)

    • Undefined

    • Unknown

    By default, such special values are disallowed so that a CalciumField represents the mathematical field $\mathbb{C}$, and any operation that would result in a special value (for example, $1 / 0 = \hat \infty$) will throw an exception. To allow special values, pass extended=true to the CalciumField constructor.

  • CalciumField instances only support single-threaded use. You must create a separate parent object for each thread to do parallel computation.

  • When performing an operation involving two ca operands with different parent objects, Nemo will arbitrarily coerce the operands (and hence the result) to one of the parents.

Calcium field options

The CalciumField parent stores various options that affect simplification power, performance, or appearance. The user can override any of the default values using C = CalciumField(options=dict) where dict is a dictionary with Symbol => Int pairs. To retrieve the option values as a dictionary (including any default values not set by the user), call options(C).

The following options are supported:

OptionExplanation
:verboseEnable debug output
:print_flagsFlags controlling print style
:mpoly_ordMonomial order for polynomials
:prec_limitPrecision limit for numerical evaluation
:qqbar_deg_limitDegree limit for algebraic numbers
:low_precInitial precision for numerical evaluation
:smooth_limitFactor size limit for smooth integer factorization
:lll_precPrecision for integer relation detection
:pow_limitMaximum exponent for in-field powering
:use_gbEnable Gröbner basis computation
:gb_length_limitMaximum ideal basis length during Gröbner basis computation
:gb_poly_length_limitMaximum polynomial length during Gröbner basis computation
:gb_poly_bits_limitMaximum bit size during Gröbner basis computation
:gb_vieta_limitMaximum degree to use Vieta's formulas
:trig_formDefault form of trigonometric functions

An important function of these options is to control how hard Calcium will try to find an answer before it gives up. For example:

  • Setting :prec_limit => 65536 will allow Calcium to use up to 65536 bits of precision (instead of the default 4096) to prove inequalities.

  • Setting :qqbar_deg_limit => typemax(Int) (instead of the default 120) will force most calculations involving algebraic numbers to run to completion, no matter how long this will take.

  • Setting :use_gb => 0 (instead of the default 1) disables use of Gröbner bases. In general, this will negatively impact Calcium's ability to simplify field elements and prove equalities, but it can speed up calculations where Gröbner bases are unnecessary.

For a detailed explanation, refer to the following section in the Calcium documentation: https://fredrikj.net/calcium/ca.html#context-options

Basic examples

julia> C = CalciumField()
-Exact Complex Field
-
-julia> exp(C(pi) * C(1im)) + 1
-0
-
-julia> log(C(-1))
-3.14159*I {a*b where a = 3.14159 [Pi], b = I [b^2+1=0]}
-
-julia> log(C(-1)) ^ 2
--9.86960 {-a^2 where a = 3.14159 [Pi], b = I [b^2+1=0]}
-
-julia> log(C(10)^23) // log(C(100))
-11.5000 {23/2}
-
-julia> 4*atan(C(1)//5) - atan(C(1)//239) == C(pi)//4
-true
-
-julia> Cx, x = polynomial_ring(C, "x")
-(Univariate Polynomial Ring in x over Exact Complex Field, x)
-
-julia> (a, b) = (sqrt(C(2)), sqrt(C(3)))
-(1.41421 {a where a = 1.41421 [a^2-2=0]}, 1.73205 {a where a = 1.73205 [a^2-3=0]})
-
-julia> (x-a-b)*(x-a+b)*(x+a-b)*(x+a+b)
-x^4 + (-10)*x^2 + 1

Conversions and numerical evaluation

Calcium numbers can created from integers (ZZ), rationals (QQ) and algebraic numbers (QQbar), and through the application of arithmetic operations and transcendental functions.

Calcium numbers can be converted to integers, rational and algebraic fields provided that the values are integer, rational or algebraic. An exception is thrown if the value does not belong to the target domain, if Calcium is unable to prove that the value belongs to the target domain, or if Calcium is unable to compute the explicit value because of evaluation limits.

julia> QQ(C(1))
-1
-
-julia> QQBar(sqrt(C(2)) // 2)
-Root 0.707107 of 2x^2 - 1
-
-julia> QQ(C(pi))
-ERROR: unable to convert to a rational number
-
-julia> QQ(C(10) ^ C(10^9))
-ERROR: unable to convert to a rational number

To compute arbitrary-precision numerical enclosures, convert to ArbField or AcbField:

julia> CC = AcbField(64);
-
-julia> CC(exp(C(1im)))
-[0.54030230586813971740 +/- 9.37e-22] + [0.84147098480789650665 +/- 2.51e-21]*im

The constructor

(R::AcbField)(a::ca; parts::Bool=false)

returns an enclosure of the complex number a. It attempts to obtain a relative accuracy of prec bits where prec is the precision of the target field, but it is not guaranteed that this goal is achieved.

If parts is set to true, it attempts to achieve the target accuracy for both real and imaginary parts. This can be significantly more expensive if one part is smaller than the other, or if the number is nontrivially purely real or purely imaginary (in which case an exact proof attempt is made).

julia> x = sin(C(1), form=:exponential)
-0.841471 + 0e-24*I {(-a^2*b+b)/(2*a) where a = 0.540302 + 0.841471*I [Exp(1.00000*I {b})], b = I [b^2+1=0]}
-
-julia> AcbField(64)(x)
-[0.84147098480789650665 +/- 2.51e-21] + [+/- 4.77e-29]*im
-
-julia> AcbField(64)(x, parts=true)
-[0.84147098480789650665 +/- 2.51e-21]

The constructor

(R::ArbField)(a::ca; check::Bool=true)

returns a real enclosure. If check is set to true (default), the number a is verified to be real, and an exception is thrown if this cannot be determined. With check set to false, this function returns an enclosure of the real part of a without checking that the imaginary part is zero. This can be significantly faster.

Comparisons and properties

Except where otherwise noted, predicate functions such as iszero, ==, < and isreal act on the mathematical values of Calcium field elements. For example, although evaluating $x = \sqrt{2} \sqrt{3}$ and $y = \sqrt{6}$ results in different internal representations ($x \in \mathbb{Q}(\sqrt{3}, \sqrt{2})$ and $y \in \mathbb{Q}(\sqrt{6})$), the numbers compare as equal:

julia> x = sqrt(C(2)) * sqrt(C(3))
-2.44949 {a*b where a = 1.73205 [a^2-3=0], b = 1.41421 [b^2-2=0]}
-
-julia> y = sqrt(C(6))
-2.44949 {a where a = 2.44949 [a^2-6=0]}
-
-julia> x == y
-true
-
-julia> iszero(x - y)
-true
-
-julia> isinteger(x - y)
-true

Predicate functions return true if the property is provably true and false if the property if provably false. If Calcium is unable to prove the truth value, an exception is thrown. For example, with default settings, Calcium is currently able to prove that $e^{e^{-1000}} \ne 1$, but it fails to prove $e^{e^{-3000}} \ne 1$:

julia> x = exp(exp(C(-1000)))
-1.00000 {a where a = 1.00000 [Exp(5.07596e-435 {b})], b = 5.07596e-435 [Exp(-1000)]}
-
-julia> x == 1
-false
-
-julia> x = exp(exp(C(-3000)))
-1.00000 {a where a = 1.00000 [Exp(1.30784e-1303 {b})], b = 1.30784e-1303 [Exp(-3000)]}
-
-julia> x == 1
-ERROR: Unable to perform operation (failed deciding truth of a predicate): isequal
-...

In this case, we can get an answer by allowing a higher working precision:

julia> C2 = CalciumField(options=Dict(:prec_limit => 10^5));
-
-julia> exp(exp(C2(-3000))) == 1
-false

Real numbers can be ordered and sorted the usual way. We illustrate finding square roots that are well-approximated by integers:

julia> sort([sqrt(C(n)) for n=0:10], by=x -> abs(x - floor(x + C(1)//2)))
-11-element Vector{ca}:
- 0
- 1
- 2
- 3
- 3.16228 {a where a = 3.16228 [a^2-10=0]}
- 2.82843 {2*a where a = 1.41421 [a^2-2=0]}
- 2.23607 {a where a = 2.23607 [a^2-5=0]}
- 1.73205 {a where a = 1.73205 [a^2-3=0]}
- 2.64575 {a where a = 2.64575 [a^2-7=0]}
- 1.41421 {a where a = 1.41421 [a^2-2=0]}
- 2.44949 {a where a = 2.44949 [a^2-6=0]}

As currently implemented, order comparisons involving nonreal numbers yield false (in both directions) rather than throwing an exception:

julia> C(1im) < C(1im)
-false
-
-julia> C(1im) > C(1im)
-false

This behavior may be changed or may become configurable in the future.

Interface

iszeroMethod
iszero(a::ca)

Return whether a is the number 0.

isoneMethod
isone(a::ca)

Return whether a is the number 1.

is_algebraicMethod
is_algebraic(a::ca)

Return whether a is an algebraic number.

is_rationalMethod
is_rational(a::ca)

Return whether a is a rational number.

isintegerMethod
isinteger(a::ca)

Return whether a is an integer.

isrealMethod
isreal(a::ca)

Return whether a is a real number. This returns false if a is a pure real infinity.

is_imaginaryMethod
is_imaginary(a::ca)

Return whether a is an imaginary number. This returns false if a is a pure imaginary infinity.

Infinities and special values

By default, CalciumField does not permit creating values that are not numbers, and any non-number value (unsigned infinity, signed infinity, Undefined) will result in an exception. This also applies to the special value Unknown, used in situations where Calcium is unable to prove that a value is a number. To enable special values, use extended=true.

julia> C = CalciumField()
-Exact Complex Field
-
-julia> 1 // C(0)
-ERROR: DomainError with UnsignedInfinity:
-Non-number result
-...
-
-julia> Cext = CalciumField(extended=true)
-Exact Complex Field (Extended)
-
-julia> 1 // Cext(0)
-UnsignedInfinity

Note that special values do not satisfy the properties of a mathematical ring or field. You will likely get meaningless results if you put infinities in matrices or polynomials.

unsigned_infinityMethod
unsigned_infinity(C::CalciumField)

Return unsigned infinity ($\hat \infty$) as an element of C. This throws an exception if C does not allow special values.

infinityMethod
infinity(C::CalciumField)

Return positive infinity ($+\infty$) as an element of C. This throws an exception if C does not allow special values.

infinityMethod
infinity(a::ca)

Return the signed infinity ($a \cdot \infty$). This throws an exception if the parent of a does not allow special values.

undefinedMethod
undefined(C::CalciumField)

Return the special value Undefined as an element of C. This throws an exception if C does not allow special values.

unknownMethod
unknown(C::CalciumField)

Return the special meta-value Unknown as an element of C. This throws an exception if C does not allow special values.

is_numberMethod
is_number(a::ca)

Return whether a is a number, i.e. not an infinity or undefined.

is_undefinedMethod
is_undefined(a::ca)

Return whether a is the special value Undefined.

isinfMethod
isinf(a::ca)

Return whether a is any infinity (signed or unsigned).

is_uinfMethod
is_uinf(a::ca)

Return whether a is unsigned infinity.

is_signed_infMethod
is_signed_inf(a::ca)

Return whether a is any signed infinity.

is_unknownMethod
is_unknown(a::ca)

Return whether a is the special value Unknown. This is a representation property and not a mathematical predicate.

Complex parts

Functions for computing components of real and complex numbers will perform automatic symbolic simplifications in special cases. In general, such operations will introduce new extension numbers.

julia> real(C(2+3im))
-2
-
-julia> sign(C(2im))
-1.00000*I {a where a = I [a^2+1=0]}
-
-julia> sign(C(2+3im))
-0.554700 + 0.832050*I {a where a = 0.554700 + 0.832050*I [13*a^4+10*a^2+13=0]}
-
-julia> angle(C(2+2im))
-0.785398 {(a)/4 where a = 3.14159 [Pi]}
-
-julia> angle(C(2+3im))
-0.982794 {a where a = 0.982794 [Arg(2.00000 + 3.00000*I {3*b+2})], b = I [b^2+1=0]}
-
-julia> angle(C(2+3im)) == atan(C(3)//2)
-true
-
-julia> floor(C(pi) ^ 100)
-5.18785e+49 {51878483143196131920862615246303013562686760680405}
-
-julia> ZZ(floor(C(pi) ^ 100))
-51878483143196131920862615246303013562686760680405

Interface

realMethod
real(a::ca)

Return the real part of a.

imagMethod
imag(a::ca)

Return the imaginary part of a.

angleMethod
angle(a::ca)

Return the complex argument of a.

csgnMethod
csgn(a::ca)

Return the extension of the real sign function taking the value 1 strictly in the right half plane, -1 strictly in the left half plane, and the sign of the imaginary part when on the imaginary axis. Equivalently, $\operatorname{csgn}(x) = x / \sqrt{x^2}$ except that the value is 0 at zero.

signMethod
sign(a::ca)

Return the complex sign of a, defined as zero if a is zero and as $a / |a|$ for any other complex number. This function also extracts the sign when a is a signed infinity.

absMethod
abs(a::ca)

Return the absolute value of a.

conjMethod
conj(a::ca; form::Symbol=:default)

Return the complex conjugate of a. The optional form argument allows specifying the representation. In :shallow form, $\overline{a}$ is introduced as a new extension number if it no straightforward simplifications are possible. In :deep form, complex conjugation is performed recursively.

floorMethod
floor(a::ca)

Return the floor function of a.

ceilMethod
ceil(a::ca)

Return the ceiling function of a.

Elementary and special functions

Elementary and special functions generally create new extension numbers. In special cases, simplifications occur automatically.

julia> exp(C(1))
-2.71828 {a where a = 2.71828 [Exp(1)]}
-
-julia> exp(C(0))
-1
-
-julia> atan(C(1))
-0.785398 {(a)/4 where a = 3.14159 [Pi]}
-
-julia> cos(C(1))^2 + sin(C(1))^2
-1
-
-julia> log(1 // exp(sqrt(C(2))+1)) == -sqrt(C(2)) - 1
-true
-
-julia> gamma(C(2+3im))
--0.0823953 + 0.0917743*I {a where a = -0.0823953 + 0.0917743*I [Gamma(2.00000 + 3.00000*I {3*b+2})], b = I [b^2+1=0]}
-
-julia> gamma(C(5) // 2)
-1.32934 {(3*a)/4 where a = 1.77245 [Sqrt(3.14159 {b})], b = 3.14159 [Pi]}
-
-julia> erf(C(1))
-0.842701 {a where a = 0.842701 [Erf(1)]}
-
-julia> erf(C(1)) + erfc(C(1))
-1

Some functions allow representing the result in different forms:

julia> s1 = sin(C(1))
-0.841471 - 0e-24*I {(-a^2*b+b)/(2*a) where a = 0.540302 + 0.841471*I [Exp(1.00000*I {b})], b = I [b^2+1=0]}
-
-julia> s2 = sin(C(1), form=:direct)
-0.841471 {a where a = 0.841471 [Sin(1)]}
-
-julia> s3 = sin(C(1), form=:exponential)
-0.841471 - 0e-24*I {(-a^2*b+b)/(2*a) where a = 0.540302 + 0.841471*I [Exp(1.00000*I {b})], b = I [b^2+1=0]}
-
-julia> s4 = sin(C(1), form=:tangent)
-0.841471 {(2*a)/(a^2+1) where a = 0.546302 [Tan(0.500000 {1/2})]}
-
-julia> s1 == s2 == s3 == s4
-true
-
-julia> isreal(s1) && isreal(s2) && isreal(s3) && isreal(s4)
-true

The exponential form is currently used by default since it tends to be the most useful for symbolic simplification. The :direct and :tangent forms are likely to be better for numerical evaluation. The default behavior of trigonometric functions can be changed using the :trig_form option of CalciumField.

Proving equalities involving transcendental function values is a difficult problem in general. Calcium will sometimes fail even in elementary cases. Here is an example of two constant trigonometric identities where the first succeeds and the second fails:

julia> a = sqrt(C(2)) + 1;
-
-julia> cos(a) + cos(2*a) + cos(3*a) == sin(7*a//2)//(2*sin(a//2)) - C(1)//2
-true
-
-julia> sin(3*a) == 4 * sin(a) * sin(C(pi)//3 - a) * sin(C(pi)//3 + a)
-ERROR: Unable to perform operation (failed deciding truth of a predicate): isequal

A possible workaround is to fall back on a numerical comparison:

julia> abs(cos(a) + cos(2*a) + cos(3*a) - (sin(7*a//2)//(2*sin(a//2)) - C(1)//2)) <= C(10)^-100
-true

Of course, this is not a rigorous proof that the numbers are equal, and CalciumField is overkill here; it would be far more efficient to use ArbField directly to check that the numbers are approximately equal.

Interface

const_piMethod
const_pi(C::CalciumField)

Return the constant $\pi$ as an element of C.

const_eulerMethod
const_euler(C::CalciumField)

Return Euler's constant $\gamma$ as an element of C.

oneiMethod
onei(C::CalciumField)

Return the imaginary unit $i$ as an element of C.

sqrtMethod
Base.sqrt(a::ca; check::Bool=true)

Return the principal square root of a.

expMethod
exp(a::ca)

Return the exponential function of a.

logMethod
log(a::ca)

Return the natural logarithm of a.

powMethod
pow(a::ca, b::Int; form::Symbol=:default)

Return a raised to the integer power b. The optional form argument allows specifying the representation. In :default form, this is equivalent to a ^ b, which may create a new extension number $a^b$ if the exponent b is too large (as determined by the parent option :pow_limit or :prec_limit depending on the case). In :arithmetic form, the exponentiation is performed arithmetically in the field of a, regardless of the size of the exponent b.

sinMethod
sin(a::ca; form::Symbol=:default)

Return the sine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :exponential form, the value is represented using complex exponentials. In :tangent form, the value is represented using tangents. In :direct form, the value is represented directly using a sine or cosine.

cosMethod
cos(a::ca; form::Symbol=:default)

Return the cosine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :exponential form, the value is represented using complex exponentials. In :tangent form, the value is represented using tangents. In :direct form, the value is represented directly using a sine or cosine.

tanMethod
tan(a::ca; form::Symbol=:default)

Return the tangent of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :exponential form, the value is represented using complex exponentials. In :direct or :tangent form, the value is represented directly using tangents. In :sine_cosine form, the value is represented using sines or cosines.

atanMethod
atan(a::ca; form::Symbol=:default)

Return the inverse tangent of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :logarithm form, the value is represented using complex logarithms. In :direct or :arctangent form, the value is represented directly using arctangents.

asinMethod
asin(a::ca; form::Symbol=:default)

Return the inverse sine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :logarithm form, the value is represented using complex logarithms. In :direct form, the value is represented directly using an inverse sine or cosine.

acosMethod
acos(a::ca; form::Symbol=:default)

Return the inverse cosine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :logarithm form, the value is represented using complex logarithms. In :direct form, the value is represented directly using an inverse sine or cosine.

gammaMethod
gamma(a::ca)

Return the gamma function of a.

erfMethod
erf(a::ca)

Return the error function of a.

erfiMethod
erfi(a::ca)

Return the imaginary error function of a.

erfcMethod
erfc(a::ca)

Return the complementary error function of a.

Rewriting and simplification

complex_normal_formMethod
complex_normal_form(a::ca, deep::Bool=true)

Returns the input rewritten using standardizing transformations over the complex numbers:

  • Elementary functions are rewritten in terms of exponentials, roots and logarithms.

  • Complex parts are rewritten using logarithms, square roots, and (deep) complex conjugates.

  • Algebraic numbers are rewritten in terms of cyclotomic fields where applicable.

If deep is set, the rewriting is applied recursively to the tower of extension numbers; otherwise, the rewriting is only applied to the top-level extension numbers.

The result is not a normal form in the strong sense (the same number can have many possible representations even after applying this transformation), but this transformation can nevertheless be a useful heuristic for simplification.

diff --git a/previews/PR2578/Nemo/factor/index.html b/previews/PR2578/Nemo/factor/index.html deleted file mode 100644 index 7c188eaad5ea..000000000000 --- a/previews/PR2578/Nemo/factor/index.html +++ /dev/null @@ -1,21 +0,0 @@ - -Factorisation · Oscar.jl

Factorisation

Nemo provides a unified interface to handle factorisations using the Fact objects. These can only be constructed using the factor function for the respective ring elements. This is best illustrated by an example.

julia> fac = factor(ZZ(-6000361807272228723606))
--1 * 2 * 229^3 * 43669^3 * 3
-
-julia> unit(fac)
--1
-
-julia> -6000361807272228723606 == unit(fac) * prod([ p^e for (p, e) in fac])
-true
-
-julia> for (p, e) in fac; println("$p $e"); end
-2 1
-229 3
-43669 3
-3 1
-
-julia> 229 in fac
-true
-
-julia> fac[229]
-3

Basic functionality

Objects of type Fac are iterable, that is, if a is an object of type Fac, then for (p, e) in a will iterate through all pairs (p, e), where p is a factor and e the corresponding exponent.

inMethod
in(a, b::Fac)

Test whether $a$ is a factor of $b$.

getindexMethod
getindex(a::Fac, b) -> Int

If $b$ is a factor of $a$, the corresponding exponent is returned. Otherwise an error is thrown.

lengthMethod
length(a::Fac) -> Int

Return the number of factors of $a$, not including the unit.

unitMethod
unit(a::Fac{T}) -> T

Return the unit of the factorization.

diff --git a/previews/PR2578/Nemo/ff_embedding/index.html b/previews/PR2578/Nemo/ff_embedding/index.html deleted file mode 100644 index 00a3a6824312..000000000000 --- a/previews/PR2578/Nemo/ff_embedding/index.html +++ /dev/null @@ -1,32 +0,0 @@ - -Finite field embeddings · Oscar.jl

Finite field embeddings

Introduction

Nemo allows the construction of finite field embeddings making use of the algorithm of Bosma, Cannon and Steel behind the scenes to ensure compatibility. Critical routines (e.g. polynomial factorization, matrix computations) are provided by the C library Flint, whereas high level tasks are written directly in Nemo.

Embedding functionality

It is possible to explicitly call the embedding embed function to create an embedding, but it is also possible to directly ask for the conversion of a finite field element x in some other finite field k via calling k(x). The resulting embedding is of type FinFieldMorphism. It is also possible to compute the preimage map of an embedding via the preimage_map function, applied to an embedding or directly to the finite fields (this actually first computes the embedding), or via conversion. An error is thrown if the element you want to compute the preimage of is not in the image of the embedding.

Computing an embedding

embedMethod
embed(k::T, K::T) where T <: FinField

Embed $k$ in $K$, with some additional computations in order to satisfy compatibility conditions with previous and future embeddings.

Examples

julia> k2, x2 = FiniteField(19, 2, "x2")
-(Finite field of degree 2 over GF(19), x2)
-
-julia> k4, x4 = FiniteField(19, 4, "x4")
-(Finite field of degree 4 over GF(19), x4)
-
-julia> f = embed(k2, k4)
-Morphism of finite fields from
-  from finite field of degree 2 over gF(19)
-  to finite field of degree 4 over gF(19)
-
-julia> y = f(x2)
-6*x4^3 + 5*x4^2 + 9*x4 + 17
-
-julia> z = k4(x2)
-6*x4^3 + 5*x4^2 + 9*x4 + 17

Computing the preimage of an embedding

preimage_mapMethod
preimage_map(k::T, k::T) where T <: FinField

Computes the preimage map corresponding to the embedding of $k$ into $K$.

preimage_mapMethod
preimage_map(f::FinFieldMorphism)

Compute the preimage map corresponding to the embedding $f$.

Examples

julia> k7, x7 = FiniteField(13, 7, "x7")
-(Finite field of degree 7 over GF(13), x7)
-
-julia> k21, x21 = FiniteField(13, 21, "x21")
-(Finite field of degree 21 over GF(13), x21)
-
-julia> s = preimage_map(k7, k21)
-Preimage of the morphism from Finite field of degree 7 over GF(13) to Finite field of degree 21 over GF(13)
-
-julia> y = k21(x7);
-
-julia> z = s(y)
-x7
-
-julia> t = k7(y)
-x7
diff --git a/previews/PR2578/Nemo/finitefield/index.html b/previews/PR2578/Nemo/finitefield/index.html deleted file mode 100644 index 4d36b2611fed..000000000000 --- a/previews/PR2578/Nemo/finitefield/index.html +++ /dev/null @@ -1,73 +0,0 @@ - -Finite fields · Oscar.jl

Finite fields

Finite fields are provided in Nemo by Flint. This allows construction of finite fields of any characteristic and degree for which there are Conway polynomials. It is also possible for the user to specify their own irreducible polynomial generating a finite field.

Finite fields are constructed using the FlintFiniteField function. However, for convenience we define

FiniteField = FlintFiniteField

so that finite fields can be constructed using FiniteField rather than FlintFiniteField. Note that this is the name of the constructor, but not of finite field type.

The types of finite field elements in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Flint$\mathbb{F}_{p^n}$ (small $p$)fqPolyRepFieldElemfqPolyRepField
Flint$\mathbb{F}_{p^n}$ (large $p$)FqPolyRepFieldElemFqPolyRepField

The only difference between the FqPolyRepFieldElem and fqPolyRepFieldElem types is the representation. The former is for finite fields with multiprecision characteristic and the latter is for characteristics that fit into a single unsigned machine word. The FlintFiniteField constructor automatically picks the correct representation for the user, and so the average user doesn't need to know about the actual types.

All the finite field types belong to the FinField abstract type and the finite field element types belong to the FinFieldElem abstract type.

Since all the functionality for the FqPolyRepFieldElem finite field type is identical to that provided for the fqPolyRepFieldElem finite field type, we simply document the former.

Finite field functionality

Finite fields in Nemo provide all the field functionality described in AbstractAlgebra:

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below we describe the functionality that is provided in addition to this.

Constructors

In order to construct finite field elements in Nemo, one must first construct the finite field itself. This is accomplished with one of the following constructors.

FlintFiniteFieldFunction
FlintFiniteField(char::ZZRingElem, deg::Int, s::VarName; cached = true)

Returns a tuple $S, x$ consisting of a finite field parent object $S$ and generator $x$ for the finite field of the given characteristic and degree. The string $s$ is used to designate how the finite field generator will be printed. The characteristic must be prime. When a Conway polynomial is known, the field is generated using the Conway polynomial. Otherwise a random sparse, irreducible polynomial is used. The generator of the field is guaranteed to be a multiplicative generator only if the field is generated by a Conway polynomial. We require the degree to be positive.

FlintFiniteField(pol::Union{ZZModPolyRingElem, FpPolyRingElem}, s::VarName; cached = true, check = true)

Returns a tuple $S, x$ consisting of a finite field parent object $S$ and generator $x$ for the finite field over $F_p$ defined by the given polynomial, i.e. $\mathbb{F}_p[t]/(pol)$. The characteristic is specified by the modulus of pol. The polynomial is required to be irreducible, but this is not checked. The base ring of the polynomial is required to be a field, which is checked by default. Use check = false to disable the check. The string $s$ is used to designate how the finite field generator will be printed. The generator will not be multiplicative in general.

FlintFiniteField(F::FqPolyRepField, deg::Int, s::VarName; cached = true)

Return a finite field with the same type as F but with a possibly different degree deg over the prime subfield.

Here are some examples of creating finite fields and making use of the resulting parent objects to coerce various elements into those fields.

Examples

julia> R, x = FiniteField(7, 3, "x")
-(Finite field of degree 3 over GF(7), x)
-
-julia> S, y = FiniteField(ZZ(12431351431561), 2, "y")
-(Finite field of degree 2 over GF(12431351431561), y)
-
-julia> T, t = polynomial_ring(residue_ring(ZZ, 12431351431561), "t")
-(Univariate polynomial ring in t over ZZ/(12431351431561), t)
-
-julia> U, z = FiniteField(t^2 + 7, "z")
-(Finite field of degree 2 over GF(12431351431561), z)
-
-julia> a = R(5)
-5
-
-julia> b = R(x)
-x
-
-julia> c = S(ZZ(11))
-11
-
-julia> d = U(7)
-7

Basic manipulation

genMethod
gen(a::FqPolyRepField)

Return the generator of the finite field. Note that this is only guaranteed to be a multiplicative generator if the finite field is generated by a Conway polynomial automatically.

is_genMethod
is_gen(a::FqPolyRepFieldElem)

Return true if the given finite field element is the generator of the finite field, otherwise return false.

coeffMethod
coeff(x::FqPolyRepFieldElem, n::Int)

Return the degree $n$ coefficient of the polynomial representing the given finite field element.

degreeMethod
degree(a::FqPolyRepField)

Return the degree of the given finite field.

modulusMethod
modulus(k::FqPolyRepField, var::VarName=:T)

Return the modulus defining the finite field $k$.

Examples

julia> R, x = FiniteField(ZZ(7), 5, "x")
-(Finite field of degree 5 over GF(7), x)
-
-julia> c = gen(R)
-x
-
-julia> d = characteristic(R)
-7
-
-julia> f = order(R)
-16807
-
-julia> g = degree(R)
-5
-
-julia> n = is_gen(x)
-true

Special functions

Various special functions with finite field specific behaviour are defined.

trMethod
tr(x::FqPolyRepFieldElem)

Return the trace of $x$. This is an element of $\mathbb{F}_p$, but the value returned is this value embedded in the original finite field.

normMethod
norm(x::FqPolyRepFieldElem)

Return the norm of $x$. This is an element of $\mathbb{F}_p$, but the value returned is this value embedded in the original finite field.

frobeniusMethod
frobenius(x::FqPolyRepFieldElem, n = 1)

Return the iterated Frobenius $\sigma_p^n(x)$ where $\sigma_p$ is the Frobenius map sending the element $a$ to $a^p$ in the finite field of characteristic $p$. By default the Frobenius map is applied $n = 1$ times if $n$ is not specified.

pth_rootMethod
pth_root(x::FqPolyRepFieldElem)

Return the $p$-th root of $x$ in the finite field of characteristic $p$. This is the inverse operation to the Frobenius map $\sigma_p$.

Examples

julia> R, x = FiniteField(ZZ(7), 5, "x")
-(Finite field of degree 5 over GF(7), x)
-
-julia> a = x^4 + 3x^2 + 6x + 1
-x^4 + 3*x^2 + 6*x + 1
-
-julia> b = tr(a)
-1
-
-julia> c = norm(a)
-4
-
-julia> d = frobenius(a)
-x^4 + 2*x^3 + 3*x^2 + 5*x + 1
-
-julia> f = frobenius(a, 3)
-3*x^4 + 3*x^3 + 3*x^2 + x + 4
-
-julia> g = pth_root(a)
-4*x^4 + 3*x^3 + 4*x^2 + 5*x + 2

Lift

liftMethod
lift(R::FpPolyRing, x::FqPolyRepFieldElem)

Lift the finite field element x to a polynomial over the prime field.

Examples

julia> R, x = FiniteField(23, 2, "x")
-(Finite field of degree 2 over GF(23), x)
-
-julia> S, y = polynomial_ring(GF(23), "y")
-(Univariate polynomial ring in y over GF(23), y)
-
-julia> f = 8x + 9
-8*x + 9
-
-julia> lift(S, f)
-8*y + 9

Uniform finite fields

An (experimental) uniform finite field interface is provided by the type FqField. Such a finite field can be constructed as an extension of a prime field $\mathbf{F}_p$ (an absolute extension) or of another finite field (a relative extension). The field over which the extension is constructed is referred to as the base field and field theoretic properties like the degree of an extension or the trace of an element are understood with respect to the base field. The corresponding functionality for the implicit absolute extension over the prime field is available by methods with the prefix absolute_.

Note that all finite fields are simple extension $k[t]/(f)$ of their base field $k$. The irreducible polynomial $f \in k[t]$ is the defining polynomial and the class of $t$ is referred to as the generator of the extension.

Construction of finite fields

_FiniteFieldFunction
_FiniteField(q::IntegerUnion, s::String; cached::Bool, check::Bool)
-_FiniteField(p::IntegerUnion, d::Int, s::String; cached::Bool, check::Bool)
-_FiniteField(f::FqPolyRingElem; s::String; cached::Bool, check::Bool)

Return a tuple $S, x$ consisting of a finite field $S$ of order $q = p^d$ and algebra generator $x$. The string $s$ is used to designate how the finite field generator will be printed.

If a polynomial $f \in k[t]$ over a finite field $k$ is specified, the finite field $S = k[t]/(f)$ will be constructed as a finite field with base field $k$.

_GFFunction
_GF(q::IntegerUnion, s::String; cached::Bool, check::Bool)
-_GF(p::IntegerUnion, d::Int, s::String; cached::Bool, check::Bool)
-_GF(f::FqPolyRingElem; s::String; cached::Bool, check::Bool)

Return a finite field $S$ of order $q = p^d$. The string $s$ is used to designate how the finite field generator will be printed.

If a polynomial $f \in k[t]$ over a finite field $k$ is specified, the finite field $S = k[t]/(f)$ will be constructed as a finite field with base field $k$.

Field properties

base_fieldMethod
base_field(F::FqField)

Return the base field of F.

prime_fieldMethod
prime_field(F::FqField)

Return the prime field of F.

degreeMethod
degree(a::FqField)

Return the degree of the given finite field over the base field.

absolute_degreeMethod
absolute_degree(a::FqField)

Return the degree of the given finite field over the prime field.

is_absoluteMethod
is_absolute(F::FqField)

Return whether the base field of $F$ is a prime field.

defining_polynomialMethod
defining_polynomial([R::FqPolyRing], L::FqField)

Return the defining polynomial of L as a polynomial over the base field of L.

If the polynomial ring R is specified, the polynomial will be an element of R.

Element properties

trMethod
tr(x::FqFieldElem)

Return the trace of $x$. This is an element of the base field.

absolute_trMethod
absolute_tr(x::FqFieldElem)

Return the absolute trace of $x$. This is an element of the prime field.

normMethod
norm(x::FqFieldElem)

Return the norm of $x$. This is an element of the base field.

absolute_normMethod
absolute_norm(x::FqFieldElem)

Return the absolute norm of $x$. This is an element of the prime field.

liftMethod
lift(R::FqPolyRing, a::FqFieldElem) -> FqPolyRingElem

Given a polynomial ring over the base field of the parent of a, return a lift such that parent(a)(lift(R, a)) == a is true.

diff --git a/previews/PR2578/Nemo/fraction/index.html b/previews/PR2578/Nemo/fraction/index.html deleted file mode 100644 index dadbdccd1848..000000000000 --- a/previews/PR2578/Nemo/fraction/index.html +++ /dev/null @@ -1,36 +0,0 @@ - -Fraction fields · Oscar.jl

Fraction fields

Nemo allows the creation of fraction fields over any ring $R$. We don't require $R$ to be an integral domain, however no attempt is made to deal with the general case. Two fractions $a/b$ and $c/d$ are equal in Nemo iff $ad = bc$. Thus, in practice, a greatest common divisor function is currently required for the ring $R$.

In order to make the representation $a/b$ unique for printing, we have a notion of canonical unit for elements of a ring $R$. When canonicalising $a/b$, each of the elements $a$ and $b$ is first divided by the canonical unit of $b$.

The canonical_unit function is defined for elements of every Nemo ring. It must have the properties

canonical_unit(u) == u
-canonical_unit(a*b) == canonical_unit(a)*canonical_unit(b)

for any unit $u$ of the ring in question, and $a$ and $b$ arbitrary elements of the ring.

For example, the canonical unit of an integer is its sign. Thus a fraction of integers always has positive denominator after canonicalisation.

The canonical unit of a polynomial is the canonical unit of its leading coefficient, etc.

There are two different kinds of implementation of fraction fields in Nemo: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of fractions over specific rings, usually provided by C/C++ libraries.

The following table shows each of the fraction types available in Nemo, the base ring $R$, and the Julia/Nemo types for that kind of fraction (the type information is mainly of concern to developers).

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jlGeneric.Frac{T}Generic.FracField{T}
$\mathbb{Z}$FlintQQFieldElemQQField

All fraction element types belong to the abstract type FracElem and all of the fraction field types belong to the abstract type FracField. This enables one to write generic functions that can accept any Nemo fraction type.

Fraction functionality

All fraction types in Nemo provide functionality for fields described in AbstractAlgebra.jl:

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

In addition all the fraction field functionality of AbstractAlgebra.jl is provided, along with generic fractions fields as described here:

https://nemocas.github.io/AbstractAlgebra.jl/stable/fraction

Basic manipulation

signMethod
sign(a::QQFieldElem)

Return the sign of $a$ ($-1$, $0$ or $1$) as a fraction.

heightMethod
height(a::QQFieldElem)

Return the height of the fraction $a$, namely the largest of the absolute values of the numerator and denominator.

height_bitsMethod
height_bits(a::QQFieldElem)

Return the number of bits of the height of the fraction $a$.

<<Method
<<(a::QQFieldElem, b::Int)

Return $a \times 2^b$.

>>Method
>>(a::QQFieldElem, b::Int)

Return $a/2^b$.

floorMethod
floor(a::QQFieldElem)

Return the greatest integer that is less than or equal to $a$. The result is returned as a rational with denominator $1$.

ceilMethod
ceil(a::QQFieldElem)

Return the least integer that is greater than or equal to $a$. The result is returned as a rational with denominator $1$.

Examples

julia> d = abs(ZZ(11)//3)
-11//3
-
-julia> 4 <= ZZ(7)//ZZ(3)
-false

Modular arithmetic

The following functions are available for rationals.

modMethod
mod(a::QQFieldElem, b::ZZRingElem)
-mod(a::QQFieldElem, b::Integer)

Return $a \pmod{b}$ where $b$ is an integer coprime to the denominator of $a$.

Examples

julia> mod(-ZZ(2)//3, 7)
-4
-
-julia> mod(ZZ(1)//2, ZZ(5))
-3

Rational Reconstruction

Rational reconstruction is available for rational numbers.

reconstructMethod
reconstruct(a::ZZRingElem, b::ZZRingElem)
-reconstruct(a::ZZRingElem, b::Integer)
-reconstruct(a::Integer, b::ZZRingElem)
-reconstruct(a::Integer, b::Integer)

Attempt to return a rational number $n/d$ such that $0 \leq |n| \leq \lfloor\sqrt{m/2}\rfloor$ and $0 < d \leq \lfloor\sqrt{m/2}\rfloor$ such that gcd$(n, d) = 1$ and $a \equiv nd^{-1} \pmod{m}$. If no solution exists, an exception is thrown.

Examples

julia> a = reconstruct(7, 13)
-1//2
-
-julia> b = reconstruct(ZZ(15), 31)
--1//2
-
-julia> c = reconstruct(ZZ(123), ZZ(237))
-9//2

Rational enumeration

Various methods exist to enumerate rationals.

next_minimalMethod
next_minimal(a::QQFieldElem)

Given $a$, return the next rational number in the sequence obtained by enumerating all positive denominators $q$, and for each $q$ enumerating the numerators $1 \le p < q$ in order and generating both $p/q$ and $q/p$, but skipping all gcd$(p,q) \neq 1$. Starting with zero, this generates every nonnegative rational number once and only once, with the first few entries being $0, 1, 1/2, 2, 1/3, 3, 2/3, 3/2, 1/4, 4, 3/4, 4/3, \ldots$. This enumeration produces the rational numbers in order of minimal height. It has the disadvantage of being somewhat slower to compute than the Calkin-Wilf enumeration. If $a < 0$ we throw a DomainError().

Examples

julia> next_minimal(ZZ(2)//3)
-3//2
next_signed_minimalMethod
next_signed_minimal(a::QQFieldElem)

Given a signed rational number $a$ assumed to be in canonical form, return the next element in the minimal-height sequence generated by next_minimal but with negative numbers interleaved. The sequence begins $0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, \ldots$. Starting with zero, this generates every rational number once and only once, in order of minimal height.

Examples

julia> next_signed_minimal(-ZZ(21)//31)
-31//21
next_calkin_wilfMethod
next_calkin_wilf(a::QQFieldElem)

Return the next number after $a$ in the breadth-first traversal of the Calkin-Wilf tree. Starting with zero, this generates every nonnegative rational number once and only once, with the first few entries being $0, 1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, \ldots$. Despite the appearance of the initial entries, the Calkin-Wilf enumeration does not produce the rational numbers in order of height: some small fractions will appear late in the sequence. This order has the advantage of being faster to produce than the minimal-height order.

Examples

julia> next_calkin_wilf(ZZ(321)//113)
-113//244
next_signed_calkin_wilfMethod
next_signed_calkin_wilf(a::QQFieldElem)

Given a signed rational number $a$ returns the next element in the Calkin-Wilf sequence with negative numbers interleaved. The sequence begins $0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, \ldots$. Starting with zero, this generates every rational number once and only once, but not in order of minimal height.

Examples

julia> next_signed_calkin_wilf(-ZZ(51)//(17))
-1//4

Random generation

rand_bitsMethod
rand_bits(::QQField, b::Int)

Return a random signed rational whose numerator and denominator both have $b$ bits before canonicalisation. Note that the resulting numerator and denominator can be smaller than $b$ bits.

Special functions

The following special functions are available for specific rings in Nemo.

harmonicMethod
harmonic(n::Int)

Return the harmonic number $H_n = 1 + 1/2 + 1/3 + \cdots + 1/n$. Table lookup is used for $H_n$ whose numerator and denominator fit in a single limb. For larger $n$, a divide and conquer strategy is used.

Examples

julia> a = harmonic(12)
-86021//27720
bernoulliMethod
bernoulli(n::Int)

Return the Bernoulli number $B_n$ for nonnegative $n$.

See also bernoulli_cache.

Examples

julia> d = bernoulli(12)
--691//2730
bernoulli_cacheMethod
bernoulli_cache(n::Int)

Precomputes and caches all the Bernoulli numbers up to $B_n$. This is much faster than repeatedly calling bernoulli(k). Once cached, subsequent calls to bernoulli(k) for any $k \le n$ will read from the cache, making them virtually free.

See also bernoulli.

Examples

julia> bernoulli_cache(100)
-
-julia> e = bernoulli(100)
--94598037819122125295227433069493721872702841533066936133385696204311395415197247711//33330
dedekind_sumMethod
dedekind_sum(h::ZZRingElem, k::ZZRingElem)

Return the Dedekind sum $s(h,k)$ for arbitrary $h$ and $k$.

Examples

julia> b = dedekind_sum(12, 13)
--11//13
-
-julia> c = dedekind_sum(-120, ZZ(1305))
--575//522
simplest_betweenMethod
  simplest_between(l::QQFieldElem, r::QQFieldElem)

Return the simplest fraction in the closed interval $[l, r]$. A canonical fraction $a_1 / b_1$ is defined to be simpler than $a_2 / b_2$ if and only if $b_1 < b_2$ or $b_1 = b_2$ and $a_1 < a_2$.

Examples

julia> simplest_between(QQ(1//10), QQ(3//10))
-1//4
diff --git a/previews/PR2578/Nemo/gfp/index.html b/previews/PR2578/Nemo/gfp/index.html deleted file mode 100644 index 784aea8e2119..000000000000 --- a/previews/PR2578/Nemo/gfp/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Galois fields · Oscar.jl

Galois fields

Nemo allows the creation of Galois fields of the form $\mathbb{Z}/p\mathbb{Z}$ for a prime $p$. Note that these are not the same as finite fields of degree 1, as Conway polynomials are not used and no generator is given.

For convenience, the following constructors are provided.

GF(n::UInt)
-GF(n::Int)
-GF(n::ZZRingElem)

For example, one can create the Galois field of characteristic $7$ as follows.

R = GF(7)

Elements of the field are then created in the usual way.

a = R(3)

Elements of Galois fields have type fpFieldElem when $p$ is given to the constructor as an Int or UInt, and of type FpFieldElem if $p$ is given as an ZZRingElem, and the type of the parent objects is fpField or FpField respectively.

The modulus $p$ of an element of a Galois field is stored in its parent object.

The fpFieldElem and FpFieldElem types belong to the abstract type FinFieldElem and the fpField and FpField parent object types belong to the abstract type FinField.

Galois field functionality

Galois fields in Nemo provide all the residue ring functionality of AbstractAlgebra.jl:

https://nemocas.github.io/AbstractAlgebra.jl/stable/residue

In addition, all the functionality for rings is available:

https://nemocas.github.io/AbstractAlgebra.jl/stable/ring

Below we describe the functionality that is provided in addition to these.

Basic manipulation

Examples

julia> F = GF(3)
-Finite field of characteristic 3
-
-julia> a = characteristic(F)
-3
-
-julia> b = order(F)
-3
diff --git a/previews/PR2578/Nemo/img/types.dia b/previews/PR2578/Nemo/img/types.dia deleted file mode 100644 index 484b473f460165ff3a5127b078da4782257ee42d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2988 zcmV;d3sdwTiwFP!000023+-K9bKAHTeb2AZXkWcBaPhrbXQw;Uv=5!OlWdMTUvE~E`@Gr|>+)hs5S~u* za=u;^?spWim~WID`|e_TUDvliou7aC@&&CPHd(!{ z(5kpYoBaHL*=m)Yn?~o;_wOc?=N&AvI$`F> z^{twA^Yv<7P42VR#q@{I?lnDcx;fwK=Y_s+vt@o&<=OAuU1Rgo`k1b7^J=%-o7?rK zFiq-*+r1_o{n&q>wP{*yOrvu7{)fM?AN(OTA3XKdcA%X`>YJ=u7UjMjb8c4tL;z9% zU`__tN@K|+c|0etH+MCxxz(`ds$tC)o6FmERaaS2@0+|@uUC0idaHGHmmhCuGtX8A zVlTNB;Kk>nuGil={?FNJbBF`}<8OD{Ywz4;RV-el_{yD(5+W{qV57D;D|YJ22aB)6vs) z)9n0vXMMNbp(n`~E&Lo@H#r@;EXXj*n_1}D6H_m>l zvvQGDi^-3ZU)Nu!PaMQBkYaH${TJRoS-b9;&P*KKJ6pHwZ;--B^D{t{@1BDF0McdP z>T0+D%6O2K%T@l(hBYzc2=gpCx%*LAlsVqC$`U*tGro9p$L%NE-B{V}oq{yl#J>jCKfE&p0SgD+{|OG4pG5SJEH zM8*WLw*rV$K4XYdW02xwE!Or_d?#A(wCTE}j^1vy+hM~0%x~7{Q(kxQ;THyxE=IC0 z>o$Y-^U3GzrdU0go6OEN}Am>zS8#H_f>`&`RsT`MNvf-W}5Jz43G?wBMNY zkD|<5hExcRNfrheV#XteG}FXJBrO@?Gl>Ys%E6DA-^W>=ugmf>FBi^}SNXT!MEa2) zi{lQ(T=Dts?h&-H;FmhJ{+QEduI*+o+CKhea&6GiM5%i1_|)X-ujWMWIoa}E(tMY0 zf0yo)%AEsxC0^SZAPt49yHhCKoyk(hPreJ38YAGzepm1$B{r5 zj$le`xB(Fp!OjRE0W)Iwg><7m)i4$o_&0OKZxauU%>&!8m}uY#X&?_yO-UFDIxI8A zb{G{Q3I2)0@e!VGcd68({52~F2Rl+IK;y95mt&c#2%O4 z=wKjAlWByo`on-M?G<3(TIS{Z?NX^^P4swyP$6w=GgKZ5s=@g$oWmzlrioh z1aszUG&F7qwpI)`)H47i2{>vfMpH2SP~@vc;)c<=VH+9~H5?x`B%}u|mN+9ANgY>= zMVt|4^;pIpn5-nSAS=kLRC*aykpRTM!*TRFn8oIu3SIZu|y9CrH4FR zti?Q2iyDN#S;550wRl4g)flQTPN|jX;V^2g7BD7u_?Fq>zt^jWE`}H`ejy>G=wQVb z)2yL~%qh08t-~042>i(TtXp$ZE)S4v?RwYJ1|FH=p#$=9ERKb+IC&Zt7cNVIhV7`x z+A7DWxYbs95(iOdegnNq3~o>cr+N@qnGC^=nh;rCr(tB!*5auTId593rhq|ogvJq)h=U! zjbVxe#WHH8?@)@U?a>@sbvyx=JI$UNK>Ofw+VU!;B6B&*tHAOq$K{MohCoFpb78)v zieD5m*8yhM2bh%wmXeXNOq~^QP&O6?0vQ|0L5?LL4+&)62au(OmBz87GFUT;`>1Se zD!UdhHkQMDOJE)}#TGrJ*vcj~6iE^{#cs@CX;W-B3qz4&W5}^>5|L8ufl}-iG^P~$ zEvMLBp-J|!#M0K4ITAYZI`_s7wnHr-uE4!jFpgy)RgrH}d>U$!LLy6d+Fa}m z;dZ^?*pxdEvVl6p-cqIux@0uaZRQiH7HS4I>uKf_1($CIy2{NdYX0ZKu09cVp{Lm$ zZnvR{JR43a_}OsfcJjhZIKw9HM&HS+)ydv<0Vf1+_sZtiFQ{QdftQX&$3dlEJ4Jvv ztOys|=+_(fdfm{|T$W%Cr9hKNn=a7?jj zjIl}d5SswJ${^~*@{=86CzchGuFj%IF|GWeDAU@KA>&gUBvXJI>EaS9$Fns)*3>@) z)~zlfSgXvk$kW zH1e7=V*`|1ac0wRNn@`#3vntfoE)+o+sh(geZ~+Yk=FogX6LU2Z(z*rMj5ej9OPJ9 zIXP(gRreE(?So`^f3b3pxz+(U4dxb^x^=EB9_FjoT9gSczfCk5|+;-^sIPO8u zXICU}1T3za&st$fSScT&&LWjCA}wFi@eQEk+lOLO@r_Vs%t;?%3ER;IaAcLSH3NtX zCo*PMNJ>rqAxE+TB88^GLeoARQ*0VzZ0cjOTib2q%|OK?%i|hLhBtY693ZOPyoUL8 zEa4w|_fPvAwiKZTSU}ni$`qu=7^G+)kN>f?0f~rGv4fPeBoOyfM?iv8FqSFcF$5{U z31|vaLp=wm6_zPXjWJC1u?vT0*iJnH#OG4hl0sZHTndN+W0~?%aH)?eMh!=$S}~bo i)JbEMf4|Be^6LFN|Hk|*tL*0eyZ-~^duTf%zyJWvio9$9 diff --git a/previews/PR2578/Nemo/img/types.png b/previews/PR2578/Nemo/img/types.png deleted file mode 100644 index 96eb037d5a2f9bcbb01c8c92fd330adbf1adda07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17647 zcmaic1yq%5yX{g`N&x{uNohq&K)OU40YRig5$Wy@U5GS_fUxKk>Fy9kKJqm)?)seQ)dc2-aZg0T6EWm#6WKso znNl6b6rIZvfgkNy*vy6_Ej^V@g$Y!jsQ+Ypg1n?z>T)|J>Ba~x_g&&w*R>?X#FBBa zpW!LrDS49DV?H5DhQ^RE=E5i;;?vhK+5!yS1+w-0KZEyKPx7*&J`Qs+-~MaBiqKe1*MSVCgfXn!&5uI-D9iZDJiA`AIp!o4*}Ddf_H zL4LV%a~8YBf~WV5X8vID$@lFVm8>0&s|if2l0KLn$$FubjzXQJq@>m5Ur2=AP;qfa zoeA-gk*|akDX%d`1hn73dDS7~>vN8n#}=^!289|!%md9KO$K-G-t9IkwFosS$KjO@ z6OEMXm-ALwowjDDL7wXB)O<2q9dqP}_z`OS{`+@{=`s`7ZpNH!%YI`GS+rB~}Ryd9zcK`yxGnai zH$KCnX`~W*@r*^htg5~JJvn4sj^In*F=;Q=G*7Ty;N}jB_E{1jHd?` zDpV`T$#VxL9gLV%da;FQH@pLYBD?~ zA7Z6i(x)d}(@&!dFB+Sbp~BR`nD#m0i=*Y%?1UQCPL>^x+3NWnBpNj?nmP_+ksL_;WAkvuQ zrYiG|Ze*&ZMKIJvlj9cso*NDQ|q`%9Xco-}Wqab#*l~hzU^M zx|Q|h4i=42nY+u>(nC$%}N;~WGhHs@u2$6N^9Bh+=QFN?Vf~TU28SuTy&^{=u@+IY%u=Z#sefr{$%v)a?oVJuAp--$t5>fIFQl8) z3!lF3wIYmYmDq0$zQwihxVxmuAlaKzEBGurmx11*5(o2}V}Wvak5p+&#tq>m3gRig z&;;X_-A>8<;$5x1FLo!n*Y)OjWV!s=i>xvQMO-!S-Mw4LZ~4^C%}q+`?Z()6U%O`N zORWBZ0lg}RfR0MHUFPG9?p{bWB`^0?%}P6l_#|Pfj=@LYk}l_jJ!hw;8{2&o!~MsF z2i49T$;`tu5K}Los(;OFz9SwPZa?2)Ib75fvz0J^7=%D=Q(Ba`&Oe#He2<1+NN8;G zyffm9c=Eg8V8bA!dbWg(q&(K<{ysiFzHyMaxcKYWuNQV+U&f8S9=W~18*jvz(d}i5 zf{ck(CpUGnOYtW|sb%+HdE@IP{^sj*&sB?B0oIs=1U4ajGw#@lT6be(W7yN_m=QzH z!evhsicV4I_B)NRI=4SRBh3f%x);BE`EqpRW;gTT42tGZ`tLu#qRq|B7IqG|=NGA^ zT&CG;)M{Ne4Rm!W3;W*^tPzEIy5HTa!$4Jc9J;OKHfc=iUoVsPLn8Xrdy<<>)Iss1jDPY?YZb1fvzx{-STXz!Ef;Eu*w?acW*T5}#}?otm{QK7U++lj}YY@Xy<^$0Twtp5Jm zHd-mkB$Oao9S`>|>fdfQtSjd9obRB8xY?H4bLV}p`!9x$N&A%E9eGR7H`4iofr;o|Lb{(5 z@yruT)`siaGqW$+y4)2d8o5eUYk2rKsSfutGBS!%rAt!om=5Rod$|u+MwSa)B0sHR zRrr#Lp%oj^8ZejnEL+X>c3K7_Q>Xr=p`4$Q_IFrqW?SAX#tU2*|M201nYnrVsCGNe zw{5Pl*;!%K-bQ&esm{IO>|s6OMt=;y*4C=DH=UzB9(VZ*m0oa@`9%}crbH3ZNF+a* z{qx85c8yd-MA!@eowL*9MbG7CYVVr5y1H~;rhDz)TKHo@q;Zp_TDcpECn1?$-4v)^ zx%3`4)^0AD#l^)G?WBRxBF!)kp%>Q_YNs(fW-h&yX?`&(lpn{E}i)mQ}- zukKXoa*trUzH;kHh#^c%tBA>8@(Q@|q3Wr4%$n9#URWdR% zDzAfS%h57f@=y5kGBO&qZl#HdliB%oRS@P`-!|{cC{8g`VMM$7qc6kMIO(z7PA45& z0&l6S^ZNeox}eiaI1dkX6kwUN<8^zA{YG4NkBzUGD*iKqfHORr8+o*R0XuG)`$+Oq0>g$WTZp|v7cw{L<*~RQGZcxg~%38EE zZ*6Tw-cxs49#{qNMngkWT3U*MiFY#XPn{Oh<$t=YfBv(j<#Se+tfHdRX1lD|Q0goZ zlj27nJj6aTJA1T}^uXp!^YD)F{@C_v`Q#N$Om%g2bb(L^WbR~ zQV~#&v9Y6HN=tX>!((HQ;3_@7)ZXW(`%rm8sYOM2c%0TJYWK(Nm7sCJ#k@~8o2i7| zD$IlY{=U|}L+^C( zUWeS?2zWFnbk2xpEhg=HAuJ#$NYG}g0Uq*fyHk`%90vzy=$9-SDs`JcHh%l|4WC+s zC8L z_oc(AUdh*=?u~wZgE`pWFDW5WaN+USRd}5J1`K=(0f*1t=V$t!yOHhAbv_s_TKElv zLWi>vIDRR4d7&Z;s%mO#s;b|k@W{A77Zh}LcIHD5P|w$!?@WwlQ_&x&^K>66E{D6h z|MCZ)%OJ-P5~9=mA_m5y=K&_#y{W^NHRawmPn^hm_7^zFwImcJuMhv5zx0Ha3(*PgVPnmod@F`9wwr zYqhI)dDo$21@>F(oZ0o{VAFgcXPR%VFY76DB+g-$-_H7^_vz8@*RNl#VVUFj?bGlw z9nq<#Fw-2yg#7sNc@IG89ZDvF7T z85tR=sYUfomt1uDNYTI>FYI3SvN;qP{`>cDeecuA2|odcg(vxXwK=%;`xEX^5QI9j zRloG~sCawV&{a!%94%&|t6=B$@bK{YL9=KYUUN1L|Am8`g@uKunTmjkAP*f^hBjA* zi{D(iHd1My+1>~P+ggcfuS>!@OmwEES>nD{ktCZPg6oe_JnfyG>%Fibzx2;&9r-43 zA;gTKmaN7*PXq)93wfWNK*^D=-o>L9v9N9^_roRa@pXl}-CG@s}wd` zCnX>tAR(EPy9UXH5_WeI6KgoyU4|x5eR2CfdaIVd2M|GK;nEmFCfnNDDl02TMn>*W zde^@pEk8e=Joh^M6OB!?xw+}Sw_^LGvenQam9{ldE&Bmk2%8$G{ahPd`z;blOhST3 zB{Za0`19vaR_(Hiid;1u;a>=mZ0&L@Nf(R`-6?XM16z&m9#8|UbdBH!Af}+;kH5Q4r!#3_UI?A)=TEst z44-uYj{}a=#^}h%O(9X|H63xR(-#plHxj+iT&sRVk+UF4Vlv59TRuywjT{xVQ&3Pa zFrcMLgU_lzJIZ#vFj7oLO}(DST80D5d8yw1;)Z2mVIkxy1Cm9fz=wbnmbk0yNy5D4 z*_^CNcZy_5TZRIP%58xLAIbda!i5X^9-B=V_(C=i!q9hnGnM2i-;=_eykQIQj1Flr zRN#ANf3&lRBuMRc*;~@~S5EnT=v1jtGh)4wfW#Nf< zi}%@fVsP-)!AHL@ag&8CN7_&@#Z8iJYlcw?!x|FbxDkm$2|6yRPAJrGUteVik(zNi z*NA3PSy6#XI?3yCurW3DJYoLY6^!_o95LAqmA-IGDtK7Ur2W7)BQAN#Us0^v`}_I1xt`O0 zq;dI~X=#QHJ{Kgy=XD@!`m3F-#ox)LbCQJ!b&`ijManU-aM}L;9v4R;5TBT6E&N#t zs&G5Cb!1f3mXI|MO4Hgtg1ctINVl8TCW24X&goz2!3iPg=Y zm|@dxbzMQ7)+n>MMe}`E8&|wBB7Wh!G?uKK+|Sn5!r@Hm>NJaqi?%g4 z*rPvupmoIJ!P4e$+*b~8GtdPXahuc|O8@D}$qJ_wI9$uCTYbMVT=;GqrnF(%k$xk3A@^q`C z+G`dwPzwwAz@A34mHg0TiGqbz*4O7Mpgsvq$VKG8hGn7i_4VD+c}#8mTrE$h)piUn zwd+dq2bsOSY$v8nTqjR(4nDQ(&&^JGzC^e zeF97ablB>_<_vl6m$I_5qN1WE+Fdrqx=+`~F2Xj3N`+CyL-Flb*AJL$ZfY8Losaj& zqjX!VoR5=L)Go6K2n;lfxjC%_%{s*#Yf_5c8E$5FAw62}XGaIn$|r~OiGbalrc(eK zKJQ9;$fOw8(%GpbCs(BY2yhu(TuVeHp9mn#G;363q-L1o@;0B)BK~b902M;+dlpb1 zc9+$laiTlfr%#_!rNiW|lbvMcArAg}|ZX*FII5cT8x_miz(?9ihD_eaqRgbNDE;oW{( z>$V#h988by*$r-YDLvK!?!&OT;b4e>zG5eZNvB`$Rl7?YuQ*t0t}fnkemZ&XD!_t( zpx}4^i>8>A65!r*c2!1P1fUuL92KU#)j|b*(_?piQk0wfBf%EHRxNf)E~B<~-pR*U zhs~mA(~B))d*~+$sk=+Z#MC^e5?cazPhCrEsk=aIZ=;0DC+EhE8zB_@A7(0m*h7i3 zr;GZNahr6($RSKk)k31Bh$xB*4<{fd{=R(zGk_(@!G8U@0@mT)sC5_x|L@^0v4JjF zit6L_dT#(|@T35I!`m2|%&hd3{ecSZ{W%dL72z`ab0Yk>Fg++s;bD zyM1s=-e-sNFnl;k&+M~F_LLo%?EUbqZ%JCeIP=FS5#EM z(3`JO*l1)&i>x{L9h6_Q^>Yv~J3N8&+E`4x(&NW*g3fuFjUP3Pj2J&eG*9_rA#N)P zZC;|8^{4hSF)=C7oca^3k9Y0bA6Ke+*NdGnKp?ih6Db`W9`+9odILn+`)O!sNFe^0 zF`|8%9x(=B9PzHc-W%otEE>p?yjo7{noTJg8JS0q9%*UCVm`u%f$EG9$8v?q7@G!y zvrt_u`AOHq=iA%cor$9Bl`UdXu#r9l;u%Vbc~9<`nVDJOsVK7QRB-U|RU{|B0J=CK z_?jUWTnUSYo`a(Rpf8fZ{gEVrI5AGsFMez?N7#Zl`OUF#btg8KwNtH^R5#XJj)IOJfd7&5j>t0 zq-7c`0`Z}x5jo49fXNjUN)z<8wB(kP!&->M(JIEDo3?%A5Kax}^h``d;%6|x2;3ne zB;+Yo=BaiN>=Mnc$B^3-?WDr5yb`Vcj>AnW@T49Vh zuyQQ6cjo9g_KPkaPbWv+nfm(L@d77r2#;3iJ!r(ujX8N$G-p*b^@VYD{ z`(x1nhZP!hjap>vP=J*rXhZpOL~EK_Hjue$+0U~3SKeQG^L1+K{w0(jJPImRB}*cg zdLYkiXYoqxya|~-XUxMO2v;BSwgh1mfr_&7^bhq(=E$Fr?L}1l@rum}1NYe2I$Bzi zw(afgC`6Ymbv3g4i}>MJjua!|&T8L<%rOlJe@aYT|LK3Zyx|@fV(JQ{r8PiLfb%45 zItM`CRA*~V7thcRC^ZMnVVw_~yjbQ3+OdT0eS5hk%_>z|@2_a~a#B{8D^R3v^VrSG zh`0O*Ay3Eqo~qGIx9s?lhbrdLFKonjJs3zIm=DB>cpd@H0hk{pK+$`d(X?Pe_zd-fMhdVUIN)J< zMXA(o6K*#?=5P%3eV9YWLt9QyPX|uz?2I>#4QeJ8ihXn26{gV$flHcG8}?iXo7+$e z%F6b}ohM7ZFa*SYeZ{zrm}=2=9*5wX!74y>pdV8@LoptZN4W=dxQ@d?*?%B+_cZUNTtkrLV)dWj5&>ZZ6P zCMMODi-`!Su=^vYp>eZw`|{<>0`ZDVHew{uEPSM36#f4FJAwF)TWw#Vj}EMv*bJjW ztOOQNlJ8-maUGW7Z-Bf4(d*Z?hpp{>%3O*h$>cwm5FtVD-Ytxj-g`eBH2P2+W_h2d zP!Z1tw5=tjqj8`m^m@FAryESvi5^?n@prS0kQU@YAJA)M%)rP9 zM6*9AZ3gyzW~Cmn*I|f~vfH{TL~sGo5&OWLgk~04oBETjAb7ek^u>)^EnXb|mlq&Q z^~>kacf?yj{7DPF>_Gt=&HYeZ{34AZ%;YMV7e(+O(__&sh7lPj;P@pYLuyH*AsQk{ zjA+bpPH>GzY9mp2u@b?cUcqMRH~F2%PpSJ7ZtGzA{dqn-Tv zvsi-PKe^nQBLfw0hDhbA$zv62us~&nFh>&nE%Q*0SdDm4rrx?vPGzVYb45Y5}s4_=Nr7CCk1{@vb zs9O_HNc0CLK~S~dx0`KgY!n|%6yf-n&=*zem2*5+qQx3-${FJz5MSW4yM#BTP?w7Z z)uxLA7(}Zq{|CV=Btid_%)`r|(iLhzKl@j`oL&m$l_(~)bSa!8bzy}y3jYLp-tsOK zL4!h=M2rm$yQpelkc9{9Hyfsilq-d7!ORw%AXujQIFI_QMG9Hqb4kL}8LA$h4fkPD#Mpoe zJ6wifBSV)ggdXtEV4=W+z(crD!mS}T1OSI3rW`l!@FTeO)zk)-`m@tR8y^8}&+3T9 z3G)V`-9K41+0Vvhf*KKC?@uM+lz*e|Jbod@7+kjyDN4>b*RHk`pfD51kPzW6l3P zt&nHfHTf8DsTYFB71IDFvK{g-KGEFfK|epr0yrOLv5rn3?51tp2nVjaaTG!(|%1%O+RUBZ!!QY@4f~KMu6x z<-B>7?d`Pu)higITwr2Z-F-Q)O|(iheUdSEV?~d*sPdfhT-oOC6qk;i;=fET4;Gsr z85PImeo9DKle<~>{W%A~)&k*P0P9f)887CwUmi>R+xKGO^lYeBJf%c|y+)^%p#m>F z&^Qkfn;6GJA}=c&pqBm0J}@X~m|M^Qa)1U&^$r5PmD(s!Ez@2jqVYKgl#xk6T2>Ny z(BX$IjO-yK7hB)2;W+79gD-}SuuNLAHzj_~@aERo;bUMyQAX8$a|y&}H{#B#0-f@6 z_HsEadwV6fd+OV9Y$+RtYVd62pCt&fpc3Og%B5@NmK_!X!TjF<&`#L8n=Y$6Hdj3p zs?NX7FXJm=Q{2;V+bi*FNP;PA4>~%IYGyp-o*Euyc1q@_?HxTbw&AV9m`1||klgZ?014)J3 z{zr%tyz7LXX2rv8dy%zYOe`%%=GGXj1PV~RAEtq!ioM@53*tgwuqD4#ualcwRg-~o zmTHPeXB1(ke^ZeLkjqp<(rgQlsz92pxDML${fub442RFy`!R41PUoJ`w>vzfKg%W(Niv!aG)rAuEFWngL;_u|n3l>)` z8@0#w_n>SfwX{aI{`?Avrv#*GsVI1xWv(?|Nz`vY^%yx*0X=c(*ADI8UJZS-6Hu;N zDO&r48J5$PotrmuZL;3r2-}B@=Ie`M%JYYskCx@mU^_(`2~W?@lU~36l`)i3aKJ=J zLEK$`fg44@Xbqcp#uiF#ld83V<6}3vAqh3OF_ex}|KpVJK1(oY1rCMZLaE;S`1lkQ za4a8Mj+9{I;guz@SLJ2K9m<2+1ANdCLu&{6Rpw0l*NL*~6Vddp+F3;K!h^q_8sGN( z?CffnP1@sm&`R@kDjU!4nneOFUYU{c_Vj5VPp!?g_@hS{@lLjP93YZZvJ76njBi!y zSXW6V5h%NXBME9LNbIpCQJ-a((xAz6=Wq7al(5#|E=S?$UI#IUoE-S}XS56E*A)wr zwS@V-Dj%Q*FXZg|5w20YEwSCb`{LCQulg6gyg4SOpe6vpO(H(6hAI22BXNC9^153%RRe#@Z@lNW@ctwFITvOo+(`=1_t*JAAVPaeL6c_WFvIigf>*= zpDWnq*F-V6vKMc?eWviscGDvb(qK?JwfRfIqy9NzLR7ZKx}JK<4KouHtgBbYK%4~B zHTEo17z9ekF&`5uchk{L-F_q0g+NfJfXGMNuHa`p|;8QD#-k3yzx*eKX+hY1Z$p7;X@G#ufUDo^K|CN6&HKt%cS!DE zA9F3%(=F+nD~ZrKY-u;D4O)32_;aFpK7T)6#X_XI_Mtg}uC>1GYC0m^Gmodw1?48FQ2Vs7RJ=#Q>btVWS!w(J)7;|53 z6BWjQXGK^SczUp#5HuzriVmes&HV5(D8DOV-Qu^Sr;$ikIo)igRyaCn@2WX%<1I5j zSguwsc}KO;q0aE-`y4YHWzUDWtn@#BT3c($EzRbf)(5oZ?d*OzrH}Npa9zH1i9q}c z9)-rUXZP(ZBZO-6~_ z+7Fye(4r^E%iQy>^Ilfm{F|?-$X?XVU-l=GS4^n6NH7qv&wqiNn&~DQhH{P{N4bNX4kH>u{H6=v^BzPDZ+#Y@FU;^zWGb!md3(E>< zgI>G+>gjmRgD~G5yaq@iB`MkMRnyki29wCmkRKpm-?*ptT%s?E%cLvmACC(}51Uqr z3|tTgeL-+t{WGv9Cnq28ue0B|bCb^|snrnY+BMJR+;RZ+bdEkE=HOicp?h#LYri(j8P#iBBf3eq7+`M@JG*Pv=y>VxP zC2Q)Dn;0kz)ZQoe;R&RvJ-LO1PQGGNe-ubjTko8upFY%LG%zqo!+R)IckmlG>ruFv zjSY|+?X9hgllAAY0bE>Mz}8^VfLG?8T8@mYY|Q3czLt^(AOiV7#|xcN%hlQ)tUr6!^W2l9b6W{w0oE7?}aQ0~06F4kFLP8$viMA-Rt8YOz6cw!po?;4o z2Bsz^pM+euK)M4`Q7pnDN8W_M7%izeDdjs&~#@*J|R%AE~IY)QKp@93z>$|U(#&8)A^z{W( zi=Ne=pXSqFKdON=g+>HSUqw!i1rX#tb&dtQ;^kC6O8nku9#Ek{;K8Th>#FxYhpBfB zMs1hn*Yk&v5NO*^=(~4!n3>5qp8FuXj|$M@D>=^!5UbRDHd6p^Eb0`Re2_W;P?FeJ``ioovugV!T?zD zeTacI4SWf}n>mCZFeSKLELV>6N4sYP9GBAm`hIY6Z~&zI0i_WX3ThD#4ON!gx1WOu zjkd6$c|WKZAYscA=5{{KQiTEt80`FDChR^|{x%Fe9t6w7K>-0VLauh6o~J+!W?3Z}8Te&UA*w8v|1h!C?he$S?XqWmGo?h6`S=3hPhc${Bc!0v(bEG8 zt$xz$cooO*H@Fka$DL4))37CgTnwN&L9rYLPZv~RVd?@3Fapr<^H=8OS+#y(fB_vW zZ>vDnY&_Jhc1rJjk9rI=EB}i|By?hMR*bMv+`0vG@mkGx2c)ho)F1E|?c0=a-gnzs zfT9M*A8_q>wZ}d{e-Qfdh?a-xkdTMc$xqOZvf0)M9$e>zu4&M<*M^Jdfv5q_fnB$1 zwp-)XOt&;On6FHM9G8=md-%||Z`$Pn48sSEK}{(tS&iSmb;j|7IXVtr(b2q~M-DK1 zTStQFZ48nVoD<7n!~o@&fP%szf7TZR^DQ3b2&b=m=|2-#f0LY^_vtQLs|U<>mxaZU zZhOQ5%nyempJ}JNWD#8{YgNl^f7wLW1hkQiKNJ@a&q-(mHEgjqR>?&(3j}UnR#u_9 z1uUdWVpZC8aA`z|wu8+?8Y|%4yCI-5?IR2k)YsFaT>Nn>w6ux(1m&I4I7`GIdu|RnM#$AtXZ-^M_6d|!-Zh> zRm&bPvm6B@)O3;!=w?;U>uY%m?&xzAgs-EBeAbWP&ah~pV1S_h$JOhvO&QGMV9?;x zvxU|VRhbT%mX_8xIH*mU#LDFSfKKajx%Vt^eP9wK60dSvJ%TM6VR@vjn3a{aHe!-3 z_LP|F9b!Wh0%j3*3OW?rffUv)P>CR{*!Ambz=PR*??+P;hy`G<%hjp0gI}e>R&xSi zDgr(W5U3M`Tsff+>@4;|7tuur#4wmPT6c~2uxP;1z=#AlTuJwQ6SyKL;9W4SoS)2# z?p(pH(0%@V3i5st6(k)(_DoaruA_wBB}m=qLd>7!WMo)0kAR{TaDt>*wlD+7wp)EoG?f&gXaOv4AJcRQ3ABqXmjQ-FqjO&@`;`uyqT~8 zMQH2iJ!ClSjZTeAVRt`V6F`6&OjG>!b1(~*TIAUELl{95nRFVpgyI#)ZK?uRfxhdm zm(jT5hi%+vV{52h7+0=-{`}cxf804f3sURwbbnI)4l!(mgWZktDYW)dqT`xRNJ*)y zs@eyO8bZ#i7{lquWB&^1zlP?*1mQgjVoRag!#R|Co{nwCTToA+7i)3E&4 zDVmkXW}GoK#r+Td7gB0@DEq>Vjg4&%ZGI8ZPax=7U=A(a*#+^%XFXNe9cHRm_Mi$3 z0;K`{!4nY6l(;_PT?VZPE*kHEch> zE9TM4&8K|$xSiN|Z4i@n|DHZ#gYdzF2Oy3j!yozM6~<(%<pB9Yth;Ty7jlWl-4I2$J!*+01w*lDz)T1Z zV|YS8@#zC6&!>?eKMuuZ0O*G!YH=&QsYqjiSZVE4aEn+%GeL#}XR(~#NL0o3CVKRq zl0EjaAJMA!@^_!r{cpo81xcj1vo?3+HTGP`%)ha+IU zBYdI1AZ`Bma`W57bu3P#l3wFUj5IOx>p*)2aF-K=#akxN&-P&?0kCwJoxKy|{ze&< zz8Z7n3NwoJh9b3)3&-8NvKj#dmdXJG=?h%F1M-%NzoKRwthmV_>Y8n#t~DOAdV2aq zU%S}i2MkDWMmtDIiokAyFe<=x=gxv3sh$h;4?x8c5fP}JiUMN|v@zwwfcx@i1`W{< zx8q(4Tk1}HWlrJO%8gPeMm@_@9Ws%{VP!&8!U+#@m_<9cmk0AnJAkRF1&7Pt`lSAo zC%2zj;6eEdINA}zL$AFdj8n*Pz_{4Pz$kU`^0>~s-v>%B-j(c{$5mLq;9x3Y0S*ou zz!zZOyxxIU#RVM}3LqgB#6C* z>&*J?tpp?ha)1*|<(8v+aJU5Op>^6j+^H)N%3GXHD;iLn!9EJ!XPkLyDJex1Pe{_{ zrHKn*HqnC_E$J^f%S~)|2YC!&B%CN4>U@Jpdp!vb0!2H!Ew}?adwa+u<>?bJB4nng zqf0KBdL|2AJWAbNnXFI5b7I2;q^e?BRa4^u)Ut}DE^}Nhwb%upd^G5-a$F|)3%Jl4io&WYt&-2M4WP9N zb%M7*Kd=jd_3#(ASQ#jdcocjEwliR3k?2kV?+$?OEg^5P`@nz55mL2Kz&&$HPA1Wi z8HWY_7g`l2Q@VWvWCp_}IG+Hm)CyEwK!wxm>|Q*eb&UNF2ugqbbsXpux1T}-nMcpa z0H|Q9(qw!t3AJZdl))0Be1{lJO4G1L!sMg~bc7W? zd=3C0CwgzGA3YWTVG7Za(fkOb@|!Ri3;|7pbw(d-B+1<-InisN`iY2$+`02PCnpE$ ze*!+fAugQ+qD4zZrRM{KJOqIyW9EONGqe%4T@>xbc-bs;Go$=pXJ^wx#nCEecquH` zG1yr^dStzK4^Ev{H9#(2xkg4zMs@_z?65NQzT@NSCu_h_F2*&+=)E!r!om8V9y|zg z@5CI36>JiPh{pjqnM*+lhR%dT+6sEa=#LatbfPIFKYeNZ4x0XBLjA`p?dFgfEKHfw}4yl@HhcJ zWYT?ISn0HAo&K1d0}`5;}aT?1MYIjQ2Y;DiiZ%|mLfO*i%1+?rK4(aCMaUyvNc+0 zLK39(E&_+@ygCBs7O>r4fgk3tD}ym2s~ZOdiT_kD%zqbrS>TSBwX)#XBsF4)w+HN6`j^Zxz&#Kg{w_$(qV5`09%Hhid7 zX&?bi0|d=YFgaql?R^q(G)r~-(r@Nemc01gf(N%#2%5Xo>3j0yKMSIkBpFt4e#?H*M>OO=D{&>1^pzVZAQy1iYo2IoE+%1wztDBP z^5$W>%I081MEgUd++h|_EJCE{%n`Rjq()p#cu2sU*(gu@xh04>lQyamEkNX zd;Lkz!$RP@j-nd1tty)ie=ZW?tnhr;Ak%cw|H-)A2rcI9>8JEqEo>LGOng9Xj4tLd zz$S7JkO1Cml)eFy2-r25BjI1UYQ_F|SFgNzBmKjYga^({hsvcB?okNn2h2PZb7LK| z#6slCy1G_^lM0-El9GOJ3=}7PuBTs{rsa7GZ{{D^kE0+qGP&O!6C!ffWx`M~KU-?k ziMGuE*aCOT1Pr`jB?Az+WMJ87+$`ym?LZq#cVe9CXW3z@!VoI|dOjH*(Q3-DlS=F# zk4rG6pjz@1IIQs3tF9qd2U$6F1x^q_;?}tBe&PBihA1I`ha-5@NhO1p?!W(laUE;8 z!uF-3V<|WQ9-}=VLvYxQjFi+F48{@<%zh#emx9sX3y@!TB)6m?mH{8ya7Ew>5{^({ zl-z+&EAX9gIsz*p7{Ecdoy8Juyo?|RI?@r07bjp{hwLX8@u+C$1cCxc@m-teD*Rq2 z6<{2}MH@%p44V*~WEvaOac>2v0k6()%D#{Px>H#Ap|@z`G+ir4fWz@7H8uOQ=Y(cG zVk=WPc&RcMe1yR&dgtD~(ZZMh?W7|YODNF32B#28!KkUhireTZry%Is4PQ2r4Gy$I ztqUUq&>UcE?}IKe>l%Tb2BRoqDE-Nuu42r;mI-N-&Iy>|((x|MUIth=CFAMo303gd zuV46-0)5%)Kww;`1YQV1f#xt_RL1@>jM0g<7)ed-Do(jB3}E<3=~O%Af-!@XO{YME z1#U51fFk@dTJpaRvmOj}mqM5}ZlnL-7AhrJTgm^iF)oVMAFl~!y@4CC+k$eI2IZS$ z;~s*04QR%zaO*&K0e=Ziyv(#W1Ddlu<;P1vIflmxVZdgRk%AQr*eDp@VNeu>Y1SbF zMBgGy7CE%%Eshh468sF1P~j{${2rh})6}g`a2}eTNvRR-wfP9;5EByavW3f@Wv!;Sdh#o zcN7zZ77c_!^PLA9$gZ0w*A|g>{QTk0jsxkN3x6xEf(`KL_;7+OFRw%QMvwCG%>gRT zn8yxiyB-&u&yCCKts)$0F!-k;>Y<%^u|ULC%B!i795dvDNojdks1qC+@ru&uk?ybg zE-tI9ittNG$;S>*R>7`o+-r5hGNmYl5PMoc4iJ~sT<==r)9`MSG%onUf{kD>qe1c$-!gH!s={Q9-jFXmqV0U^Z*Xm=L;IzW0Xp%+CnT?Kts z?b0{x2f_dC{BXQr-tqAQyFbJDz$S)&_`fY5mH*rFQ57YZUbHXBv@Dl)pfSaaPN~d*s&Vie4qHd&xX;GL z(8Vsg+-PQi@(ad}|A%`6_W6GsEvTn2ig7`S06VoTrJw)GNU8i1!7Ms*W3vj-uO~}) d8hB4dbHzieymlQj(ch^dE2$`vC;t5P{{c$LNHhQd diff --git a/previews/PR2578/Nemo/index.html b/previews/PR2578/Nemo/index.html deleted file mode 100644 index 884da250047c..000000000000 --- a/previews/PR2578/Nemo/index.html +++ /dev/null @@ -1,74 +0,0 @@ - -Getting Started · Oscar.jl

Getting Started

Nemo is a computer algebra package for the Julia programming language, maintained by William Hart, Tommy Hofmann, Claus Fieker, Fredrik Johansson with additional code by Oleksandr Motsak, Marek Kaluba and other contributors.

The features of Nemo so far include:

  • Multiprecision integers and rationals
  • Integers modulo n
  • p-adic numbers
  • Finite fields (prime and non-prime order)
  • Number field arithmetic
  • Algebraic numbers
  • Exact real and complex numbers
  • Arbitrary precision real and complex balls
  • Univariate and multivariate polynomials and matrices over the above

Nemo depends on AbstractAlgebra.jl which provides Nemo with generic routines for:

  • Univariate and multivariate polynomials
  • Absolute and relative power series
  • Laurent series
  • Fraction fields
  • Residue rings
  • Matrices and linear algebra
  • Young Tableaux
  • Permutation groups
  • Characters

Installation

To use Nemo we require Julia 1.6 or higher. Please see https://julialang.org/downloads/ for instructions on how to obtain julia for your system.

At the Julia prompt simply type

julia> using Pkg; Pkg.add("Nemo")

Quick start

Here are some examples of using Nemo.

This example computes recursive univariate polynomials.

julia> using Nemo
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over ZZ, x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over univariate polynomial ring, y)
-
-julia> T, z = polynomial_ring(S, "z")
-(Univariate polynomial ring in z over univariate polynomial ring, z)
-
-julia> f = x + y + z + 1
-z + y + x + 1
-
-julia> p = f^30; # semicolon suppresses output
-
-julia> @time q = p*(p+1);
-  0.161733 seconds (79.42 k allocations: 2.409 MiB)

Here is an example using generic recursive ring constructions.

julia> using Nemo
-
-julia> R, x = FiniteField(7, 11, "x")
-(Finite field of degree 11 over GF(7), x)
-
-julia> S, y = polynomial_ring(R, "y")
-(Univariate polynomial ring in y over GF(7^11), y)
-
-julia> T = residue_ring(S, y^3 + 3x*y + 1)
-Residue ring of univariate polynomial ring modulo y^3 + 3*x*y + 1
-
-julia> U, z = polynomial_ring(T, "z")
-(Univariate polynomial ring in z over residue ring, z)
-
-julia> f = (3y^2 + y + x)*z^2 + ((x + 2)*y^2 + x + 1)*z + 4x*y + 3;
-
-julia> g = (7y^2 - y + 2x + 7)*z^2 + (3y^2 + 4x + 1)*z + (2x + 1)*y + 1;
-
-julia> s = f^12;
-
-julia> t = (s + g)^12;
-
-julia> @time resultant(s, t)
-  0.059095 seconds (391.89 k allocations: 54.851 MiB, 5.22% gc time)
-(x^10 + 4*x^8 + 6*x^7 + 3*x^6 + 4*x^5 + x^4 + 6*x^3 + 5*x^2 + x)*y^2 + (5*x^10 + x^8 + 4*x^7 + 3*x^5 + 5*x^4 + 3*x^3 + x^2 + x + 6)*y + 2*x^10 + 6*x^9 + 5*x^8 + 5*x^7 + x^6 + 6*x^5 + 5*x^4 + 4*x^3 + x + 3

Here is an example using matrices.

julia> using Nemo
-
-julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over ZZ, x)
-
-julia> S = matrix_space(R, 40, 40)
-Matrix space of 40 rows and 40 columns
-  over univariate polynomial ring in x over ZZ
-
-julia> M = rand(S, 2:2, -20:20);
-
-julia> @time det(M);
-  0.080976 seconds (132.28 k allocations: 23.341 MiB, 4.11% gc time)

And here is an example with power series.

julia> using Nemo
-
-julia> R, x = QQ["x"]
-(Univariate polynomial ring in x over QQ, x)
-
-julia> S, t = power_series_ring(R, 100, "t")
-(Univariate power series ring over univariate polynomial ring, t + O(t^101))
-
-julia> u = t + O(t^100)
-t + O(t^100)
-
-julia> @time divexact((u*exp(x*u)), (exp(u)-1));
-  0.412813 seconds (667.49 k allocations: 33.966 MiB, 90.26% compilation time)

Building dependencies from source

Nemo depends on various C libraries which are installed using binaries by default. With julia version >= 1.3, the use of these binaries can be overridden by putting the following into the file ~/.julia/artifacts/Overrides.toml:

[e134572f-a0d5-539d-bddf-3cad8db41a82]
-FLINT = "/prefix/for/libflint"
-
-[d9960996-1013-53c9-9ba4-74a4155039c3]
-Arb = "/prefix/for/libarb"
-
-[e21ec000-9f72-519e-ba6d-10061e575a27]
-Antic = "/prefix/for/libantic"

(If only a specific library should be overridden, only the specific entry should be added.)

Experimental threading support for flint

Enabling a threaded version of flint can be done by setting the environment variable NEMO_THREADED=1. To set the actual number of threads, use Nemo.flint_set_num_threads($numberofthreads).

diff --git a/previews/PR2578/Nemo/integer/index.html b/previews/PR2578/Nemo/integer/index.html deleted file mode 100644 index e96a376539ea..000000000000 --- a/previews/PR2578/Nemo/integer/index.html +++ /dev/null @@ -1,184 +0,0 @@ - -Integers · Oscar.jl

Integers

The default integer type in Nemo is provided by Flint. The associated ring of integers is represented by the constant parent object called FlintZZ.

For convenience we define

ZZ = FlintZZ

so that integers can be constructed using ZZ instead of FlintZZ. Note that this is the name of a specific parent object, not the name of its type.

The types of the integer ring parent objects and elements of the associated rings of integers are given in the following table according to the library providing them.

LibraryElement typeParent type
FlintZZRingElemZZRing

All integer element types belong directly to the abstract type RingElem and all the integer ring parent object types belong to the abstract type Ring.

A lot of code will want to accept both ZZRingElem integers and Julia integers, that is, subtypes of Base.Integer. Thus for convenience we define

IntegerUnion = Union{Integer,ZZRingElem}

Integer functionality

Nemo integers provide all of the ring and Euclidean ring functionality of AbstractAlgebra.jl.

https://nemocas.github.io/AbstractAlgebra.jl/stable/ring

https://nemocas.github.io/AbstractAlgebra.jl/stable/euclidean_interface

Below, we describe the functionality that is specific to the Nemo/Flint integer ring.

Constructors

ZZ(n::Integer)

Coerce a Julia integer value into the integer ring.

ZZ(n::String)

Parse the given string as an integer.

ZZ(n::Float64)
-ZZ(n::Float32)
-ZZ(n::Float16)
-ZZ(n::BigFloat)

Coerce the given floating point number into the integer ring, assuming that it can be exactly represented as an integer.

Basic manipulation

signMethod
sign(a::ZZRingElem)

Return the sign of $a$, i.e. $+1$, $0$ or $-1$.

sizeMethod
size(a::ZZRingElem)

Return the number of limbs required to store the absolute value of $a$.

fitsMethod
fits(::Type{UInt}, a::ZZRingElem)

Return true if $a$ fits into a UInt, otherwise return false.

fitsMethod
fits(::Type{Int}, a::ZZRingElem)

Return true if $a$ fits into an Int, otherwise return false.

denominatorMethod
denominator(a::ZZRingElem)

Return the denominator of $a$ thought of as a rational. Always returns $1$.

numeratorMethod
numerator(a::ZZRingElem)

Return the numerator of $a$ thought of as a rational. Always returns $a$.

Examples

julia> a = ZZ(12)
-12
-
-julia> is_unit(a)
-false
-
-julia> sign(a)
-1
-
-julia> s = size(a)
-1
-
-julia> fits(Int, a)
-true
-
-julia> n = numerator(a)
-12
-
-julia> d = denominator(a)
-1

Euclidean division

Nemo also provides a large number of Euclidean division operations. Recall that for a dividend $a$ and divisor $b$, we can write $a = bq + r$ with $0 \leq |r| < |b|$. We call $q$ the quotient and $r$ the remainder.

We distinguish three cases. If $q$ is rounded towards zero, $r$ will have the same sign as $a$. If $q$ is rounded towards plus infinity, $r$ will have the opposite sign to $b$. Finally, if $q$ is rounded towards minus infinity, $r$ will have the same sign as $b$.

In the following table we list the division functions and their rounding behaviour. We also give the return value of the function, with $q$ representing return of the quotient and $r$ representing return of the remainder.

FunctionReturnRounding of the quotient
modrtowards minus infinity
remrtowards zero
divqtowards minus infinity
divrem(a::ZZRingElem, b::ZZRingElem)q, rtowards minus infinity
tdivrem(a::ZZRingElem, b::ZZRingElem)q, rtowards zero
fdivrem(a::ZZRingElem, b::ZZRingElem)q, rtowards minus infinity
cdivrem(a::ZZRingElem, b::ZZRingElem)q, rtowards plus infinity
ntdivrem(a::ZZRingElem, b::ZZRingElem)q, rnearest integer, ties toward zero
nfdivrem(a::ZZRingElem, b::ZZRingElem)q, rnearest integer, ties toward minus infinity
ncdivrem(a::ZZRingElem, b::ZZRingElem)q, rnearest integer, ties toward plus infinity

N.B: the internal definition of Nemo.div and Nemo.divrem are the same as fdiv and fdivrem. The definitions in the table are of Base.div and Base.divrem which agree with Julia's definitions of div and divrem.

Nemo also offers the following ad hoc division operators. The notation and description is as for the other Euclidean division functions.

FunctionReturnRounding
mod(a::ZZRingElem, b::Int)rtowards minus infinity
rem(a::ZZRingElem, b::Int)rtowards zero
div(a::ZZRingElem, b::Int)qtowards zero
tdiv(a::ZZRingElem, b::Int)qtowards zero
fdiv(a::ZZRingElem, b::Int)qtowards minus infinity
cdiv(a::ZZRingElem, b::Int)qtowards plus infinity

N.B: the internal definition of Nemo.div is the same as fdiv. The definition in the table is Base.div which agrees with Julia's definition of div.

The following functions are also available, for the case where one is dividing by a power of $2$. In other words, for Euclidean division of the form $a = b2^{d} + r$. These are useful for bit twiddling.

FunctionReturnRounding
tdivpow2(a::ZZRingElem, d::Int)qtowards zero
fdivpow2(a::ZZRingElem, d::Int)qtowards minus infinity
fmodpow2(a::ZZRingElem, d::Int)rtowards minus infinity
cdivpow2(a::ZZRingElem, d::Int)qtowards plus infinity

Examples

julia> a = ZZ(12)
-12
-
-julia> b = ZZ(5)
-5
-
-julia> q, r = divrem(a, b)
-(2, 2)
-
-julia> c = cdiv(a, b)
-3
-
-julia> d = fdiv(a, b)
-2
-
-julia> f = tdivpow2(a, 2)
-3
-
-julia> g = fmodpow2(a, 3)
-4

Comparison

Instead of isless we implement a function cmp(a, b) which returns a positive value if $a > b$, zero if $a == b$ and a negative value if $a < b$. We then implement all the other operators, including == in terms of cmp.

For convenience we also implement a cmpabs(a, b) function which returns a positive value if $|a| > |b|$, zero if $|a| == |b|$ and a negative value if $|a| < |b|$. This can be slightly faster than a call to cmp or one of the comparison operators when comparing nonnegative values for example.

Here is a list of the comparison functions implemented, with the understanding that cmp provides all of the comparison operators listed above.

Function
cmp(a::ZZRingElem, b::ZZRingElem)
cmpabs(a::ZZRingElem, b::ZZRingElem)

We also provide the following ad hoc comparisons which again provide all of the comparison operators mentioned above.

Function
cmp(a::ZZRingElem, b::Int)
cmp(a::Int, b::ZZRingElem)
cmp(a::ZZRingElem, b::UInt)
cmp(a::UInt, b::ZZRingElem)

Examples

julia> a = ZZ(12)
-12
-
-julia> b = ZZ(3)
-3
-
-julia> a < b
-false
-
-julia> a != b
-true
-
-julia> a > 4
-true
-
-julia> 5 <= b
-false
-
-julia> cmpabs(a, b)
-1

Shifting

<<Method
<<(x::ZZRingElem, c::Int)

Return $2^cx$ where $c \geq 0$.

>>Method
>>(x::ZZRingElem, c::Int)

Return $x/2^c$, discarding any remainder, where $c \geq 0$.

Examples

julia> a = ZZ(12)
-12
-
-julia> a << 3
-96
-
-julia> a >> 5
-0

Modular arithmetic

sqrtmodMethod
sqrtmod(x::ZZRingElem, m::ZZRingElem)

Return a square root of $x (\mod m)$ if one exists. The remainder will be in the range $[0, m)$. We require that $m$ is prime, otherwise the algorithm may not terminate.

Examples

julia> sqrtmod(ZZ(12), ZZ(13))
-5
crtFunction
crt(r1::ZZRingElem, m1::ZZRingElem, r2::ZZRingElem, m2::ZZRingElem, signed=false; check::Bool=true)
-crt(r1::ZZRingElem, m1::ZZRingElem, r2::Union{Int, UInt}, m2::Union{Int, UInt}, signed=false; check::Bool=true)
-crt(r::Vector{ZZRingElem}, m::Vector{ZZRingElem}, signed=false; check::Bool=true)
-crt_with_lcm(r1::ZZRingElem, m1::ZZRingElem, r2::ZZRingElem, m2::ZZRingElem, signed=false; check::Bool=true)
-crt_with_lcm(r1::ZZRingElem, m1::ZZRingElem, r2::Union{Int, UInt}, m2::Union{Int, UInt}, signed=false; check::Bool=true)
-crt_with_lcm(r::Vector{ZZRingElem}, m::Vector{ZZRingElem}, signed=false; check::Bool=true)

As per the AbstractAlgebra crt interface, with the following option. If signed = true, the solution is the range $(-m/2, m/2]$, otherwise it is in the range $[0,m)$, where $m$ is the least common multiple of the moduli.

Examples

julia> crt(ZZ(5), ZZ(13), ZZ(7), ZZ(37), true)
-44
-
-julia> crt(ZZ(5), ZZ(13), 7, 37, true)
-44

Integer logarithm

flogMethod
flog(x::ZZRingElem, c::ZZRingElem)
-flog(x::ZZRingElem, c::Int)

Return the floor of the logarithm of $x$ to base $c$.

Examples

julia> flog(ZZ(12), ZZ(2))
-3
-
-julia> flog(ZZ(12), 3)
-2
-
clogMethod
clog(x::ZZRingElem, c::ZZRingElem)
-clog(x::ZZRingElem, c::Int)

Return the ceiling of the logarithm of $x$ to base $c$.

Examples

julia> clog(ZZ(12), ZZ(2))
-4
-
-julia> clog(ZZ(12), 3)
-3
-

Integer roots

isqrtMethod
isqrt(x::ZZRingElem)

Return the floor of the square root of $x$.

Examples

julia> isqrt(ZZ(13))
-3
-
isqrtremMethod
isqrtrem(x::ZZRingElem)

Return a tuple $s, r$ consisting of the floor $s$ of the square root of $x$ and the remainder $r$, i.e. such that $x = s^2 + r$. We require $x \geq 0$.

Examples

julia> isqrtrem(ZZ(13))
-(3, 4)
-
rootMethod
root(x::ZZRingElem, n::Int; check::Bool=true)

Return the $n$-the root of $x$. We require $n > 0$ and that $x \geq 0$ if $n$ is even. By default the function tests whether the input was a perfect $n$-th power and if not raises an exception. If check=false this check is omitted.

Examples

julia> root(ZZ(27), 3; check=true)
-3
irootMethod
iroot(x::ZZRingElem, n::Int)

Return the integer truncation of the $n$-the root of $x$ (round towards zero). We require $n > 0$ and that $x \geq 0$ if $n$ is even.

Examples

julia> iroot(ZZ(13), 3)
-2

Number theoretic functionality

divisibleMethod
divisible(x::ZZRingElem, y::Int)

Return true if $x$ is divisible by $y$, otherwise return false. We require $x \neq 0$.

divisibleMethod
divisible(x::ZZRingElem, y::ZZRingElem)

Return true if $x$ is divisible by $y$, otherwise return false. We require $x \neq 0$.

is_squareMethod
is_square(f::PolyRingElem{T}) where T <: RingElement

Return true if $f$ is a perfect square.

is_square(a::FracElem{T}) where T <: RingElem

Return true if $a$ is a square.

is_primeMethod
is_prime(x::ZZRingElem)
-is_prime(x::Int)

Return true if $x$ is a prime number, otherwise return false.

Examples

julia> is_prime(ZZ(13))
-true
is_probable_primeMethod
is_probable_prime(x::ZZRingElem)

Return true if $x$ is very probably a prime number, otherwise return false. No counterexamples are known to this test, but it is conjectured that infinitely many exist.

factorMethod
factor(a::ZZRingElem)
-factor(a::UInt)
-factor(a::Int)

Return a factorisation of $a$ using a Fac struct (see the documentation on factorisation in Nemo).

Examples

julia> factor(ZZ(12))
-1 * 2^2 * 3
-
-julia> factor(UInt(12))
-1 * 2^2 * 3
-
-julia> factor(12)
-1 * 2^2 * 3
-
divisor_lenstraMethod
divisor_lenstra(n::ZZRingElem, r::ZZRingElem, m::ZZRingElem)

If $n$ has a factor which lies in the residue class $r (\mod m)$ for $0 < r < m < n$, this function returns such a factor. Otherwise it returns $0$. This is only efficient if $m$ is at least the cube root of $n$. We require gcd$(r, m) = 1$ and this condition is not checked.

factorialMethod
factorial(x::ZZRingElem)

Return the factorial of $x$, i.e. $x! = 1.2.3\ldots x$. We require $x \geq 0$.

Examples

julia> factorial(ZZ(100))
-93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
rising_factorialMethod
rising_factorial(x::ZZRingElem, n::ZZRingElem)

Return the rising factorial of $x$, i.e. $x(x + 1)(x + 2)\cdots (x + n - 1)$. If $n < 0$ we throw a DomainError().

rising_factorialMethod
rising_factorial(x::ZZRingElem, n::Int)

Return the rising factorial of $x$, i.e. $x(x + 1)(x + 2)\ldots (x + n - 1)$. If $n < 0$ we throw a DomainError().

rising_factorialMethod
rising_factorial(x::Int, n::Int)

Return the rising factorial of $x$, i.e. $x(x + 1)(x + 2)\ldots (x + n - 1)$. If $n < 0$ we throw a DomainError().

primorialMethod
primorial(x::ZZRingElem)

Return the primorial of $x$, i.e. the product of all primes less than or equal to $x$. If $x < 0$ we throw a DomainError().

primorialMethod
primorial(x::Int)

Return the primorial of $x$, i.e. the product of all primes less than or equal to $x$. If $x < 0$ we throw a DomainError().

fibonacciMethod
fibonacci(x::Int)

Return the $x$-th Fibonacci number $F_x$. We define $F_1 = 1$, $F_2 = 1$ and $F_{i + 1} = F_i + F_{i - 1}$ for all integers $i$.

fibonacciMethod
fibonacci(x::ZZRingElem)

Return the $x$-th Fibonacci number $F_x$. We define $F_1 = 1$, $F_2 = 1$ and $F_{i + 1} = F_i + F_{i - 1}$ for all integers $i$.

bellMethod
bell(x::ZZRingElem)

Return the Bell number $B_x$.

bellMethod
bell(x::Int)

Return the Bell number $B_x$.

binomialMethod
binomial(n::ZZRingElem, k::ZZRingElem)

Return the binomial coefficient $\frac{n (n-1) \cdots (n-k+1)}{k!}$. If $k < 0$ we return $0$, and the identity binomial(n, k) == binomial(n - 1, k - 1) + binomial(n - 1, k) always holds for integers n and k.

binomialMethod
binomial(n::UInt, k::UInt, ::ZZRing)

Return the binomial coefficient $\frac{n!}{(n - k)!k!}$ as an ZZRingElem.

moebius_muMethod
moebius_mu(x::Int)

Return the Moebius mu function of $x$ as an Int. The value returned is either $-1$, $0$ or $1$. If $x \leq 0$ we throw a DomainError().

moebius_muMethod
moebius_mu(x::ZZRingElem)

Return the Moebius mu function of $x$ as an Int. The value returned is either $-1$, $0$ or $1$. If $x \leq 0$ we throw a DomainError().

jacobi_symbolMethod
jacobi_symbol(x::Int, y::Int)

Return the value of the Jacobi symbol $\left(\frac{x}{y}\right)$. The modulus $y$ must be odd and positive, otherwise a DomainError is thrown.

jacobi_symbolMethod
jacobi_symbol(x::ZZRingElem, y::ZZRingElem)

Return the value of the Jacobi symbol $\left(\frac{x}{y}\right)$. The modulus $y$ must be odd and positive, otherwise a DomainError is thrown.

kronecker_symbolMethod
kronecker_symbol(x::ZZRingElem, y::ZZRingElem)
-kronecker_symbol(x::Int, y::Int)

Return the value of the Kronecker symbol $\left(\frac{x}{y}\right)$. The definition is as per Henri Cohen's book, "A Course in Computational Algebraic Number Theory", Definition 1.4.8.

divisor_sigmaMethod
divisor_sigma(x::ZZRingElem, y::Int)
-divisor_sigma(x::ZZRingElem, y::ZZRingElem)
-divisor_sigma(x::Int, y::Int)

Return the value of the sigma function, i.e. $\sum_{0 < d \;| x} d^y$. If $x \leq 0$ or $y < 0$ we throw a DomainError().

Examples

julia> divisor_sigma(ZZ(32), 10)
-1127000493261825
-
-julia> divisor_sigma(ZZ(32), ZZ(10))
-1127000493261825
-
-julia> divisor_sigma(32, 10)
-1127000493261825
euler_phiMethod
euler_phi(x::ZZRingElem)
-euler_phi(x::Int)

Return the value of the Euler phi function at $x$, i.e. the number of positive integers up to $x$ (inclusive) that are coprime with $x$. An exception is raised if $x \leq 0$.

Examples

julia> euler_phi(ZZ(12480))
-3072
-
-julia> euler_phi(12480)
-3072
number_of_partitionsMethod
number_of_partitions(x::Int)
-number_of_partitions(x::ZZRingElem)

Return the number of partitions of $x$.

Examples

julia> number_of_partitions(100)
-190569292
-
-julia> number_of_partitions(ZZ(1000))
-24061467864032622473692149727991
is_perfect_powerMethod
is_perfect_power(a::IntegerUnion)

Returns whether $a$ is a perfect power, that is, whether $a = m^r$ for some integer $m$ and $r > 1$.

is_prime_powerMethod
is_prime_power(q::IntegerUnion) -> Bool

Returns whether $q$ is a prime power.

is_prime_power_with_dataMethod
is_prime_power_with_data(q::IntegerUnion) -> Bool, ZZRingElem, Int

Returns a flag indicating whether $q$ is a prime power and integers $e, p$ such that $q = p^e$. If $q$ is a prime power, than $p$ is a prime.

Digits and bases

binMethod
bin(n::ZZRingElem)

Return $n$ as a binary string.

Examples

julia> bin(ZZ(12))
-"1100"
octMethod
oct(n::ZZRingElem)

Return $n$ as a octal string.

Examples

julia> oct(ZZ(12))
-"14"
decMethod
dec(n::ZZRingElem)

Return $n$ as a decimal string.

Examples

julia> dec(ZZ(12))
-"12"
hexMethod
hex(n::ZZRingElem) = base(n, 16)

Return $n$ as a hexadecimal string.

Examples

julia> hex(ZZ(12))
-"c"
baseMethod
base(n::ZZRingElem, b::Integer)

Return $n$ as a string in base $b$. We require $2 \leq b \leq 62$.

Examples

julia> base(ZZ(12), 13)
-"c"
ndigitsMethod
ndigits(x::ZZRingElem, b::Integer)

Return the number of digits of $x$ in the base $b$ (default is $b = 10$).

Examples

julia> ndigits(ZZ(12), 3)
-3
nbitsMethod
nbits(x::ZZRingElem)

Return the number of binary bits of $x$. We return zero if $x = 0$.

Examples

julia> nbits(ZZ(12))
-4

Bit twiddling

popcountMethod
popcount(x::ZZRingElem)

Return the number of ones in the binary representation of $x$.

Examples

julia> popcount(ZZ(12))
-2
prevpow2Method
prevpow2(x::ZZRingElem)

Return the previous power of $2$ up to including $x$.

nextpow2Method
nextpow2(x::ZZRingElem)

Return the next power of $2$ that is at least $x$.

Examples

julia> nextpow2(ZZ(12))
-16
trailing_zerosMethod
trailing_zeros(x::ZZRingElem)

Return the number of trailing zeros in the binary representation of $x$.

clrbit!Method
clrbit!(x::ZZRingElem, c::Int)

Clear bit $c$ of $x$, where the least significant bit is the $0$-th bit. Note that this function modifies its input in-place.

Examples

julia> a = ZZ(12)
-12
-
-julia> clrbit!(a, 3)
-
-julia> a
-4
setbit!Method
setbit!(x::ZZRingElem, c::Int)

Set bit $c$ of $x$, where the least significant bit is the $0$-th bit. Note that this function modifies its input in-place.

Examples

julia> a = ZZ(12)
-12
-
-julia> setbit!(a, 0)
-
-julia> a
-13
combit!Method
combit!(x::ZZRingElem, c::Int)

Complement bit $c$ of $x$, where the least significant bit is the $0$-th bit. Note that this function modifies its input in-place.

Examples

julia> a = ZZ(12)
-12
-
-julia> combit!(a, 2)
-
-julia> a
-8
tstbitMethod
tstbit(x::ZZRingElem, c::Int)

Return bit $i$ of x (numbered from 0) as true for 1 or false for 0.

Examples

julia> a = ZZ(12)
-12
-
-julia> tstbit(a, 0)
-false
-
-julia> tstbit(a, 2)
-true

Random generation

rand_bitsMethod
rand_bits(::ZZRing, b::Int)

Return a random signed integer whose absolute value has $b$ bits.

rand_bits_primeMethod
rand_bits_prime(::ZZRing, n::Int, proved::Bool=true)

Return a random prime number with the given number of bits. If only a probable prime is required, one can pass proved=false.

Examples

a = rand_bits(ZZ, 23)
-b = rand_bits_prime(ZZ, 7)

Complex Integers

The Gaussian integer type in Nemo is provided by a pair of Flint integers. The associated ring of integers and the fraction field can be retrieved by Nemo.GaussianIntegers() and Nemo.GaussianRationals().

Examples

julia> ZZi = Nemo.GaussianIntegers()
-Gaussian integer ring
-
-julia> a = ZZ(5)*im
-5*im
-
-julia> b = ZZi(3, 4)
-3 + 4*im
-
-julia> is_unit(a)
-false
-
-julia> factor(a)
-im * (2 - im) * (2 + im)
-
-julia> a//b
-4//5 + 3//5*im
-
-julia> abs2(a//b)
-1
diff --git a/previews/PR2578/Nemo/mathjaxhelper.js b/previews/PR2578/Nemo/mathjaxhelper.js deleted file mode 100644 index 1bd5394af59d..000000000000 --- a/previews/PR2578/Nemo/mathjaxhelper.js +++ /dev/null @@ -1,10 +0,0 @@ -MathJax.Hub.Config({ - extensions: ["tex2jax.js"], - jax: ["input/TeX", "output/HTML-CSS"], - tex2jax: { - inlineMath: [ ['$','$'], ["\\(","\\)"] ], - displayMath: [ ['$$','$$'], ["\\[","\\]"] ], - processEscapes: true - }, -}); - diff --git a/previews/PR2578/Nemo/matrix/index.html b/previews/PR2578/Nemo/matrix/index.html deleted file mode 100644 index 5b0d415b3f14..000000000000 --- a/previews/PR2578/Nemo/matrix/index.html +++ /dev/null @@ -1,104 +0,0 @@ - -Matrices · Oscar.jl

Matrices

Nemo allow the creation of dense matrices over any computable ring $R$. There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of matrices over numerous specific rings, usually provided by C/C++ libraries.

The following table shows each of the matrix types available in Nemo, the base ring $R$, and the Julia/Nemo types for that kind of matrix (the type information is mainly of concern to developers).

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jlGeneric.Mat{T}Generic.MatSpace{T}
$\mathbb{Z}$FlintZZMatrixZZMatrixSpace
$\mathbb{Z}/n\mathbb{Z}$ (small $n$)FlintzzModMatrixzzModMatrixSpace
$\mathbb{Z}/n\mathbb{Z}$ (large $n$)FlintZZModMatrixZZModMatrixSpace
$\mathbb{Q}$FlintQQMatrixQQMatrixSpace
$\mathbb{Z}/p\mathbb{Z}$ (small $p$)FlintfpMatrixfpMatrixSpace
$\mathbb{F}_{p^n}$ (small $p$)FlintfqPolyRepMatrixfqPolyRepMatrixSpace
$\mathbb{F}_{p^n}$ (large $p$)FlintFqPolyRepMatrix`FqPolyRepMatrixSpace
$\mathbb{R}$ (arbitrary precision)ArbRealMatRealMatSpace
$\mathbb{C}$ (arbitrary precision)ArbComplexMatComplexMatSpace
$\mathbb{R}$ (fixed precision)Arbarb_matArbMatSpace
$\mathbb{C}$ (fixed precision)Arbacb_matAcbMatSpace

The dimensions and base ring $R$ of a generic matrix are stored in its parent object.

All matrix element types belong to the abstract type MatElem and all of the matrix space types belong to the abstract type MatSpace. This enables one to write generic functions that can accept any Nemo matrix type.

Note that the preferred way to create matrices is not to use the type constructors but to use the matrix function, see also the Matrix element constructors section of the AbstractAlgebra manual.

Matrix functionality

All matrix spaces in Nemo provide the matrix functionality of AbstractAlgebra:

https://nemocas.github.io/AbstractAlgebra.jl/stable/matrix

Some of this functionality is provided in Nemo by C libraries, such as Flint, for various specific rings.

In the following, we list the functionality which is provided in addition to the generic matrix functionality, for specific rings in Nemo.

Comparison operators

overlapsMethod
overlaps(x::RealMat, y::RealMat)

Returns true if all entries of $x$ overlap with the corresponding entry of $y$, otherwise return false.

overlapsMethod
overlaps(x::ComplexMat, y::ComplexMat)

Returns true if all entries of $x$ overlap with the corresponding entry of $y$, otherwise return false.

containsMethod
contains(x::RealMat, y::RealMat)

Returns true if all entries of $x$ contain the corresponding entry of $y$, otherwise return false.

containsMethod
contains(x::ComplexMat, y::ComplexMat)

Returns true if all entries of $x$ contain the corresponding entry of $y$, otherwise return false.

In addition we have the following ad hoc comparison operators.

Examples

C = RR[1 2; 3 4]
-D = RR["1 +/- 0.1" "2 +/- 0.1"; "3 +/- 0.1" "4 +/- 0.1"]
-overlaps(C, D)
-contains(D, C)

Scaling

<<Method
<<(x::ZZMatrix, y::Int)

Return $2^yx$.

>>Method
>>(x::ZZMatrix, y::Int)

Return $x/2^y$ where rounding is towards zero.

Examples

S = matrix_space(ZZ, 3, 3)
-
-A = S([ZZ(2) 3 5; 1 4 7; 9 6 3])
-
-B = A<<5
-C = B>>2

Determinant

det_divisorMethod
det_divisor(x::ZZMatrix)

Return some positive divisor of the determinant of $x$, if the determinant is nonzero, otherwise return zero.

det_given_divisorMethod
det_given_divisor(x::ZZMatrix, d::Integer, proved=true)

Return the determinant of $x$ given a positive divisor of its determinant. If proved == true (the default), the output is guaranteed to be correct, otherwise a heuristic algorithm is used.

det_given_divisorMethod
det_given_divisor(x::ZZMatrix, d::ZZRingElem, proved=true)

Return the determinant of $x$ given a positive divisor of its determinant. If proved == true (the default), the output is guaranteed to be correct, otherwise a heuristic algorithm is used.

Examples

S = matrix_space(ZZ, 3, 3)
-
-A = S([ZZ(2) 3 5; 1 4 7; 9 6 3])
-
-c = det_divisor(A)
-d = det_given_divisor(A, c)

Linear solving

cansolveMethod
cansolve(a::ZZMatrix, b::ZZMatrix) -> Bool, ZZMatrix

Return true and a matrix $x$ such that $ax = b$, or false and some matrix in case $x$ does not exist.

solve_dixonMethod
solve_dixon(a::ZZMatrix, b::ZZMatrix)

Return a tuple $(x, m)$ consisting of a column vector $x$ such that $ax = b \pmod{m}$. The element $b$ must be a column vector with the same number > of rows as $a$ and $a$ must be a square matrix. If these conditions are not met or $(x, d)$ does not exist, an exception is raised.

solve_dixonMethod
solve_dixon(a::QQMatrix, b::QQMatrix)

Solve $ax = b$ by clearing denominators and using Dixon's algorithm. This is usually faster for large systems.

Examples

S = matrix_space(ZZ, 3, 3)
-T = matrix_space(ZZ, 3, 1)
-
-A = S([ZZ(2) 3 5; 1 4 7; 9 2 2])
-B = T([ZZ(4), 5, 7])
-
-X, m = solve_dixon(A, B)

Pseudo inverse

pseudo_invMethod
pseudo_inv(x::ZZMatrix)

Return a tuple $(z, d)$ consisting of a matrix $z$ and denominator $d$ such that $z/d$ is the inverse of $x$.

Examples

S = matrix_space(ZZ, 3, 3)
-
-A = S([1 0 1; 2 3 1; 5 6 7])
-
-B, d = pseudo_inv(A)

Nullspace

nullspace_right_rationalMethod
nullspace_right_rational(x::ZZMatrix)

Return a tuple $(r, U)$ consisting of a matrix $U$ such that the first $r$ columns form the right rational nullspace of $x$, i.e. a set of vectors over $\mathbb{Z}$ giving a $\mathbb{Q}$-basis for the nullspace of $x$ considered as a matrix over $\mathbb{Q}$.

Modular reduction

reduce_modMethod
reduce_mod(x::ZZMatrix, y::Integer)

Reduce the entries of $x$ modulo $y$ and return the result.

reduce_modMethod
reduce_mod(x::ZZMatrix, y::ZZRingElem)

Reduce the entries of $x$ modulo $y$ and return the result.

Examples

S = matrix_space(ZZ, 3, 3)
-
-A = S([ZZ(2) 3 5; 1 4 7; 9 2 2])
-
-reduce_mod(A, ZZ(5))
-reduce_mod(A, 2)

Lifting

liftMethod
lift(a::T) where {T <: Zmodn_mat}

Return a lift of the matrix $a$ to a matrix over $\mathbb{Z}$, i.e. where the entries of the returned matrix are those of $a$ lifted to $\mathbb{Z}$.

lift(M::smodule{T}, SM::smodule{T}) where T

Represents the generators of SM in terms of the generators of M. If SM is in M, rest is the null module, otherwise rest = reduce(SM, std(M)). Returns (result, rest) with for global orderings: Matrix(SM) - Matrix(rest) = Matrix(M)*Matrix(result) for non-global orderings: Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) where U is some diagonal matrix of units. To compute this U, see lift(M::smodule, SM::smodule, goodShape::Bool, isSB::Bool, divide::Bool).

lift(M::smodule{T}, SM::smodule{T}, goodShape::Bool, isSB::Bool, divide::Bool) where T

Represents the generators of SM in terms of the generators of M. Returns (result, rest, U) with Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) If SM is in M, then rest is the null module. Otherwise, rest = SM if !divide, and rest = normalform(SM, std(M)) if divide. U is a diagonal matrix of units, differing from the identity matrix only for local ring orderings.

There are three boolean options. goodShape: maximal non-zero index in generators of SM <= that of M, which should be come from a rank check rank(SM)==rank(M). isSB: generators of M form a Groebner basis. divide: allow SM not to be a submodule of M.

lift(M::sideal{T}, SM::sideal{T}) where T

Represents the generators of SM in terms of the generators of M. If SM is in M, rest is the null module, otherwise rest = reduce(SM, std(M)). Returns (result, rest) with for global orderings: Matrix(SM) - Matrix(rest) = Matrix(M)*Matrix(result) for non-global orderings: Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) where U is some diagonal matrix of units. To compute this U, see lift(M::sideal, SM::sideal, goodShape::Bool, isSB::Bool, divide::Bool).

lift(M::sideal{T}, SM::sideal{T}, goodShape::Bool, isSB::Bool, divide::Bool) where T

Represents the generators of SM in terms of the generators of M. Returns (result, rest, U) with Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) If SM is in M, then rest is the null module. Otherwise, rest = SM if !divide, and rest = normalform(SM, std(M)) if divide. U is a diagonal matrix of units, differing from the identity matrix only for local ring orderings.

There are three boolean options. goodShape: maximal non-zero index in generators of SM <= that of M, which should be come from a rank check rank(SM)==rank(M). isSB: generators of M form a Groebner basis divide: allow SM not to be a submodule of M, which is useful for division with remainder.

liftMethod
lift(a::fpMatrix)

Return a lift of the matrix $a$ to a matrix over $\mathbb{Z}$, i.e. where the entries of the returned matrix are those of $a$ lifted to $\mathbb{Z}$.

Examples

R = residue_ring(ZZ, 7)
-S = matrix_space(R, 3, 3)
-
-a = S([4 5 6; 7 3 2; 1 4 5])
-
- b = lift(a)

Special matrices

hadamardMethod
hadamard(R::ZZMatrixSpace)

Return the Hadamard matrix for the given matrix space. The number of rows and columns must be equal.

is_hadamardMethod
is_hadamard(x::ZZMatrix)

Return true if the given matrix is Hadamard, otherwise return false.

hilbertMethod
hilbert(R::QQMatrixSpace)

Return the Hilbert matrix in the given matrix space. This is the matrix with entries $H_{i,j} = 1/(i + j - 1)$.

Examples

R = matrix_space(ZZ, 3, 3)
-S = matrix_space(QQ, 3, 3)
-
-A = hadamard(R)
-is_hadamard(A)
-B = hilbert(R)

Hermite Normal Form

hnfMethod
hnf(x::ZZMatrix)

Return the Hermite Normal Form of $x$.

hnf_with_transformMethod
hnf_with_transform(x::ZZMatrix)

Compute a tuple $(H, T)$ where $H$ is the Hermite normal form of $x$ and $T$ is a transformation matrix so that $H = Tx$.

hnf_modularMethod
hnf_modular(x::ZZMatrix, d::ZZRingElem)

Compute the Hermite normal form of $x$ given that $d$ is a multiple of the determinant of the nonzero rows of $x$.

hnf_modular_eldivMethod
hnf_modular_eldiv(x::ZZMatrix, d::ZZRingElem)

Compute the Hermite normal form of $x$ given that $d$ is a multiple of the largest elementary divisor of $x$. The matrix $x$ must have full rank.

is_hnfMethod
is_hnf(x::ZZMatrix)

Return true if the given matrix is in Hermite Normal Form, otherwise return false.

Examples

S = matrix_space(ZZ, 3, 3)
-
-A = S([ZZ(2) 3 5; 1 4 7; 19 3 7])
-
-B = hnf(A)
-H, T = hnf_with_transform(A)
-M = hnf_modular(A, ZZ(27))
-N = hnf_modular_eldiv(A, ZZ(27))
-is_hnf(M)

Lattice basis reduction

Nemo provides LLL lattice basis reduction. Optionally one can specify the setup using a context object created by the following function.

lll_ctx(delta::Float64, eta::Float64, rep=:zbasis, gram=:approx)

Return a LLL context object specifying LLL parameters $\delta$ and $\eta$ and specifying the representation as either :zbasis or :gram and the Gram type as either :approx or :exact.

lllMethod
lll(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51))

Return the LLL reduction of the matrix $x$. By default the matrix $x$ is a $\mathbb{Z}$-basis and the Gram matrix is maintained throughout in approximate form. The LLL is performed with reduction parameters $\delta = 0.99$ and $\eta = 0.51$. All of these defaults can be overridden by specifying an optional context object.

lll_with_transformMethod
lll_with_transform(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51))

Compute a tuple $(L, T)$ where $L$ is the LLL reduction of $a$ and $T$ is a transformation matrix so that $L = Ta$. All the default parameters can be overridden by supplying an optional context object.

lll_gramMethod
lll_gram(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51, :gram))

Given the Gram matrix $x$ of a matrix, compute the Gram matrix of its LLL reduction.

lll_gram_with_transformMethod
lll_gram_with_transform(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51, :gram))

Given the Gram matrix $x$ of a matrix $M$, compute a tuple $(L, T)$ where $L$ is the gram matrix of the LLL reduction of the matrix and $T$ is a transformation matrix so that $L = TM$.

lll_with_removalMethod
lll_with_removal(x::ZZMatrix, b::ZZRingElem, ctx::lll_ctx = lll_ctx(0.99, 0.51))

Compute the LLL reduction of $x$ and throw away rows whose norm exceeds the given bound $b$. Return a tuple $(r, L)$ where the first $r$ rows of $L$ are the rows remaining after removal.

lll_with_removal_transformMethod
lll_with_removal_transform(x::ZZMatrix, b::ZZRingElem, ctx::lll_ctx = lll_ctx(0.99, 0.51))

Compute a tuple $(r, L, T)$ where the first $r$ rows of $L$ are those remaining from the LLL reduction after removal of vectors with norm exceeding the bound $b$ and $T$ is a transformation matrix so that $L = Tx$.

lll!Method
lll!(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51))

Perform the LLL reduction of the matrix $x$ inplace. By default the matrix $x$ is a > $\mathbb{Z}$-basis and the Gram matrix is maintained throughout in approximate form. The LLL is performed with reduction parameters $\delta = 0.99$ and $\eta = 0.51$. All of these defaults can be overridden by specifying an optional context object.

lll_gram!Method
lll_gram!(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51, :gram))

Given the Gram matrix $x$ of a matrix, compute the Gram matrix of its LLL reduction inplace.

Examples

S = matrix_space(ZZ, 3, 3)
-
-A = S([ZZ(2) 3 5; 1 4 7; 19 3 7])
-
-L = lll(A, lll_ctx(0.95, 0.55, :zbasis, :approx)
-L, T = lll_with_transform(A)
-
-G == lll_gram(gram(A))
-G, T = lll_gram_with_transform(gram(A))
-
-r, L = lll_with_removal(A, ZZ(100))
-r, L, T = lll_with_removal_transform(A, ZZ(100))

Smith Normal Form

snfMethod
snf(x::ZZMatrix)

Compute the Smith normal form of $x$.

snf_diagonalMethod
snf_diagonal(x::ZZMatrix)

Given a diagonal matrix $x$ compute the Smith normal form of $x$.

is_snfMethod
is_snf(x::ZZMatrix)

Return true if $x$ is in Smith normal form, otherwise return false.

Examples

S = matrix_space(ZZ, 3, 3)
-
-A = S([ZZ(2) 3 5; 1 4 7; 19 3 7])
-
-B = snf(A)
-is_snf(B) == true
-
-B = S([ZZ(2) 0 0; 0 4 0; 0 0 7])
-
-C = snf_diagonal(B)

Strong Echelon Form

strong_echelon_formMethod
strong_echelon_form(a::zzModMatrix)

Return the strong echeleon form of $a$. The matrix $a$ must have at least as many rows as columns.

strong_echelon_formMethod
strong_echelon_form(a::fpMatrix)

Return the strong echeleon form of $a$. The matrix $a$ must have at least as many rows as columns.

Examples

R = residue_ring(ZZ, 12)
-S = matrix_space(R, 3, 3)
-
-A = S([4 1 0; 0 0 5; 0 0 0 ])
-
-B = strong_echelon_form(A)

Howell Form

howell_formMethod
howell_form(a::zzModMatrix)

Return the Howell normal form of $a$. The matrix $a$ must have at least as many rows as columns.

howell_formMethod
howell_form(a::fpMatrix)

Return the Howell normal form of $a$. The matrix $a$ must have at least as many rows as columns.

Examples

R = residue_ring(ZZ, 12)
-S = matrix_space(R, 3, 3)
-
-A = S([4 1 0; 0 0 5; 0 0 0 ])
-
-B = howell_form(A)

Gram-Schmidt Orthogonalisation

gram_schmidt_orthogonalisationMethod
gram_schmidt_orthogonalisation(x::QQMatrix)

Takes the columns of $x$ as the generators of a subset of $\mathbb{Q}^m$ and returns a matrix whose columns are an orthogonal generating set for the same subspace.

Examples

julia> S = matrix_space(QQ, 3, 3);
-
-julia> A = S([4 7 3; 2 9 1; 0 5 3])
-[4   7   3]
-[2   9   1]
-[0   5   3]
-
-julia> B = gram_schmidt_orthogonalisation(A)
-[4   -11//5     95//123]
-[2    22//5   -190//123]
-[0        5    209//123]

Exponential

Examples

A = RR[2 0 0; 0 3 0; 0 0 1]
-
-B = exp(A)

Norm

bound_inf_normMethod
bound_inf_norm(x::RealMat)

Returns a nonnegative element $z$ of type arb, such that $z$ is an upper bound for the infinity norm for every matrix in $x$

bound_inf_normMethod
bound_inf_norm(x::ComplexMat)

Returns a nonnegative element $z$ of type acb, such that $z$ is an upper bound for the infinity norm for every matrix in $x$

Examples

A = RR[1 2 3; 4 5 6; 7 8 9]
-
-d = bound_inf_norm(A)

Shifting

Examples

A = RR[1 2 3; 4 5 6; 7 8 9]
-
-B = ldexp(A, 4)
-
-overlaps(16*A, B)

Predicates

Examples

A = CC[1 2 3; 4 5 6; 7 8 9]
-
-isreal(A)
-
-isreal(onei(CC)*A)

Conversion to Julia matrices

Julia matrices use a different data structure than Nemo matrices. Conversion to Julia matrices is usually only required for interfacing with other packages. It isn't necessary to convert Nemo matrices to Julia matrices in order to manipulate them.

This conversion can be performed with standard Julia syntax, such as the following, where A is an ZZMatrix:

Matrix{Int}(A)
-Matrix{BigInt}(A)

In case the matrix cannot be converted without loss, an InexactError is thrown: in this case, cast to a matrix of BigInts rather than Ints.

Eigenvalues and Eigenvectors (experimental)

eigvalsMethod
eigvals(A::ComplexMat)

Returns the eigenvalues of A as a vector of tuples (ComplexFieldElem, Int). Each tuple (z, k) corresponds to a cluster of k eigenvalues of $A$.

This function is experimental.

eigvals_simpleMethod
eigvals_simple(A::ComplexMat, algorithm::Symbol = :default)

Returns the eigenvalues of A as a vector of acb. It is assumed that A has only simple eigenvalues.

The algorithm used can be changed by setting the algorithm keyword to :vdhoeven_mourrain or :rump.

This function is experimental.

A = CC[1 2 3; 0 4 5; 0 0 6]
-eigvals_simple(A)
-A = CC[2 2 3; 0 2 5; 0 0 2])
-eigvals(A)
diff --git a/previews/PR2578/Nemo/misc/index.html b/previews/PR2578/Nemo/misc/index.html deleted file mode 100644 index 6b6417b809b9..000000000000 --- a/previews/PR2578/Nemo/misc/index.html +++ /dev/null @@ -1,16 +0,0 @@ - -Miscellaneous · Oscar.jl

Miscellaneous

Global variables and precompilation

Due to limitations of the precompilation of modules in julia, global variables referring to certain Nemo types require special attention when used inside modules. As a simple example, the following code for a module called A will not work as expected:

module A
-
-using Nemo
-Qx, x = QQ["x"]
-f(n) = x^n
-end

When running julia and loading the module via using/import A, calling f will lead to segmentation faults. The preferred workaround is to put the definitions of the global variables into the __init__() function of the module as follows:

module A
-
-using Nemo
-
-function __init__()
-  global (Qx, x) = QQ["x"]
-end
-
-f(n) = x^n
-end

Alternatively, one can disable precompilation by adding __precompile__(false) inside A. Note that this might have other unwanted side effects.

diff --git a/previews/PR2578/Nemo/mpolynomial/index.html b/previews/PR2578/Nemo/mpolynomial/index.html deleted file mode 100644 index bc7e41984085..000000000000 --- a/previews/PR2578/Nemo/mpolynomial/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Multivariate polynomials · Oscar.jl

Multivariate polynomials

Introduction

Nemo allow the creation of sparse, distributed multivariate polynomials over any computable ring $R$. There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of polynomials over numerous specific rings, usually provided by C/C++ libraries.

The following table shows each of the polynomial types available in Nemo, the base ring $R$, and the Julia/Nemo types for that kind of polynomial (the type information is mainly of concern to developers).

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jlGeneric.MPoly{T}Generic.MPolyRing{T}
$\mathbb{Z}$FlintZZMPolyRingElemZZMPolyRing
$\mathbb{Z}/n\mathbb{Z}$ (small $n$)FlintzzModMPolyRingElemzzModMPolyRing
$\mathbb{Q}$FlintQQMPolyRingElemQQMPolyRing
$\mathbb{Z}/p\mathbb{Z}$ (small prime $p$)FlintfpMPolyRingElemfpMPolyRing
$\mathbb{F}_{p^n}$ (small $p$)FlintfqPolyRepMPolyRingElemfqPolyRepMPolyRing

The string representation of the variables and the base ring $R$ of a generic polynomial is stored in its parent object.

All polynomial element types belong to the abstract type MPolyRingElem and all of the polynomial ring types belong to the abstract type MPolyRing. This enables one to write generic functions that can accept any Nemo multivariate polynomial type.

Polynomial functionality

All multivariate polynomial types in Nemo provide the multivariate polynomial functionality described by AbstractAlgebra:

https://nemocas.github.io/AbstractAlgebra.jl/stable/mpolynomial

Generic multivariate polynomials are also available.

We describe here only functions that are in addition to that guaranteed by AbstractAlgebra.jl, for specific coefficient rings.

diff --git a/previews/PR2578/Nemo/numberfield/index.html b/previews/PR2578/Nemo/numberfield/index.html deleted file mode 100644 index 800ce4eca2ae..000000000000 --- a/previews/PR2578/Nemo/numberfield/index.html +++ /dev/null @@ -1,43 +0,0 @@ - -Number field arithmetic · Oscar.jl

Number field arithmetic

Number fields are provided in Nemo by Antic. This allows construction of absolute number fields and basic arithmetic computations therein.

Number fields are constructed using the AnticNumberField function. However, for convenience we define

number_field = AnticNumberField

so that number fields can be constructed using number_field rather than AnticNumberField.

The types of number field elements in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Antic$\mathbb{Q}[x]/(f)$nf_elemAnticNumberField

All the number field types belong to the Field abstract type and the number field element types belong to the FieldElem abstract type.

The Hecke.jl library radically expands on number field functionality, providing ideals, orders, class groups, relative extensions, class field theory, etc.

The basic number field element type used in Hecke is the Nemo/antic number field element type, making the two libraries tightly integrated.

https://thofma.github.io/Hecke.jl/stable/

Number field functionality

The number fields in Nemo provide all of the AbstractAlgebra field functionality:

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document the additional functionality provided for number field elements.

Constructors

In order to construct number field elements in Nemo, one must first construct the number field itself. This is accomplished with one of the following constructors.

number_fieldMethod
number_field(f::QQPolyRingElem, s::VarName;
-            cached::Bool = true, check::Bool = true)

Return a tuple $R, x$ consisting of the parent object $R$ and generator $x$ of the number field $\mathbb{Q}[x]/(f)$ where $f$ is the supplied polynomial. The supplied string s specifies how the generator of the number field should be printed. If s is not specified, it defaults to _a.

cyclotomic_fieldMethod
cyclotomic_field(n::Int, s::VarName = "z_$n", t = "_\$"; cached = true)

Return a tuple $R, x$ consisting of the parent object $R$ and generator $x$ of the $n$-th cyclotomic field, $\mathbb{Q}(\zeta_n)$. The supplied string s specifies how the generator of the number field should be printed. If provided, the string t specifies how the generator of the polynomial ring from which the number field is constructed, should be printed. If it is not supplied, a default dollar sign will be used to represent the variable.

cyclotomic_real_subfieldMethod
cyclotomic_real_subfield(n::Int, s::VarName = "(z_$n + 1/z_$n)", t = "\$"; cached = true)

Return a tuple $R, x$ consisting of the parent object $R$ and generator $x$ of the totally real subfield of the $n$-th cyclotomic field, $\mathbb{Q}(\zeta_n)$. The supplied string s specifies how the generator of the number field should be printed. If provided, the string t specifies how the generator of the polynomial ring from which the number field is constructed, should be printed. If it is not supplied, a default dollar sign will be used to represent the variable.

Here are some examples of creating number fields and making use of the resulting parent objects to coerce various elements into those fields.

Examples

R, x = polynomial_ring(QQ, "x")
-K, a = number_field(x^3 + 3x + 1, "a")
-L, b = CyclotomicField(5, "b")
-M, c = CyclotomicRealField(5, "c")
-
-d = K(3)
-f = L(b)
-g = L(ZZ(11))
-h = L(ZZ(11)//3)
-k = M(x)

Number field element constructors

genMethod
gen(a::AnticNumberField)

Return the generator of the given number field, i.e., a symbolic root of the defining polynomial.

The easiest way of constructing number field elements is to use element arithmetic with the generator, to construct the desired element by its representation as a polynomial. See the following examples for how to do this.

Examples

R, x = polynomial_ring(QQ, "x")
-K, a = number_field(x^3 + 3x + 1, "a")
-
-d = gen(K)
-f = a^2 + 2a - 7

Basic functionality

mul_red!Method
mul_red!(z::nf_elem, x::nf_elem, y::nf_elem, red::Bool)

Multiply $x$ by $y$ and set the existing number field element $z$ to the result. Reduction modulo the defining polynomial is only performed if red is set to true. Note that $x$ and $y$ must be reduced. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.

reduce!Method
reduce!(x::nf_elem)

Reduce the given number field element by the defining polynomial, in-place. This only needs to be done after accumulating values computed by mul_red! where reduction has not been performed. All standard Nemo number field functions automatically reduce their outputs.

The following coercion function is provided for a number field $R$.

R(f::QQPolyRingElem)

Coerce the given rational polynomial into the number field $R$, i.e. consider the polynomial to be the representation of a number field element and return it.

Conversely, if $R$ is the polynomial ring to which the generating polynomial of a number field belongs, then we can coerce number field elements into the ring $R$ using the following function.

R(b::nf_elem)

Coerce the given number field element into the polynomial ring $R$ of which the number field is a quotient.

Examples

R, x = polynomial_ring(QQ, "x")
-K, a = number_field(x^3 + 3x + 1, "a")
-
-f = R(a^2 + 2a + 3)
-g = K(x^2 + 2x + 1)

Basic manipulation

varMethod
var(a::AnticNumberField)

Returns the identifier (as a symbol, not a string), that is used for printing the generator of the given number field.

is_genMethod
is_gen(a::nf_elem)

Return true if the given number field element is the generator of the number field, otherwise return false.

coeffMethod
coeff(x::nf_elem, n::Int)

Return the $n$-th coefficient of the polynomial representation of the given number field element. Coefficients are numbered from $0$, starting with the constant coefficient.

denominatorMethod
denominator(a::nf_elem)

Return the denominator of the polynomial representation of the given number field element.

degreeMethod
degree(a::AnticNumberField)

Return the degree of the given number field, i.e. the degree of its defining polynomial.

Examples

R, x = polynomial_ring(QQ, "x")
-K, a = number_field(x^3 + 3x + 1, "a")
-
-d = a^2 + 2a - 7
-m = gen(K)
-
-c = coeff(d, 1)
-is_gen(m)
-q = degree(K)
-r, s = signature(K)
-v = var(R)

Norm and trace

normMethod
norm(a::nf_elem)

Return the absolute norm of $a$. The result will be a rational number.

trMethod
tr(a::nf_elem)

Return the absolute trace of $a$. The result will be a rational number.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over QQ, x)
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Number field of degree 3 over QQ, a)
-
-julia> c = 3a^2 - a + 1
-3*a^2 - a + 1
-
-julia> d = norm(c)
-113
-
-julia> f = tr(c)
--15
diff --git a/previews/PR2578/Nemo/padic/index.html b/previews/PR2578/Nemo/padic/index.html deleted file mode 100644 index d55a88649413..000000000000 --- a/previews/PR2578/Nemo/padic/index.html +++ /dev/null @@ -1,42 +0,0 @@ - -Padics · Oscar.jl

Padics

P-adic fields are provided in Nemo by Flint. This allows construction of $p$-adic fields for any prime $p$.

P-adic fields are constructed using the FlintPadicField function. However, for convenience we define

PadicField = FlintPadicField

so that $p$-adic fields can be constructed using PadicField rather than FlintPadicField. Note that this is the name of the constructor, but not of padic field type.

The types of $p$-adic fields in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Flint$\mathbb{Q}_p$padicPadicField

All the $p$-adic field types belong to the Field abstract type and the $p$-adic field element types belong to the FieldElem abstract type.

P-adic functionality

P-adic fields in Nemo implement all the AbstractAlgebra field functionality:.

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document all the additional function that is provide by Nemo for p-adic fields.

Constructors

In order to construct $p$-adic field elements in Nemo, one must first construct the $p$-adic field itself. This is accomplished with one of the following constructors.

FlintPadicFieldMethod
FlintPadicField(p::Integer, prec::Int; kw...)

Returns the parent object for the $p$-adic field for given prime $p$, where the default absolute precision of elements of the field is given by prec.

It is also possible to call the inner constructor directly. It has the following form.

FlintPadicField(p::ZZRingElem, prec::Int)

Returns the parent object for the $p$-adic field for given prime $p$, where the default absolute precision of elements of the field is given by prec.

Here are some examples of creating $p$-adic fields and making use of the resulting parent objects to coerce various elements into those fields.

Examples

R = PadicField(7, 30)
-S = PadicField(ZZ(65537), 30)
-
-a = R()
-b = S(1)
-c = S(ZZ(123))
-d = R(ZZ(1)//7^2)

Big-oh notation

Elements of p-adic fields can be constructed using the big-oh notation. For this purpose we define the following functions.

OMethod
O(R::FlintPadicField, m::Integer)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

OMethod
O(R::FlintPadicField, m::ZZRingElem)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

OMethod
O(R::FlintPadicField, m::QQFieldElem)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

The $O(p^n)$ construction can be used to construct $p$-adic values of precision $n$ by adding it to integer values representing the $p$-adic value modulo $p^n$ as in the examples.

Examples

R = PadicField(7, 30)
-S = PadicField(ZZ(65537), 30)
-
-c = 1 + 2*7 + 4*7^2 + O(R, 7^3)
-d = 13 + 357*ZZ(65537) + O(S, ZZ(65537)^12)
-f = ZZ(1)//7^2 + ZZ(2)//7 + 3 + 4*7 + O(R, 7^2)

Beware that the expression 1 + 2*p + 3*p^2 + O(R, p^n) is actually computed as a normal Julia expression. Therefore if {Int} values are used instead of Flint integers or Julia bignums, overflow may result in evaluating the value.

Basic manipulation

primeMethod
prime(R::FlintPadicField)

Return the prime $p$ for the given $p$-adic field.

precisionMethod
precision(a::padic)

Return the precision of the given $p$-adic field element, i.e. if the element is known to $O(p^n)$ this function will return $n$.

valuationMethod
valuation(a::padic)

Return the valuation of the given $p$-adic field element, i.e. if the given element is divisible by $p^n$ but not a higher power of $p$ then the function will return $n$.

liftMethod
lift(R::ZZRing, a::padic)

Return a lift of the given $p$-adic field element to $\mathbb{Z}$.

liftMethod
lift(R::QQField, a::padic)

Return a lift of the given $p$-adic field element to $\mathbb{Q}$.

Examples

R = PadicField(7, 30)
-
-a = 1 + 2*7 + 4*7^2 + O(R, 7^3)
-b = 7^2 + 3*7^3 + O(R, 7^5)
-c = R(2)
-
-k = precision(a)
-m = prime(R)
-n = valuation(b)
-p = lift(FlintZZ, a)
-q = lift(FlintQQ, divexact(a, b))

Square root

sqrtMethod
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement

Return the square root of the given Puiseux series $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Base.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement

Return the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.

Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

sqrt(a::FieldElem)

Return the square root of the element a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Examples

R = PadicField(7, 30)
-
-a = 1 + 7 + 2*7^2 + O(R, 7^3)
-b = 2 + 3*7 + O(R, 7^5)
-c = 7^2 + 2*7^3 + O(R, 7^4)
-
-d = sqrt(a)
-f = sqrt(b)
-f = sqrt(c)
-g = sqrt(R(121))

Special functions

expMethod
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

logMethod
log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the logarithm of the given Puiseux series $a$.

log(a::SeriesElem{T}) where T <: FieldElement

Return the logarithm of the power series $a$.

teichmullerMethod
teichmuller(a::padic)

Return the Teichmuller lift of the $p$-adic value $a$. We require the valuation of $a$ to be nonnegative. The precision of the output will be the same as the precision of the input. For convenience, if $a$ is congruent to zero modulo $p$ we return zero. If the input is not valid an exception is thrown.

Examples

R = PadicField(7, 30)
-
-a = 1 + 7 + 2*7^2 + O(R, 7^3)
-b = 2 + 5*7 + 3*7^2 + O(R, 7^3)
-c = 3*7 + 2*7^2 + O(R, 7^5)
-
-c = exp(c)
-d = log(a)
-c = exp(R(0))
-d = log(R(1))
-f = teichmuller(b)
diff --git a/previews/PR2578/Nemo/polynomial/index.html b/previews/PR2578/Nemo/polynomial/index.html deleted file mode 100644 index a27510f0fd34..000000000000 --- a/previews/PR2578/Nemo/polynomial/index.html +++ /dev/null @@ -1,66 +0,0 @@ - -Univariate polynomials · Oscar.jl

Univariate polynomials

Introduction

Nemo allow the creation of dense, univariate polynomials over any computable ring $R$. There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of polynomials over numerous specific rings, usually provided by C/C++ libraries.

The following table shows each of the polynomial types available in Nemo, the base ring $R$, and the Julia/Nemo types for that kind of polynomial (the type information is mainly of concern to developers).

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jlGeneric.Poly{T}Generic.PolyRing{T}
$\mathbb{Z}$FlintZZPolyRingElemZZPolyRing
$\mathbb{Z}/n\mathbb{Z}$ (small $n$)FlintzzModPolyRingElemzzModPolyRing
$\mathbb{Z}/n\mathbb{Z}$ (large $n$)FlintZZModPolyRingElemZZModPolyRing
$\mathbb{Q}$FlintQQPolyRingElemQQPolyRing
$\mathbb{Z}/p\mathbb{Z}$ (small prime $p$)FlintfpPolyRingElemfpPolyRing
$\mathbb{Z}/p\mathbb{Z}$ (large prime $p$)FlintFpPolyRingElemFpPolyRing
$\mathbb{F}_{p^n}$ (small $p$)FlintfqPolyRepPolyRingElemfqPolyRepPolyRing
$\mathbb{F}_{p^n}$ (large $p$)FlintFqPolyRepPolyRingElemFqPolyRepPolyRing
$\mathbb{R}$ (arbitrary precision)ArbRealPolyRealPolyRing
$\mathbb{C}$ (arbitrary precision)ArbComplexPolyComplexPolyRing
$\mathbb{R}$ (fixed precision)Arbarb_polyArbPolyRing
$\mathbb{C}$ (fixed precision)Arbacb_polyAcbPolyRing

The string representation of the variable and the base ring $R$ of a generic polynomial is stored in its parent object.

All polynomial element types belong to the abstract type PolyRingElem and all of the polynomial ring types belong to the abstract type PolyRing. This enables one to write generic functions that can accept any Nemo univariate polynomial type.

Polynomial functionality

All univariate polynomial types in Nemo provide the AbstractAlgebra univariate polynomial functionality:

https://nemocas.github.io/AbstractAlgebra.jl/stable/polynomial

Generic polynomials are also available.

We describe here only functions that are in addition to that guaranteed by AbstractAlgebra.jl, for specific coefficient rings.

Remove and valuation

evaluate2Method
evaluate2(x::RealPoly, y::RingElement)

Return a tuple $p, q$ consisting of the polynomial $x$ evaluated at $y$ and its derivative evaluated at $y$.

evaluate2Method
evaluate2(x::ComplexPoly, y::RingElement; prec::Int = precision(Balls))

Return a tuple $p, q$ consisting of the polynomial $x$ evaluated at $y$ and its derivative evaluated at $y$.

Examples

RR = RealField(64)
-T, z = polynomial_ring(RR, "z")
-   
-h = z^2 + 2z + 1
-
-s, t = evaluate2(h, RR("2.0 +/- 0.1"))

Signature

signatureMethod
signature(f::ZZPolyRingElem)

Return the signature of $f$, i.e. a tuple $(r, s)$ such that $r$ is the number of real roots of $f$ and $s$ is half the number of complex roots.

Examples

julia> R, x = polynomial_ring(ZZ, "x");
-
-julia> signature(x^3 + 3x + 1)
-(1, 1)
signatureMethod
signature(f::QQPolyRingElem)

Return the signature of $f$, i.e. a tuple $(r, s)$ such that $r$ is the number of real roots of $f$ and $s$ is half the number of complex roots.

Examples

julia> R, x = polynomial_ring(QQ, "x");
-
-julia> signature(x^3 + 3x + 1)
-(1, 1)

Root finding

rootsMethod
roots(x::ComplexPoly; target=0, isolate_real=false, initial_prec=0, max_prec=0, max_iter=0)

Attempts to isolate the complex roots of the complex polynomial $x$ by iteratively refining balls in which they lie.

This is done by increasing the working precision, starting at initial_prec. The maximal number of iterations can be set using max_iter and the maximal precision can be set using max_prec.

If isolate_real is set and $x$ is strictly real, then the real roots will be isolated from the non-real roots. Every root will have either zero, positive or negative real part.

It is assumed that $x$ is squarefree.

Examples

CC = ComplexField(64)
-C, y = polynomial_ring(CC, "y")
-
-m = y^2 + 2y + 3
-n = m + CC("0 +/- 0.0001", "0 +/- 0.0001")
-
-r = roots(n)
-
-p = y^7 - 1
-
-r = roots(n, isolate_real = true)

Construction from roots

from_rootsMethod
from_roots(R::ArbPolyRing, b::Vector{arb})

Construct a polynomial in the given polynomial ring from a list of its roots.

from_rootsMethod
from_roots(R::AcbPolyRing, b::Vector{acb})

Construct a polynomial in the given polynomial ring from a list of its roots.

Examples

RR = RealField(64)
-R, x = polynomial_ring(RR, "x")
-
-xs = arb[inv(RR(i)) for i=1:5]
-f = from_roots(R, xs)

Bounding absolute values of roots

roots_upper_boundMethod
roots_upper_bound(x::RealPoly) -> arb

Returns an upper bound for the absolute value of all complex roots of $x$.

roots_upper_boundMethod
roots_upper_bound(x::ComplexPoly) -> arb

Returns an upper bound for the absolute value of all complex roots of $x$.

Lifting

When working over a residue ring it is useful to be able to lift to the base ring of the residue ring, e.g. from $\mathbb{Z}/n\mathbb{Z}$ to $\mathbb{Z}$.

liftMethod
lift(R::ZZPolyRing, y::zzModPolyRingElem)

Lift from a polynomial over $\mathbb{Z}/n\mathbb{Z}$ to a polynomial over $\mathbb{Z}$ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.

liftMethod
lift(R::ZZPolyRing, y::fpPolyRingElem)

Lift from a polynomial over $\mathbb{Z}/n\mathbb{Z}$ to a polynomial over $\mathbb{Z}$ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.

liftMethod
lift(R::ZZPolyRing, y::ZZModPolyRingElem)

Lift from a polynomial over $\mathbb{Z}/n\mathbb{Z}$ to a polynomial over $\mathbb{Z}$ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.

liftMethod
lift(R::ZZPolyRing, y::FpPolyRingElem)

Lift from a polynomial over $\mathbb{Z}/n\mathbb{Z}$ to a polynomial over $\mathbb{Z}$ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.

Examples

R = residue_ring(ZZ, 123456789012345678949)
-S, x = polynomial_ring(R, "x")
-T, y = polynomial_ring(ZZ, "y")
-
-f = x^2 + 2x + 1
-
-a = lift(T, f)

Overlapping and containment

Occasionally it is useful to be able to tell when inexact polynomials overlap or contain other exact or inexact polynomials. The following functions are provided for this purpose.

overlapsMethod
overlaps(x::RealPoly, y::RealPoly)

Return true if the coefficient balls of $x$ overlap the coefficient balls of $y$, otherwise return false.

overlapsMethod
overlaps(x::ComplexPoly, y::ComplexPoly)

Return true if the coefficient boxes of $x$ overlap the coefficient boxes of $y$, otherwise return false.

containsMethod
contains(x::RealPoly, y::RealPoly)

Return true if the coefficient balls of $x$ contain the corresponding coefficient balls of $y$, otherwise return false.

containsMethod
contains(x::ComplexPoly, y::ComplexPoly)

Return true if the coefficient boxes of $x$ contain the corresponding coefficient boxes of $y$, otherwise return false.

containsMethod
contains(x::RealPoly, y::ZZPolyRingElem)

Return true if the coefficient balls of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

containsMethod
contains(x::RealPoly, y::QQPolyRingElem)

Return true if the coefficient balls of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

containsMethod
contains(x::ComplexPoly, y::ZZPolyRingElem)

Return true if the coefficient boxes of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

containsMethod
contains(x::ComplexPoly, y::QQPolyRingElem)

Return true if the coefficient boxes of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

It is sometimes also useful to be able to determine if there is a unique integer contained in the coefficient of an inexact constant polynomial.

unique_integerMethod
unique_integer(x::RealPoly)

Return a tuple (t, z) where $t$ is true if there is a unique integer contained in each of the coefficients of $x$, otherwise sets $t$ to false. In the former case, $z$ is set to the integer polynomial.

unique_integerMethod
unique_integer(x::ComplexPoly)

Return a tuple (t, z) where $t$ is true if there is a unique integer contained in the (constant) polynomial $x$, along with that integer $z$ in case it is, otherwise sets $t$ to false.

Examples

RR = RealField(64)
-CC = ComplexField(64)
-R, x = polynomial_ring(RR, "x")
-C, y = polynomial_ring(CC, "y")
-Zx, zx = polynomial_ring(ZZ, "x")
-Qx, qx = polynomial_ring(QQ, "x")
-
-f = x^2 + 2x + 1
-h = f + RR("0 +/- 0.0001")
-k = f + RR("0 +/- 0.0001") * x^4
-m = y^2 + 2y + 1
-n = m + CC("0 +/- 0.0001", "0 +/- 0.0001")
-
-contains(h, f)
-overlaps(f, k)
-contains(n, m)
-t, z = unique_integer(k)
-isreal(n)

Factorisation

Certain polynomials can be factored (ZZPolyRingElem',zzModPolyRingElem,fpPolyRingElem,ZZModPolyRingElem,FpPolyRingElem,FqPolyRepPolyRingElem,fqPolyRepPolyRingElem`) and the interface follows the specification in AbstractAlgebra.jl. The following additional functions are available.

factor_distinct_degMethod
factor_distinct_deg(x::zzModPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

factor_distinct_degMethod
factor_distinct_deg(x::fpPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

factor_distinct_degMethod
factor_distinct_deg(x::ZZModPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

factor_distinct_degMethod
factor_distinct_deg(x::ZZModPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

factor_distinct_degMethod
factor_distinct_deg(x::FqPolyRepPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

factor_distinct_degMethod
factor_distinct_deg(x::fqPolyRepPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

Examples

R = residue_ring(ZZ, 23)
-S, x = polynomial_ring(R, "x")
-
-f = x^2 + 2x + 1
-g = x^3 + 3x + 1
-
-R = factor(f*g)
-S = factor_squarefree(f*g)
-T = factor_distinct_deg((x + 1)*g*(x^5+x^3+x+1))

Special functions

cyclotomicMethod
cyclotomic(n::Int, x::ZZPolyRingElem)

Return the $n$th cyclotomic polynomial, defined as $\Phi_n(x) = \prod_{\omega} (x-\omega),$ where $\omega$ runs over all the $n$th primitive roots of unity.

swinnerton_dyerMethod
swinnerton_dyer(n::Int, x::ZZPolyRingElem)

Return the Swinnerton-Dyer polynomial $S_n$, defined as the integer polynomial $S_n = \prod (x \pm \sqrt{2} \pm \sqrt{3} \pm \sqrt{5} \pm \ldots \pm \sqrt{p_n})$ where $p_n$ denotes the $n$-th prime number and all combinations of signs are taken. This polynomial has degree $2^n$ and is irreducible over the integers (it is the minimal polynomial of $\sqrt{2} + \ldots + \sqrt{p_n}$).

cos_minpolyMethod
cos_minpoly(n::Int, x::ZZPolyRingElem)

Return the minimal polynomial of $2 \cos(2 \pi / n)$. For suitable choice of $n$, this gives the minimal polynomial of $2 \cos(a \pi)$ or $2 \sin(a \pi)$ for any rational $a$.

theta_qexpMethod
theta_qexp(e::Int, n::Int, x::ZZPolyRingElem)

Return the $q$-expansion to length $n$ of the Jacobi theta function raised to the power $r$, i.e. $\vartheta(q)^r$ where $\vartheta(q) = 1 + \sum_{k=1}^{\infty} q^{k^2}$.

eta_qexpMethod
eta_qexp(e::Int, n::Int, x::ZZPolyRingElem)

Return the $q$-expansion to length $n$ of the Dedekind eta function (without the leading factor $q^{1/24}$) raised to the power $r$, i.e. $(q^{-1/24} \eta(q))^r = \prod_{k=1}^{\infty} (1 - q^k)^r$. In particular, $r = -1$ gives the generating function of the partition function $p(k)$, and $r = 24$ gives, after multiplication by $q$, the modular discriminant $\Delta(q)$ which generates the Ramanujan tau function $\tau(k)$.

Examples

R, x = polynomial_ring(ZZ, "x")
-S, y = polynomial_ring(R, "y")
-
-h = cyclotomic(120, x)
-j = swinnerton_dyer(5, x)
-k = cos_minpoly(30, x)
-l = theta_qexp(3, 30, x)
-m = eta_qexp(24, 30, x)
-o = cyclotomic(10, 1 + x + x^2)
diff --git a/previews/PR2578/Nemo/puiseux/index.html b/previews/PR2578/Nemo/puiseux/index.html deleted file mode 100644 index 3910b29d6184..000000000000 --- a/previews/PR2578/Nemo/puiseux/index.html +++ /dev/null @@ -1,12 +0,0 @@ - -Puiseux series · Oscar.jl

Puiseux series

Nemo allows the creation of Puiseux series over any computable ring $R$. Puiseux series are series of the form $a_jx^{j/m} + a_{j+1}x^{(j+1)/m} + \cdots + a_{k-1}x^{(k-1)/m} + O(x^{k/m})$ where $m$ is a positive integer, $a_i \in R$ and the relative precision $k - j$ is at most equal to some specified precision $n$.

There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of Puiseux series over numerous specific rings, usually provided by C/C++ libraries.

The following table shows each of the Puiseux series types available in Nemo, the base ring $R$, and the Julia/Nemo types for that kind of series (the type information is mainly of concern to developers).

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jl`Generic.PuiseuxSeriesRingElem{T}Generic.PuiseuxSeriesRing{T}
Generic field $K$AbstractAlgebra.jl`Generic.PuiseuxSeriesFieldElem{T}Generic.PuiseuxSeriesField{T}
$\mathbb{Z}$FlintFlintPuiseuxSeriesRingElem{ZZLaurentSeriesRingElem}FlintPuiseuxSeriesRing{ZZLaurentSeriesRingElem}

For convenience, FlintPuiseuxSeriesRingElem and FlintPuiseuxSeriesFieldElem both belong to a union type called FlintPuiseuxSeriesElem.

The maximum relative precision, the string representation of the variable and the base ring $R$ of a generic power series are stored in the parent object.

Note that unlike most other Nemo types, Puiseux series are parameterised by the type of the underlying Laurent series type (which must exist before Nemo can make use of it), instead of the type of the coefficients.

Puiseux power series

Puiseux series have their maximum relative precision capped at some value prec_max. This refers to the maximum precision of the underlying Laurent series. See the description of the generic Puiseux series in AbstractAlgebra.jl for details.

There are numerous important things to be aware of when working with Puiseux series, or series in general. Please refer to the documentation of generic Puiseux series and series in general in AbstractAlgebra.jl for details.

Puiseux series functionality

Puiseux series rings in Nemo implement all the same functionality that is available for AbstractAlgebra series rings, with the exception of the pol_length and polcoeff functions:

https://nemocas.github.io/AbstractAlgebra.jl/stable/series

In addition, generic Puiseux series are provided by AbstractAlgebra.jl

We list below only the functionality that differs from that described in AbstractAlgebra, for specific rings provided by Nemo.

Special functions

sqrtMethod
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement

Return the square root of the given Puiseux series $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Base.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement

Return the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.

Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

expMethod
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

eta_qexpMethod
eta_qexp(x::FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem})

Return the $q$-series for eta evaluated at $x$, which must currently be a rational power of the generator of the Puiseux series ring.

Examples

julia> S, z = PuiseuxSeriesRing(ZZ, 30, "z")
-(Puiseux series ring in z over ZZ, z + O(z^31))
-
-julia> a = 1 + z + 3z^2 + O(z^5)
-1 + z + 3*z^2 + O(z^5)
-
-julia> h = sqrt(a^2)
-1 + z + 3*z^2 + O(z^5)
-
-julia> k = eta_qexp(z)
-z^(1//24) - z^(25//24) + O(z^(31//24))
diff --git a/previews/PR2578/Nemo/qadic/index.html b/previews/PR2578/Nemo/qadic/index.html deleted file mode 100644 index b90b6abfdafb..000000000000 --- a/previews/PR2578/Nemo/qadic/index.html +++ /dev/null @@ -1,87 +0,0 @@ - -Qadics · Oscar.jl

Qadics

Q-adic fields, that is, unramified extensions of p-adic fields, are provided in Nemo by Flint. This allows construction of $q$-adic fields for any prime power $q$.

Q-adic fields are constructed using the FlintQadicField function. However, for convenience we define

QadicField = FlintQadicField

so that $q$-adic fields can be constructed using QadicField rather than FlintQadicField. Note that this is the name of the constructor, but not of qadic field type.

The types of $q$-adic fields in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Flint$\mathbb{Q}_q$qadicQadicField

All the $q$-adic field types belong to the Field abstract type and the $q$-adic field element types belong to the FieldElem abstract type.

P-adic functionality

Q-adic fields in Nemo provide all the functionality described in AbstractAlgebra for fields:.

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document all the additional function that is provide by Nemo for q-adic fields.

Constructors

In order to construct $q$-adic field elements in Nemo, one must first construct the $q$-adic field itself. This is accomplished with one of the following constructors.

FlintQadicFieldMethod
FlintQadicField(p::Integer, d::Int, prec::Int, var::String = "a")

Returns the parent object for the $q$-adic field for given prime $p$ and degree $d$, where the default absolute precision of elements of the field is given by prec and the generator is printed as var.

It is also possible to call the inner constructor directly. It has the following form.

FlintQadicField(p::ZZRingElem, d::Int, prec::Int)

Returns the parent object for the $q$-adic field for given prime $p$ and degree $d$, where the default absolute precision of elements of the field is given by prec. It also return the uniformizer p with the default precision.

Here are some examples of creating $q$-adic fields and making use of the resulting parent objects to coerce various elements into those fields.

Examples

julia> R, p = QadicField(7, 1, 30);
-
-julia> S, _ = QadicField(ZZ(65537), 1, 30);
-
-julia> a = R()
-0
-
-julia> b = S(1)
-65537^0 + O(65537^30)
-
-julia> c = S(ZZ(123))
-123*65537^0 + O(65537^30)
-
-julia> d = R(ZZ(1)//7^2)
-7^-2 + O(7^28)

Big-oh notation

Elements of p-adic fields can be constructed using the big-oh notation. For this purpose we define the following functions.

OMethod
O(R::FlintQadicField, m::Integer)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

OMethod
O(R::FlintQadicField, m::ZZRingElem)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

OMethod
O(R::FlintQadicField, m::QQFieldElem)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

The $O(p^n)$ construction can be used to construct $q$-adic values of precision $n$ by adding it to integer values representing the $q$-adic value modulo $p^n$ as in the examples.

Examples

julia> R, _ = QadicField(7, 1, 30);
-
-julia> S, _ = QadicField(ZZ(65537), 1, 30);
-
-julia> c = 1 + 2*7 + 4*7^2 + O(R, 7^3)
-7^0 + 2*7^1 + 4*7^2 + O(7^3)
-
-julia> d = 13 + 357*ZZ(65537) + O(S, ZZ(65537)^12)
-13*65537^0 + 357*65537^1 + O(65537^12)
-
-julia> f = ZZ(1)//7^2 + ZZ(2)//7 + 3 + 4*7 + O(R, 7^2)
-7^-2 + 2*7^-1 + 3*7^0 + 4*7^1 + O(7^2)

Beware that the expression 1 + 2*p + 3*p^2 + O(R, p^n) is actually computed as a normal Julia expression. Therefore if {Int} values are used instead of Flint integers or Julia bignums, overflow may result in evaluating the value.

Basic manipulation

primeMethod
prime(R::FlintQadicField)

Return the prime $p$ for the given $q$-adic field.

precisionMethod
precision(a::qadic)

Return the precision of the given $q$-adic field element, i.e. if the element is known to $O(p^n)$ this function will return $n$.

valuationMethod
valuation(a::qadic)

Return the valuation of the given $q$-adic field element, i.e. if the given element is divisible by $p^n$ but not a higher power of $q$ then the function will return $n$.

liftMethod
lift(R::QQPolyRing, a::qadic)

Return a lift of the given $q$-adic field element to $\mathbb{Q}[x]$.

liftMethod
lift(R::ZZPolyRing, a::qadic)

Return a lift of the given $q$-adic field element to $\mathbb{Z}[x]$ if possible.

Examples

R, _ = QadicField(7, 1, 30);
-
-a = 1 + 2*7 + 4*7^2 + O(R, 7^3)
-b = 7^2 + 3*7^3 + O(R, 7^5)
-c = R(2)
-
-k = precision(a)
-m = prime(R)
-n = valuation(b)
-Qx, x = FlintQQ["x"]
-p = lift(Qx, a)
-Zy, y = FlintZZ["y"]
-q = lift(Zy, divexact(a, b))

Square root

sqrtMethod
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement

Return the square root of the given Puiseux series $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Base.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement

Return the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.

Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

sqrt(a::FieldElem)

Return the square root of the element a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Examples

julia> R, _ = QadicField(7, 1, 30);
-
-julia> a = 1 + 7 + 2*7^2 + O(R, 7^3)
-7^0 + 7^1 + 2*7^2 + O(7^3)
-
-julia> b = 2 + 3*7 + O(R, 7^5)
-2*7^0 + 3*7^1 + O(7^5)
-
-julia> c = 7^2 + 2*7^3 + O(R, 7^4)
-7^2 + 2*7^3 + O(7^4)
-
-julia> d = sqrt(a)
-7^0 + 4*7^1 + 3*7^2 + O(7^3)
-
-julia> f = sqrt(b)
-4*7^0 + 7^1 + 5*7^2 + 5*7^3 + 6*7^4 + O(7^5)
-
-julia> f = sqrt(c)
-7^1 + 7^2 + O(7^3)
-
-julia> g = sqrt(R(121))
-4*7^0 + 7^1 + O(7^30)

Special functions

expMethod
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

logMethod
log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the logarithm of the given Puiseux series $a$.

log(a::SeriesElem{T}) where T <: FieldElement

Return the logarithm of the power series $a$.

teichmullerMethod
teichmuller(a::qadic)

Return the Teichmuller lift of the $q$-adic value $a$. We require the valuation of $a$ to be nonnegative. The precision of the output will be the same as the precision of the input. For convenience, if $a$ is congruent to zero modulo $q$ we return zero. If the input is not valid an exception is thrown.

frobeniusMethod
frobenius(a::qadic, e::Int = 1)

Return the image of the $e$-th power of Frobenius on the $q$-adic value $a$. The precision of the output will be the same as the precision of the input.

Examples

julia> R, _ = QadicField(7, 1, 30);
-
-julia> a = 1 + 7 + 2*7^2 + O(R, 7^3)
-7^0 + 7^1 + 2*7^2 + O(7^3)
-
-julia> b = 2 + 5*7 + 3*7^2 + O(R, 7^3)
-2*7^0 + 5*7^1 + 3*7^2 + O(7^3)
-
-julia> c = 3*7 + 2*7^2 + O(R, 7^5)
-3*7^1 + 2*7^2 + O(7^5)
-
-julia> c = exp(c)
-7^0 + 3*7^1 + 3*7^2 + 4*7^3 + 4*7^4 + O(7^5)
-
-julia> d = log(a)
-7^1 + 5*7^2 + O(7^3)
-
-julia> c = exp(R(0))
-7^0 + O(7^30)
-
-julia> d = log(R(1))
-0
-
-julia> f = teichmuller(b)
-2*7^0 + 4*7^1 + 6*7^2 + O(7^3)
-
-julia> g = frobenius(a, 2)
-7^0 + 7^1 + 2*7^2 + O(7^3)
diff --git a/previews/PR2578/Nemo/rational/index.html b/previews/PR2578/Nemo/rational/index.html deleted file mode 100644 index e717368a8b61..000000000000 --- a/previews/PR2578/Nemo/rational/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Rationals · Oscar.jl

Rationals

Nemo provides much functionality for the rational numbers. See the section on Fraction Fields where all the basic functionality is documented, along with the extra functionality only available for the rational numbers themselves.

diff --git a/previews/PR2578/Nemo/real/index.html b/previews/PR2578/Nemo/real/index.html deleted file mode 100644 index 06e1cae9c891..000000000000 --- a/previews/PR2578/Nemo/real/index.html +++ /dev/null @@ -1,225 +0,0 @@ - -Arbitrary precision real balls · Oscar.jl

Arbitrary precision real balls

Arbitrary precision real ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Real numbers are represented in mid-rad interval form $[m \pm r] = [m-r, m+r]$.

The types of real balls in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Arb$\mathbb{R}$ (balls)RealFieldElemRealField

The real field types belong to the Field abstract type and the types of elements in this field, i.e. balls in this case, belong to the FieldElem abstract type.

Real ball functionality

Real balls in Nemo provide all the field functionality described in AbstractAlgebra:

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document the additional functionality provided for real balls.

Precision management

Precision for ball arithmetic and creation of elements can be controlled using the functions:

precisionMethod
precision(::Type{Balls})

Return the precision for ball arithmetic.

Examples

julia> set_precision!(Balls, 200); precision(Balls)
-200
set_precision!Method
set_precision!(::Type{Balls}, n::Int)

Set the precision for all ball arithmetic to be n.

Examples

julia> const_pi(RealField())
-[3.141592653589793239 +/- 5.96e-19]
-
-julia> set_precision!(Balls, 200); const_pi(RealField())
-[3.14159265358979323846264338327950288419716939937510582097494 +/- 5.73e-60]
set_precision!Method
set_precision!(f, ::Type{Balls}, n::Int)

Change ball arithmetic precision to n for the duration of f..

Examples

julia> set_precision!(Balls, 4) do
-         const_pi(RealField())
-       end
-[3e+0 +/- 0.376]
-
-julia> set_precision!(Balls, 200) do
-         const_pi(RealField())
-       end
-[3.1415926535897932385 +/- 3.74e-20]
Info

This functions are not thread-safe.

Constructors

In order to construct real balls in Nemo, one must first construct the Arb real field itself. This is accomplished with the following constructor.

RealField()

Here is an example of creating the real field and using the resulting parent object to coerce values into the resulting field.

Examples

julia> RR = RealField()
-Real field
-
-julia> a = RR("0.25")
-0.25000000000000000000
-
-julia> b = RR("0.1 +/- 0.001")
-[0.1 +/- 1.01e-3]
-
-julia> c = RR(0.5)
-0.50000000000000000000
-
-julia> d = RR(12)
-12.000000000000000000

Note that whilst one can coerce double precision floating point values into an Arb real field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.

If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb field.

If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.

Real ball constructors

Using coercion into the real field, new elements can be created.

Examples

julia> RR = RealField()
-Real field
-
-julia> c = RR(1)
-1.0000000000000000000
-
-julia> d = RR(1//2)
-0.50000000000000000000

Note that for the construction, also the precision can be supplied:

RR = RealField()
-
-c = RR(1, precision = 100)
-d = RR(1//2, precision = 4)

Conversions

julia> RR = RealField()
-Real field
-
-julia> convert(Float64, RR(1//3))
-0.3333333333333333

Basic manipulation

is_nonzeroMethod
is_nonzero(x::RealFieldElem)

Return true if $x$ is certainly not equal to zero, otherwise return false.

isfiniteMethod
isfinite(x::RealFieldElem)

Return true if $x$ is finite, i.e. having finite midpoint and radius, otherwise return false.

is_exactMethod
is_exact(x::RealFieldElem)

Return true if $x$ is exact, i.e. has zero radius, otherwise return false.

isintegerMethod
isinteger(x::RealFieldElem)

Return true if $x$ is an exact integer, otherwise return false.

is_positiveMethod
is_positive(x::RealFieldElem)

Return true if $x$ is certainly positive, otherwise return false.

is_nonnegativeMethod
is_nonnegative(x::RealFieldElem)

Return true if $x$ is certainly nonnegative, otherwise return false.

is_negativeMethod
is_negative(x::RealFieldElem)

Return true if $x$ is certainly negative, otherwise return false.

is_nonpositiveMethod
is_nonpositive(x::RealFieldElem)

Return true if $x$ is certainly nonpositive, otherwise return false.

midpointMethod
midpoint(x::RealFieldElem)

Return the midpoint of the ball $x$ as an Arb ball.

radiusMethod
radius(x::RealFieldElem)

Return the radius of the ball $x$ as an Arb ball.

accuracy_bitsMethod
accuracy_bits(x::RealFieldElem)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

Examples

julia> RR = RealField()
-Real field
-
-julia> a = RR("1.2 +/- 0.001")
-[1.20 +/- 1.01e-3]
-
-julia> b = RR(3)
-3.0000000000000000000
-
-julia> is_positive(a)
-true
-
-julia> isfinite(b)
-true
-
-julia> isinteger(b)
-true
-
-julia> is_negative(a)
-false
-
-julia> c = radius(a)
-[0.0010000000038417056203 +/- 1.12e-23]
-
-julia> d = midpoint(b)
-3.0000000000000000000
-
-julia> f = accuracy_bits(a)
-9

Printing

Printing real balls can at first sight be confusing. Lets look at the following example:

RR = RealField()
-
-a = RR(1)
-b = RR(2)
-c = RR(12)
-
-x = ball(a, b)
-y = ball(c, b)
-
-mid = midpoint(x)
-rad = radius(x)
-
-print(x, "\n", y, "\n", mid, "\n", rad)

which generates

[+/- 3.01]
-[1e+1 +/- 4.01]
-1.0000000000000000000
-[2.0000000037252902985 +/- 3.81e-20]

The first reason that c is not printed as [1 +/- 2] is that the midpoint does not have a greater exponent than the radius in its scientific notation. For similar reasons y is not printed as [12 +/- 2].

The second reason is that we get an additional error term after our addition. As we see, radius(c) is not equal to $2$, which when printed rounds it up to a reasonable decimal place. This is because real balls keep track of rounding errors of basic arithmetic.

Containment

It is often necessary to determine whether a given exact value or ball is contained in a given real ball or whether two balls overlap. The following functions are provided for this purpose.

overlapsMethod
overlaps(x::RealFieldElem, y::RealFieldElem)

Returns true if any part of the ball $x$ overlaps any part of the ball $y$, otherwise return false.

containsMethod
contains(x::RealFieldElem, y::RealFieldElem)

Returns true if the ball $x$ contains the ball $y$, otherwise return false.

containsMethod
contains(x::RealFieldElem, y::Integer)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::RealFieldElem, y::ZZRingElem)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

containsMethod
contains(x::RealFieldElem, y::QQFieldElem)

Returns true if the ball $x$ contains the given rational value, otherwise return false.

containsMethod
contains(x::RealFieldElem, y::Rational{T}) where {T <: Integer}

Returns true if the ball $x$ contains the given rational value, otherwise return false.

containsMethod
contains(x::RealFieldElem, y::BigFloat)

Returns true if the ball $x$ contains the given floating point value, otherwise return false.

The following functions are also provided for determining if a ball intersects a certain part of the real number line.

contains_zeroMethod
contains_zero(x::RealFieldElem)

Returns true if the ball $x$ contains zero, otherwise return false.

contains_negativeMethod
contains_negative(x::RealFieldElem)

Returns true if the ball $x$ contains any negative value, otherwise return false.

contains_positiveMethod
contains_positive(x::RealFieldElem)

Returns true if the ball $x$ contains any positive value, otherwise return false.

contains_nonnegativeMethod
contains_nonnegative(x::RealFieldElem)

Returns true if the ball $x$ contains any nonnegative value, otherwise return false.

contains_nonpositiveMethod
contains_nonpositive(x::RealFieldElem)

Returns true if the ball $x$ contains any nonpositive value, otherwise return false.

Examples

julia> RR = RealField()
-Real field
-
-julia> x = RR("1 +/- 0.001")
-[1.00 +/- 1.01e-3]
-
-julia> y = RR("3")
-3.0000000000000000000
-
-julia> overlaps(x, y)
-false
-
-julia> contains(x, y)
-false
-
-julia> contains(y, 3)
-true
-
-julia> contains(x, ZZ(1)//2)
-false
-
-julia> contains_zero(x)
-false
-
-julia> contains_positive(y)
-true

Comparison

Nemo provides a full range of comparison operations for Arb balls. Note that a ball is considered less than another ball if every value in the first ball is less than every value in the second ball, etc.

In addition to the standard comparison operators, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.

isequalMethod
isequal(x::RealFieldElem, y::RealFieldElem)

Return true if the balls $x$ and $y$ are precisely equal, i.e. have the same midpoints and radii.

We also provide a full range of ad hoc comparison operators. These are implemented directly in Julia, but we document them as though isless and == were provided.

Function
==(x::RealFieldElem, y::Integer)
==(x::Integer, y::RealFieldElem)
==(x::RealFieldElem, y::ZZRingElem)
==(x::ZZRingElem, y::RealFieldElem)
==(x::RealFieldElem, y::Float64)
==(x::Float64, y::RealFieldElem)
isless(x::RealFieldElem, y::Integer)
isless(x::Integer, y::RealFieldElem)
isless(x::RealFieldElem, y::ZZRingElem)
isless(x::ZZRingElem, y::RealFieldElem)
isless(x::RealFieldElem, y::Float64)
isless(x::Float64, y::RealFieldElem)
isless(x::RealFieldElem, y::BigFloat)
isless(x::BigFloat, y::RealFieldElem)
isless(x::RealFieldElem, y::QQFieldElem)
isless(x::QQFieldElem, y::RealFieldElem)

Examples

julia> RR = RealField()
-Real field
-
-julia> x = RR("1 +/- 0.001")
-[1.00 +/- 1.01e-3]
-
-julia> y = RR("3")
-3.0000000000000000000
-
-julia> z = RR("4")
-4.0000000000000000000
-
-julia> isequal(x, deepcopy(x))
-true
-
-julia> x == 3
-false
-
-julia> ZZ(3) < z
-true
-
-julia> x != 1.23
-true

Absolute value

Examples

julia> RR = RealField()
-Real field
-
-julia> x = RR("-1 +/- 0.001")
-[-1.00 +/- 1.01e-3]
-
-julia> a = abs(x)
-[1.00 +/- 1.01e-3]

Shifting

Examples

julia> RR = RealField()
-Real field
-
-julia> x = RR("-3 +/- 0.001")
-[-3.00 +/- 1.01e-3]
-
-julia> a = ldexp(x, 23)
-[-2.52e+7 +/- 4.26e+4]
-
-julia> b = ldexp(x, -ZZ(15))
-[-9.16e-5 +/- 7.78e-8]

Miscellaneous operations

add_error!Method
add_error!(x::RealFieldElem, y::RealFieldElem)

Adds the absolute values of the midpoint and radius of $y$ to the radius of $x$.

trimMethod
trim(x::RealFieldElem)

Return an arb interval containing $x$ but which may be more economical, by rounding off insignificant bits from the midpoint.

unique_integerMethod
unique_integer(x::RealFieldElem)

Return a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the interval $x$ contains a unique integer. If this is the case, the second return value is set to this unique integer.

setunionMethod
setunion(x::RealFieldElem, y::RealFieldElem)

Return an arb containing the union of the intervals represented by $x$ and $y$.

Examples

julia> RR = RealField()
-Real field
-
-julia> x = RR("-3 +/- 0.001")
-[-3.00 +/- 1.01e-3]
-
-julia> y = RR("2 +/- 0.5")
-[2e+0 +/- 0.501]
-
-julia> a = trim(x)
-[-3.00 +/- 1.01e-3]
-
-julia> b, c = unique_integer(x)
-(true, -3)
-
-julia> d = setunion(x, y)
-[+/- 3.01]

Constants

const_piMethod
const_pi(r::RealField)

Return $\pi = 3.14159\ldots$ as an element of $r$.

const_eMethod
const_e(r::RealField)

Return $e = 2.71828\ldots$ as an element of $r$.

const_log2Method
const_log2(r::RealField)

Return $\log(2) = 0.69314\ldots$ as an element of $r$.

const_log10Method
const_log10(r::RealField)

Return $\log(10) = 2.302585\ldots$ as an element of $r$.

const_eulerMethod
const_euler(r::RealField)

Return Euler's constant $\gamma = 0.577215\ldots$ as an element of $r$.

const_catalanMethod
const_catalan(r::RealField)

Return Catalan's constant $C = 0.915965\ldots$ as an element of $r$.

const_khinchinMethod
const_khinchin(r::RealField)

Return Khinchin's constant $K = 2.685452\ldots$ as an element of $r$.

const_glaisherMethod
const_glaisher(r::RealField)

Return Glaisher's constant $A = 1.282427\ldots$ as an element of $r$.

Examples

julia> RR = RealField()
-Real field
-
-julia> a = const_pi(RR)
-[3.141592653589793239 +/- 5.96e-19]
-
-julia> b = const_e(RR)
-[2.718281828459045235 +/- 4.29e-19]
-
-julia> c = const_euler(RR)
-[0.5772156649015328606 +/- 4.35e-20]
-
-julia> d = const_glaisher(RR)
-[1.282427129100622637 +/- 3.01e-19]

Mathematical and special functions

rsqrtMethod
rsqrt(x::RealFieldElem)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

sqrt1pm1Method
sqrt1pm1(x::RealFieldElem)

Return $\sqrt{1+x}-1$, evaluated accurately for small $x$.

sqrtposMethod
sqrtpos(x::RealFieldElem)

Return the sqrt root of $x$, assuming that $x$ represents a nonnegative number. Thus any negative number in the input interval is discarded.

gammaMethod
gamma(x::RealFieldElem)

Return the Gamma function evaluated at $x$.

lgammaMethod
lgamma(x::RealFieldElem)

Return the logarithm of the Gamma function evaluated at $x$.

rgammaMethod
rgamma(x::RealFieldElem)

Return the reciprocal of the Gamma function evaluated at $x$.

digammaMethod
digamma(x::RealFieldElem)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

gammaMethod
gamma(s::RealFieldElem, x::RealFieldElem)

Return the upper incomplete gamma function $\Gamma(s,x)$.

gamma_regularizedMethod
gamma_regularized(s::RealFieldElem, x::RealFieldElem)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

gamma_lowerMethod
gamma_lower(s::RealFieldElem, x::RealFieldElem)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

gamma_lower_regularizedMethod
gamma_lower_regularized(s::RealFieldElem, x::RealFieldElem)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

zetaMethod
zeta(x::RealFieldElem)

Return the Riemann zeta function evaluated at $x$.

atan2Method
atan2(y::RealFieldElem, x::RealFieldElem)

Return $\operatorname{atan2}(y,x) = \arg(x+yi)$. Same as atan(y, x).

agmMethod
agm(x::RealFieldElem, y::RealFieldElem)

Return the arithmetic-geometric mean of $x$ and $y$

zetaMethod
zeta(s::RealFieldElem, a::RealFieldElem)

Return the Hurwitz zeta function $\zeta(s,a)$.

rootMethod
root(x::RealFieldElem, n::Int)

Return the $n$-th root of $x$. We require $x \geq 0$.

factorialMethod
factorial(x::RealFieldElem)

Return the factorial of $x$.

factorialMethod
factorial(n::Int, r::RealField)

Return the factorial of $n$ in the given Arb field.

binomialMethod
binomial(x::RealFieldElem, n::UInt)

Return the binomial coefficient ${x \choose n}$.

binomialMethod
binomial(n::UInt, k::UInt, r::RealField)

Return the binomial coefficient ${n \choose k}$ in the given Arb field.

fibonacciMethod
fibonacci(n::ZZRingElem, r::RealField)

Return the $n$-th Fibonacci number in the given Arb field.

fibonacciMethod
fibonacci(n::Int, r::RealField)

Return the $n$-th Fibonacci number in the given Arb field.

gammaMethod
gamma(x::ZZRingElem, r::RealField)

Return the Gamma function evaluated at $x$ in the given Arb field.

gammaMethod
gamma(x::QQFieldElem, r::RealField)

Return the Gamma function evaluated at $x$ in the given Arb field.

zetaMethod
zeta(n::Int, r::RealField)

Return the Riemann zeta function $\zeta(n)$ as an element of the given Arb field.

bernoulliMethod
bernoulli(n::Int, r::RealField)

Return the $n$-th Bernoulli number as an element of the given Arb field.

rising_factorialMethod
rising_factorial(x::RealFieldElem, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Arb.

rising_factorialMethod
rising_factorial(x::QQFieldElem, n::Int, r::RealField)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an element of the given Arb field.

rising_factorial2Method
rising_factorial2(x::RealFieldElem, n::Int)

Return a tuple containing the rising factorial $x(x + 1)\ldots (x + n - 1)$ and its derivative.

polylogMethod
polylog(s::Union{RealFieldElem,Int}, a::RealFieldElem)

Return the polylogarithm Li$_s(a)$.

chebyshev_tMethod
chebyshev_t(n::Int, x::RealFieldElem)

Return the value of the Chebyshev polynomial $T_n(x)$.

chebyshev_uMethod
chebyshev_u(n::Int, x::RealFieldElem)

Return the value of the Chebyshev polynomial $U_n(x)$.

chebyshev_t2Method
chebyshev_t2(n::Int, x::RealFieldElem)

Return the tuple $(T_{n}(x), T_{n-1}(x))$.

chebyshev_u2Method
chebyshev_u2(n::Int, x::RealFieldElem)

Return the tuple $(U_{n}(x), U_{n-1}(x))$

bellMethod
bell(n::ZZRingElem, r::RealField)

Return the Bell number $B_n$ as an element of $r$.

bellMethod
bell(n::Int, r::RealField)

Return the Bell number $B_n$ as an element of $r$.

numpartMethod
numpart(n::ZZRingElem, r::RealField)

Return the number of partitions $p(n)$ as an element of $r$.

numpartMethod
numpart(n::Int, r::RealField)

Return the number of partitions $p(n)$ as an element of $r$.

airy_aiMethod
airy_ai(x::RealFieldElem)

Return the Airy function $\operatorname{Ai}(x)$.

airy_ai_primeMethod
airy_ai_prime(x::RealFieldElem)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

airy_biMethod
airy_bi(x::RealFieldElem)

Return the Airy function $\operatorname{Bi}(x)$.

airy_bi_primeMethod
airy_bi_prime(x::RealFieldElem)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

Examples

julia> RR = RealField()
-Real field
-
-julia> a = floor(exp(RR(1)))
-2.0000000000000000000
-
-julia> b = sinpi(QQ(5,6), RR)
-0.50000000000000000000
-
-julia> c = gamma(QQ(1,3), RR)
-[2.678938534707747634 +/- 7.13e-19]
-
-julia> d = bernoulli(1000, RR)
-[-5.318704469415522036e+1769 +/- 6.61e+1750]
-
-julia> f = polylog(3, RR(-10))
-[-5.92106480375697 +/- 6.68e-15]

Linear dependence

lindepMethod
lindep(A::Vector{RealFieldElem}, bits::Int)

Find a small linear combination of the entries of the array $A$ that is small (using LLL). The entries are first scaled by the given number of bits before truncating to integers for use in LLL. This function can be used to find linear dependence between a list of real numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.

Examples

julia> RR = RealField()
-Real field
-
-julia> a = RR(-0.33198902958450931620250069492231652319)
-[-0.33198902958450932088 +/- 4.15e-22]
-
-julia> V = [RR(1), a, a^2, a^3, a^4, a^5]
-6-element Vector{RealFieldElem}:
- 1.0000000000000000000
- [-0.33198902958450932088 +/- 4.15e-22]
- [0.11021671576446420510 +/- 7.87e-21]
- [-0.03659074051063616184 +/- 4.17e-21]
- [0.012147724433904692427 +/- 4.99e-22]
- [-0.004032911246472051677 +/- 6.25e-22]
-
-julia> W = lindep(V, 20)
-6-element Vector{ZZRingElem}:
- 1
- 3
- 0
- 0
- 0
- 1
simplest_rational_insideMethod
  simplest_rational_inside(x::RealFieldElem)

Return the simplest fraction inside the ball $x$. A canonical fraction $a_1/b_1$ is defined to be simpler than $a_2/b_2$ iff $b_1 < b_2$ or $b_1 = b_2$ and $a_1 < a_2$.

Examples

julia> RR = RealField()
-Real field
-
-julia> simplest_rational_inside(const_pi(RR))
-8717442233//2774848045

Random generation

randMethod
rand(r::RealField; randtype::Symbol=:urandom)

Return a random element in given Arb field.

The randtype default is :urandom which return an arb contained in $[0,1]$.

The rest of the methods return non-uniformly distributed values in order to exercise corner cases. The option :randtest will return a finite number, and :randtest_exact the same but with a zero radius. The option :randtest_precise return an arb with a radius around $2^{-\mathrm{prec}}$ the magnitude of the midpoint, while :randtest_wide return a radius that might be big relative to its midpoint. The :randtest_special-option might return a midpoint and radius whose values are NaN or inf.

rand([rng=GLOBAL_RNG,] G::SymmetricGroup)

Return a random permutation from G.

Examples

RR = RealField()
-
-a = rand(RR)
-b = rand(RR; randtype = :null_exact)
-c = rand(RR; randtype = :exact)
-d = rand(RR; randtype = :special)
diff --git a/previews/PR2578/Nemo/residue/index.html b/previews/PR2578/Nemo/residue/index.html deleted file mode 100644 index e937b160018c..000000000000 --- a/previews/PR2578/Nemo/residue/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Residue rings · Oscar.jl

Residue rings

Nemo allows the creation of residue rings of the form $R/(a)$ for an element $a$ of a ring $R$.

We don't require $(a)$ to be a prime or maximal ideal. Instead, we allow the creation of the residue ring $R/(a)$ for any nonzero $a$ and simply raise an exception if an impossible inverse is encountered during computations involving elements of $R/(a)$. Of course, a GCD function must be available for the base ring $R$.

There is a generic implementation of residue rings of this form in AbstractAlgebra.jl, which accepts any ring $R$ as base ring.

The associated types of parent object and elements for each kind of residue rings in Nemo are given in the following table.

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jlGeneric.ResidueRingElem{T}Generic.ResidueRing{T}
$\mathbb{Z}$ (Int modulus)FlintzzModRingElemzzModRing
$\mathbb{Z}$ (ZZ modulus)FlintZZModRingElemZZModRing

The modulus $a$ of a residue ring is stored in its parent object.

All residue element types belong to the abstract type ResElem and all the residue ring parent object types belong to the abstract type ResidueRing. This enables one to write generic functions that accept any Nemo residue type.

Residue functionality

All the residue rings in Nemo provide the functionality described in AbstractAlgebra for residue rings:

https://nemocas.github.io/AbstractAlgebra.jl/stable/residue

In addition, generic residue rings are available.

We describe Nemo specific residue ring functionality below.

GCD

gcdxMethod
gcdx(a::zzModRingElem, b::zzModRingElem)

Compute the extended gcd with the Euclidean structure inherited from $\mathbb{Z}$.

gcdxMethod
gcdx(a::ZZModRingElem, b::ZZModRingElem)

Compute the extended gcd with the Euclidean structure inherited from $\mathbb{Z}$.

Examples

julia> R = residue_ring(ZZ, 123456789012345678949)
-Integers modulo 123456789012345678949
-
-julia> g, s, t = gcdx(R(123), R(456))
-(1, 123456789012345678928, 41152263004115226322)
diff --git a/previews/PR2578/Nemo/series/index.html b/previews/PR2578/Nemo/series/index.html deleted file mode 100644 index bfeb4c3666f5..000000000000 --- a/previews/PR2578/Nemo/series/index.html +++ /dev/null @@ -1,27 +0,0 @@ - -Power series and Laurent series · Oscar.jl

Power series and Laurent series

Nemo allows the creation of capped relative and absolute power series over any computable ring $R$. Capped relative power series are power series of the form $a_jx^j + a_{j+1}x^{j+1} + \cdots + a_{k-1}x^{k-1} + O(x^k)$ where $j \geq 0$, $a_j \in R$ and the relative precision $k - j$ is at most equal to some specified precision $n$. On the other hand capped absolute power series are power series of the form $a_jx^j + a_{j+1}x^{j+1} + \cdots + a_{n-1}x^{n-1} + O(x^n)$ where $j \geq 0$, $a_j \in R$ and the precision $n$ is fixed.

There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of power series over numerous specific rings, usually provided by C/C++ libraries.

The following table shows each of the relative power series types available in Nemo, the base ring $R$, and the Julia/Nemo types for that kind of series (the type information is mainly of concern to developers).

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jl`Generic.RelSeries{T}Generic.RelPowerSeriesRing{T}
$\mathbb{Z}$FlintZZRelPowerSeriesRingElemZZRelPowerSeriesRing
$\mathbb{Z}/n\mathbb{Z}$ (small $n$)FlintzzModRelPowerSeriesRingElemzzModRelPowerSeriesRing
$\mathbb{Z}/n\mathbb{Z}$ (large $n$)FlintZZModRelPowerSeriesRingElemZZModRelPowerSeriesRing
$\mathbb{Q}$FlintQQRelPowerSeriesRingElemQQRelPowerSeriesRing
$\mathbb{F}_p$ (small $n$)FlintfpRelPowerSeriesRingElemfpRelPowerSeriesRing
$\mathbb{F}_p$ (large $n$)FlintFpRelPowerSeriesRingElemFpRelPowerSeriesRing
$\mathbb{F}_{p^n}$ (small $p$)FlintfqPolyRepRelPowerSeriesRingElemfqPolyRepRelPowerSeriesRing
$\mathbb{F}_{p^n}$ (large $p$)FlintFqPolyRepRelPowerSeriesRingElemFqPolyRepRelPowerSeriesRing

All relative power series elements belong to the abstract type RelPowerSeriesRingElem and all of the relative power series ring types belong to the abstract type RelPowerSeriesRing.

The maximum relative precision, the string representation of the variable and the base ring $R$ of a generic power series are stored in its parent object.

Here is the corresponding table for the absolute power series types.

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jlGeneric.AbsSeries{T}Generic.AbsPowerSeriesRing{T}
$\mathbb{Z}$FlintZZAbsPowerSeriesRingElemZZAbsPowerSeriesRing
$\mathbb{Z}/n\mathbb{Z}$ (small $n$)FlintzzModAbsPowerSeriesRingElemzzModAbsPowerSeriesRing
$\mathbb{Z}/n\mathbb{Z}$ (large $n$)FlintZZModAbsPowerSeriesRingElemZZModAbsPowerSeriesRing
$\mathbb{Q}$FlintQQAbsPowerSeriesRingElemQQAbsPowerSeriesRing
$\mathbb{F}_p$ (small $n$)FlintfpAbsPowerSeriesRingElemfpAbsPowerSeriesRing
$\mathbb{F}_p$ (large $n$)FlintFpAbsPowerSeriesRingElemFpAbsPowerSeriesRing
$\mathbb{F}_{p^n}$ (small $n$)FlintfqPolyRepAbsPowerSeriesRingElemfqPolyRepAbsPowerSeriesRing
$\mathbb{F}_{p^n}$ (large $n$)FlintFqPolyRepAbsPowerSeriesRingElemFqPolyRepAbsPowerSeriesRing

All absolute power series elements belong to the abstract type AbsPowerSeriesRingElem and all of the absolute power series ring types belong to the abstract type AbsPowerSeriesRing.

The absolute precision, the string representation of the variable and the base ring $R$ of a generic power series are stored in its parent object.

All power series element types belong to the abstract type SeriesElem and all of the power series ring types belong to the abstract type SeriesRing. This enables one to write generic functions that can accept any Nemo power series type.

AbstractAlgebra.jl also provides Nemo with a generic implementation of Laurent series over a given ring $R$. For completeness, we list it here.

Base ringLibraryElement typeParent type
Generic ring $R$AbstractAlgebra.jlGeneric.LaurentSeriesRingElem{T}Generic.LaurentSeriesRing{T}
Generic field $K$AbstractAlgebra.jlGeneric.LaurentSeriesFieldElem{T}Generic.LaurentSeriesField{T}

Capped relative power series

Capped relative power series have their maximum relative precision capped at some value prec_max. This means that if the leading term of a nonzero power series element is $c_ax^a$ and the precision is $b$ then the power series is of the form $c_ax^a + c_{a+1}x^{a+1} + \ldots + O(x^{a + b})$.

The zero power series is simply taken to be $0 + O(x^b)$.

The capped relative model has the advantage that power series are stable multiplicatively. In other words, for nonzero power series $f$ and $g$ we have that divexact(f*g), g) == f.

However, capped relative power series are not additively stable, i.e. we do not always have $(f + g) - g = f$.

In the capped relative model we say that two power series are equal if they agree up to the minimum absolute precision of the two power series. Thus, for example, $x^5 + O(x^{10}) == 0 + O(x^5)$, since the minimum absolute precision is $5$.

During computations, it is possible for power series to lose relative precision due to cancellation. For example if $f = x^3 + x^5 + O(x^8)$ and $g = x^3 + x^6 + O(x^8)$ then $f - g = x^5 - x^6 + O(x^8)$ which now has relative precision $3$ instead of relative precision $5$.

Amongst other things, this means that equality is not transitive. For example $x^6 + O(x^{11}) == 0 + O(x^5)$ and $x^7 + O(x^{12}) == 0 + O(x^5)$ but $x^6 + O(x^{11}) \neq x^7 + O(x^{12})$.

Sometimes it is necessary to compare power series not just for arithmetic equality, as above, but to see if they have precisely the same precision and terms. For this purpose we introduce the isequal function.

For example, if $f = x^2 + O(x^7)$ and $g = x^2 + O(x^8)$ and $h = 0 + O(x^2)$ then $f == g$, $f == h$ and $g == h$, but isequal(f, g), isequal(f, h) and isequal(g, h) would all return false. However, if $k = x^2 + O(x^7)$ then isequal(f, k) would return true.

There are further difficulties if we construct polynomial over power series. For example, consider the polynomial in $y$ over the power series ring in $x$ over the rationals. Normalisation of such polynomials is problematic. For instance, what is the leading coefficient of $(0 + O(x^{10}))y + (1 + O(x^{10}))$?

If one takes it to be $(0 + O(x^{10}))$ then some functions may not terminate due to the fact that algorithms may require the degree of polynomials to decrease with each iteration. Instead, the degree may remain constant and simply accumulate leading terms which are arithmetically zero but not identically zero.

On the other hand, when constructing power series over other power series, if we simply throw away terms which are arithmetically equal to zero, our computations may have different output depending on the order in which the power series are added!

One should be aware of these difficulties when working with power series. Power series, as represented on a computer, simply don't satisfy the axioms of a ring. They must be used with care in order to approximate operations in a mathematical power series ring.

Simply increasing the precision will not necessarily give a "more correct" answer and some computations may not even terminate due to the presence of arithmetic zeroes!

Capped absolute power series

An absolute power series ring over a ring $R$ with precision $p$ behaves very much like the quotient $R[x]/(x^p)$ of the polynomial ring over $R$.

Power series functionality

Power series rings in Nemo provide all the functionality described for power series in AbstractAlgebra:

https://nemocas.github.io/AbstractAlgebra.jl/stable/series

In addition, generic power series and Laurent series are provided by AbstractAlgebra.

We list below only the functionality that is Nemo specific for power series rings.

Special functions

Examples

julia> T, z = power_series_ring(QQ, 30, "z")
-(Univariate power series ring over QQ, z + O(z^31))
-
-julia> a = 1 + z + 3z^2 + O(z^5)
-1 + z + 3*z^2 + O(z^5)
-
-julia> b = z + 2z^2 + 5z^3 + O(z^5)
-z + 2*z^2 + 5*z^3 + O(z^5)
-
-julia> d = divexact(z, exp(z + O(z^40)) - 1)
-1 - 1//2*z + 1//12*z^2 - 1//720*z^4 + 1//30240*z^6 - 1//1209600*z^8 + 1//47900160*z^10 - 691//1307674368000*z^12 + 1//74724249600*z^14 - 3617//10670622842880000*z^16 + 43867//5109094217170944000*z^18 - 174611//802857662698291200000*z^20 + 77683//14101100039391805440000*z^22 - 236364091//1693824136731743669452800000*z^24 + 657931//186134520519971831808000000*z^26 - 3392780147//37893265687455865519472640000000*z^28 + O(z^29)
-
-julia> f = exp(b)
-1 + z + 5//2*z^2 + 43//6*z^3 + 193//24*z^4 + O(z^5)
-
-julia> g = log(a)
-z + 5//2*z^2 - 8//3*z^3 - 7//4*z^4 + O(z^5)
-
-julia> h = sqrt(a)
-1 + 1//2*z + 11//8*z^2 - 11//16*z^3 - 77//128*z^4 + O(z^5)
-
-julia> k = sin(b)
-z + 2*z^2 + 29//6*z^3 - z^4 + O(z^5)
-
-julia> m = atanh(b)
-z + 2*z^2 + 16//3*z^3 + 2*z^4 + O(z^5)
diff --git a/previews/PR2578/Nemo/types/index.html b/previews/PR2578/Nemo/types/index.html deleted file mode 100644 index 51153ec3dc0d..000000000000 --- a/previews/PR2578/Nemo/types/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Types in Nemo · Oscar.jl

Types in Nemo

Nemo is fully compatible with AbstractAlgebra.jl, but specialises implementations of various commonly used rings with a highly optimised C implementation, provided by the C libraries wrapped by Nemo.

Below, we give a list of all of the specialised types available in Nemo that implement rings using a specialised C library. The types of elements of the respective rings and other mathematical structures are given, and in parentheses we list the types of the parent objects of the given rings and structures.

  • Flint

    • ZZRingElem (ZZRing)
    • QQFieldElem (QQField)
    • zzModRingElem (zzModRing)
    • ZZModRingElem (ZZModRing`)
    • fqPolyRepFieldElem (fqPolyRepField)
    • fpFieldElem (fpField)
    • FpFieldElem (FpField)
    • FqPolyRepFieldElem (FqPolyRepField)
    • padic (FlintPadicField)
    • qadic (FlintQadicField)
    • ZZPolyRingElem (ZZPolyRing)
    • QQPolyRingElem (QQPolyRing)
    • zzModPolyRingElem (zzModPolyRing)
    • ZZModPolyRingElem (ZZModPolyRing)
    • FqPolyRepPolyRingElem (FqPolyRepPolyRing)
    • fqPolyRepPolyRingElem (fqPolyRepPolyRing)
    • ZZMPolyRingElem (ZZMPolyRing)
    • QQMPolyRingElem (QQMPolyRing)
    • zzModMPolyRingElem (zzModMPolyRing)
    • fqPolyRepMPolyRingElem (fqPolyRepMPolyRing`)
    • fpPolyRingElem (fpPolyRing)
    • FpPolyRingElem (FpPolyRing)
    • ZZRelPowerSeriesRingElem (ZZRelPowerSeriesRing)
    • ZZAbsPowerSeriesRingElem (ZZAbsPowerSeriesRing)
    • QQRelPowerSeriesRingElem (QQRelPowerSeriesRing)
    • QQAbsPowerSeriesRingElem (QQAbsPowerSeriesRing)
    • ZZModRelPowerSeriesRingElem (ZZModRelPowerSeriesRing)
    • ZZModAbsPowerSeriesRingElem (ZZModAbsPowerSeriesRing)
    • zzModRelPowerSeriesRingElem (zzModRelPowerSeriesRing)
    • zzModAbsPowerSeriesRingElem (zzModAbsPowerSeriesRing)
    • fpRelPowerSeriesRingElem (fpRelPowerSeriesRing)
    • fpAbsPowerSeriesRingElem (fpAbsPowerSeriesRing)
    • FpRelPowerSeriesRingElem (FpRelPowerSeriesRing)
    • FpAbsPowerSeriesRingElem (FpAbsPowerSeriesRing)
    • fqPolyRepRelPowerSeriesRingElem (fqPolyRepRelPowerSeriesRing)
    • fqPolyRepAbsPowerSeriesRingElem (fqPolyRepAbsPowerSeriesRing)
    • FqPolyRepRelPowerSeriesRingElem (FqPolyRepRelPowerSeriesRing)
    • FqPolyRepAbsPowerSeriesRingElem (FqPolyRepAbsPowerSeriesRing)
    • ZZMatrix (ZZMatrixSpace)
    • QQMatrix (QQMatrixSpace)
    • zzModMatrix (zzModMatrixSpace)
    • ZZModMatrix (ZZModMatrixSpace`)
    • fqPolyRepMatrix (fqPolyRepMatrixSpace)
    • FqPolyRepMatrix (FqPolyRepMatrixSpace)
    • fpMatrix (fpMatrixSpace)
    • perm (SymmetricGroup)
  • Antic

    • nf_elem (AnticNumberField)
  • Arb

    • arb (ArbField)
    • acb (AcbField)
    • arb_poly (ArbPolyRing)
    • acb_poly (AcbPolyRing)
    • arb_mat (ArbMatSpace)
    • acb_mat (AcbMatSpace)
  • Calcium

    • qqbar (CalciumQQBarField)
    • ca (CalciumField)
diff --git a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/creation/index.html b/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/creation/index.html deleted file mode 100644 index f7201c6e376c..000000000000 --- a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/creation/index.html +++ /dev/null @@ -1,90 +0,0 @@ - -Creating PBW-Algebras · Oscar.jl

Creating PBW-Algebras

Types

PBW-algebras are modelled by objects of type PBWAlgRing{T, S} <: NCRing, their elements are objects of type PBWAlgElem{T, S} <: NCRingElem. Here, T is the element type of the field over which the PBW-algebra is defined (the type S is added for internal use).

Constructors

The basic constructor below allows one to build PBW-algebras:

pbw_algebraMethod
pbw_algebra(R::MPolyRing{T}, rel, ord::MonomialOrdering; check::Bool = true) where T

Given a multivariate polynomial ring R over a field, say $R=K[x_1, \dots, x_n]$, given a strictly upper triangular matrix rel with entries in R of type $c_{ij} \cdot x_ix_j+d_{ij}$, where the $c_{ij}$ are nonzero scalars and where we think of the $x_jx_i = c_{ij} \cdot x_ix_j+d_{ij}$ as setting up relations in the free associative algebra $K\langle x_1, \dots , x_n\rangle$, and given an ordering ord on $\text{Mon}(x_1, \dots, x_n)$, return the PBW-algebra

\[A = K\langle x_1, \dots , x_n \mid x_jx_i = c_{ij} \cdot x_ix_j+d_{ij}, \ 1\leq i<j \leq n \rangle.\]

Note

The input data gives indeed rise to a PBW-algebra if:

  • The ordering ord is admissible for A.
  • The standard monomials in $K\langle x_1, \dots , x_n\rangle$ represent a K-basis for A.

See the definition of PBW-algebras in the OSCAR documentation for details.

Note

The K-basis condition above is checked by default. This check may be skipped by passing check = false.

Examples

julia> R, (x, y, z) = QQ["x", "y", "z"];
-
-julia> L = [x*y, x*z, y*z + 1];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)))
-(PBW-algebra over Rational field in x, y, z with relations y*x = x*y, z*x = x*z, z*y = y*z + 1, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z])
source

Some PBW-algebras are predefined in OSCAR.

Weyl Algebras

The $n$-th Weyl algebra over a field $K$ is the PBW-algebra

\[D_n(K)=K \langle x_1,\ldots, x_n, \partial _1,\dots \partial _n \mid \partial_i x_i=x_i\partial _i +1, \partial _i x_j=x_j \partial _i \ \text { for }\ i\neq j\rangle.\]

Here, we tacitly assume that

\[x_j x_i=x_i x _j \; \text{ and } \; \partial _j \partial_i=\partial_i \partial _j \; \text{ for all } \; i,j.\]

Note that any global monomial ordering on $\text{Mon}_{2n}(x, \partial)$ is admissible for $D_n(K)$.

The constructor below returns the algebras equipped with degrevlex.

weyl_algebraMethod
weyl_algebra(K::Ring, xs::AbstractVector{<:VarName})

Given a field K and a vector xs of, say, $n$ Strings, Symbols, or Characters, return the $n$-th Weyl algebra over K.

The generators of the returned algebra print according to the entries of xs. See the example below.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"])
-(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])
-
-julia> dx*x
-x*dx + 1
source

Universal Enveloping Algebras of Finite Dimensional Lie Algebras

Let $\mathfrak g$ be an $n$-dimensional Lie algebra over a field $K$, and let $x_1, \dots, x_n$ be a $K$-basis of $\mathfrak g$. Consider $n$ indeterminates which are also denoted by $x_1, \dots, x_n$. The universal enveloping algebra of $\mathfrak g$ is the PBW-algebra

\[U(\mathfrak g)=K \langle x_1,\ldots, x_n \mid x_jx_i = x_ix_j+[x_j, x_i], \ 1\leq i<j \leq n \rangle,\]

where $[x_j, x_i]$ corresponds to evaluating the Lie bracket $[x_j, x_i]_\mathfrak g$. That the standard monomials in $U(\mathfrak g)$ indeed form a $K$-basis for $U(\mathfrak g)$ is the content of the Poincar$\'{\text{e}}$-Birkhoff-Witt theorem (the names PBW-basis and PBW-algebra are derived from this fact).

Note that any degree compatible global monomial ordering on $\N^n$ is admissible for $U(\mathfrak g)$.

The constructors below return the algebras equipped with degrevlex.

Quantized Enveloping Algebras

Non-Standard Quantum Deformation of $so_3$

Data Associated to PBW-Algebras

Given a PBW-algebra A over a field K,

  • coefficient_ring(A) refers to K,
  • gens(A) to the generators of A,
  • ngens(A) to the number of these generators, and
  • gen(A, i) as well as A[i] to the i-th such generator.
Examples
julia> R, (x,y,z) = QQ["x", "y", "z"];
-
-julia> L = [x*y, x*z, y*z + 1];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));
-
-julia> coefficient_ring(A)
-Rational field
-
-julia> gens(A)
-3-element Vector{PBWAlgElem{QQFieldElem, Singular.n_Q}}:
- x
- y
- z
-
-julia> gen(A, 2)
-y
-
-julia> A[3]
-z 
-
-julia> ngens(A)
-3
-

Elements of PBW-Algebras

Elements of PBW-algebras are stored and printed in their standard representation.

Constructors

One way to create elements of a PBW-algebra A over a field K is to build them up from the generators of A using basic arithmetic as shown below:

Examples
julia> R, (x,y,z) = QQ["x", "y", "z"];
-
-julia> L = [x*y, x*z, y*z + 1];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));
-
-julia> f = 3*x^2+z*y
-3*x^2 + y*z + 1
-

Alternatively, there is the following constructor:

(A::PBWAlgRing)(cs::AbstractVector, es::AbstractVector{Vector{Int}})

Its return value is the element of A whose standard representation is built from the elements of cs as coefficients, and the elements of es as exponents.

Examples
julia> R, (x,y,z) = QQ["x", "y", "z"];
-
-julia> L = [x*y, x*z, y*z + 1];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));
-
-julia> f = 3*x^2+z*y
-3*x^2 + y*z + 1
-
-julia> g = A(QQ.([3, 1, 1]), [[2, 0, 0], [0, 1, 1], [0, 0, 0]])
-3*x^2 + y*z + 1
-
-julia> f == g
-true
-

An often more effective way to create elements is to use the corresponding build context as indicated below:

julia> R, (x,y,z) = QQ["x", "y", "z"];
-
-julia> L = [x*y, x*z, y*z + 1];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));
-
-julia> B =  build_ctx(A);
-
-julia> for i = 1:5 push_term!(B, QQ(i), [i+1, i, i-1]) end
-
-julia> finish(B)
-5*x^6*y^5*z^4 + 4*x^5*y^4*z^3 + 3*x^4*y^3*z^2 + 2*x^3*y^2*z + x^2*y
-

Special Elements

Given a PBW-algebra A, zero(A) and one(A) refer to the additive and multiplicative identity of A, respectively. Relevant test calls on an element f of A are iszero(f) and isone(f).

Data Associated to Elements of PBW-algebras

Given an element f of a PBW-algebra A,

  • parent(f) refers to A,

Opposite Algebras

opposite_algebraMethod
opposite_algebra(A::PBWAlgRing)

Return the opposite algebra of A.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"])
-(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])
-
-julia> Dop, opp = opposite_algebra(D);
-
-julia> Dop
-PBW-algebra over Rational field in dy, dx, y, x with relations dx*dy = dy*dx, y*dy = dy*y + 1, x*dy = dy*x, y*dx = dx*y, x*dx = dx*x + 1, x*y = y*x
-
-julia> opp
-Map to opposite of Weyl-algebra over Rational field in variables (x, y)
-
-julia> opp(dx*x)
-dx*x + 1
source

If a map opp from a PBW-algebra to its opposite algebra is given, then inv(opp) refers to the inverse of opp.

diff --git a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html b/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html deleted file mode 100644 index 5156f75f3dd5..000000000000 --- a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html +++ /dev/null @@ -1,335 +0,0 @@ - -Ideals in PBW-algebras · Oscar.jl

Ideals in PBW-algebras

Types

The OSCAR type for ideals in PBW-algebras is of parametrized form PBWAlgIdeal{D, T, S}, where D encodes the direction left, right, or two-sided, and T is the element type of the field over which the PBW-algebra is defined (the type S is added for internal use).

Constructors

left_idealMethod
left_ideal(g::Vector{<:PBWAlgElem})

Given a vector g of elements in a PBW-algebra A, say, return the left ideal of A generated by these elements.

left_ideal(A::PBWAlgRing, g::AbstractVector)

Given a vector g of elements of A, return the left ideal of A generated by these elements.

Examples

julia> R, (x, y, z) = QQ["x", "y", "z"];
-
-julia> L = [x*y, x*z, y*z + 1];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)))
-(PBW-algebra over Rational field in x, y, z with relations y*x = x*y, z*x = x*z, z*y = y*z + 1, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z])
-
-julia> I = left_ideal(A, [x^2*y^2, x*z+y*z])
-left_ideal(x^2*y^2, x*z + y*z)
source
right_idealMethod
right_ideal(g::Vector{<:PBWAlgElem})

Given a vector g of elements in a PBW-algebra A, say, return the right ideal of A generated by these elements.

right_ideal(A::PBWAlgRing, g::AbstractVector)

Given a vector g of elements of A, return the right ideal of A generated by these elements.

source
two_sided_idealMethod
two_sided_ideal(g::Vector{<:PBWAlgElem})

Given a vector g of elements in a PBW-algebra A, say, return the two-sided ideal of A generated by these elements.

two_sided_ideal(A::PBWAlgRing, g::AbstractVector)

Given a vector g of elements of A, return the two-sided ideal of A generated by these elements.

source

Gröbner bases

Data Associated to Ideals

If I is an ideal of a PBW-algebra A, then

  • base_ring(I) refers to A,
  • gens(I) to the generators of I,
  • ngens(I) to the number of these generators, and
  • gen(I, k) as well as I[k] to the k-th such generator.
Examples
julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"])
-(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])
-
-julia> I = left_ideal(D, [x, dx])
-left_ideal(x, dx)
-
-julia> base_ring(I)
-Weyl-algebra over Rational field in variables (x, y)
-
-julia> gens(I)
-2-element Vector{PBWAlgElem{QQFieldElem, Singular.n_Q}}:
- x
- dx
-
-julia> ngens(I)
-2
-
-julia> gen(I, 2)
-dx
-

Operations on Ideals

Simple Ideal Operations

Powers of Ideal

^Method
^(I::PBWAlgIdeal{D, T, S}, k::Int) where {D, T, S}

Given a two_sided ideal I, return the k-th power of I.

Examples

julia> D, (x, dx) = weyl_algebra(GF(3), ["x"]);
-
-julia> I = two_sided_ideal(D, [x^3])
-two_sided_ideal(x^3)
-
-julia> I^2
-two_sided_ideal(x^6)
source

Sum of Ideals

+Method
+(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}

Return the sum of I and J.

source

Product of Ideals

*Method
*(I::PBWAlgIdeal{DI, T, S}, J::PBWAlgIdeal{DJ, T, S}) where {DI, DJ, T, S}

Given two ideals I and J such that both I and J are two-sided ideals or I and J are a left and a right ideal, respectively, return the product of I and J.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(GF(3), ["x", "y"]);
-
-julia> I = left_ideal(D, [x^3+y^3, x*y^2])
-left_ideal(x^3 + y^3, x*y^2)
-
-julia> J = right_ideal(D, [dx^3, dy^5])
-right_ideal(dx^3, dy^5)
-
-julia> I*J
-two_sided_ideal(x^3*dx^3 + y^3*dx^3, x^3*dy^5 + y^3*dy^5, x*y^2*dx^3, x*y^2*dy^5)
source

Intersection of Ideals

intersectMethod
intersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}
-intersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}

Return the intersection of two or more ideals.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"]);
-
-julia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))
-left_ideal(-x^3 + dy^2 + x)
source
intersectMethod
intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T
-intersect(V::Vector{MPolyIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])
-
-julia> I = ideal(R, [x, y])^2;
-
-julia> J = ideal(R, [y^2-x^3+x]);
-
-julia> intersect(I, J)
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
-
-julia> intersect([I, J])
-ideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)
source
intersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T
-intersect(V::Vector{MPolyQuoIdeal{T}}) where T

Return the intersection of two or more ideals.

Examples

julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
-
-julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
-
-julia> a = ideal(A, [y^2])
-ideal(y^2)
-
-julia> b = ideal(A, [x])
-ideal(x)
-
-julia> intersect(a,b)
-ideal(x*y)
-
-julia> intersect([a,b])
-ideal(x*y)
source
intersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}
-intersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}

Return the intersection of two or more ideals.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"]);
-
-julia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))
-left_ideal(-x^3 + dy^2 + x)
source
intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.

Additionally, return the inclusion maps M $\cap$ N $\to$ M and M $\cap$ N $\to$ N.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 1)
-Free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-
-julia> AM = R[x;]
-[x]
-
-julia> BM = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> M = SubquoModule(F, AM, BM)
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = R[y;]
-[y]
-
-julia> BN = R[x^2; y^3; z^4]
-[x^2]
-[y^3]
-[z^4]
-
-julia> N = SubquoModule(F, AN, BN)
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> x*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-, Map with following data
-Domain:
-=======
-Subquotient of Submodule with 2 generators
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-Codomain:
-=========
-Subquotient of Submodule with 1 generator
-1 -> y*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-)
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);
-
-julia> Z = abelian_group(0);
-
-julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);
-
-julia> F = graded_free_module(Rg, 1);
-
-julia> AM = Rg[x;];
-
-julia> BM = Rg[x^2; y^3; z^4];
-
-julia> M = SubquoModule(F, AM, BM)
-Graded subquotient of submodule of F generated by
-1 -> x*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> AN = Rg[y;];
-
-julia> BN = Rg[x^2; y^3; z^4];
-
-julia> N = SubquoModule(F, AN, BN)
-Graded subquotient of submodule of F generated by
-1 -> y*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> intersect(M, N)
-(Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1], Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> M
--x*y*e[1] -> -x*y*e[1]
-x*z^4*e[1] -> x*z^4*e[1]
-Homogeneous module homomorphism, Graded subquotient of submodule of F generated by
-1 -> -x*y*e[1]
-2 -> x*z^4*e[1]
-by submodule of F generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1] -> N
--x*y*e[1] -> x*y*e[1]
-x*z^4*e[1] -> 0
-Homogeneous module homomorphism)
-
source
intersect(T1, T2)

Intersect two tropical varieties.

Examples

julia> RR = TropicalSemiring(min)
-Tropical semiring (min)
-
-julia> S,(x,y) = RR["x","y"]
-(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])
-
-julia> f1 = x+y+1
-x + y + (1)
-
-julia> f2 = x^2+y^2+RR(-6)
-x^2 + y^2 + (-6)
-
-julia> hyp1 = TropicalHypersurface(f1)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> hyp2 = TropicalHypersurface(f2)
-min tropical hypersurface embedded in 2-dimensional Euclidean space
-
-julia> tv12 = intersect(hyp1, hyp2)
-min tropical variety of dimension 1 embedded in 2-dimensional Euclidean space
source
intersect(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl

Returns $a \cap b$.

intersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl

Returns $a \cap b$.

Elimination

Let

\[A = K\langle x_1, \dots , x_n \mid x_jx_i = c_{ij}x_ix_j+d_{ij}, \ 1\leq i<j \leq n \rangle,\]

be a PBW-algebra. Fix a subset $\sigma\subset \{1,\dots, n\}$, write $x_\sigma$ for the set of variables $x_i$ with $i\in\sigma$, and let $A_\sigma$ be the $K$-linear subspace of $A$ which is generated by the standard monomials in $\langle x_\sigma \rangle$. Suppose there exists a global monomial ordering $>$ on $A$ which is both admissible for $A$ and an elimination ordering for $x\smallsetminus x_\sigma$. Then $A_\sigma$ is a subalgebra of $A$ with $d_{ij}\in A_\sigma$ for each pair of indices $1\leq i<j \leq n$ with $i,j\in\sigma$. In particular, $A_\sigma$ is a PBW-algebra with admissible ordering $>_\sigma$, where $>_\sigma$ is the restriction of $>$ to the set of standard monomials in $\langle x_\sigma\rangle$. Moreover, if $I\subset A$ is a nonzero (left, right, two-sided) ideal, and $\mathcal G$ is a (left, right, two-sided) Gröbner basis for $I$ with respect to $>$, then $\mathcal G\cap A_\sigma$ is a (left, right, two-sided) Gröbner basis for $I\cap A_\sigma$ with respect to $>_\sigma$. We refer to computing $I\cap A_\sigma$ as eliminating the variables in $x\smallsetminus x_\sigma$ from $I.$

Note

If the relevant $d_{ij}$ are all contained in $A_\sigma$, we also say that $A_\sigma$ is admissible for elimination.

Note

A monomial ordering which is both admissible for $A$ and an elimination ordering for $x\smallsetminus x_\sigma$ may not exist.

eliminateMethod
eliminate(I::PBWAlgIdeal, V::Vector{<:PBWAlgElem}; ordering = nothing)

Given a vector V of variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.

eliminate(I::PBWAlgIdeal, V::Vector{Int}; ordering = nothing)

Given a vector V of indices which specify variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.

Note

The return value is an ideal of the original algebra.

Note

If provided, the ordering must be an admissible elimination ordering (this is checked by the function). If not provided, finding an admissible elimination ordering may involve solving a particular linear programming problem. Here, the function is implemented so that it searches for solutions in a certain range only. If no solution is found in that range, the function will throw an error.

Examples

julia> R, (x, y, z, a) = QQ["x", "y", "z", "a"];
-
-julia> L = [x*y-z, x*z+2*x, x*a, y*z-2*y, y*a, z*a];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x, y, z, a) = pbw_algebra(R, REL, deglex(gens(R)))
-(PBW-algebra over Rational field in x, y, z, a with relations y*x = x*y - z, z*x = x*z + 2*x, a*x = x*a, z*y = y*z - 2*y, a*y = y*a, a*z = z*a, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z, a])
-
-julia> f = 4*x*y+z^2-2*z-a;
-
-julia> I = left_ideal(A, [x^2, y^2, z^2-1, f])
-left_ideal(x^2, y^2, z^2 - 1, 4*x*y + z^2 - 2*z - a)
-
-julia> eliminate(I, [x, y, z])
-left_ideal(a - 3)
-
-julia> eliminate(I, [1, 2 ,3])
-left_ideal(a - 3)
-
-julia> try eliminate(I, [z, a]); catch e; e; end
-ErrorException("no elimination is possible: subalgebra is not admissible")
julia> R, (p, q) = QQ["p", "q"];
-
-julia> L = [p*q+q^2];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (p, q) = pbw_algebra(R, REL, lex(gens(R)))
-(PBW-algebra over Rational field in p, q with relations q*p = p*q + q^2, PBWAlgElem{QQFieldElem, Singular.n_Q}[p, q])
-
-julia> I = left_ideal(A, [p, q])
-left_ideal(p, q)
-
-julia> try eliminate(I, [q]); catch e; e; end   # in fact, no elimination ordering exists
-ErrorException("could not find elimination ordering")
source

Tests on Ideals

is_zeroMethod
is_zero(I::PBWAlgIdeal)

Return true if I is the zero ideal, false otherwise.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"])
-(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])
-
-julia> I = left_ideal(D, [x, dx])
-left_ideal(x, dx)
-
-julia> is_zero(I)
-false
source
is_oneMethod
is_one(I::PBWAlgIdeal{D}) where D

Return true if I is generated by 1, false otherwise.

Examples

julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"])
-(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])
-
-julia> I = left_ideal(D, [x, dx])
-left_ideal(x, dx)
-
-julia> is_one(I)
-true
-
-julia> J = left_ideal(D, [y*x])
-left_ideal(x*y)
-
-julia> is_one(J)
-false
-
-julia> K = two_sided_ideal(D, [y*x])
-two_sided_ideal(x*y)
-
-julia> is_one(K)
-true
julia> D, (x, y, dx, dy) = weyl_algebra(GF(3), ["x", "y"]);
-
-julia> I = two_sided_ideal(D, [x^3])
-two_sided_ideal(x^3)
-
-julia> is_one(I)
-false
source
is_subsetMethod
is_subset(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}

Return true if I is contained in J, false otherwise.

Examples

julia> D, (x, dx) = weyl_algebra(QQ, ["x"]);
-
-julia> I = left_ideal(D, [dx^2])
-left_ideal(dx^2)
-
-julia> J = left_ideal(D, [x*dx^4, x^3*dx^2])
-left_ideal(x*dx^4, x^3*dx^2)
-
-julia> is_subset(I, J)
-true
source
==Method
==(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}

Return true if I is equal to J, false otherwise.

Examples

julia> D, (x, dx) = weyl_algebra(QQ, ["x"]);
-
-julia> I = left_ideal(D, [dx^2])
-left_ideal(dx^2)
-
-julia> J = left_ideal(D, [x*dx^4, x^3*dx^2])
-left_ideal(x*dx^4, x^3*dx^2)
-
-julia> I == J
-true
source
ideal_membershipMethod
ideal_membership(f::PBWAlgElem{T, S}, I::PBWAlgIdeal{D, T, S}) where {D, T, S}

Return true if f is contained in I, false otherwise. Alternatively, use f in I.

Examples

julia> D, (x, dx) = weyl_algebra(QQ, ["x"]);
-
-julia> I = left_ideal(D, [x*dx^4, x^3*dx^2])
-left_ideal(x*dx^4, x^3*dx^2)
-
-julia> dx^2 in I
-true
julia> D, (x, y, dx, dy) = weyl_algebra(QQ, ["x", "y"]);
-
-julia> I = two_sided_ideal(D, [x, dx])
-two_sided_ideal(x, dx)
-
-julia> one(D) in I
-true
source
diff --git a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/intro/index.html b/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/intro/index.html deleted file mode 100644 index 9966126a47c6..000000000000 --- a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

We start our discussion of PBW-algebras by recalling their definition. Let $K$ be a field. Given a set of variables $x=\{x_1, \ldots, x_n\},$ we write ${\left\langle {x}\right\rangle}:=\langle x_{1},\ldots, x_{n} \rangle$ for the free monoid on $x$. That is, the elements of $\langle x \rangle$ are the words in the finite alphabet $x$, multiplication means concatenation of words, and the identity element is the empty word. The free associative $K$-algebra generated by $x_{1},\dots, x_{n}$ is the corresponding monoid algebra

\[K \langle {x}\rangle:= K \langle x_{1},\dots, x_{n} \rangle.\]

We consider quotients of type $A = K\langle x_1, \dots, x_n \rangle/J$, for some $n$ and some two-sided ideal $J$ of $K\langle x_1, \dots, x_n \rangle$. In case $J$ is given by a finite set of two-sided generators $g_1, \dots, g_r$, we say that $A$ is generated by $x_1, \dots, x_n$, subject to the relations $g_1 = 0, \dots, g_r = 0$, and write

\[A = K\langle x_1, \dots , x_n \mid g_k=0, \ 1\leq k \leq r \rangle.\]

The relations considered in this chapter are "commutation relations", written as

\[x_jx_i = c_{ij}x_ix_j+d_{ij}.\]

Working with Gröbner bases requires that we take monomial orderings into account (see the section on Gröbner bases in the commutative algebra chapter for monomial orderings). In our context here, we use the following notation. A standard monomial in $K \langle x \rangle$ is a word of type $x^\alpha=x_{1}^{\alpha_{1}}\cdots x_{n}^{\alpha_{n}},$ where $\alpha=(\alpha_1,\dots,\alpha_n)\in\mathbb N^n$. A standard polynomial in $K \langle x \rangle$ is a $K$-linear combination of standard monomials. Each global monomial ordering $>$ on $K[x]$ gives rise to a (total) well-ordering on the set of standard monomials. Abusing our notation, we denote the induced ordering again by $>$, and refer to it as a global monomial ordering on $A$. Given $>$, it makes sense to speak of the leading monomial $\text{LM}_>(f)$ of a standard polynomial $0\neq f \in K \langle x \rangle.$ The notion of a global elimination ordering with respect to a subset of $\{ x_{1},\ldots, x_{n} \}$ carries over from $K[x]$ to $A$.

Definition. $\;$ Let $A$ be a $K$-algebra of type

\[A = K\langle x_1, \dots , x_n \mid x_jx_i = c_{ij}x_ix_j+d_{ij}, \ 1\leq i<j \leq n \rangle,\]

where the $c_{ij}\in K$ are nonzero scalars, and the $d_{ij}\in K\langle x_1, \dots , x_n\rangle$ are standard polynomials. Then $A$ is called a PBW-algebra if the following two conditions hold:

(1) $\;$ There exists a global monomial ordering $>$ on $A$ such that

\[d_{ij}=0\ \text{ or }\ x_ix_j> \text{LM}_>(d_{ij})\ \text{ for all }\ 1\leq i<j \leq n.\]

(2) $\;$ The standard monomials in $K \langle x \rangle$ represent a $K$-basis for $A$. We then refer to this basis as a PBW-basis for $A$.

Every ordering as in (1) is called admissible for the given relations or simply admissible for $A$.

Given a PBW-algebra $A$ as above, we sometimes abuse our notation by denoting the class of a standard monomial $x^{\alpha}$ in $A$ also by $x^{\alpha}$, and refer to this class as a standard monomial in $A$. As these monomials form a $K$-basis for $A$, every element $0\neq f\in A$ has a unique representation

\[f=\sum c_{\alpha}x^{\alpha}, \; \text{ with nonzero coefficients } \; c_{\alpha}\in K.\]

We refer to this representation as the standard representation of $f$, with coefficients $c_{\alpha}$, and exponents $\alpha$.

Note

PBW-algebras are also known as G-algebras or algebras of solvable type. See Remark 1 in Viktor Levandovskyy, Hans Schönemann (2003) for a brief historical account.

Proposition. $\;$ Let $A$ be a PBW-algebra. Then:

  • $A$ is an integral domain,
  • $A$ is (left and right) Noetherian.

Given any associative $K$-algebra $A = (A, +, \cdot)$, its opposite algebra is defined by setting $A^{\text{op}} = (A, +, \ast)$, where $f\ast g:=g\cdot f$ for all $f, g\in A.$ If

\[A = K\langle x_1, \dots , x_n \mid x_jx_i = c_{ij} x_ix_j+d_{ij}, \ 1\leq i<j \leq n \rangle\]

is a PBW-algebra, then $A^{\text{op}}$ is again a PBW-algebra in a natural way. Indeed, consider the automorphism ${\text{op}}$ of $K\langle x_1, \dots , x_n\rangle$ which sends a word $x_{i_1}\cdots x_{i_r}$ to the "opposite word" $x^{\text{op}}:=x_{i_r}\cdots x_{i_1}$. Apply this automorphism to the relations of $A$ to obtain the "opposite relations"

\[x_ix_j = c_{ij}x_jx_i+d_{ij}^{\text{\;\!op}}.\]

Also, if $\alpha=(\alpha_1, \ldots, \alpha_n)\in \N^n$, then set $\alpha^{\text{op}} =(\alpha_n, \ldots, \alpha_1)\in \N^n$, and if $>$ is an admissible monomial ordering for $A$, then define the "opposite ordering" $ >^{\text{op}}$ by setting

\[\alpha >^{\text{op}} \beta \;\Leftrightarrow\; \alpha^{\text{op}} > \beta^{\text{op}}.\]

Finally, reverse the order of the variables: set $x ^{\text{op}}=\{x_n, \ldots, x_1\}$, and consider the free associative $K$-algebra $K \langle x^\text{op}\rangle = K \langle x_{n},\dots, x_{1} \rangle.$ Altogether, we obtain a PBW-algebra which can be naturally identified with $A^{\text{op}}$:

\[A ^{\text{op}} = K\langle x_n, \dots , x_1 \mid x_ix_j = c_{ij}x_jx_i+d_{ij}^{\text{\;\!op}}, \ 1\leq i<j \leq n \rangle,\]

with admissible ordering $>^{\text{op}}$.

When implementing functionality for PBW-algebras, taking the opposite algebra into account often allows one to focus on left ideals, left modules, and left Gröbner bases: Given a PBW-algebra $A$, right Gröbner bases in $A$ are found by computing left Gröbner bases in $A^{\text{op}}$. Here, Gröbner bases are considered with respect to an admissible ordering $>$ for $A$ and the opposite ordering $>^{\text{op}}$ for $A^{\text{op}}$, respectively. Each left Gröbner basis of a two-sided ideal $I$ is also a right Gröbner basis of $I$. Moreover, there is an algorithm which, starting from a left Gröbner basis of $I$, computes a two-sided Gröbner basis of $I$ (see, for example, Wolfram Decker, Christoph Lossen (2006)).

diff --git a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html b/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html deleted file mode 100644 index 5f6d690c4114..000000000000 --- a/previews/PR2578/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html +++ /dev/null @@ -1,88 +0,0 @@ - -GR-Algebras: Quotients of PBW-Algebras · Oscar.jl

GR-Algebras: Quotients of PBW-Algebras

In analogy to the affine algebras section in the commutative algebra chapter, we describe OSCAR functionality for dealing with quotients of PBW-algebras modulo two-sided ideals.

Note

Quotients of PBW-algebras modulo two-sided ideals are also known as GR-algebras (here, GR stands for Gröbner-Ready; see Viktor Levandovskyy (2005)).

Types

GR-algebras are modelled by objects of type PBWAlgQuo{T, S} <: NCRing, their elements are objects of type PBWAlgQuoElem{T, S} <: NCRingElem. Here, T is the element type of the field over which the GR-algebra is defined (the type S is added for internal use).

Constructors

quoMethod
quo(A::PBWAlgRing, I::PBWAlgIdeal)

Given a two-sided ideal I of A, create the quotient algebra $A/I$ and return the new algebra together with the quotient map $A\to A/I$.

Examples

julia> R, (x, y, z) = QQ["x", "y", "z"];
-
-julia> L = [-x*y, -x*z, -y*z];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)))
-(PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z])
-
-julia> I = two_sided_ideal(A, [x^2, y^2, z^2])
-two_sided_ideal(x^2, y^2, z^2)
-
-julia> Q, q = quo(A, I);
-
-julia> Q
-(PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z)/two_sided_ideal(x^2, y^2, z^2)
-
-julia> q
-Map from
-PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z to (PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z)/two_sided_ideal(x^2, y^2, z^2) defined by a julia-function with inverse
Note

The example above, shows one way of constructing the exterior algebra on the variables x, y, z over $\mathbb Q$. For reasons of efficiency, it is recommended to use the built-in constructor exterior_algebra when working with exterior algebras in OSCAR.

source

Exterior Algebras

The $n$-th exterior algebra over a field $K$ is the quotient of the PBW-algebra

\[A=K \langle e_1,\dots, e_n \mid e_i e_j = - e_j e_i \ \text { for }\ i\neq j\rangle\]

modulo the two-sided ideal

\[\langle e_1^2,\dots, e_n^2\rangle.\]

exterior_algebraFunction
exterior_algebra(K::Field, numVars::Int)
-exterior_algebra(K::Field, listOfVarNames::AbstractVector{<:VarName})

The first form returns an exterior algebra with coefficient field K and numVars variables: numVars must be positive, and the variables are called e1, e2, ....

The second form returns an exterior algebra with coefficient field K, and variables named as specified in listOfVarNames (which must be non-empty).

NOTE: Creating an exterior_algebra with many variables will create an object occupying a lot of memory (probably cubic in numVars).

Examples

julia> ExtAlg, (e1,e2)  =  exterior_algebra(QQ, 2);
-
-julia> e2*e1
--e1*e2
-
-julia> (e1+e2)^2  # result is automatically reduced!
-0
-
-julia> ExtAlg, (x,y)  =  exterior_algebra(QQ, ["x","y"]);
-
-julia> y*x
--x*y
source

Data Associated to Affine GR-Algebras

Basic Data

If Q=A/I is the quotient ring of a PBW-algebra A modulo a two-sided ideal I of A, then

  • base_ring(Q) refers to A,
  • modulus(Q) to I,
  • gens(Q) to the generators of Q,
  • ngens(Q) to the number of these generators, and
  • gen(Q, i) as well as Q[i] to the i-th such generator.
Examples
julia> R, (x, y, z) = QQ["x", "y", "z"];
-
-julia> L = [-x*y, -x*z, -y*z];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)));
-
-julia> I = two_sided_ideal(A, [x^2, y^2, z^2]);
-
-julia> Q, q = quo(A, I);
-
-julia> base_ring(Q)
-PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z
-
-julia> modulus(Q)
-two_sided_ideal(x^2, y^2, z^2)
-
-julia> gens(Q)
-3-element Vector{PBWAlgQuoElem{QQFieldElem, Singular.n_Q}}:
- x
- y
- z
-
-julia> ngens(Q)
-3
-
-julia> gen(Q, 2)
-y

Elements of GR-Algebras

Types

The OSCAR type for elements of quotient rings of multivariate polynomial rings PBW-algebras is of parametrized form PBWAlgQuoElem{T, S}, where T is the element type of the field over which the GR-algebra is defined (the type S is added for internal use).

Creating Elements of GR-Algebras

Elements of a GR-algebra $Q = A/I$ are created as images of elements of $A$ under the projection map or by directly coercing elements of $A$ into $Q$. The function simplify reduces a given element with regard to the modulus $I$.

Examples
julia> R, (x, y, z) = QQ["x", "y", "z"];
-
-julia> L = [-x*y, -x*z, -y*z];
-
-julia> REL = strictly_upper_triangular_matrix(L);
-
-julia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)));
-
-julia> I = two_sided_ideal(A, [x^2, y^2, z^2]);
-
-julia> Q, q = quo(A, I);
-
-julia> f = q(y*x+z^2)
--x*y + z^2
-
-julia> typeof(f)
-PBWAlgQuoElem{QQFieldElem, Singular.n_Q}
-
-julia> simplify(f);
-
-julia> f
--x*y
-
-julia> g = Q(y*x+x^2)
-x^2 - x*y
-
-julia> f == g
-true

Data associated to Elements of GR-Algebras

Given an element f of an affine GR-algebra Q,

  • parent(f) refers to Q.

Ideals in GR-Algebras

diff --git a/previews/PR2578/NoncommutativeAlgebra/free_associative_algebra/index.html b/previews/PR2578/NoncommutativeAlgebra/free_associative_algebra/index.html deleted file mode 100644 index 558cbf371af1..000000000000 --- a/previews/PR2578/NoncommutativeAlgebra/free_associative_algebra/index.html +++ /dev/null @@ -1,3 +0,0 @@ - -Free Associative Algebras · Oscar.jl

Free Associative Algebras

Two-sided ideals

Types

The OSCAR type for two-sided ideals in a free associative algebra is FreeAssAlgIdeal{T}, where T is the element type of the algebra.

Constructors

ideal(R::FreeAssAlgebra, g::Vector{T}) where T <: FreeAssAlgElem
-ideal(g::Vector{T}) where T <: FreeAssAlgElem

Ideal Membership

ideal_membershipMethod
ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int)

Return true if calucations with intermediate degrees bounded by deg_bound prove that $a$ is in $I$. Otherwise, a return of false indicates an inconclusive answer, but larger deg_bounds give more confidence in a negative answer.

source
diff --git a/previews/PR2578/NoncommutativeAlgebra/intro/index.html b/previews/PR2578/NoncommutativeAlgebra/intro/index.html deleted file mode 100644 index d80bd8173c21..000000000000 --- a/previews/PR2578/NoncommutativeAlgebra/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Working over a field $K$, our focus in this chapter is on noncommutative Gröbner bases and their application to the computational study of finitely presented associative $K$-algebras. At present state, OSCAR offers

  • a comprehensive toolkit for dealing with PBW-algebras and their quotients modulo two-sided ideals,
  • functionality for computing and applying (partial) two-sided Gröbner bases in free associative algebras on finitely many letters.
Note

In contrast to the general case of finitely presented associative algebras, (left, right, two-sided) ideals in PBW-algebras admit finite (left, right, two-sided) Gröbner bases. In particular, PBW-algebras are Noetherian.

Note

The class of PBW-algebras includes the Weyl algebras. Algebras which arise as quotients of PBW-algebras include the Clifford algebras (in particular, the exterior algebras).

The textbooks

and the thesis

offer details on theory and algorithms.

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/NumberTheory/abelian_closure/index.html b/previews/PR2578/NumberTheory/abelian_closure/index.html deleted file mode 100644 index 6319239d74d3..000000000000 --- a/previews/PR2578/NumberTheory/abelian_closure/index.html +++ /dev/null @@ -1,25 +0,0 @@ - -Abelian closure of the rationals · Oscar.jl

Abelian closure of the rationals

The abelian closure $\mathbf{Q}^\text{ab}$ is the maximal abelian extension of $\mathbf{Q}$ inside a fixed algebraic closure and can explicitly described as

\[\mathbf{Q}^{\mathrm{ab}} = \mathbf{Q}(\zeta_n \mid n \in \mathbf{N}),\]

the union of all cyclotomic extensions. Here for $n \in \mathbf{N}$ we denote by $\zeta_n$ a primitive $n$-th root of unity.

Creation of the abelian closure and elements

abelian_closureMethod
abelian_closure(QQ::RationalField)

Return a pair (K, z) consisting of the abelian closure K of the rationals and a generator z that can be used to construct primitive roots of unity in K.

An optional keyword argument sparse can be set to true to switch to a sparse representation. Depending on the application this can be much faster or slower.

Examples

julia> K, z = abelian_closure(QQ);
-
-julia> z(36)
-zeta(36)
-
-julia> K, z = abelian_closure(QQ, sparse = true);
-
-julia> z(36)
--zeta(36, 9)*zeta(36, 4)^4 - zeta(36, 9)*zeta(36, 4)
-
source

Given the abelian closure, the generator can be recovered as follows:

genMethod
gen(M::SubquoModule{T}, i::Int) where T

Return the ith generator of M.

source

Printing

The n-th primitive root of the abelian closure of will by default be printed as z(n). The printing can be manipulated using the following functions:

genMethod
gen(K::QQAbField, s::String)

Return the generator of the abelian closure K that can be used to construct primitive roots of unity. The string s will be used during printing.

source
set_variable!Method
set_variable!(K::QQAbField, s::String)

Change the printing of the primitive n-th root of the abelian closure of the rationals to s(n), where s is the supplied string.

source
get_variableMethod
get_variable(K::QQAbField)

Return the string used to print the primitive n-th root of the abelian closure of the rationals.

source

Examples

julia> K, z = abelian_closure(QQ);
-
-julia> z(4)
-z(4)
-
-julia> ζ = gen(K, "ζ")
-Generator of abelian closure of Q
-
-julia> ζ(5) + ζ(3)
-ζ(15)^5 + ζ(15)^3

Reduction to characteristic $p$

reduceMethod
reduce(val::QQAbElem, F::FinField)

Return the element of F that is the $p$-modular reduction of val, where $p$ is the characteristic of F. An exception is thrown if val cannot be reduced modulo $p$ or if the reduction does not lie in F.

Examples

julia> K, z = abelian_closure(QQ);
-
-julia> F = GF(2, 3);
-
-julia> reduce(z(7), F)
-o
source
diff --git a/previews/PR2578/NumberTheory/galois/index.html b/previews/PR2578/NumberTheory/galois/index.html deleted file mode 100644 index 80bc1663e4d5..000000000000 --- a/previews/PR2578/NumberTheory/galois/index.html +++ /dev/null @@ -1,162 +0,0 @@ - -Galois Theory · Oscar.jl

Galois Theory

Let K be a finite (separable) field extension of k. Then, in contrast to most of the literature we distinguish two concepts

  • the automorphism group
  • the Galois group

The automorphism group deals with the actual automorphism of K fixing k and thus is, in general trivial. Access is via two constructions:

  • a list of all automorphisms (usually only the identity)
  • the group of automorphisms, returned as an abstract group and a map linking group elements to actual automorphisms

On the other hand, the Galois group is isomorphic to the automorphism group of the normal closure and is explicitly given as a group of permutations of the roots of the defining polynomial. Thus even in the case of K over k being normal, elements of the Galois group do not immediately give automorphisms at all.

Currently, the computation of Galois groups is possible for

  • K a simple extension of the rationals (AnticNumberField)
  • K a simple extension of an AnticNumberField
  • K a finite extension of the rational function field over the rationals. In this case the monodromy group can be computed as well, ie. the automorphism group over the complex numbers.
  • f a polynomial over the rationals, or an AnticNumberField

Independently of the Galois group, subfields, that is intermediate fields between K and k can be computed as well.

Automorphism Group

The automorphisms are computed using various specialised factoring algorithms: lifting the roots of the defining polynomial in the given field modulo suitable prime ideal powers and recovering the true roots from this information.

The main information is included in the number field chapter, see for example

Subfields

The main information is included in the number field chapter, see

By setting set_verbose_level(:Subfields, n::Int) to 1 or 2 information about the progress can be obtained.

Galois Group

The computation of Galois groups follows Stauduhars algorithm with many improvements, see ... for an overview.

The entrire computation can also be thought of finding a description of the splitting field of the polynomial. In fact, the information returned can be used to verify any algebraic identity between the roots, and find explicit subfields of the splitting field as well.

Information about the progress is available via

  • set_verbose_level(:GaloisGroup, n::Int)
  • set_verbose_level(:GaloisInvariants, n::Int)
galois_groupFunction
galois_group(K::AnticNumberField, extra::Int = 5; useSubfields::Bool = true, pStart::Int = 2*degree(K)) -> PermGroup, GaloisCtx

Computes the Galois group of the splitting field of the defining polynomial of K. Currently the polynomial needs to be monic.

The group is returned as an explicit permutation group permuting the roots as contained in the context object (the 2nd return value). The roots live in a suitable unramifed extension of the p-adics.

Examples

julia> K, a = cyclotomic_field(5);
-
-julia> G, C = galois_group(K)
-(Group([ (1,4,2,3), (1,2)(3,4) ]), Galois Context for x^4 + x^3 + x^2 + x + 1 and prime 19)
-
-julia> describe(G)
-"C4"
-
-julia> roots(C, 2)
-4-element Vector{qadic}:
- (4*19^0 + 2*19^1 + O(19^2))*a + 5*19^0 + 9*19^1 + O(19^2)
- (15*19^0 + 16*19^1 + O(19^2))*a + 9*19^0 + 7*19^1 + O(19^2)
- (18*19^0 + 18*19^1 + O(19^2))*a + 12*19^0 + O(19^2)
- (19^0 + O(19^2))*a + 11*19^0 + 19^1 + O(19^2)
source
galois_groupMethod
galois_group(f::PolyRingElem{<:FieldElem})

Computes the automorphism group of a splitting field of f as an explicit group of permutations of the roots. Furthermore, the GaloisCtx is returned allowing algorithmic access to the splitting field.

source

Over the rational function field, we can also compute the monodromy group:

julia> Qt, t = RationalFunctionField(QQ, "t");
-
-julia> Qtx, x = Qt["x"];
-
-julia> F, a = function_field(x^6 + 108*t^2 + 108*t + 27);
-
-julia> subfields(F)
-4-element Vector{Any}:
- (Function Field over Rational field with defining polynomial a^3 + 54*t + 27, (1//12*_a^4 + (3//2*t + 3//4)*_a)//(t + 1//2))
- (Function Field over Rational field with defining polynomial a^2 + 108*t^2 + 108*t + 27, _a^3)
- (Function Field over Rational field with defining polynomial a^3 - 108*t^2 - 108*t - 27, -_a^2)
- (Function Field over Rational field with defining polynomial a^3 - 54*t - 27, (-1//12*_a^4 + (3//2*t + 3//4)*_a)//(t + 1//2))
-
-julia> galois_group(F)
-(Group([ (), (1,5)(2,3)(4,6), (1,3,4)(2,5,6) ]), Galois Context for s^6 + 108*t^2 + 540*t + 675)
-
-julia> G, C, k = galois_group(F, overC = true)
-(Group([ (1,4,3)(2,6,5) ]), Galois Context for s^6 + 108*t^2 + 540*t + 675, Number field of degree 2 over QQ)
-

So, while the splitting field over Q(t) has degree 6, the galois group there is isomorphic to the S(3) or D(3) (on 6 points), the splitting field over C(t) is only of degree 3. Here the group collapses to a cyclic group of degree 3, the algebraic closure of Q in the splitting field is the quadratic field returned last. It can be seen to be isomorphic to a cyclotomic field:

julia> is_isomorphic(k, cyclotomic_field(3)[1])
-true

The information returned consists always at least of a group G and a GaloisCtx: C. Jointly, they can be used to further work with the information:

rootsMethod
roots(G::GaloisCtx, pr::Int)

The roots of the polynomial used to define the Galois context in the fixed order used in the algorithm. The roots are returned up to a precision of pr p-adic digits, thus they are correct modulo $p^{pr}$

For non-monic polynomials the roots are scaled by the leading coefficient. If raw is set to true, the scaling is omitted. The bound in the GaloisCtx is also adjusted.

source
upper_boundFunction
upper_bound(G::GaloisCtx, f...)

Given a GaloisCtx and some multivariate function, upper_bound the image of f upon evaluation at the roots implicit in G.

f can be

  • a multivariate polynomial or straight-line polynomial (strictly: any object allowing evaluate
  • elementary_symmetric or power_sum, in which case more arguments are needed: the array with the values and the index. upper_bound(G, power_sum, A, i) is equivalent to upper_bound(G, power_sum(A, i)) but more efficient.

In every case a univariate polynomial (over the integers) can be added, it will act as a Tschirnhaus-transformation, ie. the roots (bounds) implicit in G will first be transformed.

source
isintegerFunction
isinteger(C::GaloisCtx, B::BoundRingElem, v)

For an element v representing an integral polynomial evaluated at the roots stored in C, known to be bounded from above by B, either return true and an explicit (algebraic) integer in the base ring of the context or return false.

source
resolventFunction
resolvent(C::GaloisCtx, G::PermGroup, U::PermGroup)

Find a G-relative H-invariant I and form the corresponding resolvent polynomial $\prod (x-I^t)$ where the product runs over all coset-representatives of G/U.

source

To illustrate:

julia> Qx, x = QQ["x"];
-
-julia> f = (x^2-2)*(x^2-3);
-
-julia> G, C = galois_group(f)
-(Group([ (1,2), (3,4) ]), Galois Context for x^4 - 5*x^2 + 6 and prime 11)
-
-julia> r = roots(C, 5)
-4-element Vector{qadic}:
- 5*11^0 + 2*11^1 + 6*11^2 + 8*11^3 + 11^4 + O(11^5)
- 6*11^0 + 8*11^1 + 4*11^2 + 2*11^3 + 9*11^4 + O(11^5)
- (11^0 + 6*11^1 + 6*11^2 + 2*11^4 + O(11^5))*a + 9*11^0 + 4*11^1 + 6*11^2 + 7*11^3 + 11^4 + O(11^5)
- (10*11^0 + 4*11^1 + 4*11^2 + 10*11^3 + 8*11^4 + O(11^5))*a + 2*11^0 + 6*11^1 + 4*11^2 + 3*11^3 + 9*11^4 + O(11^5)
-
-julia> r[1]^2
-3*11^0 + O(11^5)
-
-julia> r[3]^2
-2*11^0 + O(11^5)

To illustrate the use as a splitting field, we will prove that r[1]^2 is actually an integer - and that r[1]+r[3] is not.

Any multivariate polynomial in four variables and with integer coefficients defines via evaluation at the roots an element in the splitting field. In case the evaluation is actually an integer, this can be proven with the tools provided.

julia> I, s = polynomial_ring(ZZ, 4);
-
-julia> s[1]^2
-x1^2
-

Next, we need a bound for the evaluation as a complex number, and compute the precision necessary:

julia> B = Oscar.GaloisGrp.upper_bound(C, s[1]^2)
-(x <= 36)
-
-julia> pr = Oscar.GaloisGrp.bound_to_precision(C, B)
-7
-

Finally, we evaluate the polynomial at the roots and verify that the exact value is 3:

julia> evaluate(s[1]^2, roots(C, 7))
-3*11^0 + O(11^7)
-
-julia> Oscar.GaloisGrp.isinteger(C, B, ans)
-(true, 3)

Now, to show that r[1] + r[3] is not an integer:

julia> B = Oscar.GaloisGrp.upper_bound(C, s[1] + s[3])
-(x <= 12)
-
-julia> Oscar.GaloisGrp.isinteger(C, B, evaluate(s[1] + s[3], roots(C, 7)))
-(false, nothing)

More interestingly, we can use this to find the minimal polynomial of r[1] + r[3]. Generically, the Galois-conjugates of r[1]+r[3] should be the G-orbit of s[1]+s[3] evaluated at the roots.

Once the orbit is known, the coefficients of the minimal polynomial are just the elementary symmetric functions evaluated at the roots:

julia> o = collect(orbit(G, s[1]+s[3]))
-4-element Vector{ZZMPolyRingElem}:
- x1 + x3
- x1 + x4
- x2 + x4
- x2 + x3
-
-julia> for i=1:4
-         B = Oscar.GaloisGrp.upper_bound(C, elementary_symmetric, o, i)
-         pr = Oscar.GaloisGrp.bound_to_precision(C, B)
-         co = [evaluate(x, roots(C, pr)) for x = o]
-         println(i, ": ", Oscar.GaloisGrp.isinteger(C, B, elementary_symmetric(co, i)))
-       end
-1: (true, 0)
-2: (true, -10)
-3: (true, 0)
-4: (true, 1)

So, x^4-10x^2+1 should be the minimal polynomial to $\sqrt 3 + \sqrt 2$ - which it is.

In the case of computations over the rational function field, both the precision and the bound are more complicated - but can be used in the same way: Here, the roots are power series with q-adic coefficients, thus the precision has to cover both the precision of the coefficient as well as the number of terms in the series. Similarly, in this context, an isinteger is now a polynomial with integer coefficients. Thus the bound needs to bound the degree as well as the coefficient size.

julia> Qt,t = RationalFunctionField(QQ, "t");
-
-julia> Qtx, x = Qt["x"];
-
-julia> F, a = function_field(x^3+t+2);
-
-julia> G, C = galois_group(F);
-
-julia> describe(G)
-"S3"
-
-julia> _, s = slpoly_ring(ZZ, 3);
-
-julia> B = Oscar.GaloisGrp.upper_bound(C, prod(s))
-(x <= (9261, 2, 1))
-
-julia> pr = Oscar.GaloisGrp.bound_to_precision(C, B)
-(2, 2)
-
-julia> Oscar.GaloisGrp.isinteger(C, B, evaluate(prod(s), roots(C, pr)))
-(true, -t - 2)
galois_quotientMethod
galois_quotient(C::GaloisCtx, Q::PermGroup)

Finds all(?) subfields of the splitting field s.th. the galois group will be permutation isomorphic to Q.

source
galois_quotientMethod
galois_quotient(C::GaloisCtx, d::Int)

Finds all(?) subfields (up to isomorphism) of the splitting field of degree d with galois group isomorphic to the original one.

Examples

julia> Qx, x = QQ["x"];
-
-julia> G, C = galois_group(x^3-2);
-
-julia> galois_quotient(C, 6)
-1-element Vector{Any}:
- Number field of degree 6 over QQ
-
-julia> galois_group(ans[1])
-(Group([ (), (1,5)(2,4)(3,6), (1,2,3)(4,5,6) ]), Galois Context for x^6 + 324*x^4 - 4*x^3 + 34992*x^2 + 1296*x + 1259716 and prime 13)
-
-julia> is_isomorphic(ans[1], G)
-true
source
galois_quotientMethod
galois_quotient(C::GaloisCtx, d::Int, n::Int)

Finds all subfields of the splitting field with galois group the n-th transitive group in degree d

source
galois_quotientMethod
galois_quotient(f::PolyRingElem, p::Vector{Int})

Equivalent to

galois_quotient(galois_group(f)[2], p[1], p[2])

Finds all subfields of the splitting field of f with galois group the p[2]-th transitive group of degree p[1]

source
fixed_fieldFunction
fixed_field(GC::GaloisCtx, U::PermGroup, extra::Int = 5)

Given the GaloisCtx as returned by a call to galois_group and a subgroup U of the Galois group, compute the field fixed by U as a simple extension.

source
minpolyFunction
minpoly(C::GaloisCtx, I, extra::Int = 5)

Computes the minimal polynomial of I evaluated at the roots stored in C.

source
cauchy_idealMethod
cauchy_ideal(f::PolyRingElem{<:FieldElem})

The coefficients of f are the elementary symmetric functions evaluated at the roots of f. The cauchy_ideal is the ideal generated by the differences between the elementary symmetric functions and the coefficients.

Examples

julia> Qx, x = QQ["x"];
-
-julia> cauchy_ideal(x^4-2)
-ideal(x4^4 - 2, x3^3 + x3^2*x4 + x3*x4^2 + x4^3, x2^2 + x2*x3 + x2*x4 + x3^2 + x3*x4 + x4^2, x1 + x2 + x3 + x4)
-
source
galois_idealFunction
galois_ideal(C::GaloisCtx, extra::Int = 5)

The so-called Galois ideal is a description of the splitting field of the polynomial underlying Cas a quotient by some maximal ideal. Algebraically, this ideal is an irreducible component of the Cauchy ideal, the ideal generated by the elementary symmetric functions and the coefficients of the polynomial.

Examples

julia> Qx, x = QQ["x"];
-
-julia> i = galois_ideal(galois_group(x^4-2)[2])
-ideal(x4^4 - 2, x3^3 + x3^2*x4 + x3*x4^2 + x4^3, x2^2 + x2*x3 + x2*x4 + x3^2 + x3*x4 + x4^2, x1 + x2 + x3 + x4, x1*x3 + x2*x4, x1^2*x3^2 + x2^2*x4^2 - 4, x1^4 - 2, x2^4 - 2, x3^4 - 2, x4^4 - 2)
-
-julia> k, _ = number_field(i);
-
-
-julia> length(roots(k, x^4-2))
-4
-
source

Over the integers, if the Galois group is solvable, the roots can be expressed as radicals:

solveMethod
Oscar.solve(f::ZZPolyRingElem; max_prec::Int=typemax(Int))
-Oscar.solve(f::QQPolyRingElem; max_prec::Int=typemax(Int))

Compute a presentation of the roots of f in a radical tower. The necessary roots of unity are not themselves computed as radicals.

See also galois_group.

VERBOSE

Supports set_verbose_level(:SolveRadical, i) to obtain information.

Examples

julia> Qx,x = QQ["x"];
-
-julia> K, r = solve(x^3+3*x+5)
-(Relative number field over with defining polynomial x^3 + (3*z_3 + 3//2)*a2 + 135//2
- over Relative number field over with defining polynomial x^2 + 783
- over Number field over Rational Field with defining polynomial x^2 + x + 1, Any[((1//81*z_3 + 1//162)*a2 - 5//18)*a3^2 + 1//3*a3, ((-1//162*z_3 + 1//162)*a2 + 5//18*z_3 + 5//18)*a3^2 + 1//3*z_3*a3, ((-1//162*z_3 - 1//81)*a2 - 5//18*z_3)*a3^2 + (-1//3*z_3 - 1//3)*a3])
-
-julia> #z_3 indicates the 3-rd root-of-1 used
-
-julia> map(x^3+3*x+5, r)
-3-element Vector{Hecke.NfRelElem{Hecke.NfRelElem{nf_elem}}}:
- 0
- 0
- 0
-
-julia> solve(cyclotomic(12, x)) #zeta_12 as radical
-(Relative number field over with defining polynomial x^2 - 3//4
- over Number field over Rational Field with defining polynomial x^2 + 1, Any[a2 + 1//2*a1, a2 - 1//2*a1, -a2 - 1//2*a1, -a2 + 1//2*a1])
-
source
fixed_fieldMethod
fixed_field(C::GaloisCtx, s::Vector{PermGroup})

Given a descending chain of subgroups, each being maximal in the previous one, compute the corresponding subfields as a tower.

Examples

julia> Qx, x = QQ["x"];
-
-julia> G, C = galois_group(x^3-3*x+17)
-(Sym( [ 1 .. 3 ] ), Galois Context for x^3 - 3*x + 17 and prime 7)
-
-julia> d = derived_series(G)
-3-element Vector{PermGroup}:
- Sym( [ 1 .. 3 ] )
- Alt( [ 1 .. 3 ] )
- Group(())
-
-julia> fixed_field(C, d)
-(Relative number field of degree 3 over number field, a2)
source
diff --git a/previews/PR2578/NumberTheory/intro/index.html b/previews/PR2578/NumberTheory/intro/index.html deleted file mode 100644 index a40c01a46264..000000000000 --- a/previews/PR2578/NumberTheory/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The number theory part of OSCAR provides functionality for algebraic number theory.

It is under development with regard to providing both the functionality and the documentation.

General textbooks offering details on theory and algorithms include:

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/PolyhedralGeometry/Polyhedra/auxiliary/index.html b/previews/PR2578/PolyhedralGeometry/Polyhedra/auxiliary/index.html deleted file mode 100644 index e36a95f26132..000000000000 --- a/previews/PR2578/PolyhedralGeometry/Polyhedra/auxiliary/index.html +++ /dev/null @@ -1,559 +0,0 @@ - -Auxiliary functions · Oscar.jl

Auxiliary functions

Geometric data

facetsMethod
facets(as::Type{T} = AffineHalfspace, P::Polyhedron)

Return the facets of P in the format defined by as.

The allowed values for as are

  • Halfspace,
  • Polyhedron,
  • Pair.

Examples

We can retrieve the six facets of the 3-dimensional cube this way:

julia> C = cube(3);
-
-julia> facets(Polyhedron, C)
-6-element SubObjectIterator{Polyhedron{QQFieldElem}}:
- Polyhedron in ambient dimension 3
- Polyhedron in ambient dimension 3
- Polyhedron in ambient dimension 3
- Polyhedron in ambient dimension 3
- Polyhedron in ambient dimension 3
- Polyhedron in ambient dimension 3
-
-julia> facets(Halfspace, C)
-6-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:
--x₁ ≦ 1
-x₁ ≦ 1
--x₂ ≦ 1
-x₂ ≦ 1
--x₃ ≦ 1
-x₃ ≦ 1
source
facets(P::Polyhedron)

Return the facets of P as halfspaces.

Examples

We can retrieve the six facets of the 3-dimensional cube this way:

julia> C = cube(3);
-
-julia> facets(C)
-6-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:
--x₁ ≦ 1
-x₁ ≦ 1
--x₂ ≦ 1
-x₂ ≦ 1
--x₃ ≦ 1
-x₃ ≦ 1
source
verticesMethod
vertices(P::Polyhedron)

Return an iterator over the vertices of a polyhedron P as points.

Examples

The following code computes the vertices of the Minkowski sum of a triangle and a square:

julia> P = simplex(2) + cube(2);
-
-julia> vertices(P)
-5-element SubObjectIterator{PointVector{QQFieldElem}}:
- [-1, -1]
- [2, -1]
- [2, 1]
- [-1, 2]
- [1, 2]
source
raysMethod
rays(P::Polyhedron)

Return minimal set of generators of the cone of unbounded directions of P (i.e. its rays) as points.

Examples

We can verify that the positive orthant of the plane is generated by the two rays in positive unit direction:

julia> PO = convex_hull([0 0], [1 0; 0 1]);
-
-julia> rays(PO)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [0, 1]
-
-julia> matrix(QQ, rays(PO))
-[1   0]
-[0   1]
-
-julia> matrix(ZZ, rays(PO))
-[1   0]
-[0   1]
source
rays_modulo_linealityMethod
rays_modulo_lineality(as, P::Polyhedron)

Return the rays of the recession cone of P up to lineality as a NamedTuple with two iterators. If P has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of P/L. The iterator lineality_basis gives a basis of the lineality space L.

Examples

julia> P = convex_hull([0 0 1], [0 1 0], [1 0 0])
-Polyhedron in ambient dimension 3
-
-julia> rmlP = rays_modulo_lineality(P)
-(rays_modulo_lineality = RayVector{QQFieldElem}[[0, 1, 0]], lineality_basis = RayVector{QQFieldElem}[[1, 0, 0]])
-
-julia> rmlP.rays_modulo_lineality
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [0, 1, 0]
-
-julia> rmlP.lineality_basis
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0, 0]
source
minimal_facesMethod
minimal_faces(as, P::Polyhedron)

Return the minimal faces of a polyhedron as a NamedTuple with two iterators. For a polyhedron without lineality, the base_points are the vertices. If P has lineality L, then every minimal face is an affine translation p+L, where p is only unique modulo L. The return type is a dict, the key :base_points gives an iterator over such p, and the key :lineality_basis lets one access a basis for the lineality space L of P.

Examples

The polyhedron P is just a line through the origin:

julia> P = convex_hull([0 0], nothing, [1 0])
-Polyhedron in ambient dimension 2
-
-julia> lineality_dim(P)
-1
-
-julia> vertices(P)
-0-element SubObjectIterator{PointVector{QQFieldElem}}
-
-julia> minimal_faces(P)
-(base_points = PointVector{QQFieldElem}[[0, 0]], lineality_basis = RayVector{QQFieldElem}[[1, 0]])
source
affine_hullMethod
affine_hull(P::Polytope)

Return the (affine) hyperplanes generating the affine hull of P.

Examples

This triangle in $\mathbb{R}^4$ is contained in the plane defined by $P = \{ (x_1, x_2, x_3, x_4) | x_3 = 2 ∧ x_4 = 5 \}$.

julia> t = convex_hull([0 0 2 5; 1 0 2 5; 0 1 2 5]);
-
-julia> affine_hull(t)
-2-element SubObjectIterator{AffineHyperplane{QQFieldElem}} over the Hyperplanes of R^4 described by:
-x₃ = 2
-x₄ = 5
source
ambient_dimMethod
ambient_dim(P::Polyhedron)

Return the ambient dimension of P.

Examples

julia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];
-
-julia> P = convex_hull(V);
-
-julia> ambient_dim(P)
-3
source
dimMethod
dim(P::Polyhedron)

Return the dimension of P.

Examples

julia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];
-
-julia> P = convex_hull(V);
-
-julia> dim(P)
-2
source
codimMethod
codim(P::Polyhedron)

Return the codimension of P.

Examples

julia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];
-
-julia> P = convex_hull(V);
-
-julia> codim(P)
-1
source
is_boundedMethod
is_bounded(P::Polyhedron)

Check whether P is bounded.

Examples

julia> P = polyhedron([1 -3; -1 1; -1 0; 0 -1],[1,1,1,1]);
-
-julia> is_bounded(P)
-false
source
is_feasibleMethod
is_feasible(P::Polyhedron)

Check whether P is feasible, i.e. non-empty.

Examples

julia> P = polyhedron([1 -1; -1 1; -1 0; 0 -1],[-1,-1,1,1]);
-
-julia> is_feasible(P)
-false
source
is_fulldimensionalMethod
is_fulldimensional(P::Polyhedron)

Check whether P is full-dimensional.

Examples

julia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];
-
-julia> is_fulldimensional(convex_hull(V))
-false
source
is_lattice_polytopeMethod
is_lattice_polytope(P::Polyhedron{QQFieldElem})

Check whether P is a lattice polytope, i.e. it is bounded and has integral vertices.

Examples

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> is_lattice_polytope(c)
-true
-
-julia> c = cube(3, 0, 4//3)
-Polyhedron in ambient dimension 3
-
-julia> is_lattice_polytope(c)
-false
source
lineality_dimMethod
lineality_dim(P::Polyhedron)

Return the dimension of the lineality space, i.e. the dimension of the largest affine subspace contained in P.

Examples

Polyhedron with one lineality direction.

julia> C = convex_hull([0 0], [1 0], [1 1])
-Polyhedron in ambient dimension 2
-
-julia> lineality_dim(C)
-1
source
lineality_spaceMethod
lineality_space(P::Polyhedron)

Return a matrix whose row span is the lineality space of P.

Examples

Despite not being reflected in this construction of the upper half-plane, its lineality in $x$-direction is recognized:

julia> UH = convex_hull([0 0],[0 1; 1 0; -1 0]);
-
-julia> lineality_space(UH)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
source
recession_coneMethod
recession_cone(P::Polyhedron)

Return the recession cone of P.

Examples

julia> P = polyhedron([1 -2; -1 1; -1 0; 0 -1],[2,1,1,1]);
-
-julia> vertices(P)
-3-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, -1]
- [-1, 0]
- [-1, -1]
-
-julia> recession_cone(P)
-Polyhedral cone in ambient dimension 2
-
-julia> rays(recession_cone(P))
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 1//2]
- [1, 1]
source
relative_interior_pointMethod
relative_interior_point(P::Polyhedron)

Compute a point in the relative interior point of P, i.e. a point in P not contained in any facet.

Examples

The square $[-1,1]^3$ has the origin as a relative interior point.

julia> square = cube(2)
-Polyhedron in ambient dimension 2
-
-julia> relative_interior_point(square)
-2-element PointVector{QQFieldElem}:
- 0
- 0
-
-julia> vertices(square)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [-1, -1]
- [1, -1]
- [-1, 1]
- [1, 1]
-
-julia> matrix(QQ, vertices(square))
-[-1   -1]
-[ 1   -1]
-[-1    1]
-[ 1    1]
source

Combinatorial data

nfacetsMethod
nfacets(P::Polyhedron)

Return the number of facets of P.

Examples

The number of facets of the 5-dimensional cross polytope can be retrieved via the following line:

julia> nfacets(cross_polytope(5))
-32
source
nverticesMethod
nvertices(P::Polyhedron)

Return the number of vertices of P.

Examples

The 3-cube's number of vertices can be obtained with this input:

julia> C = cube(3);
-
-julia> nvertices(C)
-8
source
f_vectorMethod
f_vector(P::Polyhedron)

Return the vector $(f₀,f₁,f₂,...,f_{(dim(P)-1))$` where $f_i$ is the number of faces of $P$ of dimension $i$.

Examples

Here we compute the f-vector of the 5-cube:

julia> f_vector(cube(5))
-5-element Vector{ZZRingElem}:
- 32
- 80
- 80
- 40
- 10
source
g_vectorMethod
g_vector(P::Polyhedron)

Return the (toric) $g$-vector of a polytope. Defined by $g_0 = 1 $ and $g_k = h_k - h_{k-1}$, for $1 \leq k \leq \lceil (d+1)/2\rceil$ where $h$ is the $h$-vector and $d=\dim(P)$. Undefined for unbounded polyhedra.

Examples

julia> g_vector(cross_polytope(3))
-2-element Vector{ZZRingElem}:
- 1
- 2
source
h_vectorMethod
h_vector(P::Polyhedron)

Return the (toric) h-vector of a polytope. For simplicial polytopes this is a linear transformation of the f-vector. Undefined for unbounded polyhedra.

Examples

julia> h_vector(cross_polytope(3))
-4-element Vector{ZZRingElem}:
- 1
- 3
- 3
- 1
source

Groups

linear_symmetriesMethod
linear_symmetries(P::Polyhedron)

Get the group of linear symmetries on the vertices of a polyhedron. These are morphisms of the form $x\mapsto Ax+b$,with $A$ a matrix and $b$ a vector, that preserve the polyhedron $P$. The result is given as permutations of the vertices (or rather vertex indices) of $P$.

Examples

The 3-dimensional cube has 48 linear symmetries.

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> G = linear_symmetries(c)
-Group([ (3,5)(4,6), (2,3)(6,7), (1,2)(3,4)(5,6)(7,8) ])
-
-julia> order(G)
-48

The quadrangle one obtains from moving one vertex of the square out along the diagonal has two linear symmetries.

julia> quad = convex_hull([0 0; 1 0; 2 2; 0 1])
-Polyhedron in ambient dimension 2
-
-julia> G = linear_symmetries(quad)
-Group([ (2,4) ])
-
-julia> order(G)
-2
source
combinatorial_symmetriesMethod
combinatorial_symmetries(P::Polyhedron)

Compute the combinatorial symmetries (i.e., automorphisms of the face lattice) of a given polytope $P$. The result is given as permutations of the vertices (or rather vertex indices) of $P$. This group contains the linear_symmetries as a subgroup.

Examples

The quadrangle one obtains from moving one vertex of the square out along the diagonal has eight combinatorial symmetries, but only two linear symmetries.

julia> quad = convex_hull([0 0; 1 0; 2 2; 0 1])
-Polyhedron in ambient dimension 2
-
-julia> G = combinatorial_symmetries(quad)
-Group([ (2,4), (1,2)(3,4) ])
-
-julia> order(G)
-8
-
-julia> G = linear_symmetries(quad)
-Group([ (2,4) ])
-
-julia> order(G)
-2
source
automorphism_group_generatorsMethod
automorphism_group_generators(P::Polyhedron; type = :combinatorial, action = :all)

Compute generators of the group of automorphisms of a polyhedron.

The optional parameter type takes two values:

  • :combinatorial (default) – Return the combinatorial symmetries, the automorphisms of the face lattice.
  • :linear – Return the linear automorphisms.

The optional parameter action takes three values:

  • :all (default) – Return the generators of the permutation action on both vertices and facets as a Dict{Symbol, Vector{PermGroupElem}}.
  • :on_vertices – Only return generators of the permutation action on the vertices.
  • :on_facets – Only return generators of the permutation action on the facets.

The return value is a Dict{Symbol, Vector{PermGroupElem}} with two entries, one for the key :on_vertices containing the generators for the action permuting the vertices, and :on_facets for the facets.

Examples

Compute the automorphisms of the 3dim cube:

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> automorphism_group_generators(c)
-Dict{Symbol, Vector{PermGroupElem}} with 2 entries:
-  :on_vertices => [(3,5)(4,6), (2,3)(6,7), (1,2)(3,4)(5,6)(7,8)]
-  :on_facets   => [(3,5)(4,6), (1,3)(2,4), (1,2)]
-
-julia> automorphism_group_generators(c; action = :on_vertices)
-3-element Vector{PermGroupElem}:
- (3,5)(4,6)
- (2,3)(6,7)
- (1,2)(3,4)(5,6)(7,8)
-
-julia> automorphism_group_generators(c; action = :on_facets)
-3-element Vector{PermGroupElem}:
- (3,5)(4,6)
- (1,3)(2,4)
- (1,2)

Compute the automorphisms of a non-quadratic quadrangle. Since it has less symmetry than the square, it has less linear symmetries.

julia> quad = convex_hull([0 0; 1 0; 2 2; 0 1])
-Polyhedron in ambient dimension 2
-
-julia> automorphism_group_generators(quad)
-Dict{Symbol, Vector{PermGroupElem}} with 2 entries:
-  :on_vertices => [(2,4), (1,2)(3,4)]
-  :on_facets   => [(1,2)(3,4), (1,3)]
-
-julia> automorphism_group_generators(quad; type = :combinatorial)
-Dict{Symbol, Vector{PermGroupElem}} with 2 entries:
-  :on_vertices => [(2,4), (1,2)(3,4)]
-  :on_facets   => [(1,2)(3,4), (1,3)]
-
-julia> automorphism_group_generators(quad; type = :linear)
-Dict{Symbol, Vector{PermGroupElem}} with 2 entries:
-  :on_vertices => [(2,4)]
-  :on_facets   => [(1,2)(3,4)]
source
automorphism_group_generatorsMethod
automorphism_group_generators(IM::IncidenceMatrix; action = :all)

Compute the generators of the group of automorphisms of an IncidenceMatrix.

The optional parameter action takes three values:

  • :all (default) – Return the generators of the permutation action on both columns and rows as a Dict{Symbol, Vector{PermGroupElem}}.
  • :on_cols – Only return generators of the permutation action on the columns.
  • :on_rows – Only return generators of the permutation action on the rows.

Examples

Compute the automorphisms of the incidence matrix of the 3dim cube:

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> IM = vertex_indices(facets(c))
-6×8 IncidenceMatrix
-[1, 3, 5, 7]
-[2, 4, 6, 8]
-[1, 2, 5, 6]
-[3, 4, 7, 8]
-[1, 2, 3, 4]
-[5, 6, 7, 8]
-
-
-julia> automorphism_group_generators(IM)
-Dict{Symbol, Vector{PermGroupElem}} with 2 entries:
-  :on_cols => [(3,5)(4,6), (2,3)(6,7), (1,2)(3,4)(5,6)(7,8)]
-  :on_rows => [(3,5)(4,6), (1,3)(2,4), (1,2)]
-
-julia> automorphism_group_generators(IM; action = :on_rows)
-3-element Vector{PermGroupElem}:
- (3,5)(4,6)
- (1,3)(2,4)
- (1,2)
-
-julia> automorphism_group_generators(IM; action = :on_cols)
-3-element Vector{PermGroupElem}:
- (3,5)(4,6)
- (2,3)(6,7)
- (1,2)(3,4)(5,6)(7,8)
source

Other

all_triangulationsFunction
all_triangulations(pts::AbstractCollection[PointVector]; full=false)

Compute all triangulations on the points given as the rows of pts. Optionally select full=true to output full triangulations only, i.e. those that use all given points.

The return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.

Examples

julia> c = cube(2,0,1)
-Polyhedron in ambient dimension 2
-
-julia> V = vertices(c)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [1, 0]
- [0, 1]
- [1, 1]
-
-julia> all_triangulations(V)
-2-element Vector{Vector{Vector{Int64}}}:
- [[1, 2, 3], [2, 3, 4]]
- [[1, 2, 4], [1, 3, 4]]
source
all_triangulations(P::Polyhedron)

Compute all triangulations that can be formed using the vertices of the given bounded and full-dimensional polytope P.

The return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.

Examples

julia> c = cube(2,0,1)
-Polyhedron in ambient dimension 2
-
-julia> all_triangulations(c)
-2-element Vector{Vector{Vector{Int64}}}:
- [[1, 2, 3], [2, 3, 4]]
- [[1, 2, 4], [1, 3, 4]]
source
boundary_lattice_pointsMethod
boundary_lattice_points(P::Polyhedron{QQFieldElem})

Return the integer points contained in the boundary of the bounded polyhedron P.

Examples

julia> c = polarize(cube(3))
-Polyhedron in ambient dimension 3
-
-julia> boundary_lattice_points(c)
-6-element SubObjectIterator{PointVector{ZZRingElem}}:
- [-1, 0, 0]
- [0, -1, 0]
- [0, 0, -1]
- [0, 0, 1]
- [0, 1, 0]
- [1, 0, 0]
-
-julia> matrix(ZZ, boundary_lattice_points(c))
-[-1    0    0]
-[ 0   -1    0]
-[ 0    0   -1]
-[ 0    0    1]
-[ 0    1    0]
-[ 1    0    0]
source
inMethod
in(v::AbstractVector, P::Polyhedron)

Check whether the vector v is contained in the polyhedron P.

Examples

The positive orthant only contains vectors with non-negative entries:

julia> PO = polyhedron([-1 0; 0 -1], [0, 0]);
-
-julia> [1, 2] in PO
-true
-
-julia> [1, -2] in PO
-false
source
issubsetMethod
issubset(P::Polyhedron, Q::Polyhedron)

Check whether P is a subset of the polyhedron Q.

Examples

julia> P = cube(3,0,1)
-Polyhedron in ambient dimension 3
-
-julia> Q = cube(3,-1,2)
-Polyhedron in ambient dimension 3
-
-julia> issubset(P, Q)
-true
-
-julia> issubset(Q, P)
-false
source
ehrhart_polynomialMethod
ehrhart_polynomial(P::Polyhedron{QQFieldElem})

Compute the Ehrhart polynomial of P.

Examples

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> ehrhart_polynomial(c)
-8*x^3 + 12*x^2 + 6*x + 1
source
ehrhart_polynomialMethod
ehrhart_polynomial(R::QQMPolyRing, P::Polyhedron{QQFieldElem})

Compute the Ehrhart polynomial of P and return it as a polynomial in R.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over QQ, x)
-
-julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> ehrhart_polynomial(R, c)
-8*x^3 + 12*x^2 + 6*x + 1
source
h_star_polynomialMethod
h_star_polynomial(P::Polyhedron)

Compute the $h^*$ polynomial of P.

Examples

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> h_star_polynomial(c)
-x^3 + 23*x^2 + 23*x + 1
source
h_star_polynomialMethod
h_star_polynomial(R::QQMPolyRing, P::Polyhedron)

Compute the $h^*$ polynomial of P and return it as a polynomial in R.

Examples

julia> R, x = polynomial_ring(QQ, "x")
-(Univariate polynomial ring in x over QQ, x)
-
-julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> h_star_polynomial(R, c)
-x^3 + 23*x^2 + 23*x + 1
source
interior_lattice_pointsMethod
interior_lattice_points(P::Polyhedron{QQFieldElem})

Return the integer points contained in the interior of the bounded polyhedron P.

Examples

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> interior_lattice_points(c)
-1-element SubObjectIterator{PointVector{ZZRingElem}}:
- [0, 0, 0]
-
-julia> matrix(ZZ, interior_lattice_points(c))
-[0   0   0]
source
is_normalMethod
is_normal(P::Polyhedron{QQFieldElem})

Check whether P is normal.

Examples

The 3-cube is normal.

julia> C = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> is_normal(C)
-true

But this pyramid is not:

julia> P = convex_hull([0 0 0; 0 1 1; 1 1 0; 1 0 1]);
-
-julia> is_normal(P)
-false
source
is_simpleMethod
is_simple(P::Polyhedron)

Check whether P is simple.

Examples

julia> c = cube(2,0,1)
-Polyhedron in ambient dimension 2
-
-julia> is_simple(c)
-true
source
is_smoothMethod
is_smooth(P::Polyhedron{QQFieldElem})

Check whether P is smooth.

Examples

A cube is always smooth.

julia> C = cube(8);
-
-julia> is_smooth(C)
-true
source
is_very_ampleMethod
is_very_ample(P::Polyhedron{QQFieldElem})

Check whether P is very ample.

Examples

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> is_very_ample(c)
-true
-
-julia> P = convex_hull([0 0 0; 1 1 0; 1 0 1; 0 1 1])
-Polyhedron in ambient dimension 3
-
-julia> is_very_ample(P)
-false
source
lattice_pointsMethod
lattice_points(P::Polyhedron{QQFieldElem})

Return the integer points contained in the bounded polyhedron P.

Examples

julia> S = 2 * simplex(2);
-
-julia> lattice_points(S)
-6-element SubObjectIterator{PointVector{ZZRingElem}}:
- [0, 0]
- [0, 1]
- [0, 2]
- [1, 0]
- [1, 1]
- [2, 0]
-
-julia> matrix(ZZ, lattice_points(S))
-[0   0]
-[0   1]
-[0   2]
-[1   0]
-[1   1]
-[2   0]
source
lattice_volumeMethod
lattice_volume(P::Polyhedron{QQFieldElem})

Return the lattice volume of P.

Examples

julia> C = cube(2);
-
-julia> lattice_volume(C)
-8
source
normalized_volumeMethod
normalized_volume(P::Polyhedron)

Return the (normalized) volume of P.

Examples

julia> C = cube(2);
-
-julia> normalized_volume(C)
-8
source
polarizeMethod
polarize(P::Polyhedron)

Return the polar dual of the polyhedron P, consisting of all linear functions whose evaluation on P does not exceed 1.

Examples

julia> square = cube(2)
-Polyhedron in ambient dimension 2
-
-julia> P = polarize(square)
-Polyhedron in ambient dimension 2
-
-julia> vertices(P)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 0]
- [-1, 0]
- [0, 1]
- [0, -1]
source
project_fullMethod
project_full(P::Polyhedron)

Project the polyhedron down such that it becomes full dimensional in the new ambient space.

Examples

julia> P = convex_hull([1 0 0; 0 0 0])
-Polyhedron in ambient dimension 3
-
-julia> is_fulldimensional(P)
-false
-
-julia> p = project_full(P)
-Polyhedron in ambient dimension 1
-
-julia> is_fulldimensional(p)
-true
source
print_constraintsMethod
print_constraints(A::AnyVecOrMat, b::AbstractVector; trivial::Bool = false, numbered::Bool = false)

Pretty print the constraints given by $P(A,b) = \{ x | Ax ≤ b \}$.

Trivial inequalities are counted but omitted. They are included if trivial is set to true.

Examples

julia> print_constraints([-1 0 4 5; 4 4 4 3; 1 0 0 0; 0 0 0 0; 0 0 0 0; 9 9 9 9], [0, 1, 2, 3, -4, 5]; numbered = true)
-1: -x₁ + 4*x₃ + 5*x₄ ≦ 0
-2: 4*x₁ + 4*x₂ + 4*x₃ + 3*x₄ ≦ 1
-3: x₁ ≦ 2
-5: 0 ≦ -4
-6: 9*x₁ + 9*x₂ + 9*x₃ + 9*x₄ ≦ 5
-
-julia> print_constraints([-1 0 4 5; 4 4 4 3; 1 0 0 0; 0 0 0 0; 0 0 0 0; 9 9 9 9], [0, 1, 2, 3, -4, 5]; trivial = true)
--x₁ + 4*x₃ + 5*x₄ ≦ 0
-4*x₁ + 4*x₂ + 4*x₃ + 3*x₄ ≦ 1
-x₁ ≦ 2
-0 ≦ 3
-0 ≦ -4
-9*x₁ + 9*x₂ + 9*x₃ + 9*x₄ ≦ 5
source
print_constraintsMethod
print_constraints(P::Polyhedron; trivial::Bool = false, numbered::Bool = false)

Pretty print the constraints given by $P(A,b) = \{ x | Ax ≤ b \}$.

Trivial inequalities are counted but omitted. They are included if trivial is set to true.

Examples

The 3-cube is given by $-1 ≦ x_i ≦ 1 ∀ i ∈ \{1, 2, 3\}$.

julia> print_constraints(cube(3))
--x₁ ≦ 1
-x₁ ≦ 1
--x₂ ≦ 1
-x₂ ≦ 1
--x₃ ≦ 1
-x₃ ≦ 1
source
regular_triangulationsFunction
regular_triangulations(pts::AbstractCollection[PointVector]; full=false)

Compute all regular triangulations on the points given as the rows of pts.

A triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope). Optionally specify full, i.e. that every triangulation must use all points.

The return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.

Examples

julia> c = cube(2,0,1)
-Polyhedron in ambient dimension 2
-
-julia> V = vertices(c)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [1, 0]
- [0, 1]
- [1, 1]
-
-julia> regular_triangulations(V)
-2-element Vector{Vector{Vector{Int64}}}:
- [[1, 2, 3], [2, 3, 4]]
- [[1, 2, 4], [1, 3, 4]]
source
regular_triangulations(P::Polyhedron)

Compute all regular triangulations that can be formed using the vertices of the given bounded and full-dimensional polytope P.

A triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope).

The return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.

Examples

julia> c = cube(2,0,1)
-Polyhedron in ambient dimension 2
-
-julia> regular_triangulations(c)
-2-element Vector{Vector{Vector{Int64}}}:
- [[1, 2, 3], [2, 3, 4]]
- [[1, 2, 4], [1, 3, 4]]
source
regular_triangulationFunction
regular_triangulation(pts::AbstractCollection[PointVector]; full=false)

Computes ONE regular triangulations on the points given as the rows of pts.

A triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope). Optionally specify full, i.e. that every triangulation must use all points.

As for regular_triangulation(pts::AnyVecOrMat; full=false) the return type is Vector{Vector{Vector{Int}}}. Here, only one triangulation is computed, so the outer vector is of length one. Its entry of type Vector{Vector{Int}} encodes the triangulation in question. Recall that a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.

Examples

julia> c = cube(2,0,1)
-Polyhedron in ambient dimension 2
-
-julia> V = vertices(c)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [1, 0]
- [0, 1]
- [1, 1]
-
-julia> regular_triangulation(V)
-1-element Vector{Vector{Vector{Int64}}}:
- [[1, 2, 3], [2, 3, 4]]
source
regular_triangulation(P::Polyhedron)

Computes ONE regular triangulations that can be formed using the vertices of the given bounded and full-dimensional polytope P.

A triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope).

As for regular_triangulations(P::Polyhedron) the return type is Vector{Vector{Vector{Int}}}. Here, only one triangulation is computed, so the outer vector is of length one. Its entry of type Vector{Vector{Int}} encodes the triangulation in question. Recall that a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.

Examples

julia> c = cube(2,0,1)
-Polyhedron in ambient dimension 2
-
-julia> regular_triangulation(c)
-1-element Vector{Vector{Vector{Int64}}}:
- [[1, 2, 3], [2, 3, 4]]
source
secondary_polytopeFunction
secondary_polytope(P::Polyhedron)

Compute the secondary polytope of a polyhedron, i.e. the convex hull of all the gkz vectors of all its (regular) triangulations. A triangulation here means only using the vertices of P.

Examples

Compute the secondary polytope of the cube.

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> sc = secondary_polytope(c)
-Polyhedron in ambient dimension 8
source
solve_ineqMethod
solve_ineq(as::Type{T}, A::ZZMatrix, b::ZZMatrix) where {T}

Solve $Ax<=b$, assumes finite set of solutions.

The output type may be specified in the variable as:

  • ZZMatrix (default) a matrix with integers is returned.
  • SubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.

Examples

The following gives the vertices of the square. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.

julia> A = ZZMatrix([1 0; 0 1; -1 0; 0 -1]);
-
-julia> b = zero_matrix(FlintZZ, 4,1); b[1,1]=1; b[2,1]=1; b[3,1]=0; b[4,1]=0;
-
-julia> sortslices(Matrix{BigInt}(solve_ineq(A, b)), dims=1)
-4×2 Matrix{BigInt}:
- 0  0
- 0  1
- 1  0
- 1  1
-
-julia> typeof(solve_ineq(A,b))
-ZZMatrix
-
-julia> typeof(solve_ineq(ZZMatrix, A,b))
-ZZMatrix
-
-julia> typeof(solve_ineq(SubObjectIterator{PointVector{ZZRingElem}}, A,b))
-SubObjectIterator{PointVector{ZZRingElem}}
source
solve_mixedMethod
solve_mixed(as::Type{T}, A::ZZMatrix, b::ZZMatrix, C::ZZMatrix, d::ZZMatrix) where {T}

Solve $Ax = b$ under $Cx >= d$, assumes a finite solution set.

The output type may be specified in the variable as:

  • ZZMatrix (default) a matrix with integers is returned.
  • SubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.

Examples

Find all $(x_1, x_2)\in\mathbb{Z}^2$ such that $x_1+x_2=7$, $x_1\ge 2$, and $x_2\ge 3$. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.

julia> A = ZZMatrix([1 1]);
-
-julia> b = zero_matrix(FlintZZ, 1,1); b[1,1]=7;
-
-julia> C = ZZMatrix([1 0; 0 1]);
-
-julia> d = zero_matrix(FlintZZ,2,1); d[1,1]=2; d[2,1]=3;
-
-julia> sortslices(Matrix{BigInt}(solve_mixed(A, b, C, d)), dims=1)
-3×2 Matrix{BigInt}:
- 2  5
- 3  4
- 4  3
-
-julia> typeof(solve_mixed(A, b, C, d))
-ZZMatrix
-
-julia> typeof(solve_mixed(ZZMatrix, A, b, C, d))
-ZZMatrix
-
-julia> typeof(solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C, d))
-SubObjectIterator{PointVector{ZZRingElem}}
source
solve_mixedMethod
solve_mixed(as::Type{T}, A::ZZMatrix, b::ZZMatrix, C::ZZMatrix) where {T}

Solve $Ax = b$ under $Cx >= 0$, assumes a finite solution set.

The output type may be specified in the variable as:

  • ZZMatrix (default) a matrix with integers is returned.
  • SubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.

Examples

Find all $(x_1, x_2)\in\mathbb{Z}^2_{\ge 0}$ such that $x_1+x_2=3$. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.

julia> A = ZZMatrix([1 1]);
-
-julia> b = zero_matrix(FlintZZ, 1,1); b[1,1]=3;
-
-julia> C = ZZMatrix([1 0; 0 1]);
-
-julia> sortslices(Matrix{BigInt}(solve_mixed(A, b, C)), dims=1)
-4×2 Matrix{BigInt}:
- 0  3
- 1  2
- 2  1
- 3  0
-
-julia> typeof(solve_mixed(A, b, C))
-ZZMatrix
-
-julia> typeof(solve_mixed(ZZMatrix, A, b, C))
-ZZMatrix
-
-julia> typeof(solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C))
-SubObjectIterator{PointVector{ZZRingElem}}
source
solve_non_negativeMethod
solve_non_negative(as::Type{T}, A::ZZMatrix, b::ZZMatrix) where {T}

Find all solutions to $Ax = b$, $x>=0$. Assumes a finite set of solutions.

The output type may be specified in the variable as:

  • ZZMatrix (default) a matrix with integers is returned.
  • SubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.

Examples

Find all $(x_1, x_2)\in\mathbb{Z}^2_{\ge 0}$ such that $x_1+x_2=3$. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.

julia> A = ZZMatrix([1 1]);
-
-julia> b = zero_matrix(FlintZZ, 1,1); b[1,1]=3;
-
-julia> sortslices(Matrix{BigInt}(solve_non_negative(A, b)), dims=1)
-4×2 Matrix{BigInt}:
- 0  3
- 1  2
- 2  1
- 3  0
-
-julia> typeof(solve_non_negative(A,b))
-ZZMatrix
-
-julia> typeof(solve_non_negative(ZZMatrix, A,b))
-ZZMatrix
-
-julia> typeof(solve_non_negative(SubObjectIterator{PointVector{ZZRingElem}}, A,b))
-SubObjectIterator{PointVector{ZZRingElem}}
source
support_functionMethod
support_function(P::Polyhedron; convention::Symbol = :max)

Produce a function $h(ω) = max\{dot(x,ω)\ |\ x \in P\}$. $max$ may be changed to $min$ by setting convention = :min.

Examples

julia> P = cube(3) + simplex(3);
-
-julia> φ = support_function(P);
-
-julia> φ([1,2,3])
-9
-
-julia> ψ = support_function(P, convention = :min);
-
-julia> ψ([1,2,3])
--6
source
volumeMethod
volume(P::Polyhedron)

Return the (Euclidean) volume of P.

Examples

julia> C = cube(2);
-
-julia> volume(C)
-4
source
diff --git a/previews/PR2578/PolyhedralGeometry/Polyhedra/constructions/index.html b/previews/PR2578/PolyhedralGeometry/Polyhedra/constructions/index.html deleted file mode 100644 index ec3a35702ba0..000000000000 --- a/previews/PR2578/PolyhedralGeometry/Polyhedra/constructions/index.html +++ /dev/null @@ -1,351 +0,0 @@ - -Constructions · Oscar.jl

Constructions

The standard way to define a polyhedron is by either giving a $V$-representation or an $H$-representation. But polyhedra may also be constructed through other means: by name, via operations on other polyhedra, or from other objects in OSCAR.

$H$- and $V$-representations

Intersecting halfspaces: $H$-representation

polyhedronMethod
polyhedron([::Union{Type{T}, Field},] A::AnyVecOrMat, b) where T<:scalar_types

The (convex) polyhedron defined by

\[P(A,b) = \{ x | Ax ≤ b \}.\]

see Def. 3.35 and Section 4.1. of Michael Joswig, Thorsten Theobald (2013)

The first argument either specifies the Type of its coefficients or their parent Field.

Examples

The following lines define the square $[0,1]^2 \subset \mathbb{R}^2$:

julia> A = [1 0; 0 1; -1 0 ; 0 -1];
-
-julia> b = [1, 1, 0, 0];
-
-julia> polyhedron(A,b)
-Polyhedron in ambient dimension 2
source
polyhedronMethod
polyhedron(::Union{Type{T}, Field}, I::Union{Nothing, AbstractCollection[AffineHalfspace]}, E::Union{Nothing, AbstractCollection[AffineHyperplane]} = nothing) where T<:scalar_types

The (convex) polyhedron obtained intersecting the halfspaces I (inequalities) and the hyperplanes E (equations). The first argument either specifies the Type of its coefficients or their parent Field.

Examples

The following lines define the square $[0,1]^2 \subset \mathbb{R}^2$:

julia> A = [1 0; 0 1; -1 0 ; 0 -1];
-
-julia> b = [1, 1, 0, 0];
-
-julia> polyhedron((A,b))
-Polyhedron in ambient dimension 2

As an example for a polyhedron constructed from both inequalities and equations, we construct the polytope $[0,1]\times\{0\}\subset\mathbb{R}^2$

julia> P = polyhedron(([-1 0; 1 0], [0,1]), ([0 1], [0]))
-Polyhedron in ambient dimension 2
-
-julia> is_feasible(P)
-true
-
-julia> dim(P)
-1
-
-julia> vertices(P)
-2-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 0]
- [0, 0]
source

The complete $H$-representation can be retrieved using facets and affine_hull:

julia> P = polyhedron(([-1 0; 1 0], [0,1]), ([0 1], [0]))
-Polyhedron in ambient dimension 2
-
-julia> facets(P)
-2-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^2 described by:
--x₁ ≦ 0
-x₁ ≦ 1
-
-
-julia> affine_hull(P)
-1-element SubObjectIterator{AffineHyperplane{QQFieldElem}} over the Hyperplanes of R^2 described by:
-x₂ = 0
-
-
-julia> Q0 = polyhedron(facets(P))
-Polyhedron in ambient dimension 2
-
-julia> P == Q0
-false
-
-julia> Q1 = polyhedron(facets(P), affine_hull(P))
-Polyhedron in ambient dimension 2
-
-julia> P == Q1
-true

Computing convex hulls: $V$-representation

convex_hullMethod
convex_hull([::Union{Type{T}, Field} = QQFieldElem,] V [, R [, L]]; non_redundant::Bool = false)

Construct the convex hull of the vertices V, rays R, and lineality L. If R or L are omitted, then they are assumed to be zero.

Arguments

  • The first argument either specifies the Type of its coefficients or their

parent Field.

  • V::AbstractCollection[PointVector]: Points whose convex hull is to be computed.
  • R::AbstractCollection[RayVector]: Rays completing the set of points.
  • L::AbstractCollection[RayVector]: Generators of the Lineality space.

If an argument is given as a matrix, its content has to be encoded row-wise.

R can be given as an empty matrix or as nothing if the user wants to compute the convex hull only from V and L.

If it is known that V and R only contain extremal points and that the description of the lineality space is complete, set non_redundant = true to avoid unnecessary redundancy checks.

See Def. 2.11 and Def. 3.1 of Michael Joswig, Thorsten Theobald (2013).

Examples

The following lines define the square $[0,1]^2 \subset \mathbb{R}^2$:

julia> Square = convex_hull([0 0; 0 1; 1 0; 1 1])
-Polyhedron in ambient dimension 2

To construct the positive orthant, rays have to be passed:

julia> V = [0 0];
-
-julia> R = [1 0; 0 1];
-
-julia> PO = convex_hull(V, R)
-Polyhedron in ambient dimension 2

The closed-upper half plane can be constructed by passing rays and a lineality space:

julia> V = [0 0];
-
-julia> R = [0 1];
-
-julia> L = [1 0];
-
-julia> UH = convex_hull(V, R, L)
-Polyhedron in ambient dimension 2

To obtain the x-axis in $\mathbb{R}^2$:

julia> V = [0 0];
-
-julia> R = nothing;
-
-julia> L = [1 0];
-
-julia> XA = convex_hull(V, R, L)
-Polyhedron in ambient dimension 2
source

This is a standard triangle, defined via a (redundant) $V$-representation and its unique minimal $H$-representation:

julia> T = convex_hull([ 0 0 ; 1 0 ; 0 1; 0 1/2 ])
-Polyhedron in ambient dimension 2
-
-julia> halfspace_matrix_pair(facets(T))
-(A = [-1 0; 0 -1; 1 1], b = QQFieldElem[0, 0, 1])
-

The complete $V$-representation can be retrieved using minimal_faces, rays_modulo_lineality and lineality_space:

julia> P = convex_hull([0 0], [1 0], [0 1])
-Polyhedron in ambient dimension 2
-
-julia> Q0 = convex_hull(vertices(P))
-Polyhedron in ambient dimension 2
-
-julia> P == Q0
-false
-
-julia> mfP = minimal_faces(P)
-(base_points = PointVector{QQFieldElem}[[0, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])
-
-julia> rmlP = rays_modulo_lineality(P)
-(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])
-
-julia> Q1 = convex_hull(mfP.base_points, rmlP.rays_modulo_lineality)
-Polyhedron in ambient dimension 2
-
-julia> P == Q1
-false
-
-julia> Q0 == Q1
-false
-
-julia> Q2 = convex_hull(mfP.base_points, rmlP.rays_modulo_lineality, lineality_space(P))
-Polyhedron in ambient dimension 2
-
-julia> P == Q2
-true

Regular polytopes

A polytope is regular, in the strict sense, if it admits a flag-transtive group of (linear) automorphisms. There are three infinite families of regular polytopes which exist in each dimension: the (regular) simplices, cubes and cross polytopes. In addition there are two exceptional regular 3-polytopes (dodecahedron and icosahedron) plus three exceptional regular 4-polytopes (24-cell, 120-cell and 600-cell).

The regular 3-polytopes are also known as the Platonic solids. Here we also list the Archimedean, Catalan and Johnson solids, which form various generalizations of the Platonic solids. However, here we implement "disjoint families", i.e., the proper Archimedean solids exclude the Platonic solids; similarly, the proper Johnson solids exclude the Archmidean solids.

simplexFunction
simplex([::Union{Type{T}, Field} = QQFieldElem,] d::Int [,n])

Construct the simplex which is the convex hull of the standard basis vectors along with the origin in $\mathbb{R}^d$, scaled by $n$. The first argument either specifies the Type of its coefficients or their parent Field.

Examples

Here we take a look at the facets of the 7-simplex and a scaled 7-simplex:

julia> s = simplex(7)
-Polyhedron in ambient dimension 7
-
-julia> facets(s)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^7 described by:
--x₁ ≦ 0
--x₂ ≦ 0
--x₃ ≦ 0
--x₄ ≦ 0
--x₅ ≦ 0
--x₆ ≦ 0
--x₇ ≦ 0
-x₁ + x₂ + x₃ + x₄ + x₅ + x₆ + x₇ ≦ 1
-
-julia> t = simplex(7, 5)
-Polyhedron in ambient dimension 7
-
-julia> facets(t)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^7 described by:
--x₁ ≦ 0
--x₂ ≦ 0
--x₃ ≦ 0
--x₄ ≦ 0
--x₅ ≦ 0
--x₆ ≦ 0
--x₇ ≦ 0
-x₁ + x₂ + x₃ + x₄ + x₅ + x₆ + x₇ ≦ 5
source
cross_polytopeFunction
cross_polytope([::Union{Type{T}, Field} = QQFieldElem,] d::Int [,n])

Construct a $d$-dimensional cross polytope around origin with vertices located at $\pm e_i$ for each unit vector $e_i$ of $R^d$, scaled by $n$. The first argument either specifies the Type of its coefficients or their parent Field.

Examples

Here we print the facets of a non-scaled and a scaled 3-dimensional cross polytope:

julia> C = cross_polytope(3)
-Polyhedron in ambient dimension 3
-
-julia> facets(C)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:
-x₁ + x₂ + x₃ ≦ 1
--x₁ + x₂ + x₃ ≦ 1
-x₁ - x₂ + x₃ ≦ 1
--x₁ - x₂ + x₃ ≦ 1
-x₁ + x₂ - x₃ ≦ 1
--x₁ + x₂ - x₃ ≦ 1
-x₁ - x₂ - x₃ ≦ 1
--x₁ - x₂ - x₃ ≦ 1
-
-julia> D = cross_polytope(3, 2)
-Polyhedron in ambient dimension 3
-
-julia> facets(D)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:
-x₁ + x₂ + x₃ ≦ 2
--x₁ + x₂ + x₃ ≦ 2
-x₁ - x₂ + x₃ ≦ 2
--x₁ - x₂ + x₃ ≦ 2
-x₁ + x₂ - x₃ ≦ 2
--x₁ + x₂ - x₃ ≦ 2
-x₁ - x₂ - x₃ ≦ 2
--x₁ - x₂ - x₃ ≦ 2
source
cubeFunction
cube([::Union{Type{T}, Field} = QQFieldElem,] d::Int , [l::Rational = -1, u::Rational = 1])

Construct the $[l,u]$-cube in dimension $d$. The first argument either specifies the Type of its coefficients or their parent Field.

Examples

In this example the 5-dimensional unit cube is constructed to ask for one of its properties:

julia> C = cube(5,0,1);
-
-julia> normalized_volume(C)
-120
source
tetrahedronFunction
tetrahedron()

Construct the regular tetrahedron, one of the Platonic solids.

source
dodecahedronFunction
dodecahedron()

Construct the regular dodecahedron, one out of two Platonic solids.

source
icosahedronFunction
icosahedron()

Construct the regular icosahedron, one out of two exceptional Platonic solids.

source
platonic_solidFunction
platonic_solid(s)

Construct a Platonic solid with the name given by String s from the list below.

Arguments

  • s::String: The name of the desired Archimedean solid. Possible values:
    • "tetrahedron" : Tetrahedron. Regular polytope with four triangular facets.
    • "cube" : Cube. Regular polytope with six square facets.
    • "octahedron" : Octahedron. Regular polytope with eight triangular facets.
    • "dodecahedron" : Dodecahedron. Regular polytope with 12 pentagonal facets.
    • "icosahedron" : Icosahedron. Regular polytope with 20 triangular facets.

Examples

julia> T = platonic_solid("icosahedron")
-Polyhedron in ambient dimension 3 with EmbeddedElem{nf_elem} type coefficients
-
-julia> nfacets(T)
-20
source
archimedean_solidFunction
archimedean_solid(s)

Construct an Archimedean solid with the name given by String s from the list below. The polytopes are realized with floating point numbers and thus not exact; Vertex-facet-incidences are correct in all cases.

Arguments

  • s::String: The name of the desired Archimedean solid. Possible values:
    • "truncated_tetrahedron" : Truncated tetrahedron. Regular polytope with four triangular and four hexagonal facets.
    • "cuboctahedron" : Cuboctahedron. Regular polytope with eight triangular and six square facets.
    • "truncated_cube" : Truncated cube. Regular polytope with eight triangular and six octagonal facets.
    • "truncated_octahedron" : Truncated Octahedron. Regular polytope with six square and eight hexagonal facets.
    • "rhombicuboctahedron" : Rhombicuboctahedron. Regular polytope with eight triangular and 18 square facets.
    • "truncated_cuboctahedron" : Truncated Cuboctahedron. Regular polytope with 12 square, eight hexagonal and six octagonal facets.
    • "snub_cube" : Snub Cube. Regular polytope with 32 triangular and six square facets. The vertices are realized as floating point numbers. This is a chiral polytope.
    • "icosidodecahedron" : Icosidodecahedon. Regular polytope with 20 triangular and 12 pentagonal facets.
    • "truncated_dodecahedron" : Truncated Dodecahedron. Regular polytope with 20 triangular and 12 decagonal facets.
    • "truncated_icosahedron" : Truncated Icosahedron. Regular polytope with 12 pentagonal and 20 hexagonal facets.
    • "rhombicosidodecahedron" : Rhombicosidodecahedron. Regular polytope with 20 triangular, 30 square and 12 pentagonal facets.
    • "truncated_icosidodecahedron" : Truncated Icosidodecahedron. Regular polytope with 30 square, 20 hexagonal and 12 decagonal facets.
    • "snub_dodecahedron" : Snub Dodecahedron. Regular polytope with 80 triangular and 12 pentagonal facets. The vertices are realized as floating point numbers. This is a chiral polytope.

Examples

julia> T = archimedean_solid("cuboctahedron")
-Polyhedron in ambient dimension 3
-
-julia> sum([nvertices(F) for F in faces(T, 2)] .== 3)
-8
-
-julia> sum([nvertices(F) for F in faces(T, 2)] .== 4)
-6
-
-julia> nfacets(T)
-14
source
johnson_solidFunction
johnson_solid(i::Int)

Construct the i-th proper Johnson solid.

A Johnson solid is a 3-polytope whose facets are regular polygons, of various gonalities. It is proper if it is not an Archimedean solid. Up to scaling there are exactly 92 proper Johnson solids.

source
catalan_solidFunction
catalan_solid(s::String)

Construct a Catalan solid with the name s from the list below. The polytopes are realized with floating point coordinates and thus are not exact. However, vertex-facet-incidences are correct in all cases.

Arguments

  • s::String: The name of the desired Archimedean solid. Possible values:
    • "triakis_tetrahedron" : Triakis Tetrahedron. Dual polytope to the Truncated Tetrahedron, made of 12 isosceles triangular facets.
    • "triakis_octahedron" : Triakis Octahedron. Dual polytope to the Truncated Cube, made of 24 isosceles triangular facets.
    • "rhombic_dodecahedron" : Rhombic dodecahedron. Dual polytope to the cuboctahedron, made of 12 rhombic facets.
    • "tetrakis_hexahedron" : Tetrakis hexahedron. Dual polytope to the truncated octahedron, made of 24 isosceles triangluar facets.
    • "disdyakis_dodecahedron" : Disdyakis dodecahedron. Dual polytope to the truncated cuboctahedron, made of 48 scalene triangular facets.
    • "pentagonal_icositetrahedron" : Pentagonal Icositetrahedron. Dual polytope to the snub cube, made of 24 irregular pentagonal facets. The vertices are realized as floating point numbers.
    • "pentagonal_hexecontahedron" : Pentagonal Hexecontahedron. Dual polytope to the snub dodecahedron, made of 60 irregular pentagonal facets. The vertices are realized as floating point numbers.
    • "rhombic_triacontahedron" : Rhombic triacontahedron. Dual polytope to the icosidodecahedron, made of 30 rhombic facets.
    • "triakis_icosahedron" : Triakis icosahedron. Dual polytope to the icosidodecahedron, made of 30 rhombic facets.
    • "deltoidal_icositetrahedron" : Deltoidal Icositetrahedron. Dual polytope to the rhombicubaoctahedron, made of 24 kite facets.
    • "pentakis_dodecahedron" : Pentakis dodecahedron. Dual polytope to the truncated icosahedron, made of 60 isosceles triangular facets.
    • "deltoidal_hexecontahedron" : Deltoidal hexecontahedron. Dual polytope to the rhombicosidodecahedron, made of 60 kite facets.
    • "disdyakis_triacontahedron" : Disdyakis triacontahedron. Dual polytope to the truncated icosidodecahedron, made of 120 scalene triangular facets.

Examples

julia> T = catalan_solid("triakis_tetrahedron");
-
-julia> count(F -> nvertices(F) == 3, faces(T, 2))
-12
-
-julia> nfacets(T)
-12
source
regular_24_cellFunction
regular_24_cell()

Construct the regular 24-cell, one out of three exceptional regular 4-polytopes.

source
regular_120_cellFunction
regular_120_cell()

Construct the regular 120-cell, one out of three exceptional regular 4-polytopes.

source
regular_600_cellFunction
regular_600_cell()

Construct the regular 600-cell, one out of three exceptional regular 4-polytopes.

source

Other polytope constructions

billera_lee_polytopeFunction
billera_lee_polytope(h::AbstractVector)

Construct a simplicial polytope whose h-vector is $h$. The corresponding g-vector must be an M-sequence. The ambient dimension equals the length of $h$, and the polytope lives in codimension one.

Examples

julia> BL = billera_lee_polytope([1,3,3,1])
-Polyhedron in ambient dimension 4
-
-julia> f_vector(BL)
-3-element Vector{ZZRingElem}:
- 6
- 12
- 8
-
source
birkhoff_polytopeFunction
birkhoff_polytope(n::Integer, even::Bool = false)

Construct the Birkhoff polytope of dimension $n^2$.

This is the polytope of $n \times n$ stochastic matrices (encoded as row vectors of length $n^2$), i.e., the matrices with non-negative real entries whose row and column entries sum up to one. Its vertices are the permutation matrices.

Use even = true to get the vertices only for the even permutation matrices.

Examples

julia> b = birkhoff_polytope(3)
-Polyhedron in ambient dimension 9
-
-julia> vertices(b)
-6-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 0, 0, 0, 1, 0, 0, 0, 1]
- [0, 1, 0, 1, 0, 0, 0, 0, 1]
- [0, 0, 1, 1, 0, 0, 0, 1, 0]
- [1, 0, 0, 0, 0, 1, 0, 1, 0]
- [0, 1, 0, 0, 0, 1, 1, 0, 0]
- [0, 0, 1, 0, 1, 0, 1, 0, 0]
source
cyclic_polytopeFunction
cyclic_polytope(d::Int, n::Int)

Construct the cyclic polytope that is the convex hull of $n$ points on the moment curve in dimension $d$.

Examples

julia> cp = cyclic_polytope(3, 20)
-Polyhedron in ambient dimension 3
-
-julia> nvertices(cp)
-20
source
del_pezzo_polytopeFunction
del_pezzo_polytope(d::Int)

Produce the d-dimensional del Pezzo polytope, which is the convex hull of the cross polytope together with the all-ones and minus all-ones vector.

Examples

julia> DP = del_pezzo_polytope(4)
-Polyhedron in ambient dimension 4
-
-julia> f_vector(DP)
-4-element Vector{ZZRingElem}:
- 10
- 40
- 60
- 30
source
fano_simplexFunction
fano_simplex(d::Int)

Construct a lattice simplex such that the origin is the unique interior lattice point. The normal toric variety associated with its face fan is smooth.

Examples

julia> S = fano_simplex(3)
-Polyhedron in ambient dimension 3
-
-julia> X = normal_toric_variety(face_fan(S))
-Normal toric variety
-
-julia> is_smooth(X)
-true
source
fractional_cut_polytopeFunction
fractional_cut_polytope(G::Graph{Undirected})

Construct the fractional cut polytope of the graph $G$.

Examples

julia> G = complete_graph(4);
-
-julia> fractional_cut_polytope(G)
-Polyhedron in ambient dimension 6
source
fractional_matching_polytopeFunction
fractional_matching_polytope(G::Graph{Undirected})

Construct the fractional matching polytope of the graph $G$.

Examples

julia> G = complete_graph(4);
-
-julia> fractional_matching_polytope(G)
-Polyhedron in ambient dimension 6
source
gelfand_tsetlin_polytopeFunction
gelfand_tsetlin_polytope(lambda::AbstractVector)

Construct the Gelfand-Tsetlin polytope indexed by a weakly decreasing vector lambda.

Examples

julia> P = gelfand_tsetlin_polytope([5,3,2])
-Polyhedron in ambient dimension 6
-
-julia> is_fulldimensional(P)
-false
-
-julia> p = project_full(P)
-Polyhedron in ambient dimension 3
-
-julia> is_fulldimensional(p)
-true
-
-julia> volume(p)
-3
source
gelfand_tsetlin_polytope(lambda::AbstractVector, sigma::PermGroupElem)

Construct the generalized Gelfand-Tsetlin polytope indexed by a weakly decreasing vector lambda and a permutation sigma.

julia> P = gelfand_tsetlin_polytope([5,3,2], @perm (1,3,2))
-Polyhedron in ambient dimension 6
source
newton_polytopeFunction
newton_polytope(poly::Polynomial)

Compute the Newton polytope of the multivariate polynomial poly.

Examples

julia> S, (x, y) = polynomial_ring(ZZ, ["x", "y"])
-(Multivariate polynomial ring in 2 variables over ZZ, ZZMPolyRingElem[x, y])
-
-julia> f = x^3*y + 3x*y^2 + 1
-x^3*y + 3*x*y^2 + 1
-
-julia> NP = newton_polytope(f)
-Polyhedron in ambient dimension 2
-
-julia> vertices(NP)
-3-element SubObjectIterator{PointVector{QQFieldElem}}:
- [3, 1]
- [1, 2]
- [0, 0]
source
orbit_polytopeFunction
orbit_polytope(V::AbstractCollection[PointVector], G::PermGroup)

Construct the convex hull of the orbit of one or several points (given row-wise in V) under the action of G.

Examples

This will construct the $3$-dimensional permutahedron:

julia> V = [1 2 3];
-
-julia> G = symmetric_group(3);
-
-julia> P = orbit_polytope(V, G)
-Polyhedron in ambient dimension 3
-
-julia> vertices(P)
-6-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 2, 3]
- [1, 3, 2]
- [2, 1, 3]
- [2, 3, 1]
- [3, 1, 2]
- [3, 2, 1]
source
perles_nonrational_8_polytopeFunction
perles_nonrational_8_polytope()

Construct an 8-dimensional polytope with 12 vertices which is not combinatorially equivalent to any rational polytope.

Examples

julia> perles_nonrational_8_polytope()
-Polyhedron in ambient dimension 8 with EmbeddedElem{nf_elem} type coefficients
source
rand_spherical_polytopeFunction
rand_spherical_polytope([rng::AbstractRNG,] d::Int, n::Int;
-distribution=:uniform, precision=nothing, seed=nothing)

Construct the convex hull of $n$ points on the unit sphere in $\mathbb{R}^d$. Almost surely this is a simplicial polytope.

Keywords

  • distribution::Symbol: One of the following two options:
    • :uniform (default): Use intermediate floating point numbers for an almost uniform distribution on the sphere. The points will not be exactly on the sphere.
    • :exact: Create exact rational points on the unit sphere, this works at the expense of both uniformity and log-height of the points.
  • precision::Int64: Precision in bits during floating point approximation for uniform distribution.
  • seed::Int64: Seed for random number generation. Cannot be used together with the AbstractRNG argument.

Examples

julia> rsph = rand_spherical_polytope(3, 20)
-Polyhedron in ambient dimension 3
-
-julia> is_simplicial(rsph)
-true
-
-julia> rsph = rand_spherical_polytope(3, 4; precision=5, seed=132)
-Polyhedron in ambient dimension 3
-
-julia> map(x->dot(x,x), vertices(rsph))
-4-element Vector{QQFieldElem}:
- 4306545//4194304
- 15849//16384
- 4165//4096
- 8281//8192
-
-julia> rsph = rand_spherical_polytope(3, 4; distribution=:exact)
-Polyhedron in ambient dimension 3
-
-julia> map(x->dot(x,x), vertices(rsph))
-4-element Vector{QQFieldElem}:
- 1
- 1
- 1
- 1
-
source
rand_subpolytopeFunction
rand_subpolytope(P::Polyhedron, n::Int; seed=nothing)

Construct a subpolytope of $P$ as the convex hull of $n$ vertices, chosen uniformly at random. The polyhedron $P$ must be bounded, and the number $n$ must not exceed the number of vertices.

Keywords

  • seed::Int64: Seed for random number generation.

Examples

julia> nvertices(rand_subpolytope(cube(3), 5))
-5
-
source

Operations on polyhedra

Polyhedra can be produced through operations on other polyhedra. For example, they can be added using Minkowski addition or scaled; each of which results in a new polyhedron.

+Method
+(P::Polyhedron, Q::Polyhedron)

Return the Minkowski sum $P + Q = \{ x+y\ |\ x∈P, y∈Q\}$ of P and Q (see also minkowski_sum).

Examples

The Minkowski sum of a square and the 2-dimensional cross-polytope is an octagon:

julia> P = cube(2);
-
-julia> Q = cross_polytope(2);
-
-julia> M = minkowski_sum(P, Q)
-Polyhedron in ambient dimension 2
-
-julia> nvertices(M)
-8
source
*Method
*(k::Union{Number, FieldElem}, Q::Polyhedron)

Return the scaled polyhedron $kQ = \{ kx\ |\ x∈Q\}$.

Note that k*Q = Q*k.

Examples

Scaling an $n$-dimensional bounded polyhedron by the factor $k$ results in the volume being scaled by $k^n$. This example confirms the statement for the 6-dimensional cube and $k = 2$.

julia> C = cube(6);
-
-julia> SC = 2*C
-Polyhedron in ambient dimension 6
-
-julia> volume(SC)//volume(C)
-64
source
*Method
*(P::Polyhedron, Q::Polyhedron)

Return the Cartesian product of P and Q (see also product).

Examples

The Cartesian product of a triangle and a line segment is a triangular prism.

julia> T=simplex(2)
-Polyhedron in ambient dimension 2
-
-julia> S=cube(1)
-Polyhedron in ambient dimension 1
-
-julia> length(vertices(T*S))
-6
source
bipyramidFunction
bipyramid(P::Polyhedron, z::Union{Number, FieldElem} = 1, z_prime::Union{Number, FieldElem} = -z)

Make a bipyramid over a pointed polyhedron P.

The bipyramid is the convex hull of the input polyhedron P and two apexes (v, z), (v, z_prime) on both sides of the affine span of P. For bounded polyhedra, the projections of the apexes v to the affine span of P is the vertex barycenter of P.

Examples

julia> c = cube(2)
-Polyhedron in ambient dimension 2
-
-julia> vertices(bipyramid(c,2))
-6-element SubObjectIterator{PointVector{QQFieldElem}}:
- [-1, -1, 0]
- [1, -1, 0]
- [-1, 1, 0]
- [1, 1, 0]
- [0, 0, 2]
- [0, 0, -2]
-
source
intersectMethod
intersect(P::Polyhedron...)

Return the intersection $\bigcap\limits_{p \in P} p$.

Examples

The positive orthant of the plane is the intersection of the two halfspaces with $x≥0$ and $y≥0$ respectively.

julia> UH1 = convex_hull([0 0],[1 0],[0 1]);
-
-julia> UH2 = convex_hull([0 0],[0 1],[1 0]);
-
-julia> PO = intersect(UH1, UH2)
-Polyhedron in ambient dimension 2
-
-julia> rays(PO)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [0, 1]
source
pyramidFunction
pyramid(P::Polyhedron, z::Union{Number, FieldElem} = 1)

Make a pyramid over the given polyhedron P.

The pyramid is the convex hull of the input polyhedron P and a point v outside the affine span of P. For bounded polyhedra, the projection of v to the affine span of P coincides with the vertex barycenter of P. The scalar z is the distance between the vertex barycenter and v.

Examples

julia> c = cube(2)
-Polyhedron in ambient dimension 2
-
-julia> vertices(pyramid(c,5))
-5-element SubObjectIterator{PointVector{QQFieldElem}}:
- [-1, -1, 0]
- [1, -1, 0]
- [-1, 1, 0]
- [1, 1, 0]
- [0, 0, 5]
source

The convex hull of two polytopes can be computed via convex_hull.

convex_hullMethod
convex_hull(P::Polyhedron, Q::Polyhedron)

Return the convex_hull of P and Q.

Examples

The convex hull of the following two line segments in $R^3$ is a tetrahedron.

julia> L₁ = convex_hull([-1 0 0; 1 0 0])
-Polyhedron in ambient dimension 3
-
-julia> L₂ = convex_hull([0 -1 0; 0 1 0])
-Polyhedron in ambient dimension 3
-
-julia> T=convex_hull(L₁,L₂);
-
-julia> f_vector(T)
-2-element Vector{ZZRingElem}:
- 4
- 4
source
diff --git a/previews/PR2578/PolyhedralGeometry/Polyhedra/intro/index.html b/previews/PR2578/PolyhedralGeometry/Polyhedra/intro/index.html deleted file mode 100644 index 0f2221b82d3c..000000000000 --- a/previews/PR2578/PolyhedralGeometry/Polyhedra/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Let $\mathbb{F}$ be an ordered field; the default is that $\mathbb{F}=\mathbb{Q}$ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.

A set $P \subseteq \mathbb{F}^n$ is called a (convex) polyhedron if it can be written as the intersection of finitely many closed affine halfspaces in $\mathbb{F}^n$. That is, there exists a matrix $A$ and a vector $b$ such that $P = P(A,b) = \{ x \in \mathbb{F}^n \mid Ax \leq b\}.$ Writing $P$ as above is called an $H$-representation of $P$.

When a polyhedron $P \subset \mathbb{F}^n$ is bounded, it is called a polytope and the fundamental theorem of polytopes states that it may be written as the convex hull of finitely many points. That is $P = \textrm{conv}(p_1,\ldots,p_N), p_i \in \mathbb{F}^n.$ Writing $P$ in this way is called a $V$-representation. Polytopes are necessarily compact, i.e., they form convex bodies.

Each polytope has a unique $V$-representation which is minimal with respect to inclusion (or cardinality). Conversely, a polyhedron which is full-dimensional, has a unique minimal $H$-representation. If the polyhedron is not full-dimensional, then there is no canonical choice of an $H$-representation.

diff --git a/previews/PR2578/PolyhedralGeometry/Polyhedra/polymake/index.html b/previews/PR2578/PolyhedralGeometry/Polyhedra/polymake/index.html deleted file mode 100644 index 1cf7aff1aa30..000000000000 --- a/previews/PR2578/PolyhedralGeometry/Polyhedra/polymake/index.html +++ /dev/null @@ -1,42 +0,0 @@ - -Polyhedron and polymake's Polytope · Oscar.jl

Polyhedron and polymake's Polytope

Many polyhedral computations are done through polymake. polymake (Ewgenij Gawrilow, Michael Joswig (2000), polymake.org) is open source software for research in polyhedral geometry and is attached to Julia via Polymake.jl (Marek Kaluba, Benjamin Lorenz, Sascha Timme (2020), Polymake.jl). This is visible in the structure Polyhedron via a pointer pm_polytope to the corresponding polymake object. Using Polymake.jl one can apply all functionality of polymake to the polymake object hidden behind this pointer.

Sometimes it can be necessary to directly invoke some polymake functions on an OSCAR Polyhedron object (e.g. because some functionality has not yet been made available via OSCAR's interface). In that case, the following two functions allow extracting the underlying Polymake.jl object from a Polyhedron, respectively wrapping a Polymake.jl object representing a polyhedron into a high-level Polyhedron object.

PolyhedronMethod
Polyhedron{T}(P::Polymake.BigObject, F::Field) where T<:scalar_types

Construct a Polyhedron corresponding to a Polymake.BigObject of type Polytope with scalars from Field F.

source

The following shows all the data currently known for a Polyhedron.

julia> C = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> C.pm_polytope
-type: Polytope<Rational>
-description: cube of dimension 3
-
-AFFINE_HULL
-
-
-BOUNDED
-	true
-
-CONE_AMBIENT_DIM
-	4
-
-CONE_DIM
-	4
-
-FACETS
-  1   1   0   0
-  1  -1   0   0
-  1   0   1   0
-  1   0  -1   0
-  1   0   0   1
-  1   0   0  -1
-
-VERTICES_IN_FACETS
-	{0 2 4 6}
-	{1 3 5 7}
-	{0 1 4 5}
-	{2 3 6 7}
-	{0 1 2 3}
-	{4 5 6 7}
-

polymake allows for an interactive visualization of 3-dimensional polytopes in the browser: Polymake.visual(C.pm_polytope).

Warning

There are several design differences between polymake and OSCAR. Polyhedra in polymake and Polymake.jl use homogeneous coordinates. The polyhedra in OSCAR use affine coordinates. Indices in polymake are zero-based, whereas in OSCAR they are one-based.

The next example shows a purely combinatorial construction of a polytope (here: a square). In spite of being given no coordinates, polymake can check for us that this is a simple polytope; i.e., each vertex is contained in dimension many facets.

julia> Q = Polymake.polytope.Polytope(VERTICES_IN_FACETS=[[0,2],[1,3],[0,1],[2,3]]);
-
-julia> Q.SIMPLE
-true
-

However, without coordinates, some operations such as computing the volume cannot work:

julia> Q.VOLUME
-polymake:  WARNING: available properties insufficient to compute 'VOLUME'
-
diff --git a/previews/PR2578/PolyhedralGeometry/cones/index.html b/previews/PR2578/PolyhedralGeometry/cones/index.html deleted file mode 100644 index 04d4e8faeb06..000000000000 --- a/previews/PR2578/PolyhedralGeometry/cones/index.html +++ /dev/null @@ -1,196 +0,0 @@ - -Cones · Oscar.jl

Cones

Introduction

Let $\mathbb{F}$ be an ordered field; the default is that $\mathbb{F}=\mathbb{Q}$ is the field of rational numbers.

A set $C \subseteq \mathbb{F}^n$ is called a (polyhedral) cone if it can be written as the set of nonnegative linear combinations of finitely many vectors in $\mathbb{F}^n$. Equivalently, cones can be written as the intersection of finitely many homogeneous linear inequalities.

Any cone is a special case of a polyhedron. Conversely, intersecting a cone with a suitable affine hyperplane yields a polyhedron whose faces are in bijection with the faces of the cone. Going back and forth between polyhedra and their homogenizations, the cones, is a frequent operation. This is one reason for keeping cones as a distinct type.

Construction

positive_hullMethod
positive_hull([::Union{Type{T}, Field} = QQFieldElem,] R::AbstractCollection[RayVector] [, L::AbstractCollection[RayVector]]; non_redundant::Bool = false) where T<:scalar_types

A polyhedral cone, not necessarily pointed, defined by the positive hull of the rays R, with lineality given by L. The first argument either specifies the Type of its coefficients or their parent Field.

R is given row-wise as representative vectors, with lineality generated by the rows of L, i.e. the cone consists of all positive linear combinations of the rows of R plus all linear combinations of the rows of L.

This is an interior description, analogous to the $V$-representation of a polytope.

Redundant rays are allowed.

Examples

To construct the positive orthant as a Cone, you can write:

julia> R = [1 0; 0 1];
-
-julia> PO = positive_hull(R)
-Polyhedral cone in ambient dimension 2

To obtain the upper half-space of the plane:

julia> R = [0 1];
-
-julia> L = [1 0];
-
-julia> HS = positive_hull(R, L)
-Polyhedral cone in ambient dimension 2
source
cone_from_inequalitiesFunction
cone_from_inequalities([::Union{Type{T}, Field} = QQFieldElem,] I::AbstractCollection[LinearHalfspace] [, E::AbstractCollection[LinearHyperplane]]; non_redundant::Bool = false)

The (convex) cone defined by

\[\{ x | Ix ≤ 0, Ex = 0 \}.\]

Use non_redundant = true if the given description contains no redundant rows to avoid unnecessary redundancy checks. The first argument either specifies the Type of its coefficients or their parent Field.

Examples

julia> C = cone_from_inequalities([0 -1; -1 1])
-Polyhedral cone in ambient dimension 2
-
-julia> rays(C)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [1, 1]
source
cone_from_equationsFunction
cone_from_equations([::Union{Type{T}, Field} = QQFieldElem,] E::AbstractCollection[LinearHyperplane]; non_redundant::Bool = false)

The (convex) cone defined by

\[\{ x | Ex = 0 \}.\]

Use non_redundant = true if the given description contains no redundant rows to avoid unnecessary redundancy checks. The first argument either specifies the Type of its coefficients or their parent Field.

Examples

julia> C = cone_from_equations([1 0 0; 0 -1 1])
-Polyhedral cone in ambient dimension 3
-
-julia> lineality_space(C)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [0, 1, 1]
-
-julia> dim(C)
-1
source
secondary_coneMethod
secondary_cone(SOP::SubdivisionOfPoints)

Return the secondary cone of a subdivision of points, the closure of all the weight vectors inducing the given subdivision of points.

Examples

For a non-regular subdivision, the secondary cone can still contain non-trivial weights, but it will not be full-dimensional.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);
-
-julia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0)
-Subdivision of points in ambient dimension 3
-
-julia> C = secondary_cone(MOAE)
-Polyhedral cone in ambient dimension 6
-
-julia> dim(C)
-4
source

Auxiliary functions

ambient_dimMethod
ambient_dim(C::Cone)

Return the ambient dimension of C.

Examples

The cone C in this example is 2-dimensional within a 3-dimensional ambient space.

julia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);
-
-julia> ambient_dim(C)
-3
source
inMethod
in(v::AbstractVector, C::Cone)

Check whether the vector v is contained in the cone C.

Examples

The positive orthant only contains vectors with non-negative entries:

julia> C = positive_hull([1 0; 0 1]);
-
-julia> [1, 2] in C
-true
-
-julia> [1, -2] in C
-false
source
issubsetMethod
issubset(C0::Cone, C1::Cone)

Check whether C0 is a subset of the cone C1.

Examples

julia> C0 = positive_hull([1 1])
-Polyhedral cone in ambient dimension 2
-
-julia> C1 = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> issubset(C0, C1)
-true
-
-julia> issubset(C1, C0)
-false
source
f_vectorMethod
f_vector(C::Cone)

Compute the vector $(f₁,f₂,...,f_{(dim(C)-1))$` where $f_i$ is the number of faces of $C$ of dimension $i$.

Examples

Take the cone over a square, then the f-vector of the cone is the same as of the square.

julia> C = positive_hull([1 0 0; 1 1 0; 1 1 1; 1 0 1])
-Polyhedral cone in ambient dimension 3
-
-julia> f_vector(C)
-2-element Vector{ZZRingElem}:
- 4
- 4
-
-julia> square = cube(2)
-Polyhedron in ambient dimension 2
-
-julia> f_vector(square)
-2-element Vector{ZZRingElem}:
- 4
- 4
source
hilbert_basisMethod
hilbert_basis(C::Cone{QQFieldElem})

Return the Hilbert basis of a pointed cone C as the rows of a matrix.

Examples

This (non-smooth) cone in the plane has a hilbert basis with three elements.

julia> C = positive_hull([1 0; 1 2])
-A polyhedral cone in ambient dimension 2
-
-julia> matrix(ZZ, hilbert_basis(C))
-[1   0]
-[1   2]
-[1   1]
-
source
codimMethod
codim(C::Cone)

Return the codimension of C.

Examples

The cone C in this example is 2-dimensional within a 3-dimensional ambient space.

julia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);
-
-julia> codim(C)
-1
source
dimMethod
dim(C::Cone)

Return the dimension of C.

Examples

The cone C in this example is 2-dimensional within a 3-dimensional ambient space.

julia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);
-
-julia> dim(C)
-2
source
polarizeMethod
polarize(C::Cone)

Return the polar dual of C, the cone consisting of all those linear functions that evaluate positively on all of C.

Examples

julia> C = positive_hull([1 0; -1 2])
-Polyhedral cone in ambient dimension 2
-
-julia> Cv = polarize(C)
-Polyhedral cone in ambient dimension 2
-
-julia> rays(Cv)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 1//2]
- [0, 1]
source
intersectMethod
intersect(C::Cone...)

Return the intersection $\bigcap\limits_{c \in C} c$.

Examples

julia> C0 = positive_hull([1 0])
-Polyhedral cone in ambient dimension 2
-
-julia> C1 = positive_hull([0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> C01 = intersect(C0, C1)
-Polyhedral cone in ambient dimension 2
-
-julia> rays(C01)
-0-element SubObjectIterator{RayVector{QQFieldElem}}
-
-julia> dim(C01)
-0
source
is_pointedMethod
is_pointed(C::Cone)

Determine whether C is pointed, i.e. whether the origin is a face of C.

Examples

A cone with lineality is not pointed, but a cone only consisting of a single ray is.

julia> C = positive_hull([1 0], [0 1]);
-
-julia> is_pointed(C)
-false
-
-julia> C = positive_hull([1 0]);
-
-julia> is_pointed(C)
-true
source
is_fulldimensionalMethod
is_fulldimensional(C::Cone)

Determine whether C is full-dimensional.

Examples

The cone C in this example is 2-dimensional within a 3-dimensional ambient space.

julia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);
-
-julia> is_fulldimensional(C)
-false
source
lineality_dimMethod
lineality_dim(C::Cone)

Compute the dimension of the lineality space of $C$, i.e. the largest linear subspace contained in $C$.

Examples

A cone is pointed if and only if the dimension of its lineality space is zero.

julia> C = positive_hull([1 0 0; 1 1 0; 1 1 1; 1 0 1])
-Polyhedral cone in ambient dimension 3
-
-julia> is_pointed(C)
-true
-
-julia> lineality_dim(C)
-0
-
-julia> C1 = positive_hull([1 0],[0 1; 0 -1])
-Polyhedral cone in ambient dimension 2
-
-julia> is_pointed(C1)
-false
-
-julia> lineality_dim(C1)
-1
source
lineality_spaceMethod
lineality_space(C::Cone)

Return a basis of the lineality space of C.

Examples

Three rays are used here to construct the upper half-plane. Actually, two of these rays point in opposite directions. This gives us a 1-dimensional lineality.

julia> UH = positive_hull([1 0; 0 1; -1 0]);
-
-julia> lineality_space(UH)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
source
nfacetsMethod
nfacets(C::Cone)

Return the number of facets of a cone C.

Examples

The cone over a square at height one has four facets.

julia> C = positive_hull([1 0 0; 1 1 0; 1 1 1; 1 0 1])
-Polyhedral cone in ambient dimension 3
-
-julia> nfacets(C)
-4
source
nraysMethod
nrays(C::Cone)

Return the number of rays of C.

Examples

Here a cone is constructed from three rays. Calling nrays reveals that one of these was redundant:

julia> R = [1 0; 0 1; 0 2];
-
-julia> PO = positive_hull(R);
-
-julia> nrays(PO)
-2
source
raysMethod
rays(C::Cone)

Return the rays of C.

Examples

Here a cone is constructed from three rays. Calling rays reveals that one of these was redundant:

julia> R = [1 0; 0 1; 0 2];
-
-julia> PO = positive_hull(R);
-
-julia> rays(PO)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [0, 1]

The rays can also be converted to a matrix using the matrix(ring, ...) function. If ring=ZZ the primitive generators of the rays are returned.

julia> R = [1 0; 2 3];
-
-julia> P = positive_hull(R);
-
-julia> rays(P)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [1, 3//2]
-
-julia> matrix(QQ, rays(P))
-[1      0]
-[1   3//2]
-
-julia> matrix(ZZ, rays(P))
-[1   0]
-[2   3]
source
rays_modulo_linealityMethod
rays_modulo_lineality(as, C::Cone)

Return the rays of the cone of C up to lineality as a NamedTuple with two iterators. If C has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of C/L. The iterator lineality_basis gives a basis of the lineality space L.

Examples

For a pointed cone, with two generators, we get the usual rays:

julia> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> rays(C)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [0, 1]
-
-julia> RML = rays_modulo_lineality(C)
-(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0], [0, 1]], lineality_basis = RayVector{QQFieldElem}[])
-
-julia> RML.rays_modulo_lineality
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [0, 1]
-
-julia> RML.lineality_basis
-0-element SubObjectIterator{RayVector{QQFieldElem}}

If the cone has lineality, the second iterator iterates over a basis for the space of lineality. The following example has one generator for the positive hull plus one generator for the lineality space:

julia> C = positive_hull([1 0],[0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> lineality_dim(C)
-1
-
-julia> rays(C)
-0-element SubObjectIterator{RayVector{QQFieldElem}}
-
-julia> RML = rays_modulo_lineality(C)
-(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])
-
-julia> RML.lineality_basis
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [0, 1]
source
diff --git a/previews/PR2578/PolyhedralGeometry/fans/index.html b/previews/PR2578/PolyhedralGeometry/fans/index.html deleted file mode 100644 index c616c370cd81..000000000000 --- a/previews/PR2578/PolyhedralGeometry/fans/index.html +++ /dev/null @@ -1,306 +0,0 @@ - -Polyhedral Fans · Oscar.jl

Polyhedral Fans

Introduction

Let $\mathbb{F}$ be an ordered field; the default is that $\mathbb{F}=\mathbb{Q}$ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.

A nonempty finite collection $\mathcal{F}$ of (polyhedral) cones in $\mathbb{F}^n$, for $n$ fixed, is a (polyhedral) fan if

  • the set $\mathcal{F}$ is closed with respect to taking faces and
  • if $C,D\in\mathcal{F}$ then $C\cap D$ is a face of both, $C$ and $D$.

Construction

To construct a polyhedral fan, you must pass the rays of each cone in the fan, along with an IncidenceMatrix encoding which rays generate which cones.

polyhedral_fanFunction
polyhedral_fan(T, Rays::AbstractCollection[RayVector], LS::Union{AbstractCollection[RayVector], Nothing}, Incidence::IncidenceMatrix) where T<:scalar_types

Assemble a polyhedral fan from ray generators, lineality generators, and an IncidenceMatrix indicating which rays form a cone.

Arguments

  • T: Type or parent Field of scalar to use, defaults to QQFieldElem.
  • Rays::AbstractCollection[RayVector]: Rays generating the cones of the fan; encoded row-wise as representative vectors.
  • LS::AbstractCollection[RayVector]: Contains row-wise generators of the lineality space of the fan. (optional argument)
  • Cones::IncidenceMatrix: An incidence matrix; there is a 1 at position (i,j) if cone i has ray j as extremal ray, and 0 otherwise.

Examples

To obtain the upper half-space of the plane:

julia> R = [1 0; 1 1; 0 1; -1 0; 0 -1];
-
-julia> IM=IncidenceMatrix([[1,2],[2,3],[3,4],[4,5],[1,5]]);
-
-julia> PF=polyhedral_fan(R,IM)
-Polyhedral fan in ambient dimension 2

Polyhedral fan with lineality space:

julia> R = [1 0 0; 0 0 1];
-
-julia> L = [0 1 0];
-
-julia> IM = IncidenceMatrix([[1],[2]]);
-
-julia> PF=polyhedral_fan(R, L, IM)
-Polyhedral fan in ambient dimension 3
-
-julia> lineality_dim(PF)
-1
source
polyhedral_fan(v::AbstractNormalToricVariety)

Return the fan of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor
-
-julia> polyhedral_fan(p2)
-Polyhedral fan in ambient dimension 2
source
polyhedral_fan_from_rays_actionFunction
polyhedral_fan_from_rays_action([::Union{Type{T}, Field} = QQFieldElem,] Rays::AbstractCollection[RayVector], MC_reps::IncidenceMatrix, perms::AbstractVector{PermGroupElem}) where T<:scalar_types

Construct a polyhedral fan with a group action.

Arguments

  • The first argument either specifies the Type of its coefficients or their

parent Field.

  • Rays: The rays of the fan
  • MC_reps: IncidenceMatrix whose rows give the indices of the rays forming representatives of the maximal cones under the group action.
  • perms: A vector of permutations PermGroupElem that form generators of the group acting on the rays of the fan.
source
normal_fanMethod
normal_fan(P::Polyhedron)

Return the normal fan of P. The maximal cones of the normal fan of P are dual to the edge cones at the vertices of P.

Examples

The rays of a normal fan of a cube point in every positive and negative unit direction.

julia> C = cube(3);
-
-julia> NF = normal_fan(C)
-Polyhedral fan in ambient dimension 3
-
-julia> rays(NF)
-6-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0, 0]
- [-1, 0, 0]
- [0, 1, 0]
- [0, -1, 0]
- [0, 0, 1]
- [0, 0, -1]
source
face_fanMethod
face_fan(P::Polyhedron)

Return the face fan of P. The polytope P has to contain the origin, then the maximal cones of the face fan of P are the cones over the facets of P.

Examples

By definition, this bounded polyhedron's number of facets equals the amount of maximal cones of its face fan.

julia> C = cross_polytope(3);
-
-julia> FF = face_fan(C)
-Polyhedral fan in ambient dimension 3
-
-julia> n_maximal_cones(FF) == nfacets(C)
-true
source

Auxiliary functions

ambient_dimMethod
ambient_dim(PF::PolyhedralFan)

Return the ambient dimension PF, which is the dimension of the embedding space.

This is equal to the dimension of the fan if and only if the fan is full-dimensional.

Examples

The normal fan of the 4-cube is embedded in the same ambient space.

julia> ambient_dim(normal_fan(cube(4)))
-4
source
ambient_dim(T::TropicalVariety{M, EMB})
-ambient_dim(T::TropicalCurve{M, EMB})
-ambient_dim(T::TropicalHypersurface{M, EMB})
-ambient_dim(T::TropicalLinearSpace{M, EMB})

Return the ambient dimension of T if it is embedded. Otherwise an error is thrown.

Examples

A tropical hypersurface in $\mathbb{R}^n$ is of ambient dimension n

julia> RR = TropicalSemiring(min);
-
-julia> S,(x,y) = RR["x","y"];
-
-julia> f = x+y+1;
-
-julia> tropicalLine = TropicalHypersurface(f);
-
-julia> ambient_dim(tropicalLine)
-2
source
dimMethod
dim(PF::PolyhedralFan)

Return the dimension of PF.

Examples

This fan in the plane contains a 2-dimensional cone and is thus 2-dimensional itself.

julia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]));
-
-julia> dim(PF)
-2
source
dim(T::TropicalVariety{M, EMB})
-dim(T::TropicalCurve{M, EMB})
-dim(T::TropicalHypersurface{M, EMB})
-dim(T::TropicalLinearSpace{M, EMB})

Return the dimension of T.

Examples

A tropical hypersurface in $\mathbb{R}^n$ is always of dimension n-1

julia> RR = TropicalSemiring(min);
-
-julia> S,(x,y) = RR["x","y"];
-
-julia> f = x+y+1;
-
-julia> tropicalLine = TropicalHypersurface(f);
-
-julia> dim(tropicalLine)
-1
source
f_vectorMethod
f_vector(PF::PolyhedralFan)

Compute the vector $(f₁,f₂,...,f_{dim(PF)-1})$` where $f_i$ is the number of faces of $PF$ of dimension $i$.

Examples

The f-vector of the normal fan of a polytope is the reverse of the f-vector of the polytope.

julia> c = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> f_vector(c)
-3-element Vector{ZZRingElem}:
- 8
- 12
- 6
-
-
-julia> nfc = normal_fan(c)
-Polyhedral fan in ambient dimension 3
-
-julia> f_vector(nfc)
-3-element Vector{ZZRingElem}:
- 6
- 12
- 8
source
f_vector(T::TropicalVariety{M, EMB})
-f_vector(T::TropicalCurve{M, EMB})
-f_vector(T::TropicalHypersurface{M, EMB})
-f_vector(T::TropicalLinearSpace{M, EMB})

Return the f-Vector of T.

Examples

A tropical hypersurface in $\mathbb{R}^n$ is of lineality dimension n

julia> RR = TropicalSemiring(min);
-
-julia> S,(x,y) = RR["x","y"];
-
-julia> f = x+y+1;
-
-julia> tropicalLine = TropicalHypersurface(f);
-
-julia> f_vector(tropicalLine)
-2-element Vector{Int64}:
- 1
- 3
source
is_completeMethod
is_complete(PF::PolyhedralFan)

Determine whether PF is complete, i.e. its support, the set-theoretic union of its cones, covers the whole space.

Examples

Normal fans of polytopes are complete.

julia> is_complete(normal_fan(cube(3)))
-true
source
is_pointedMethod
is_pointed(PF::PolyhedralFan)

Determine whether PF is pointed, i.e. all its cones are pointed.

Examples

The normal fan of a non-fulldimensional polytope is not pointed.

julia> C = convex_hull([0 0; 1 0])
-Polyhedron in ambient dimension 2
-
-julia> is_fulldimensional(C)
-false
-
-julia> nf = normal_fan(C)
-Polyhedral fan in ambient dimension 2
-
-julia> is_pointed(nf)
-false
-
-julia> lineality_dim(nf)
-1
source
is_regularMethod
is_regular(PF::PolyhedralFan)

Determine whether PF is regular, i.e. the normal fan of a polytope.

Examples

This fan is not complete and thus not regular.

julia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]));
-
-julia> is_regular(PF)
-false
source
is_simplicialMethod
is_simplicial(PF::PolyhedralFan)

Determine whether PF is simplicial, i.e. every cone should be generated by a basis of the ambient space.

Examples

The normal_fan of the cube is simplicial, while the face_fan is not.

julia> is_simplicial(normal_fan(cube(3)))
-true
-
-julia> is_simplicial(face_fan(cube(3)))
-false
source
is_simplicial(T::TropicalVariety{M, EMB})
-is_simplicial(T::TropicalCurve{M, EMB})
-is_simplicial(T::TropicalHypersurface{M, EMB})
-is_simplicial(T::TropicalLinearSpace{M, EMB})

Return true if T is a simplicial polyhedral complex, false otherwise.

Examples

A tropical hypersurface in $\mathbb{R}^n$ is of lineality dimension n

julia> RR = TropicalSemiring(min);
-
-julia> S,(x,y) = RR["x","y"];
-
-julia> f = x+y+1;
-
-julia> tropicalLine = TropicalHypersurface(f);
-
-julia> is_simplicial(tropicalLine)
-true
source
is_smoothMethod
is_smooth(PF::PolyhedralFan{QQFieldElem})

Determine whether PF is smooth.

Examples

Even though the cones of this fan cover the positive orthant together, one of these und thus the whole fan is not smooth.

julia> PF = polyhedral_fan([0 1; 2 1; 1 0], IncidenceMatrix([[1, 2], [2, 3]]));
-
-julia> is_smooth(PF)
-false
source
lineality_dimMethod
lineality_dim(PF::PolyhedralFan)

Return the dimension of the lineality space of the polyhedral fan PF, i.e. the dimension of the largest linear subspace.

Examples

The dimension of the lineality space is zero if and only if the fan is pointed.

julia> C = convex_hull([0 0; 1 0])
-Polyhedron in ambient dimension 2
-
-julia> is_fulldimensional(C)
-false
-
-julia> nf = normal_fan(C)
-Polyhedral fan in ambient dimension 2
-
-julia> is_pointed(nf)
-false
-
-julia> lineality_dim(nf)
-1
source
lineality_dim(T::TropicalVariety{M, EMB})
-lineality_dim(T::TropicalCurve{M, EMB})
-lineality_dim(T::TropicalHypersurface{M, EMB})
-lineality_dim(T::TropicalLinearSpace{M, EMB})

Return the dimension of the lineality space of T if it is embedded. Otherwise an error is thrown.

Examples

A tropical hypersurface in $\mathbb{R}^n$ is of lineality dimension n

julia> RR = TropicalSemiring(min);
-
-julia> S,(x,y) = RR["x","y"];
-
-julia> f = x+y;
-
-julia> tropicalAndAffineLine = TropicalHypersurface(f);
-
-julia> lineality_dim(tropicalAndAffineLine)
-1
source
lineality_spaceMethod
lineality_space(PF::PolyhedralFan)

Return a non-redundant matrix whose rows are generators of the lineality space of PF.

Examples

This fan consists of two cones, one containing all the points with $y ≤ 0$ and one containing all the points with $y ≥ 0$. The fan's lineality is the common lineality of these two cones, i.e. in $x$-direction.

julia> PF = polyhedral_fan([1 0; 0 1; -1 0; 0 -1], IncidenceMatrix([[1, 2, 3], [3, 4, 1]]))
-Polyhedral fan in ambient dimension 2
-
-julia> lineality_space(PF)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
source
lineality_space(T::TropicalVariety{M, EMB})
-lineality_space(T::TropicalCurve{M, EMB})
-lineality_space(T::TropicalHypersurface{M, EMB})
-lineality_space(T::TropicalLinearSpace{M, EMB})

Return the lineality space of T if it is embedded. Otherwise an error is thrown.

Examples

A tropical hypersurface in $\mathbb{R}^n$ is of lineality spaceension n

julia> RR = TropicalSemiring(min);
-
-julia> S,(x,y) = RR["x","y"];
-
-julia> f = x+y;
-
-julia> tropicalAndAffineLine = TropicalHypersurface(f);
-
-julia> lineality_space(tropicalAndAffineLine)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [-1, -1]
source
maximal_conesMethod
maximal_cones(PF::PolyhedralFan)

Return the maximal cones of PF.

Examples

Here we ask for the the number of rays for each maximal cone of the face fan of the 3-cube and use that maximal_cones returns an iterator.

julia> PF = face_fan(cube(3));
-
-julia> for c in maximal_cones(PF)
-       println(nrays(c))
-       end
-4
-4
-4
-4
-4
-4
source
conesMethod
cones(PF::PolyhedralFan, cone_dim::Int)

Return an iterator over the cones of PF of dimension cone_dim.

Examples

The 12 edges of the 3-cube correspond to the 2-dimensional cones of its face fan:

julia> PF = face_fan(cube(3));
-
-julia> cones(PF, 2)
-12-element SubObjectIterator{Cone{QQFieldElem}}:
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
- Polyhedral cone in ambient dimension 3
source
conesMethod
cones(PF::PolyhedralFan)

Return the ray indices of all non-zero-dimensional cones in a polyhedral fan.

Examples

julia> PF = face_fan(cube(2))
-Polyhedral fan in ambient dimension 2
-
-julia> cones(PF)
-8×4 IncidenceMatrix
-[1, 3]
-[2, 4]
-[1, 2]
-[3, 4]
-[1]
-[3]
-[2]
-[4]
source
n_maximal_conesMethod
n_maximal_cones(PF::PolyhedralFan)

Return the number of maximal cones of PF.

Examples

The cones given in this construction are non-redundant. Thus there are two maximal cones.

julia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]));
-
-julia> n_maximal_cones(PF)
-2
source
n_conesMethod
n_cones(PF::PolyhedralFan)

Return the number of cones of PF.

Examples

The cones given in this construction are non-redundant. There are six cones in this fan.

julia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]))
-Polyhedral fan in ambient dimension 2
-
-julia> n_cones(PF)
-4
source
nraysMethod
nrays(PF::PolyhedralFan)

Return the number of rays of PF.

Examples

The 3-cube has 8 vertices. Accordingly, its face fan has 8 rays.

julia> nrays(face_fan(cube(3)))
-8
source
raysMethod
rays(PF::PolyhedralFan)

Return the rays of PF.

Examples

The rays of a normal fan of a cube point in every positive and negative unit direction.

julia> C = cube(3);
-
-julia> NF = normal_fan(C);
-
-julia> rays(NF)
-6-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0, 0]
- [-1, 0, 0]
- [0, 1, 0]
- [0, -1, 0]
- [0, 0, 1]
- [0, 0, -1]

As for the Cone, the rays may be converted to a matrix using the matrix(ring, ...) function.

julia> C = cube(3);
-
-julia> NF = normal_fan(C);
-
-julia> matrix(QQ, rays(NF))
-[ 1    0    0]
-[-1    0    0]
-[ 0    1    0]
-[ 0   -1    0]
-[ 0    0    1]
-[ 0    0   -1]
source
rays_modulo_linealityMethod
rays_modulo_lineality(as, F::PolyhedralFan)

Return the rays of the polyhedral fan F up to lineality as a NamedTuple with two iterators. If F has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of F/L. The iterator lineality_basis gives a basis of the lineality space L.

Examples

julia> P = convex_hull(QQFieldElem, [0 0; 1 0])
-Polyhedron in ambient dimension 2
-
-julia> NF = normal_fan(P)
-Polyhedral fan in ambient dimension 2
-
-julia> rmlF = rays_modulo_lineality(NF)
-(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0], [-1, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])
-
-julia> rmlF.rays_modulo_lineality
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
- [-1, 0]
-
-julia> rmlF.lineality_basis
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [0, 1]
-
-julia> rays(NF)
-0-element SubObjectIterator{RayVector{QQFieldElem}}
source
primitive_collectionsMethod
primitive_collections(PF::PolyhedralFan)

Return the primitive collections of a polyhedral fan.

Examples

julia> primitive_collections(normal_fan(simplex(3)))
-1-element Vector{Set{Int64}}:
- Set([4, 2, 3, 1])
source
star_subdivisionMethod
star_subdivision(PF::PolyhedralFan, n::Int)

Return the star subdivision of a polyhedral fan at its n-th torus orbit. Note that this torus orbit need not be maximal. We follow definition 3.3.17 of David A. Cox, John B. Little, Henry K. Schenck (2011).

Examples

julia> star = star_subdivision(normal_fan(simplex(3)), 1)
-Polyhedral fan in ambient dimension 3
-
-julia> rays(star)
-5-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0, 0]
- [0, 1, 0]
- [0, 0, 1]
- [-1, -1, -1]
- [1, 1, 1]
-
-julia> ray_indices(maximal_cones(star))
-6×5 IncidenceMatrix
-[2, 3, 5]
-[1, 3, 5]
-[1, 2, 5]
-[2, 3, 4]
-[1, 3, 4]
-[1, 2, 4]
source
star_subdivisionMethod
star_subdivision(PF::PolyhedralFan, new_ray::AbstractVector{<:IntegerUnion})

Return the star subdivision of a polyhedral fan by a primitive element of the underlying lattice. We follow the definition at the top of page 515 in David A. Cox, John B. Little, Henry K. Schenck (2011).

Examples

julia> fan = normal_fan(simplex(3))
-Polyhedral fan in ambient dimension 3
-
-julia> new_ray = [1, 1, 1];
-
-julia> star = star_subdivision(fan, new_ray)
-Polyhedral fan in ambient dimension 3
-
-julia> rays(star)
-5-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0, 0]
- [0, 1, 0]
- [0, 0, 1]
- [-1, -1, -1]
- [1, 1, 1]
-
-julia> ray_indices(maximal_cones(star))
-6×5 IncidenceMatrix
-[2, 3, 5]
-[1, 3, 5]
-[1, 2, 5]
-[2, 3, 4]
-[1, 3, 4]
-[1, 2, 4]
source
*Method
*(PF1::PolyhedralFan{QQFieldElem}, PF2::PolyhedralFan{QQFieldElem})

Return the Cartesian/direct product of two polyhedral fans.

Examples

julia> normal_fan(simplex(2))*normal_fan(simplex(3))
-Polyhedral fan in ambient dimension 5
source
diff --git a/previews/PR2578/PolyhedralGeometry/intro/index.html b/previews/PR2578/PolyhedralGeometry/intro/index.html deleted file mode 100644 index a708c715fbff..000000000000 --- a/previews/PR2578/PolyhedralGeometry/intro/index.html +++ /dev/null @@ -1,53 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The polyhedral geometry part of OSCAR provides functionality for handling

  • convex polytopes, unbounded polyhedra and cones
  • polyhedral fans
  • linear programs

General textbooks offering details on theory and algorithms include:

Scalar types

The objects from polyhedral geometry operate on a given type, which (usually) resembles a field. This is indicated by the template parameter, e.g. the properties of a Polyhedron{QQFieldElem} are rational numbers of type QQFieldElem, if applicable. Supported scalar types are FieldElem and Float64, but some functionality might not work properly if the parent Field does not satisfy certain mathematic conditions, like being ordered. When constructing a polyhedral object from scratch, for the "simpler" types QQFieldElem and Float64 it suffices to pass the Type, but more complex FieldElems require a parent Field object. This can be set by either passing the desired Field instead of the type, or by inserting the type and have a matching FieldElem in your input data. If no type or field is given, the scalar type defaults to QQFieldElem.

The parent Field of the coefficients of an object O with coefficients of type T can be retrieved with the coefficient_field function, and it holds elem_type(coefficient_field(O)) == T.

coefficient_fieldMethod
coefficient_field(P::Union{Polyhedron{T}, Cone{T}, PolyhedralFan{T}, PolyhedralComplex{T}) where T<:scalar_types

Return the parent Field of the coefficients of P.

Examples

julia> c = cross_polytope(2)
-Polyhedron in ambient dimension 2
-
-julia> coefficient_field(c)
-Rational field
source
Warning

Support for fields other than the rational numbers is currently in an experimental stage.

These three lines result in the same polytope over rational numbers. Besides the general support mentioned above, naming a Field explicitly is encouraged because it allows user control and increases efficiency.

julia> P = convex_hull(QQ, [1 0 0; 0 0 1]) # passing a `Field` always works
-Polyhedron in ambient dimension 3
-
-julia> P == convex_hull(QQFieldElem, [1 0 0; 0 0 1]) # passing the type works for `QQFieldElem` and `Float64` only
-true
-
-julia> P == convex_hull([1 0 0; 0 0 1]) # `Field` defaults to `QQ`
-true
-

Type compatibility

When working in polyhedral geometry it can prove advantageous to have various input formats for the same kind of re-occurring quantitative input information. This example shows three different ways to write the points whose convex hull is to be computed, all resulting in identical Polyhedron objects:

julia> P = convex_hull([1 0 0; 0 0 1])
-Polyhedron in ambient dimension 3
-
-julia> P == convex_hull([[1, 0, 0], [0, 0, 1]])
-true
-
-julia> P == convex_hull(vertices(P))
-true

convex_hull is only one of many functions and constructors supporting this behavior, and there are also more types that can be described this way besides PointVector. Whenever the docs state an argument is required to be of type AbstractCollection[ElType] (where ElType is the Oscar type of single instances described in this collection), the user can choose the input to follow any of the corresponding notions below.

Vectors

While RayVectors can not be used do describe PointVectors (and vice versa), matrices are generally allowed.

AbstractCollection[PointVector] can be given as:

TypeA PointVector corresponds to...
AbstractVector{<:ṔointVector}an element of the vector.
AbstractVector{<:AbstractVector}an element of the vector.
AbstractMatrix/MatElema row of the matrix.
AbstractVector/PointVectorthe vector itself (only one PointVector is described).
SubObjectIterator{<:PointVector}an element of the iterator.

AbstractCollection[RayVector] can be given as:

TypeA RayVector corresponds to...
AbstractVector{<:RayVector}an element of the vector.
AbstractVector{<:AbstractVector}an element of the vector.
AbstractMatrix/MatElema row of the matrix.
AbstractVector/RayVectorthe vector itself (only one RayVector is described).
SubObjectIterator{<:RayVector}an element of the iterator.

Halfspaces and Hyperplanes

These collections allow to mix up affine halfspaces/hyperplanes and their linear counterparts, but note that an error will be produced when trying to convert an affine description with bias not equal to zero to a linear description.

AbstractCollection[LinearHalfspace] can be given as:

TypeA LinearHalfspace corresponds to...
AbstractVector{<:Halfspace}an element of the vector.
AbstractMatrix/MatElem Athe halfspace with normal vector A[i, :].
AbstractVector{<:AbstractVector} Athe halfspace with normal vector A[i].
SubObjectIterator{<:Halfspace}an element of the iterator.

AbstractCollection[LinearHyperplane] can be given as:

TypeA LinearHyperplane corresponds to...
AbstractVector{<:Hyperplane}an element of the vector.
AbstractMatrix/MatElem Athe hyperplane with normal vector A[i, :].
AbstractVector{<:AbstractVector} Athe hyperplane with normal vector A[i].
SubObjectIterator{<:Hyperplane}an element of the iterator.

AbstractCollection[AffineHalfspace] can be given as:

TypeAn AffineHalfspace corresponds to...
AbstractVector{<:Halfspace}an element of the vector.
Tuple over matrix A and vector bthe affine halfspace with normal vector A[i, :] and bias b[i].
SubObjectIterator{<:Halfspace}an element of the iterator.

AbstractCollection[AffineHyperplane] can be given as:

TypeAn AffineHyperplane corresponds to...
AbstractVector{<:Hyperplane}an element of the vector.
Tuple over matrix A and vector bthe affine hyperplane with normal vector A[i, :] and bias b[i].
SubObjectIterator{<:Hyperplane}an element of the iterator.

IncidenceMatrix

Some methods will require input or return output in form of an IncidenceMatrix.

IncidenceMatrixType
 IncidenceMatrix

A matrix with boolean entries. Each row corresponds to a fixed element of a collection of mathematical objects and the same holds for the columns and a second (possibly equal) collection. A 1 at entry (i, j) is interpreted as an incidence between object i of the first collection and object j of the second one.

Examples

Note that the input and print of an IncidenceMatrix lists the non-zero indices for each row.

julia> IM = IncidenceMatrix([[1,2,3],[4,5,6]])
-2×6 IncidenceMatrix
-[1, 2, 3]
-[4, 5, 6]
-
-
-julia> IM[1, 2]
-true
-
-julia> IM[2, 3]
-false
-
-julia> IM[:, 4]
-2-element SparseVectorBool
-[2]
source

From the example it can be seen that this type supports julia's matrix functionality. There are also functions to retrieve specific rows or columns as a Set over the non-zero indices.

rowMethod
 row(i::IncidenceMatrix, n::Int)

Return the indices where the n-th row of i is true, as a Set{Int}.

Examples

julia> IM = IncidenceMatrix([[1,2,3],[4,5,6]])
-2×6 IncidenceMatrix
-[1, 2, 3]
-[4, 5, 6]
-
-
-julia> row(IM, 2)
-Set{Int64} with 3 elements:
-  5
-  4
-  6
source
columnMethod
 column(i::IncidenceMatrix, n::Int)

Return the indices where the n-th column of i is true, as a Set{Int}.

Examples

julia> IM = IncidenceMatrix([[1,2,3],[4,5,6]])
-2×6 IncidenceMatrix
-[1, 2, 3]
-[4, 5, 6]
-
-
-julia> column(IM, 5)
-Set{Int64} with 1 element:
-  2
source

A typical application is the assignment of rays to the cones of a polyhedral fan for its construction, see polyhedral_fan.

Visualization

Lower dimensional polyhedral objects can be visualized through polymake's backend.

visualizeMethod
visualize(P::Union{Polyhedron{T}, Cone{T}, PolyhedralFan{T}, PolyhedralComplex{T}}) where T<:Union{QQFieldElem, Float64}

Visualize a polyhedral object of dimension at most four (in 3-space). In dimensions up to 3 a usual embedding is shown. Four-dimensional polytopes are visualized as a Schlegel diagram, which is a projection onto one of the facets; e.g., see Chapter 5 of Günter M. Ziegler (1995).

In higher dimensions there is no standard method; use projections to lower dimensions or try ideas from Ewgenij Gawrilow, Michael Joswig, Thilo Rörig, Nikolaus Witte (2010).

source

Serialization

Most objects from the polyhedral geometry section can be saved through the polymake interface in the background. These functions are documented in the subsections on the different objects. The format of the files is JSON and you can find details of the specification here.

More details on the serialization, albeit concerning the older XML format, can be found in Ewgenij Gawrilow, Simon Hampe, Michael Joswig (2016). Even though the underlying format changed to JSON, the abstract mathematical structure of the data files is still the same.

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/PolyhedralGeometry/linear_programs/index.html b/previews/PR2578/PolyhedralGeometry/linear_programs/index.html deleted file mode 100644 index 0ec05b6a8270..000000000000 --- a/previews/PR2578/PolyhedralGeometry/linear_programs/index.html +++ /dev/null @@ -1,115 +0,0 @@ - -Linear Programs · Oscar.jl

Linear Programs

Introduction

The purpose of a linear program is to optimize a linear function over a polyhedron.

Constructions

Linear programs are constructed from a polyhedron and a linear objective function which is described by a vector and (optionally) a translation. One can select whether the optimization problem is to maximize or to minimize the objective function.

linear_programFunction
linear_program(P, c; k = 0, convention = :max)

The linear program on the feasible set P (a Polyhedron) with respect to the function x ↦ dot(c,x)+k.

source

Solving a linear program - an example

Let $P=[-1,1]^3$ be the $3$-dimensional cube in $\mathbb{R}^3$, and consider the linear function $\ell$, given by $\ell(x,y,z) = 3x-2y+4z+2$. Minimizing $\ell$ over $P$ can be done by solving the corresponding linear program. Computationally, this means first defining a linear program:

julia> P = cube(3)
-Polyhedron in ambient dimension 3
-
-julia> LP = linear_program(P,[3,-2,4];k=2,convention = :min)
-Linear program
-   min{c⋅x + k | x ∈ P}
-where P is a Polyhedron{QQFieldElem} and
-   c=Polymake.LibPolymake.Rational[3 -2 4]
-   k=2

The information about the linear program LP can be easily extracted.

julia> P = cube(3);
-
-julia> LP = linear_program(P,[3,-2,4];k=2,convention = :min);
-
-julia> c, k = objective_function(LP)
-(QQFieldElem[3, -2, 4], 2)
-
-julia> P == feasible_region(LP)
-true

To solve the optimization problem call solve_lp, which returns a pair m, v where the optimal value is m, and that value is attained at v.

julia> P = cube(3);
-
-julia> LP = linear_program(P,[3,-2,4];k=2,convention = :min);
-
-julia> m, v = solve_lp(LP)
-(-7, QQFieldElem[-1, 1, -1])
-
-julia> ℓ = objective_function(LP; as = :function);
-
-julia> ℓ(v) == convert(QQFieldElem, m)
-true
Infinite solutions

Note that the optimal value may be $\pm\infty$ which currently is well-defined by Polymake.jl, but not with the QQFieldElem number type. Hence manual conversion is necessary, until this issue has been resolved.

The optimal value and an optimal vertex may be obtained individually as well.

julia> P = cube(3);
-
-julia> LP = linear_program(P,[3,-2,4];k=2,convention = :min);
-
-julia> M = optimal_value(LP)
--7
-
-julia> V = optimal_vertex(LP)
-3-element PointVector{QQFieldElem}:
- -1
- 1
- -1

Functions

feasible_regionMethod
feasible_region(lp::LinearProgram)

Return the feasible region of the linear program lp, which is a Polyhedron.

source
objective_functionMethod
objective_function(LP::LinearProgram; as = :pair)

Return the objective function x ↦ dot(c,x)+k of the linear program LP. The allowed values for as are

  • pair: Return the pair (c,k)
  • function: Return the objective function as a function.
source
solve_lpMethod
solve_lp(LP::LinearProgram)

Return a pair (m,v) where the optimal value m of the objective function of LP is attained at v (if m exists). If the optimum is not attained, m may be inf or -inf in which case v is nothing.

source
optimal_valueMethod
optimal_value(LP::LinearProgram)

Return, if it exists, the optimal value of the objective function of LP over the feasible region of LP. Otherwise, return -inf or inf depending on convention.

Examples

The following example constructs a linear program over the three dimensional cube, and obtains the minimal value of the function (x,y,z) ↦ x+2y-3z over that cube.

julia> C=cube(3)
-Polyhedron in ambient dimension 3
-
-julia> LP=linear_program(C,[1,2,-3]; convention = :min)
-Linear program
-   min{c⋅x + k | x ∈ P}
-where P is a Polyhedron{QQFieldElem} and
-   c=Polymake.LibPolymake.Rational[1 2 -3]
-   k=0
-
-julia> optimal_value(LP)
--6
source
optimal_vertexMethod
optimal_vertex(LP::LinearProgram)

Return either a point of the feasible region of LP which optimizes the objective function of LP, or nothing if no such point exists.

Examples

The following example constructs a linear program over the three dimensional cube, and obtains the vertex of the cube which maximizes the function (x,y,z) ↦ x+2y-3z.

julia> C=cube(3)
-Polyhedron in ambient dimension 3
-
-julia> LP=linear_program(C,[1,2,-3])
-Linear program
-   max{c⋅x + k | x ∈ P}
-where P is a Polyhedron{QQFieldElem} and
-   c=Polymake.LibPolymake.Rational[1 2 -3]
-   k=0
-
-julia> optimal_vertex(LP)
-3-element PointVector{QQFieldElem}:
- 1
- 1
- -1
source
load_lpMethod
load_lp(file::String)

Load a (mixed integer) linear program from an .lp file using the LP file format.

source
save_lpMethod
save_lp(target::Union{String, IO}, lp::Union{MixedIntegerLinearProgram,LinearProgram})

Save a (mixed integer) linear program to an .lp file using the LP file format.

Examples

Take the square $[-1/2,3/2]^2$ with objective $[1,1]$ and one integer variable. Print the object in LP format to stdout:

julia> c = cube(2, -1//2, 3//2)
-Polyhedron in ambient dimension 2
-
-julia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])
-Mixed integer linear program
-
-julia> save_lp(stdout, milp)
-MAXIMIZE
-  obj: +1 x1 +1 x2
-Subject To
-  ie0: +2 x1 >= -1
-  ie1: -2 x1 >= -3
-  ie2: +2 x2 >= -1
-  ie3: -2 x2 >= -3
-BOUNDS
-  x1 free
-  x2 free
-GENERAL
-  x1
-END
source
load_mpsMethod
load_mps(file::String)

Load a (mixed integer) linear program from an .mps file using the MPS file format.

source
save_mpsMethod
save_mps(target::String, lp::Union{MixedIntegerLinearProgram,LinearProgram})

Save a (mixed integer) linear program to an .mps file using the MPS file format.

Examples

Create the square $[-1/2,3/2]^2$ with objective $[1,1]$ and one integer variable. Print the object in MPS format to stdout:

julia> c = cube(2, -1//2, 3//2)
-Polyhedron in ambient dimension 2
-
-julia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])
-Mixed integer linear program
-
-julia> save_mps(stdout, milp)
-* Class:	MIP
-* Rows:		5
-* Columns:	2
-* Format:	MPS
-*
-NAME          unnamed#0
-ROWS
- N  C0000000
- G  R0000000
- G  R0000001
- G  R0000002
- G  R0000003
-COLUMNS
-    M0000000  'MARKER'                 'INTORG'
-    x1        C0000000  1                        R0000000  1
-    x1        R0000001  -1                       
-    M0000000  'MARKER'                 'INTEND'
-    x2        C0000000  1                        R0000002  1
-    x2        R0000003  -1                       
-RHS
-    B         R0000000  -0.5                     R0000001  -1.5
-    B         R0000002  -0.5                     R0000003  -1.5
-BOUNDS
- FR BND       x1  
- FR BND       x2  
-ENDATA
source
diff --git a/previews/PR2578/PolyhedralGeometry/mixed_integer_linear_programs/index.html b/previews/PR2578/PolyhedralGeometry/mixed_integer_linear_programs/index.html deleted file mode 100644 index 06bd6d3e416b..000000000000 --- a/previews/PR2578/PolyhedralGeometry/mixed_integer_linear_programs/index.html +++ /dev/null @@ -1,45 +0,0 @@ - -Mixed Integer Linear Programs · Oscar.jl

Mixed Integer Linear Programs

Introduction

The purpose of a mixed integer linear program is to optimize a linear function over a polyhedron, where we require a given subset of the variables to be integers.

Constructions

Mixed integer linear programs are constructed from a polyhedron and a linear objective function which is described by a vector and (optionally) a translation. One can select whether the optimization problem is to maximize or to minimize the objective function. Furthermore one can optionally specify integer_variables, a subset of variables that are required to be integral, given as a set of integers, their respective indices.

mixed_integer_linear_programFunction
mixed_integer_linear_program(P, c; integer_variables = [], k = 0, convention = :max)

The mixed integer linear program on the feasible set P (a Polyhedron) with respect to the function x ↦ dot(c,x)+k, where $x_i\in\mathbb{Z}$ for all $i$ in integer_variables. If integer_variables is empty, or not specified, all entries of x are required to be integral. If this is not intended, consider using a linear_program instead.

source

Functions

optimal_valueMethod
optimal_value(MILP::MixedIntegerLinearProgram)

Return, if it exists, the optimal value of the objective function of MILP over the feasible region of MILP. Otherwise, return -inf or inf depending on convention.

Examples

Take the square $[-1/2,3/2]^2$ and optimize $[1,1]$ in different settings.

julia> c = cube(2, -1//2, 3//2)
-Polyhedron in ambient dimension 2
-
-julia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])
-Mixed integer linear program
-
-julia> optimal_value(milp)
-5/2
-
-julia> milp = mixed_integer_linear_program(c, [1,1])
-Mixed integer linear program
-
-julia> optimal_value(milp)
-2
source
optimal_solutionFunction
optimal_solution(MILP::MixedIntegerLinearProgram)

Return either a point of the feasible region of MILP which optimizes the objective function of MILP, or nothing if no such point exists.

Examples

Take the square $[-1/2,3/2]^2$ and optimize $[1,1]$ in different settings.

julia> c = cube(2, -1//2, 3//2)
-Polyhedron in ambient dimension 2
-
-julia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])
-Mixed integer linear program
-
-julia> optimal_solution(milp)
-2-element PointVector{QQFieldElem}:
- 1
- 3//2
-
-julia> milp = mixed_integer_linear_program(c, [1,1])
-Mixed integer linear program
-
-julia> optimal_solution(milp)
-2-element PointVector{QQFieldElem}:
- 1
- 1
source
solve_milpFunction
solve_milp(MILP::MixedIntegerLinearProgram)

Return a pair (m,v) where the optimal value m of the objective function of MILP is attained at v (if m exists). If the optimum is not attained, m may be inf or -inf in which case v is nothing.

Examples

Take the square $[-1/2,3/2]^2$ and optimize $[1,1]$ in different settings.

julia> c = cube(2, -1//2, 3//2)
-Polyhedron in ambient dimension 2
-
-julia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])
-Mixed integer linear program
-
-julia> solve_milp(milp)
-(5/2, QQFieldElem[1, 3//2])
-
-julia> milp = mixed_integer_linear_program(c, [1,1])
-Mixed integer linear program
-
-julia> solve_milp(milp)
-(2, QQFieldElem[1, 1])
source
diff --git a/previews/PR2578/PolyhedralGeometry/polyhedral_complexes/index.html b/previews/PR2578/PolyhedralGeometry/polyhedral_complexes/index.html deleted file mode 100644 index 9bbb0d97f84a..000000000000 --- a/previews/PR2578/PolyhedralGeometry/polyhedral_complexes/index.html +++ /dev/null @@ -1,251 +0,0 @@ - -Polyhedral Complexes · Oscar.jl

Polyhedral Complexes

Introduction

Let $\mathbb{F}$ be an ordered field; the default is that $\mathbb{F}=\mathbb{Q}$ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.

A nonempty finite collection $\mathcal{P}$ of polyhedra in $\mathbb{F}^n$, for $n$ fixed, is a polyhedral complex if

  • the set $\mathcal{F}$ is closed with respect to taking faces and
  • if $C,D\in\mathcal{F}$ then $C\cap D$ is a face of both $C$ and $D$.

Construction

To construct a polyhedral complex, you must pass points of each polyhedron in the polyhedral complex, such that the polyhedron is the convex hull thereof, along with an IncidenceMatrix encoding which points generate which polyhedron.

polyhedral_complexFunction
polyhedral_complex(::T, polyhedra, vr, far_vertices, L) where T<:scalar_types

Arguments

  • T: Type or parent Field of scalar to use, defaults to QQFieldElem.
  • polyhedra::IncidenceMatrix: An incidence matrix; there is a 1 at position (i,j) if the ith polytope contains point j and 0 otherwise.
  • vr::AbstractCollection[PointVector]: The points whose convex hulls make up the polyhedral complex. This matrix also contains the far vertices.
  • far_vertices::Vector{Int}: Vector containing the indices of the rows corresponding to the far vertices in vr.
  • L::AbstractCollection[RayVector]: Generators of the lineality space of the polyhedral complex.

A polyhedral complex formed from points, rays, and lineality combined into polyhedra indicated by an incidence matrix, where the columns represent the points and the rows represent the polyhedra.

Examples

julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])
-2×4 IncidenceMatrix
-[1, 2, 3]
-[1, 3, 4]
-
-
-julia> vr = [0 0; 1 0; 1 1; 0 1]
-4×2 Matrix{Int64}:
- 0  0
- 1  0
- 1  1
- 0  1
-
-julia> PC = polyhedral_complex(IM, vr)
-Polyhedral complex in ambient dimension 2

Polyhedral complex with rays and lineality:

julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> L = [0 0 1];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices, L)
-Polyhedral complex in ambient dimension 3
-
-julia> lineality_dim(PC)
-1
source

Auxiliary functions

ambient_dimMethod
ambient_dim(PC::PolyhedralComplex)

Return the ambient dimension of PC.

Examples

julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])
-2×4 IncidenceMatrix
-[1, 2, 3]
-[1, 3, 4]
-
-
-julia> V = [0 0; 1 0; 1 1; 0 1]
-4×2 Matrix{Int64}:
- 0  0
- 1  0
- 1  1
- 0  1
-
-julia> PC = polyhedral_complex(IM, V)
-Polyhedral complex in ambient dimension 2
-
-julia> ambient_dim(PC)
-2
source
codimMethod
codim(PC::PolyhedralComplex)

Compute the codimension of a polyhedral complex.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices)
-A polyhedral complex in ambient dimension 2
-
-julia> codim(PC)
-1
source
dimMethod
dim(PC::PolyhedralComplex)

Compute the dimension of the polyhedral complex.

Examples

julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);
-
-julia> VR = [0 0; 1 0; 1 1; 0 1];
-
-julia> PC = polyhedral_complex(IM, VR)
-Polyhedral complex in ambient dimension 2
-
-julia> dim(PC)
-2
source
f_vectorMethod
f_vector(PC::PolyhedralComplex)

Compute the vector $(f₀,f₁,f₂,...,f_{dim(PC))$` where $f_i$ is the number of faces of $PC$ of dimension $i$.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices);
-
-julia> f_vector(PC)
-3-element Vector{Int64}:
- 1
- 3
- 2
source
is_embeddedMethod
is_embedded(PC::PolyhedralComplex)

Return true if PC is embedded, i.e. if its vertices can be computed as a subset of some $\mathbb{R}^n$.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]]);
-
-julia> PC = polyhedral_complex(IM, VR)
-Polyhedral complex in ambient dimension 2
-
-julia> is_embedded(PC)
-true
source
maximal_polyhedraMethod
maximal_polyhedra(PC::PolyhedralComplex)

Return the maximal polyhedra of PC

Examples

julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])
-2×4 IncidenceMatrix
-[1, 2, 3]
-[1, 3, 4]
-
-
-julia> VR = [0 0; 1 0; 1 1; 0 1]
-4×2 Matrix{Int64}:
- 0  0
- 1  0
- 1  1
- 0  1
-
-julia> PC = polyhedral_complex(IM, VR, [2])
-Polyhedral complex in ambient dimension 2
-
-julia> maximal_polyhedra(PC)
-2-element SubObjectIterator{Polyhedron{QQFieldElem}}:
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
source
minimal_facesMethod
minimal_faces(as, PC::PolyhedralComplex)

Return the minimal faces of a polyhedral complex as a NamedTuple with two iterators. For a polyhedral complex without lineality, the base_points are the vertices. If PC has lineality L, then every minimal face is an affine translation p+L, where p is only unique modulo L. The return type is a dict, the key :base_points gives an iterator over such p, and the key :lineality_basis lets one access a basis for the lineality space L of PC.

Examples

julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> L = [0 0 1];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices, L)
-Polyhedral complex in ambient dimension 3
-
-julia> MFPC = minimal_faces(PC)
-(base_points = PointVector{QQFieldElem}[[0, 0, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 0, 1]])
-
-julia> MFPC.base_points
-1-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0, 0]
-
-julia> MFPC.lineality_basis
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [0, 0, 1]
source
n_maximal_polyhedraMethod
n_maximal_polyhedra(PC::PolyhedralComplex)

Return the number of maximal polyhedra of PC

Examples

julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])
-2×4 IncidenceMatrix
-[1, 2, 3]
-[1, 3, 4]
-
-
-julia> VR = [0 0; 1 0; 1 1; 0 1]
-4×2 Matrix{Int64}:
- 0  0
- 1  0
- 1  1
- 0  1
-
-julia> PC = polyhedral_complex(IM, VR, [2])
-Polyhedral complex in ambient dimension 2
-
-julia> n_maximal_polyhedra(PC)
-2
source
npolyhedraMethod
npolyhedra(PC::PolyhedralComplex)

Return the total number of polyhedra in the polyhedral complex PC.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices);
-
-julia> npolyhedra(PC)
-6
source
nraysMethod
nrays(PC::PolyhedralComplex)

Return the number of rays of PC.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices);
-
-julia> nrays(PC)
-3
source
nverticesMethod
nvertices(PC::PolyhedralComplex)

Return the number of vertices of PC.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices);
-
-julia> nvertices(PC)
-1
source
polyhedra_of_dimFunction
polyhedra_of_dim(PC::PolyhedralComplex, polyhedron_dim::Int)

Return the polyhedra of a given dimension in the polyhedral complex PC.

Examples

julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);
-
-julia> VR = [0 0; 1 0; 1 1; 0 1];
-
-julia> PC = polyhedral_complex(IM, VR);
-
-julia> P1s = polyhedra_of_dim(PC,1)
-5-element SubObjectIterator{Polyhedron{QQFieldElem}}:
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
-
-julia> for p in P1s
-       println(dim(p))
-       end
-1
-1
-1
-1
-1
source
raysMethod
rays(PC::PolyhedralComplex)

Return the rays of PC

Examples

julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);
-
-julia> VR = [0 0; 1 0; 1 1; 0 1];
-
-julia> PC = polyhedral_complex(IM, VR, [2])
-Polyhedral complex in ambient dimension 2
-
-julia> rays(PC)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
-
-julia> matrix(QQ, rays(PC))
-[1   0]
source
rays_modulo_linealityMethod
rays_modulo_lineality(as, PC::PolyhedralComplex)

Return the rays of the recession cone of PC up to lineality as a NamedTuple with two iterators. If PC has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of PC/L. The iterator lineality_basis gives a basis of the lineality space L.

Examples

julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-julia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> L = [0 0 1];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices, L)
-Polyhedral complex in ambient dimension 3
-
-julia> RML = rays_modulo_lineality(PC)
-(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0, 0], [0, 1, 0], [-1, 0, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 0, 1]])
-
-julia> RML.rays_modulo_lineality
-3-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0, 0]
- [0, 1, 0]
- [-1, 0, 0]
-
-julia> RML.lineality_basis
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [0, 0, 1]
source
verticesMethod
vertices(T::TropicalVariety{M, EMB})
-vertices(T::TropicalCurve{M, EMB})
-vertices(T::TropicalHypersurface{M, EMB})
-vertices(T::TropicalLinearSpace{M, EMB})

Return the vertices of T, which are points in euclidean space if T is embedded or elements in an ordered set otherwise.

Examples

The vertices of a plane tropical line, plane tropical honeycomb quadric, and plane tropical honeycomb cubic

julia> RR = TropicalSemiring(min);
-
-julia> S,(x,y) = RR["x","y"];
-
-julia> f1 = x+y+1;
-
-julia> tropicalLine = TropicalHypersurface(f1);
-
-julia> vertices(tropicalLine)
-1-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 1]
-
-julia> f2 = 1*x^2+x*y+1*y^2+x+y+1;
-
-julia> tropicalQuadric = TropicalHypersurface(f1);
-
-julia> vertices(tropicalQuadric)
-1-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 1]
-
-julia> f3 = x^3+x*y^2+x^2*y+y^3+x^2+x*y+y^2+x+y+1;
-
-julia> tropicalCubic = TropicalHypersurface(f3);
-
-julia> vertices(tropicalCubic)
-2-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [1, 1]
source
diff --git a/previews/PR2578/PolyhedralGeometry/subdivisions_of_points/index.html b/previews/PR2578/PolyhedralGeometry/subdivisions_of_points/index.html deleted file mode 100644 index 0265c31d0fe9..000000000000 --- a/previews/PR2578/PolyhedralGeometry/subdivisions_of_points/index.html +++ /dev/null @@ -1,114 +0,0 @@ - -Subdivisions of Points · Oscar.jl

Subdivisions of Points

Introduction

Let $\mathbb{F}$ be an ordered field; the default is that $\mathbb{F}=\mathbb{Q}$ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.

A subdivision of points consists of

  • a finite set $\mathcal{P}\subseteq\mathbb{F}^n$ of points; and
  • a finite set of cells $\mathcal{S}\subseteq 2^{\mathcal{P}}$.

The cells are only allowed to intersect in common faces. In contrast to the maximal cones of a polyhedral fan or the maximal polytopes of a polyhedral complex, cells are allowed to have interior points here, i.e. they are not given in terms of their vertices.

Construction

There are two ways to construct a subdivision of points. First, one can specify the cells directly. Second, one can assign a weight or height to every point, take the convex hull and take the cells corresponding to facets visible from below ("lower envelope"). Not every subdivision of points comes from a weight vector, but if it does, it is called regular.

subdivision_of_pointsMethod
subdivision_of_points([f = QQFieldElem,] points, cells)

Arguments

  • f::Union{Type{T}, Field}: either specifies the Type of its coefficients or their

parent Field.

  • points::AbstractCollection[PointVector]: Points generating the cells of the subdivision; encoded row-wise as representative vectors.
  • cells::IncidenceMatrix: An incidence matrix; there is a 1 at position (i,j) if cell i contains point j, and 0 otherwise.

A subdivision of points formed from points and cells made of these points. The cells are given as an IncidenceMatrix, where the columns represent the points and the rows represent the cells.

Examples

The following is the famous "mother of all examples" (MOAE) non-regular triangulation.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);
-
-julia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0)
-Subdivision of points in ambient dimension 3
source
subdivision_of_pointsMethod
subdivision_of_points([f = QQFieldElem,] points, weights)

Arguments

  • f::Union{Type{T}, Field}: either specifies the Type of its coefficients or their

parent Field.

  • points::AbstractCollection[PointVector]: Points generating the cells of the subdivision; encoded row-wise as representative vectors.
  • weights::AbstractVector: A vector with one entry for every point indicating the height of this point.

A subdivision of points formed by placing every point at the corresponding height, then taking the convex hull and then only considering those cells corresponding to faces visible from below ("lower envelope").

Examples

We use the MOAE points, but give a weight vector instead of cells:

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1])
-Subdivision of points in ambient dimension 3
-
-julia> n_maximal_cells(SOP)
-1
source

From a subdivision of points one can construct the secondary_cone(SOP::SubdivisionOfPoints), i.e. the cone that is the closure of the set of all weight vectors realizing that subdivision.

Auxiliary functions

ambient_dimMethod
ambient_dim(SOP::SubdivisionOfPoints)

Return the ambient dimension SOP, which is the dimension of the embedding space.

Examples

The ambient dimension of the MOAE is 3, independent of the subdivision chosen.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);
-
-julia> ambient_dim(SOP)
-3
source
is_regularMethod
is_regular(SOP::SubdivisionOfPoints)

Determine whether SOP is regular, i.e. can be given via a height function.

Examples

This is the so-called "mother of all examples", a very famous non-regular triangulation of six points.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);
-
-julia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0);
-
-julia> is_regular(MOAE)
-false
-
-julia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);
-
-julia> is_regular(SOP)
-true
source
maximal_cellsFunction
maximal_cells(SOP::SubdivisionOfPoints)

Return an iterator over the maximal cells of SOP.

Examples

Display the cells of the "mother of all examples" non-regular triangulation.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2]
-6×3 Matrix{Int64}:
- 4  0  0
- 0  4  0
- 0  0  4
- 2  1  1
- 1  2  1
- 1  1  2
-
-julia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]])
-7×6 IncidenceMatrix
-[4, 5, 6]
-[1, 2, 4]
-[2, 4, 5]
-[2, 3, 5]
-[3, 5, 6]
-[1, 3, 6]
-[1, 4, 6]
-
-
-julia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0);
-
-julia> maximal_cells(MOAE)
-7-element SubObjectIterator{Vector{Int64}}:
- [4, 5, 6]
- [1, 2, 4]
- [2, 4, 5]
- [2, 3, 5]
- [3, 5, 6]
- [1, 3, 6]
- [1, 4, 6]
source
maximal_cells(IncidenceMatrix, SOP::SubdivisionOfPoints)

Return the maximal cells of SOP as an incidence matrix.

The rows of the output correspond to the maximal cells and the columns correspond to the cells.

Examples

If we give all points the same weight there is only one cell containing all points.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2]
-6×3 Matrix{Int64}:
- 4  0  0
- 0  4  0
- 0  0  4
- 2  1  1
- 1  2  1
- 1  1  2
-
-julia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1])
-Subdivision of points in ambient dimension 3
-
-julia> maximal_cells(IncidenceMatrix, SOP)
-1×6 IncidenceMatrix
-[1, 2, 3, 4, 5, 6]
source
min_weightsFunction
min_weights(SOP::SubdivisionOfPoints)

Return the minimal weights inducing a subdivision of points. This method will give an error if the input subdivision is non-regular.

Examples

If all points have the same weight, then the 0-vector is minimal.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);
-
-julia> min_weights(SOP)
-6-element Vector{Int64}:
- 0
- 0
- 0
- 0
- 0
- 0
source
n_maximal_cellsMethod
n_maximal_cells(SOP::SubdivisionOfPoints)

Return the number of maximal cells of SOP.

Examples

If all points have the same weight, there is only one cell.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);
-
-julia> n_maximal_cells(SOP)
-1
source
pointsMethod
points(SOP::SubdivisionOfPoints)

Return the points of the subdivision of points, SOP.

Examples

Display the points of the "mother of all examples" non-regular triangulation.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);
-
-julia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0);
-
-julia> points(MOAE)
-6-element SubObjectIterator{PointVector{QQFieldElem}}:
- [4, 0, 0]
- [0, 4, 0]
- [0, 0, 4]
- [2, 1, 1]
- [1, 2, 1]
- [1, 1, 2]
source
secondary_coneFunction
secondary_cone(SOP::SubdivisionOfPoints)

Return the secondary cone of a subdivision of points, the closure of all the weight vectors inducing the given subdivision of points.

Examples

For a non-regular subdivision, the secondary cone can still contain non-trivial weights, but it will not be full-dimensional.

julia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];
-
-julia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);
-
-julia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0)
-Subdivision of points in ambient dimension 3
-
-julia> C = secondary_cone(MOAE)
-Polyhedral cone in ambient dimension 6
-
-julia> dim(C)
-4
source
diff --git a/previews/PR2578/Rings/integer/index.html b/previews/PR2578/Rings/integer/index.html deleted file mode 100644 index d6239e1c85b2..000000000000 --- a/previews/PR2578/Rings/integer/index.html +++ /dev/null @@ -1,225 +0,0 @@ - -Integers · Oscar.jl

Integers

An important design decision in Oscar.jl is to use Julia as the user language by default. This means that integers typed at the REPL are Julia integers. However, for performance reasons, OSCAR has its own integer format.

Julia has a number of different integer types, but the two that are most relevant here are Int and BigInt. All the Julia integer types belong to Integer.

The Int type is for machine integers which are highly efficient, but can only represent integers up to a certain size, and most basic arithmetic operations are performed unchecked, that is, they can silently overflow. The Int type is the type of literal input such as 12, and should be used for loop control flow, array indices, and other situations where the overflow can be provably avoided.

The BigInt type is backed by GMP multiprecision integers and can represent integers whose size is usually only limited by available memory. While the BigInt type avoids overflow problems, it can be relatively slow in the Int range.

OSCAR currently has the integer type ZZRingElem, which for performance reasons scales internally from machine integers to GMP multiprecision integers.

The ring of integers

Every object in OSCAR representing a mathematical element has a parent. This is an object encoding information about where that element belongs.

The parent of an OSCAR integer is the ring of integers ZZ.

julia> ZZ
-Integer Ring
-

Integer constructors

OSCAR integers are created using ZZ:

julia> ZZ(2)^100
-1267650600228229401496703205376
-
-julia> ZZ(618970019642690137449562111)
-618970019642690137449562111
-

One can also construct the integer $0$ with the empty constructor:

julia> ZZ()
-0
-

The following special constructors are also provided:

  • zero(ZZ)
  • one(ZZ)
julia> zero(ZZ)
-0
-
-julia> one(ZZ)
-1
-

Note that ZZ is not a Julia type, but the above methods of constructing OSCAR integers are similar to the way that Julia integer types can be used to construct Julia integers.

julia> Int(123)
-123
-
-julia> BigInt(123456343567843598776327698374259876295438725)
-123456343567843598776327698374259876295438725
-
-julia> zero(BigInt)
-0
-
-julia> one(Int)
-1
-

Limitations

OSCAR integers have the same limitations as GMP multiprecision integers, namely that they are limited by the available memory on the machine and in any case to signed integers whose absolute value does not exceed $2^{37}$ bits.

Note

The Julia Int type is either a 32 or 64 bit integer, depending on the machine architecture (usually 64 bits on most modern machines). The range of values is machine dependent, but can be found by typing typemin(Int) and typemax(Int) in Julia.

Julia integers in OSCAR functions

For convenience, all basic arithmetic and exact division functions in OSCAR also accept Julia integers. If all of the arguments to an OSCAR function are julia integers, the resulting integers should be julia integers. However, once at least one of the arguments is an ZZRingElem, the function will generally behave as if all integer arguments were promoted to the type ZZRingElem, and the integers in the return generally should also be of type ZZRingElem. For example:

julia> divexact(ZZ(234), 2)
-117
-
-julia> typeof(gcd(4, 6))
-Int64
-
-julia> typeof(gcdx(4, 6))
-Tuple{Int64, Int64, Int64}
-
-julia> typeof(gcd(4, ZZ(6)))
-ZZRingElem
-
-julia> typeof(gcdx(4, ZZ(6)))
-Tuple{ZZRingElem, ZZRingElem, ZZRingElem}
-
-julia> typeof(jacobi_symbol(ZZ(2), ZZ(3)))
-Int64
-

In the first example, 2 is a Julia integer but is still valid in the call to the OSCAR function divexact. In the last example, the exceptional function jacobi_symbol returns an Int as this will always be able to hold the three possible return values of -1, 0, or 1.

Predicates

  • iszero(n::ZZRingElem) -> Bool
  • isone(n::ZZRingElem) -> Bool
  • is_unit(n::ZZRingElem) -> Bool
  • isodd(n::ZZRingElem) -> Bool
  • iseven(n::ZZRingElem) -> Bool
  • is_square(n::ZZRingElem) -> Bool
  • is_prime(n::ZZRingElem) -> Bool
  • is_probable_prime(n::ZZRingElem) -> Bool

The is_prime predicate will prove primality, whereas is_probable_prime may declare a composite number to be prime with very low probability.

Negative numbers, $0$ and $1$ are not considered prime by is_prime and is_probable_prime.

julia> isone(ZZ(1))
-true
-
-julia> is_unit(ZZ(-1))
-true
-
-julia> is_square(ZZ(16))
-true
-
-julia> is_probable_prime(ZZ(23))
-true
-

Properties

  • sign(n::ZZRingElem) -> ZZRingElem

Return the sign of n, i.e. $n/|n|$ if $n \neq 0$, or $0$ otherwise.

julia> sign(ZZ(23))
-1
-
-julia> sign(ZZ(0))
-0
-
-julia> sign(ZZ(-1))
--1
-
  • abs(n::ZZRingElem) -> ZZRingElem

Return the absolute value of $n$, i.e. $n$ if $n \geq 0$ and $-n$ otherwise

julia> abs(ZZ(-3))
-3
-

Basic arithmetic

OSCAR provides the basic arithmetic operations +, - and * and comparison operators ==, !=, <, <=, >, >=, including mixed operations between Julia and OSCAR integers. It also provides division and powering as described below.

Division in OSCAR

OSCAR distinguishes a number of different kinds of division:

These choices have been made for maximum parsimony with the Julia language.

Note

It is a common error to enter 1/2 for the fraction 'one half' in Julia. This expression is reserved for floating point division. Instead, the double slash operator // should be used for fractions.

Exact Division

  • divexact(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem

Return the quotient of $a$ by $b$. The result of the exact division of two integers will always be another integer. Exact division raises an exception if the division is not exact, or if division by zero is attempted.

julia> divexact(ZZ(6), ZZ(3))
-2
-
-julia> divexact(ZZ(6), ZZ(0))
-ERROR: DivideError: integer division error
-
-julia> divexact(ZZ(6), ZZ(5))
-ERROR: ArgumentError: Not an exact division
-
-julia> divexact(ZZ(6), 2)
-3
-

Powering

  • ^(a::ZZRingElem, b::Int) -> ZZRingElem

Return the result of powering $a$ by $b$.

julia> ZZ(37)^37
-10555134955777783414078330085995832946127396083370199442517
-
-julia> ZZ(1)^(-2)
-1
-
Note

An exception will be raised if an integer other than $-1$ or $1$ is raised to a negative exponent.

Note

In Julia 2^-2 is called a literal power. The value returned is a floating point value. To get behaviour that agrees with OSCAR, one can write 2^Int(-2).

The following is allowed for convenience.

julia> ZZ(0)^0
-1
-
Note

In Julia, 2^64 will return zero, as the Julia integer $2$ is a machine integer. In OSCAR, the expression ZZ(2)^64 will return the expected result, just as the Julia equivalent BigInt(2)^64 does.

Euclidean division

The ring of integers is a Euclidean domain and OSCAR provides Euclidean division through the functions divrem, div and rem.

Integer Euclidean division of $a$ by $b$ computes a quotient and remainder such that

a = qb + r

with $|r| < |b|$.

Division with remainder

  • divrem(a::ZZRingElem, b::ZZRingElem) -> (ZZRingElem, ZZRingElem) : division with remainder
  • div(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem : quotient only
  • rem(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem : remainder only

Both rem and divrem compute the remainder $r$ such that when $r \neq 0$ the sign of $r$ is the same as the sign of $a$.

All three functions raise an exception if the modulus $b$ is zero.

julia> divrem(ZZ(5), ZZ(3))
-(1, 2)
-
-julia> div(ZZ(7), ZZ(2))
-3
-
-julia> rem(ZZ(4), ZZ(3))
-1
-
-julia> div(ZZ(2), ZZ(0))
-ERROR: DivideError: integer division error
-
Note

The rem function does not provide a minimal set of representatives, e.g. rem(-2, 3) = -2 but rem(1, 3) = 1.

Modular arithmetic

Modular reduction

  • mod(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem : remainder only

The mod function computes a remainder $r$ such that when $r \neq 0$ the sign of $r$ is the same as the sign of $b$. Thus, if $b > 0$ then mod(a, b) will be in the range $[0, b)$. An exception is raised if the modulus $b$ is zero. This is summarised in the following table.

remainderdivisionsignrounding
remdiv/divremsame as dividendtowards zero
modsame as divisortowards $-\infty$

There is no function implemented to compute the quotient corresponding to the remainder given by mod.

julia> mod(ZZ(4), ZZ(3))
-1
-
-julia> mod(ZZ(2), ZZ(0))
-ERROR: DivideError: integer division error
-

Divisibility testing

  • divides(a::ZZRingElem, b::ZZRingElem) -> (Bool, ZZRingElem)

In OSCAR, we say that $b$ divides $a$ if there exists $c$ in the same ring such that $a = bc$.

The call divides(a, b) returns a tuple (flag, q) where flag is either true if b divides a in which case q will be a quotient, or flag is false if b does not divide a in which case q will be an integer whose value is not defined.

julia> divides(ZZ(6), ZZ(3))
-(true, 2)
-
-julia> divides(ZZ(5), ZZ(2))
-(false, 0)
-

Note that for convenience we define:

julia> divides(ZZ(0), ZZ(0))
-(true, 0)
-

Greatest common divisor

Greatest common divisor

  • gcd(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem

Return the greatest common divisor of its inputs, which is by definition the largest integer dividing the two inputs, unless both inputs are zero in which case it returns zero. The result will always be non-negative and will only be zero if both inputs are zero.

julia> gcd(ZZ(34), ZZ(17))
-17
-
-julia> gcd(ZZ(3), ZZ(0))
-3
-

Extended GCD

  • gcdx(a::ZZRingElem, b::ZZRingElem) -> (ZZRingElem, ZZRingElem, ZZRingElem)

Return a tuple $(g, s, t)$ such that $g$ is the greatest common divisor of $a$ and $b$ and $g = as + bt$. Normally $s$ and $t$ are chosen so that $|s| < |b|/(2g)$ and $|t| < |a|/(2g)$, where this uniquely defines $s$ and $t$. The following cases are handled specially:

  1. if $|a| = |b|$ then $t = b/|b|$
  2. if $b = 0$ or $|b| = 2g$ then $s = a/|a|$
  3. if $a = 0$ or $|a| = 2g$ then $t = b/|b|$

Least common multiple

  • lcm(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem

Return the least common multiple of $a$ and $b$. This is the least positive multiple of $a$ and $b$, unless $a = 0$ or $b = 0$ which case we define the least common multiple to be zero.

julia> lcm(ZZ(6), ZZ(21))
-42
-
-julia> lcm(ZZ(0), ZZ(0))
-0
-

Roots

Square roots

Julia and OSCAR distinguish two kinds of square root:

  • Integer square root (isqrt)
  • Floating point square root (sqrt)

We describe only the first of these here.

  • isqrt(n::ZZRingElem) -> ZZRingElem

Return the floor of the square root of its argument, i.e. the largest integer whose square does not exceed its input. An exception is raised if a negative input is passed.

julia> isqrt(ZZ(16))
-4
-
-julia> isqrt(ZZ(0))
-0
-
-julia> isqrt(ZZ(5))
-2
-
-julia> isqrt(ZZ(-3))
-ERROR: DomainError with -3:
-Argument must be non-negative
-
  • isqrtrem(n::ZZRingElem) -> (ZZRingElem, ZZRingElem)

Return the tuple (s, r) such that $s$ is equal to isqrt(n) and $n = s^2 + r$.

julia> isqrtrem(ZZ(16))
-(4, 0)
-
-julia> isqrtrem(ZZ(5))
-(2, 1)
-

General roots

  • root(a::ZZRingElem, n::Int) -> ZZRingElem

Return an $n$-th root of $a$ or throw an error if it does not exist.

When $n$ is even, the non-negative root is always returned. An exception is raised if $n \leq 0$ or if $n$ is even and $a < 0$.

julia> root(ZZ(16), 4)
-2
-
-julia> root(ZZ(-5), 2)
-ERROR: DomainError with (-5, 2):
-Argument `x` must be positive if exponent `n` is even
-
-julia> root(ZZ(12), -2)
-ERROR: DomainError with -2:
-Exponent must be positive

Conversions

  • Int(n::ZZRingElem) -> Int
  • BigInt(n::ZZRingElem) -> BigInt

Convert the OSCAR integer to the respective Julia integer.

julia> n = ZZ(123)
-123
-
-julia> Int(n)
-123
-
-julia> BigInt(n)
-123
-

In the case of Int, if the OSCAR integer is too large to fit, an exception is raised.

julia> Int(ZZ(12348732648732648763274868732687324))
-ERROR: InexactError: convert(Int64, 12348732648732648763274868732687324)
-
  • fits(::Type{Int}, n::ZZRingElem) -> Bool

Return true if the OSCAR integer will fit in an Int.

julia> fits(Int, ZZ(123))
-true
-
-julia> fits(Int, ZZ(12348732648732648763274868732687324))
-false
-

Factorisation

  • factor(n::ZZRingElem) -> Fac{ZZRingElem}

Return a factorisation of the given integer. The return value is a special factorisation struct which can be manipulated using the functions below.

julia> factor(ZZ(-6000361807272228723606))
--1 * 2 * 229^3 * 43669^3 * 3
-
-julia> factor(ZZ(0))
-ERROR: ArgumentError: Argument is not non-zero
-
  • unit(F::Fac) -> ZZRingElem
julia> F = factor(ZZ(-12))
--1 * 2^2 * 3
-
-julia> unit(F)
--1
-

Factorisation are iterable

Once created, a factorisation is iterable:

julia> F = factor(ZZ(-60))
--1 * 5 * 2^2 * 3
-
-julia> for (p, e) in F; println("$p^$e"); end
-5^1
-2^2
-3^1
-

The pairs (p, e) in a factorisation represent the prime power factors $p^e$ of the non-unit part of the factorisation. They can be placed in an array using collect:

julia> F = factor(ZZ(-60))
--1 * 5 * 2^2 * 3
-
-julia> collect(F)
-3-element Vector{Pair{ZZRingElem, Int64}}:
- 5 => 1
- 2 => 2
- 3 => 1
-

Accessing exponents in a factorisation

One can also determine whether a given prime is in the non-unit part of a factorisation and if so return its exponent. If the exponent of a prime that is not in a factorisation is requested, an exception is raised.

For convenience, a Int can be used instead of an OSCAR integer for this functionality.

julia> F = factor(ZZ(-60))
--1 * 5 * 2^2 * 3
-
-julia> 5 in F
-true
-
-julia> ZZ(3) in F
-true
-
-julia> 7 in F
-false
-
-julia> F[3]
-1
-
-julia> F[ZZ(7)]
-ERROR: 7 is not a factor of -1 * 5 * 2^2 * 3
-

Combinatorial functions

Note

The functions in this section that take Int arguments will return an Int, which may overflow or throw an error. Use the ZZRingElem versions if this is not the desired behaviour.

Factorial

  • factorial(n::ZZRingElem) -> ZZRingElem

Return the factorial of $n$, i.e. $n!$. An exception is raised if $n < 0$. We define $0! = 1$.

  • rising_factorial(x::Int, n::Int) -> Int
  • rising_factorial(x::ZZRingElem, n::Int) -> ZZRingElem
  • rising_factorial(x::ZZRingElem, n::ZZRingElem) -> ZZRingElem

Return $x(x + 1)(x + 2)\ldots(x + n - 1)$. An exception is raised if $n < 0$. We define rising_factorial(x, 0) to be $1$.

julia> factorial(ZZ(30))
-265252859812191058636308480000000
-
-julia> rising_factorial(ZZ(-30), 3)
--24360
-

Primorial

  • primorial(n::Int) -> Int
  • primorial(n::ZZRingElem) -> ZZRingElem

Return the primorial $P(n)$, i.e. the product of all primes less than or equal to $n$. An exception is raised if $n < 0$. We define $P(0) = P(1) = 1$.

julia> primorial(ZZ(100))
-2305567963945518424753102147331756070
-

Bell numbers

  • bell(n::Int) -> Int
  • bell(n::ZZRingElem) -> ZZRingElem

Return the $n$-th Bell number $B(n)$, i.e. the number of ways of partitioning a set of $n$ elements. An exception is raised if $n < 0$.

julia> bell(ZZ(20))
-51724158235372
-

Binomial coefficients

  • binomial(n::ZZRingElem, k::ZZRingElem) -> ZZRingElem

Return the binomial coefficient $\frac{n (n-1) \cdots (n-k+1)}{k!}$ for $k \ge 0$ and returns 0 for k < 0.

Note

Julia already defines the binomial function for Int, which throws an error on overflow.

julia> binomial(ZZ(72), ZZ(15))
-1155454041309504
-

Integer partitions

  • number_of_partitions(n::Int) -> Int
  • number_of_partitions(n::ZZRingElem) -> ZZRingElem

Return the number of integer partitions $p(n)$ of $n$, i.e. the number of distinct ways to write $n$ as a sum of positive integers. Note that $p(0) = 1$, as the empty sum is counted. For $n < 0$ we return zero.

julia> number_of_partitions(ZZ(10^6))
-1471684986358223398631004760609895943484030484439142125334612747351666117418918618276330148873983597555842015374130600288095929387347128232270327849578001932784396072064228659048713020170971840761025676479860846908142829356706929785991290519899445490672219997823452874982974022288229850136767566294781887494687879003824699988197729200632068668735996662273816798266213482417208446631027428001918132198177180646511234542595026728424452592296781193448139994664730105742564359154794989181485285351370551399476719981691459022015599101959601417474075715430750022184895815209339012481734469448319323280150665384042994054179587751761294916248142479998802936507195257074485047571662771763903391442495113823298195263008336489826045837712202455304996382144601028531832004519046591968302787537418118486000612016852593542741980215046267245473237321845833427512524227465399130174076941280847400831542217999286071108336303316298289102444649696805395416791875480010852636774022023128467646919775022348562520747741843343657801534130704761975530375169707999287040285677841619347472368171772154046664303121315630003467104673818
-

Fibonacci sequence

  • fibonacci(n::Int) -> Int
  • fibonacci(n::ZZRingElem) -> ZZRingElem

Return the $n$-th Fibonacci number $F(n)$, defined by the recurrence relation $F(1) = 1$, $F(2) = 1$ and $F(n) = F(n - 1) + F(n - 2)$ for $n \geq 3$. We define $F(0) = 0$ and for $n > 0$ we have $F(-n) = (-1)^{n+1}F(n)$.

julia> fibonacci(ZZ(100))
-354224848179261915075
-
-julia> fibonacci(-2)
--1
-

Number theoretic functionality

Note

The functions in this section that take Int arguments will return a Int, which may overflow or throw an error. Use the ZZRingElem versions if this is not the desired behaviour.

Moebius mu function

  • moebius_mu(n::Int) -> Int
  • moebius_mu(n::ZZRingElem) -> Int

Return the Moebius function $\mu(n)$, which is defined to be $0$ if $n$ is not squarefree and otherwise is defined to be $+1$ or $-1$ if $n$ has an even or odd number of prime factors, respectively. Alternatively, $\mu(n)$ can be defined to be the sum of the primitive $n$-th roots of unity. An exception is raised if $n \leq 0$.

julia> moebius_mu(30)
--1
-

Jacobi symbols

  • jacobi_symbol(m::Int, n::Int) -> Int
  • jacobi_symbol(m::ZZRingElem, n::ZZRingElem) -> Int

Return the Jacobi symbol $\left(\frac{m}{n}\right)$, which is defined for integers $m$ and odd, positive integers $n$. If the factorisation of $n$ is $n = p_1^{i_1}p_2^{i_2}\ldots p_r^{i_r}$ then we define

\[\left(\frac{m}{n}\right) = \left(\frac{m}{p_1}\right)^{i_1}\left(\frac{m}{p_2}\right)^{i_2}\ldots \left(\frac{m}{p_r}\right)^{i_r}\]

where $\left(\frac{m}{p}\right)$ on the right hand side is the Legendre symbol, which is defined for an odd prime number $p$ to be $0$ if $p$ divides $m$ and otherwise $+1$ or $-1$ depending on whether $m$ is a square modulo $p$ or not. An exception is raised if $n$ is even or if $n \leq 0$.

julia> jacobi_symbol(3, 37)
-1
-

Sigma function

  • divisor_sigma(m::Int, n::Int) -> Int
  • divisor_sigma(m::ZZRingElem, n::Int) -> ZZRingElem
  • divisor_sigma(m::ZZRingElem, n::ZZRingElem) -> ZZRingElem

Return the sum of the $n$-th powers of the divisors of $m$

\[\sigma(m, n) = \sum_{d\;|\;m} d^n.\]

If $m \leq 0$ or $n < 0$ we raise an exception.

julia> divisor_sigma(60, 5)
-806220408
-

Euler totient function

  • euler_phi(n::Int) -> Int
  • euler_phi(n::ZZRingElem) -> ZZRingElem

Return the Euler totient function $\varphi(n)$, i.e. the number of positive integers $1 \leq x \leq n$ which are coprime to $n$. Note that $\varphi(1) = 1$. We raise an exception if $n \leq 0$.

julia> euler_phi(200)
-80
-
diff --git a/previews/PR2578/Rings/intro/index.html b/previews/PR2578/Rings/intro/index.html deleted file mode 100644 index 49e84a9bfcb5..000000000000 --- a/previews/PR2578/Rings/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The rings part of OSCAR provides functionality for handling various kinds of rings:

General textbooks offering details on theory and algorithms include:

  • ...

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/Rings/rational/index.html b/previews/PR2578/Rings/rational/index.html deleted file mode 100644 index 3959bb581d4d..000000000000 --- a/previews/PR2578/Rings/rational/index.html +++ /dev/null @@ -1,107 +0,0 @@ - -Rationals · Oscar.jl

Rationals

Fractions are created in Julia with the double slash operator //. If a fraction is created from Julia integers, a Julia fraction results, and if either the numerator or denominator is an OSCAR integer of type ZZRingElem, an OSCAR fraction of type QQFieldElem results.

Julia has its own parameterised type Rational{T} for its own fractions, where T is the integer type of the numerator and denominator, e.g. Rational{Int} and Rational{BigInt}. Unlike with Int, all of the basic arithmetic operations on Julia's Rational{Int} are checked for overflow in the numerator and denominator.

The field of rationals

The parent of an OSCAR rational number is the field of rationals. It can be constructed from the ring of integers ZZ using the fraction_field constructor.

For convenience, QQ is already defined to be the field of rational numbers.

julia> S = fraction_field(ZZ)
-Rational field
-
-julia> QQ
-Rational field
-

Integer constructors

OSCAR rationals can be created using QQ. Two arguments can be passed to specify numerator and denominator. If a single argument is passed, the denominator is set to 1.

For convenience, QQ also accepts Julia integers and rationals, but will always construct an OSCAR rational.

Naturally, Julia's double slash operator can also be used to construct fractions. However, unlike QQ, the double slash operator only constructs an OSCAR rational if either the numerator or denominator is an OSCAR integer.

An exception is raised if a fraction is constructed with denominator zero.

julia> QQ(1, 2)
-1//2
-
-julia> QQ(5)
-5
-
-julia> ZZ(3)//5
-3//5
-
-julia> 1//ZZ(7)
-1//7
-
-julia> QQ(2//3)
-2//3
-
-julia> ZZ(3)//0
-ERROR: DivideError: integer division error
-

One can also construct the rational number $0$ with the empty constructor:

julia> QQ()
-0
-

The following special constructors are also provided:

  • zero(QQ)
  • one(QQ)
julia> zero(QQ)
-0
-
-julia> one(QQ)
-1
-

Predicates

  • iszero(n::QQFieldElem) -> Bool
  • isone(n::QQFieldElem) -> Bool
  • is_unit(n::QQFieldElem) -> Bool

The is_unit function will return true iff $n \neq 0$.

julia> iszero(QQ())
-true
-
-julia> isone(one(QQ))
-true
-
-julia> is_unit(QQ(-2, 3))
-true
-

Properties

  • numerator(n::QQFieldElem) -> ZZRingElem
  • denominator(n::QQFieldElem) -> ZZRingElem

Return the numerator and denominator respectively, of $n$.

  • sign(n::QQFieldElem) -> QQFieldElem

Return the sign of n, i.e. $n/|n|$ if $n \neq 0$, or $0$ otherwise.

julia> sign(QQ(2, 3))
-1
-
-julia> sign(QQ())
-0
-
-julia> sign(QQ(-1))
--1
-
  • abs(n::QQFieldElem) -> QQFieldElem

Return the absolute value of $n$, i.e. $n$ if $n \geq 0$ and $-n$ otherwise.

julia> abs(QQ(-3, 2))
-3//2
-
  • height(n::QQFieldElem) -> ZZRingElem

Return the maximum of the absolute values of the numerator and denominator of $n$.

julia> height(QQ(324987329, -8372492324))
-8372492324
-
  • floor(n::QQFieldElem) -> QQFieldElem

Return the greatest integer $m$ (as a rational number) such that $m \leq n$.

  • ceil(n::QQFieldElem) -> QQFieldElem

Return the least integer $m$ (as a rational number) such that $m \geq n$.

julia> floor(QQ(-2, 3))
--1
-
-julia> ceil(QQ(7, 2))
-4
-
-julia> typeof(ans)
-QQFieldElem
-
-julia> ceil(QQ(5))
-5
-
  • floor(ZZRingElem, n::QQFieldElem) -> ZZRingElem

Return the greatest integer $m$ such that $m \leq n$.

  • ceil(ZZRingElem, n::QQFieldElem) -> ZZRingElem

Return the least integer $m$ such that $m \geq n$.

julia> floor(ZZRingElem, QQ(-2, 3))
--1
-
-julia> ceil(ZZRingElem, QQ(7, 2))
-4
-
-julia> typeof(ans)
-ZZRingElem
-
-julia> ceil(ZZRingElem, QQ(5))
-5
-

Basic arithmetic

OSCAR provides the basic arithmetic operations +, - and * and comparison operators ==, !=, <, <=, >, >=, including mixed operations between Julia and OSCAR rationals and integers.

[Exact Division]

  • divexact(a::QQFieldElem, b::QQFieldElem) -> QQFieldElem
  • divexact(a::QQFieldElem, b::Union{ZZRingElem,Base.Integer,Base.Rational}) -> QQFieldElem
  • divexact(a::Union{ZZRingElem,Base.Integer,Base.Rational}, b::QQFieldElem) -> QQFieldElem

Return the quotient of $a$ by $b$. Exact division raises an exception if division by zero is attempted.

julia> divexact(QQ(2, 3), QQ(3, 5))
-10//9
-
-julia> divexact(QQ(1, 3), ZZ(0))
-ERROR: DivideError: integer division error
-
-julia> divexact(QQ(3, 4), ZZ(5))
-3//20
-
-julia> divexact(ZZ(6), QQ(2, 3))
-9
-
-julia> divexact(QQ(1, 3), 5)
-1//15
-

Powering

  • ^(a::QQFieldElem, b::Int) -> QQFieldElem

Return the result of powering $a$ by $b$.

julia> QQ(5, 7)^32
-23283064365386962890625//1104427674243920646305299201
-
-julia> QQ(1, 2)^(-2)
-4
-

The following is allowed for convenience.

julia> QQ(0)^0
-1
-
Note

In Julia, the rational number $0//1$ when raised to a negative power returns $1//0$ to indicate that the value is undefined. OSCAR raises an exception.

julia> QQ(0)^-2
-ERROR: DivideError: integer division error
-
  • is_power(a::QQFieldElem, b::Int) -> Bool, QQFieldElem

Test if $a$ is an $n$-th power. If so, return true and the root, false and any rational otherwise.

  • is_power(a::QQFieldElem) -> Int, QQFieldElem

Find the largest $n$ such that $a$ is an $n$-th power. Return $n$ and the root.

  • root(a::QQFieldElem, b::Int) -> QQFieldElem

Compute an $n$-th root of $a$, raises an error if $a$ is not an $n$-th power.

julia> is_power(QQ(8), 3)
-(true, 2)
-
-julia> is_power(QQ(8), 2)
-(false, 8)
-
-julia> is_power(QQ(9//16))
-(2, 3//4)
-
-julia> root(QQ(25//9), 2)
-5//3
-
diff --git a/previews/PR2578/StraightLinePrograms/abstractalgebra/index.html b/previews/PR2578/StraightLinePrograms/abstractalgebra/index.html deleted file mode 100644 index ba67916d21b2..000000000000 --- a/previews/PR2578/StraightLinePrograms/abstractalgebra/index.html +++ /dev/null @@ -1,140 +0,0 @@ - -AbstractAlgebra's polynomial interface · Oscar.jl

AbstractAlgebra's polynomial interface

This is the initial API of SLPs which hasn't been updated in a while and might not work as-is with the current state of the package.

Currently, SLPs have a polynomial interface (SLPoly).

Examples

julia> using AbstractAlgebra, StraightLinePrograms, BenchmarkTools;
-
-julia> S = SLPolyRing(zz, [:x, :y]); x, y = gens(S)
-2-element Vector{SLPoly{Int64,SLPolyRing{Int64,AbstractAlgebra.Integers{Int64}}}}:
- x
- y
-
-julia> p = 3 + 2x * y^2 # each line of the SLP is shown with current value
-  #1 = * 2 x    ==>     (2x)
-  #2 = ^ y 2    ==>     y^2
-  #3 = * #1 #2  ==>     (2xy^2)
-  #4 = + 3 #3   ==>     (3 + (2xy^2))
-
-julia> p.cs # constants used in the program
-2-element Vector{Int64}:
- 3
- 2
-
-julia> p.lines # each line is a UInt64 encoding an opcode and 2 arguments
- Line(0x0500000028000001)
- Line(0x8780000020000002)
- Line(0x0500000030000004)
- Line(0x0300000010000005)
-
-julia> SLP.evaluate(p, [2, 3])
-39
-
-julia> p2 = (p*(x*y))^6
-#1 = *  2  x  ==>  (2x)
-#2 = ^  y  2  ==>  y^2
-#3 = * #1 #2  ==>  (2xy^2)
-#4 = +  3 #3  ==>  (3 + (2xy^2))
-#5 = *  x  y  ==>  (xy)
-#6 = * #4 #5  ==>  ((3 + (2xy^2))xy)
-#7 = ^ #6  6  ==>  ((3 + (2xy^2))xy)^6
-
-julia> R, (x1, y1) = polynomial_ring(zz, ["x", "y"]); R
-Multivariate Polynomial Ring in x, y over Integers
-
-julia> q = convert(R, p2)
-64*x^12*y^18+576*x^11*y^16+2160*x^10*y^14+4320*x^9*y^12+4860*x^8*y^10+2916*x^7*y^8+729*x^6*y^6
-
-julia> v = [3, 5]; @btime SLP.evaluate($q, $v)
-  32.101 μs (634 allocations: 45.45 KiB)
--1458502820125772303
-
-julia> @btime SLP.evaluate($p2, $v)
-  270.341 ns (4 allocations: 352 bytes)
--1458502820125772303
-
-julia> res = Int[]; @btime StraightLinePrograms.evaluate!($res, $p2, $v)
-  171.013 ns (0 allocations: 0 bytes)
--1458502820125772303
-
-julia> res # intermediate computations (first 2 elements are constants)
-9-element Vector{Int64}:
-                    3
-                    2
-                    6
-                   25
-                  150
-                  153
-                   15
-                 2295
- -1458502820125772303
-
-julia> f2 = StraightLinePrograms.compile!(p2) # compile to machine code
-#3 (generic function with 1 method)
-
-julia> @btime SLP.evaluate($p2, $v)
-  31.153 ns (1 allocation: 16 bytes)
--1458502820125772303
-
-julia> @btime $f2($v) # use a function barrier for last bit of efficiency
- 7.980 ns (0 allocations: 0 bytes)
--1458502820125772303
-
-julia> q
-64*x^12*y^18+576*x^11*y^16+2160*x^10*y^14+4320*x^9*y^12+4860*x^8*y^10+2916*x^7*y^8+729*x^6*y^6
-
-julia> p3 = convert(S, q) # convert back q::Mpoly to an SLPoly
- #1 = ^    x   6  ==>  x^6
- #2 = ^    x   7  ==>  x^7
- #3 = ^    x   8  ==>  x^8
- #4 = ^    x   9  ==>  x^9
- #5 = ^    x  10  ==>  x^10
- #6 = ^    x  11  ==>  x^11
- #7 = ^    x  12  ==>  x^12
- #8 = ^    y   6  ==>  y^6
- #9 = ^    y   8  ==>  y^8
-#10 = ^    y  10  ==>  y^10
-#11 = ^    y  12  ==>  y^12
-#12 = ^    y  14  ==>  y^14
-#13 = ^    y  16  ==>  y^16
-#14 = ^    y  18  ==>  y^18
-#15 = *   64  #7  ==>  (64x^12)
-#16 = *  #15 #14  ==>  (64x^12y^18)
-#17 = *  576  #6  ==>  (576x^11)
-#18 = *  #17 #13  ==>  (576x^11y^16)
-#19 = +  #16 #18  ==>  ((64x^12y^18) + (576x^11y^16))
-#20 = * 2160  #5  ==>  (2160x^10)
-#21 = *  #20 #12  ==>  (2160x^10y^14)
-#22 = +  #19 #21  ==>  ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14))
-#23 = * 4320  #4  ==>  (4320x^9)
-#24 = *  #23 #11  ==>  (4320x^9y^12)
-#25 = +  #22 #24  ==>  ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12))
-#26 = * 4860  #3  ==>  (4860x^8)
-#27 = *  #26 #10  ==>  (4860x^8y^10)
-#28 = +  #25 #27  ==>  ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12) + (4860x^8y^10))
-#29 = * 2916  #2  ==>  (2916x^7)
-#30 = *  #29  #9  ==>  (2916x^7y^8)
-#31 = +  #28 #30  ==>  ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12) + (4860x^8y^10) + (2916x^7y^8))
-#32 = *  729  #1  ==>  (729x^6)
-#33 = *  #32  #8  ==>  (729x^6y^6)
-#34 = +  #31 #33  ==>  ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12) + (4860x^8y^10) + (2916x^7y^8) + (729x^6y^6))
-
-julia> @btime SLP.evaluate($p3, $v)
-  699.465 ns (5 allocations: 1008 bytes)
--1458502820125772303
-
-julia> @time f3 = StraightLinePrograms.compile!(p3);
-  0.002830 seconds (1.40 k allocations: 90.930 KiB)
-
-julia> @btime $f3($v)
- 80.229 ns (0 allocations: 0 bytes)
--1458502820125772303
-
-julia> p4 = convert(S, q, limit_exp=true); # use different encoding
-
-julia> @btime SLP.evaluate($p4, $v)
-  766.864 ns (5 allocations: 1008 bytes)
--1458502820125772303
-
-julia> @time f4 = StraightLinePrograms.compile!(p4);
-  0.002731 seconds (1.74 k allocations: 108.676 KiB)
-
-julia> @btime $f4($v)
-  11.781 ns (0 allocations: 0 bytes)
--1458502820125772303
diff --git a/previews/PR2578/StraightLinePrograms/gapslps/index.html b/previews/PR2578/StraightLinePrograms/gapslps/index.html deleted file mode 100644 index c9c69ddcf783..000000000000 --- a/previews/PR2578/StraightLinePrograms/gapslps/index.html +++ /dev/null @@ -1,91 +0,0 @@ - -GAP's SLPs · Oscar.jl

GAP's SLPs

There are two other available SLP types: GAPSLProgram and AtlasSLProgram, and related GAPSLDecision and AtlasSLDecision, which are constructed similarly as in GAP:

julia> prg = GAPSLProgram( [ [1,2,2,3], [3,-1] ], 2 )
-# input:
-r = [ g1, g2 ]
-# program:
-r[3] = r[1]^2*r[2]^3
-r[4] = r[3]^-1
-# return value:
-r[4]
-
-julia> SLP.evaluate(prg, [perm1, perm2])
-(1,3,4,2)
-
-julia> SLP.evaluate(prg, [x, y])
-#1 = ^  x  2  ==>  x^2
-#2 = ^  y  3  ==>  y^3
-#3 = * #1 #2  ==>  (x^2y^3)
-#4 = ^ #3 -1  ==>  (x^2y^3)^-1
-return: #4
-
-julia> SLProgram(prg) # direct compilation (with room for optimizations obviously)
-#1 =    x     ==>  x
-#2 =    y     ==>  y
-#3 = ^ #1  2  ==>  x^2
-#4 = ^ #2  3  ==>  y^3
-#5 = * #3 #4  ==>  (x^2y^3)
-#3 =   #5     ==>  (x^2y^3)
-keep: #1..#3
-#4 = ^ #3 -1  ==>  (x^2y^3)^-1
-keep: #1..#4
-return: #4
-
-julia> GAPSLProgram( [ [2,3], [ [3,1,1,4], [1,2,3,1] ] ], 2 )
-# input:
-r = [ g1, g2 ]
-# program:
-r[3] = r[2]^3
-# return values:
-[ r[3]*r[1]^4, r[1]^2*r[3] ]
-
-julia> GAPSLDecision([ [ [ 1, 1, 2, 1 ], 3 ], [ "Order", 1, 2 ], [ "Order", 2, 3 ], [ "Order", 3, 5 ] ] )
-# input:
-r = [ g1, g2 ]
-# program:
-r[3] = r[1]*r[2]
-order( r[1] ) == 2 || return false
-order( r[2] ) == 3 || return false
-order( r[3] ) == 5 || return false
-# return value:
-true
-
-julia> SLProgram(ans)
-#1 =    x     ==>  x
-#2 =    y     ==>  y
-#3 = * #1 #2  ==>  (xy)
-keep: #1..#3
-test: order(#1) == 2 || return false
-test: order(#2) == 3 || return false
-test: order(#3) == 5 || return false
-return: true
-
-julia> d = AtlasSLDecision("inp 2\nchor 1 2\nchor 2 3\nmu 1 2 3\nchor 3 5")
-inp 2
-chor 1 2
-chor 2 3
-mu 1 2 3
-chor 3 5
-
-376> SLP.evaluate(d, [perm1, perm2])
-false
-
-julia> GAPSLDecision(d)
-# input:
-r = [ g1, g2 ]
-# program:
-order( r[1] ) == 2 || return false
-order( r[2] ) == 3 || return false
-r[3] = r[1]*r[2]
-order( r[3] ) == 5 || return false
-# return value:
-true
-
-julia> SLProgram(d)
-#1 =    x     ==>  x
-#2 =    y     ==>  y
-test: order(#1) == 2 || return false
-test: order(#2) == 3 || return false
-#3 = * #1 #2  ==>  (xy)
-keep: #1..#3
-test: order(#3) == 5 || return false
-return: true
diff --git a/previews/PR2578/StraightLinePrograms/intro/index.html b/previews/PR2578/StraightLinePrograms/intro/index.html deleted file mode 100644 index fd1c19933af6..000000000000 --- a/previews/PR2578/StraightLinePrograms/intro/index.html +++ /dev/null @@ -1,134 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This is the documentation of the straight-line programs (SLP) implementation by Rafael Fourquet. Originally this was supposed to become a separate Julia module, however it has now been incorporated into the OSCAR core.

The main SLP type is SLProgram, to which other types can "compile" (or "transpile"). The easiest way to create an SLProgram is to combine "generators":

julia> using Oscar;
-
-julia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;
-
-julia> x, y, z = SLP.gens(SLProgram, 3)
-3-element Vector{SLProgram{Union{}}}:
- x
- y
- z
-
-julia> p = (x*y^2 + 1.3*z)^-1
-#1 = ^   y  2  ==>  y^2
-#2 = *   x #1  ==>  (x*y^2)
-#3 = * 1.3  z  ==>  (1.3*z)
-#4 = +  #2 #3  ==>  ((x*y^2) + (1.3*z))
-#5 = ^  #4 -1  ==>  ((x*y^2) + (1.3*z))^-1
-return: #5

On the right side of the above output is the representation of the computation so far. It's done via another SLP type (tentatively) called Lazy which represent "formulas" as trees:

julia> using Oscar;
-
-julia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;
-
-julia> x, y, z = SLP.gens(SLProgram, 3);
-
-julia> p = (x*y^2 + 1.3*z)^-1;
-
-julia> X, Y, Z = SLP.gens(Lazy, 3)
-3-element Vector{Lazy}:
- x
- y
- z
-
-julia> q = (X*Y^2 + 1.3*Z)^-1
-((x*y^2) + (1.3*z))^-1
-
-julia> f = SLP.evaluate(p, [X, Y, Z])
-((x*y^2) + (1.3*z))^-1
-
-julia> SLP.evaluate(f, [X, Y, Z]) == f
-true
-
-julia> SLP.evaluate(p, Any[x, y, z]) == p
-true
-
-julia> dump(q) # q::Lazy is a tree
-Oscar.StraightLinePrograms.Lazy
-  x: Oscar.StraightLinePrograms.Exp
-    p: Oscar.StraightLinePrograms.Plus
-      xs: Array{Oscar.StraightLinePrograms.LazyRec}((2,))
-        1: Oscar.StraightLinePrograms.Times
-          xs: Array{Oscar.StraightLinePrograms.LazyRec}((2,))
-            1: Oscar.StraightLinePrograms.Input
-              n: Int64 1
-            2: Oscar.StraightLinePrograms.Exp
-              p: Oscar.StraightLinePrograms.Input
-                n: Int64 2
-              e: Int64 2
-        2: Oscar.StraightLinePrograms.Times
-          xs: Array{Oscar.StraightLinePrograms.LazyRec}((2,))
-            1: Oscar.StraightLinePrograms.Const{Float64}
-              c: Float64 1.3
-            2: Oscar.StraightLinePrograms.Input
-              n: Int64 3
-    e: Int64 -1
-  gens: Array{Symbol}((3,))
-    1: Symbol x
-    2: Symbol y
-    3: Symbol z

Evaluation of SLPs is done via evaluate, which can take a vector of anything which supports the operations used in the SLP (e.g. *, + and ^ in this example; - is also supported but division not yet). Note that currently, the eltype of the input vector for SLProgram must be a supertype of any intermediate computation (so it's always safe to pass a Vector{Any}).

julia> using Oscar;
-
-julia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;
-
-julia> x, y, z = SLP.gens(SLProgram, 3);
-
-julia> p = (x*y^2 + 1.3*z)^-1;
-
-julia> X, Y, Z = SLP.gens(Lazy, 3);
-
-
-julia> SLP.evaluate(p, [2.0, 3.0, 5.0])
-0.04081632653061224
-
-julia> SLP.evaluate(X*Y^2, ['a', 'b'])
-"abb"

Returning multiple values

There is a low-level interface to return multiple values from an SLProgram; for example, to return the second and last intermediate values from p above, we would "assign" these values to positions #1 and #2, delete all other positions (via the "keep" operation), and return the resulting array (the one used for intermediate computations):

julia> using Oscar;
-
-julia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;
-
-julia> x, y, z = SLP.gens(SLProgram, 3);
-
-julia> p = (x*y^2 + 1.3*z)^-1;
-
-julia> X, Y, Z = SLP.gens(Lazy, 3);
-
-
-julia> SLP.pushop!(p, SLP.assign, SLP.Arg(2), SLP.Arg(1))
-       SLP.pushop!(p, SLP.assign, SLP.Arg(5), SLP.Arg(2))
-       SLP.pushop!(p, SLP.keep, SLP.Arg(2))
-       SLP.setmultireturn!(p)
-#1 = ^   y  2  ==>  y^2
-#2 = *   x #1  ==>  (x*y^2)
-#3 = * 1.3  z  ==>  (1.3*z)
-#4 = +  #2 #3  ==>  ((x*y^2) + (1.3*z))
-#5 = ^  #4 -1  ==>  ((x*y^2) + (1.3*z))^-1
-#1 =    #2     ==>  (x*y^2)
-#2 =    #5     ==>  ((x*y^2) + (1.3*z))^-1
-keep: #1..#2
-return: [#1, #2]
-
-julia> SLP.evaluate(p, [X, Y, Z])
-list([(x*y^2), ((x*y^2) + (1.3*z))^-1])

Straight line decisions

A "decision" is a special operation which allows to stop prematurely the execution of the program if a condition is false, and the program returns true if no condition failed. Currently, the interface is modeled after GAP's SLPs and defaults to testing the AbstractAlgebra.order of an element. More specifically, test(prg, n::Integer) tests whether the order of the result of prg is equal to n, and dec1 & dec2 chains two programs with a short-circuiting behavior:

julia> p1 = SLP.test(x*y^2, 2)
-#1 = ^ y  2  ==>  y^2
-#2 = * x #1  ==>  (xy^2)
-test: order(#2) == 2 || return false
-return: true
-
-julia> p2 = SLP.test(y, 4)
-test: order(y) == 4 || return false
-return: true
-
-julia> p1 & p2
-#1 = ^ y  2  ==>  y^2
-#2 = * x #1  ==>  (xy^2)
-test: order(#2) == 2 || return false
-test: order(y) == 4 || return false
-return: true
-
-julia> SLP.evaluate(p1 & p2, [X, Y])
-test((xy^2), 2) & test(y, 4)
-
-julia> using AbstractAlgebra; perm1, perm2 = perm"(1, 4)", perm"(1, 3, 4, 2)";
-
-julia> SLP.evaluate(p1 & p2, [perm1, perm2])
-true
-
-julia> SLP.evaluate(p1 & p2, [perm2, perm1])
-false

Contact

Please direct questions about this part of OSCAR to the following people:

You can ask questions in the OSCAR Slack.

Alternatively, you can raise an issue on github.

diff --git a/previews/PR2578/assets/documenter.js b/previews/PR2578/assets/documenter.js deleted file mode 100644 index 6adfbbbf4b70..000000000000 --- a/previews/PR2578/assets/documenter.js +++ /dev/null @@ -1,331 +0,0 @@ -// Generated by Documenter.jl -requirejs.config({ - paths: { - 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/languages/julia.min', - 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', - 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min', - 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.24/contrib/auto-render.min', - 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min', - 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', - 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.24/katex.min', - 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min', - 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/languages/julia-repl.min', - }, - shim: { - "highlight-julia": { - "deps": [ - "highlight" - ] - }, - "katex-auto-render": { - "deps": [ - "katex" - ] - }, - "headroom-jquery": { - "deps": [ - "jquery", - "headroom" - ] - }, - "highlight-julia-repl": { - "deps": [ - "highlight" - ] - } -} -}); -//////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) { -$(document).ready(function() { - renderMathInElement( - document.body, - { - "delimiters": [ - { - "left": "$", - "right": "$", - "display": false - }, - { - "left": "$$", - "right": "$$", - "display": true - }, - { - "left": "\\[", - "right": "\\]", - "display": true - } - ] -} - - ); -}) - -}) -//////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($) { -$(document).ready(function() { - hljs.highlightAll(); -}) - -}) -//////////////////////////////////////////////////////////////////////////////// -require([], function() { -function addCopyButtonCallbacks() { - for (const el of document.getElementsByTagName("pre")) { - const button = document.createElement("button"); - button.classList.add("copy-button", "fas", "fa-copy"); - el.appendChild(button); - - const success = function () { - button.classList.add("success", "fa-check"); - button.classList.remove("fa-copy"); - }; - - const failure = function () { - button.classList.add("error", "fa-times"); - button.classList.remove("fa-copy"); - }; - - button.addEventListener("click", function () { - copyToClipboard(el.innerText).then(success, failure); - - setTimeout(function () { - button.classList.add("fa-copy"); - button.classList.remove("success", "fa-check", "fa-times"); - }, 5000); - }); - } -} - -function copyToClipboard(text) { - // clipboard API is only available in secure contexts - if (window.navigator && window.navigator.clipboard) { - return window.navigator.clipboard.writeText(text); - } else { - return new Promise(function (resolve, reject) { - try { - const el = document.createElement("textarea"); - el.textContent = text; - el.style.position = "fixed"; - el.style.opacity = 0; - document.body.appendChild(el); - el.select(); - document.execCommand("copy"); - - resolve(); - } catch (err) { - reject(err); - } finally { - document.body.removeChild(el); - } - }); - } -} - -if (document.readyState === "loading") { - document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks); -} else { - addCopyButtonCallbacks(); -} - -}) -//////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) { - -// Manages the top navigation bar (hides it when the user starts scrolling down on the -// mobile). -window.Headroom = Headroom; // work around buggy module loading? -$(document).ready(function() { - $('#documenter .docs-navbar').headroom({ - "tolerance": {"up": 10, "down": 10}, - }); -}) - -}) -//////////////////////////////////////////////////////////////////////////////// -require(['jquery'], function($) { - -// Modal settings dialog -$(document).ready(function() { - var settings = $('#documenter-settings'); - $('#documenter-settings-button').click(function(){ - settings.toggleClass('is-active'); - }); - // Close the dialog if X is clicked - $('#documenter-settings button.delete').click(function(){ - settings.removeClass('is-active'); - }); - // Close dialog if ESC is pressed - $(document).keyup(function(e) { - if (e.keyCode == 27) settings.removeClass('is-active'); - }); -}); - -}) -//////////////////////////////////////////////////////////////////////////////// -require(['jquery'], function($) { - -// Manages the showing and hiding of the sidebar. -$(document).ready(function() { - var sidebar = $("#documenter > .docs-sidebar"); - var sidebar_button = $("#documenter-sidebar-button") - sidebar_button.click(function(ev) { - ev.preventDefault(); - sidebar.toggleClass('visible'); - if (sidebar.hasClass('visible')) { - // Makes sure that the current menu item is visible in the sidebar. - $("#documenter .docs-menu a.is-active").focus(); - } - }); - $("#documenter > .docs-main").bind('click', function(ev) { - if ($(ev.target).is(sidebar_button)) { - return; - } - if (sidebar.hasClass('visible')) { - sidebar.removeClass('visible'); - } - }); -}) - -// Resizes the package name / sitename in the sidebar if it is too wide. -// Inspired by: https://github.com/davatron5000/FitText.js -$(document).ready(function() { - e = $("#documenter .docs-autofit"); - function resize() { - var L = parseInt(e.css('max-width'), 10); - var L0 = e.width(); - if(L0 > L) { - var h0 = parseInt(e.css('font-size'), 10); - e.css('font-size', L * h0 / L0); - // TODO: make sure it survives resizes? - } - } - // call once and then register events - resize(); - $(window).resize(resize); - $(window).on('orientationchange', resize); -}); - -// Scroll the navigation bar to the currently selected menu item -$(document).ready(function() { - var sidebar = $("#documenter .docs-menu").get(0); - var active = $("#documenter .docs-menu .is-active").get(0); - if(typeof active !== 'undefined') { - sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15; - } -}) - -}) -//////////////////////////////////////////////////////////////////////////////// -require(['jquery'], function($) { - -function set_theme(theme) { - var active = null; - var disabled = []; - for (var i = 0; i < document.styleSheets.length; i++) { - var ss = document.styleSheets[i]; - var themename = ss.ownerNode.getAttribute("data-theme-name"); - if(themename === null) continue; // ignore non-theme stylesheets - // Find the active theme - if(themename === theme) active = ss; - else disabled.push(ss); - } - if(active !== null) { - active.disabled = false; - if(active.ownerNode.getAttribute("data-theme-primary") === null) { - document.getElementsByTagName('html')[0].className = "theme--" + theme; - } else { - document.getElementsByTagName('html')[0].className = ""; - } - disabled.forEach(function(ss){ - ss.disabled = true; - }); - } - - // Store the theme in localStorage - if(typeof(window.localStorage) !== "undefined") { - window.localStorage.setItem("documenter-theme", theme); - } else { - console.error("Browser does not support window.localStorage"); - } -} - -// Theme picker setup -$(document).ready(function() { - // onchange callback - $('#documenter-themepicker').change(function themepick_callback(ev){ - var themename = $('#documenter-themepicker option:selected').attr('value'); - set_theme(themename); - }); - - // Make sure that the themepicker displays the correct theme when the theme is retrieved - // from localStorage - if(typeof(window.localStorage) !== "undefined") { - var theme = window.localStorage.getItem("documenter-theme"); - if(theme !== null) { - $('#documenter-themepicker option').each(function(i,e) { - e.selected = (e.value === theme); - }) - } else { - $('#documenter-themepicker option').each(function(i,e) { - e.selected = $("html").hasClass(`theme--${e.value}`); - }) - } - } -}) - -}) -//////////////////////////////////////////////////////////////////////////////// -require(['jquery'], function($) { - -// update the version selector with info from the siteinfo.js and ../versions.js files -$(document).ready(function() { - // If the version selector is disabled with DOCUMENTER_VERSION_SELECTOR_DISABLED in the - // siteinfo.js file, we just return immediately and not display the version selector. - if (typeof DOCUMENTER_VERSION_SELECTOR_DISABLED === 'boolean' && DOCUMENTER_VERSION_SELECTOR_DISABLED) { - return; - } - - var version_selector = $("#documenter .docs-version-selector"); - var version_selector_select = $("#documenter .docs-version-selector select"); - - version_selector_select.change(function(x) { - target_href = version_selector_select.children("option:selected").get(0).value; - window.location.href = target_href; - }); - - // add the current version to the selector based on siteinfo.js, but only if the selector is empty - if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) { - var option = $(""); - version_selector_select.append(option); - } - - if (typeof DOC_VERSIONS !== 'undefined') { - var existing_versions = version_selector_select.children("option"); - var existing_versions_texts = existing_versions.map(function(i,x){return x.text}); - DOC_VERSIONS.forEach(function(each) { - var version_url = documenterBaseURL + "/../" + each; - var existing_id = $.inArray(each, existing_versions_texts); - // if not already in the version selector, add it as a new option, - // otherwise update the old option with the URL and enable it - if (existing_id == -1) { - var option = $(""); - version_selector_select.append(option); - } else { - var option = existing_versions[existing_id]; - option.value = version_url; - option.disabled = false; - } - }); - } - - // only show the version selector if the selector has been populated - if (version_selector_select.children("option").length > 0) { - version_selector.toggleClass("visible"); - } -}) - -}) diff --git a/previews/PR2578/assets/logo.png b/previews/PR2578/assets/logo.png deleted file mode 100644 index dcd2ef285fd2b27436cebf3069abd000d61a53e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15093 zcmZvDRY03f6K;S8DDLi1C{8F8cPO;DyF105A`MX7-Q67u#ogUqgBB^;;&$HeKNsib zT)ZSCyR)-1yED%-y9rZLkVZ!#K>>k4=$~aIRX`wkGT?n9G9vId{y=R5czNq6qwN9$ zq2m1az|C&>J%K<}pwE(GYMz;=St9Ohyi0>QX&=h>n;coq!8euNa=RZFQHC3A@++yv zQS!NLB&tN6Pw4-l(9{@}t_~0`uwCIdH(2Yu5yK$_F+NSsq=hlU#a^8EbP#qMet&rq zGfWNo`vH^!`Z@6}$@9u!kyS1Drwf%N4d6DTSu@@Qsh;v4?g zQQCpA+EyjbB!y$g|x7uACGV>d(K$v^I zft}kP57!sBn;vJU(RKJ`@%bEF@=0!sZNc-eJRA%d>diy48|KMlJA!ooXhXm4;e@>& zr_1Pn>T~ew(yoDzGQTgQWu+m!?KJ#9`6I9xS{9Gjf(vp}rv}mJh%)6^+9bfouTyKy?JUaINpKkFq zZMS}-V`)5lEpFCMUo$M%pFOyitYM%LHoPKH$(Af(=rz%M51+rOr;p9EPxm9F_~n4+ z7DP~DV@G${73g)zOPZdfRKE-grsfT|B4vI(Gavx$_hd^jnF4z0b42WV3uOnn@0k#h z)jLv*_j)11NP}rVf|NZ(04o=L_EH+}y>}&;#6_#% z7PzVqZX9LTIx;j`c_L^j={SANi*PX_=|?ckY$hGWCEEML4EgsWl0<(If6+75j8qMoL0 zRO8DpesTLxZcdyU5X3>O#c1;cOlv|iyo$Pk3!fMHG|{_M@3~Uc9#skVym=>oiZG00 z2S!PjIO#|}QXHee!2ZNjr|a@_rw{X8A??o#cscJiHS?ge*+|8O%{lShqg~w{FV$na!x?V9BU+65Bcg$>N?8GRMzgDYeZC`%x z42O-mP1i6hzkMPXd?mV!M5dc0-H19J*X<66_^I?~pi~4b7nXtNcagAtRnF&67(Rro z?;55&wAp>jgWn6+qN(?jN$(%z(?s8BOzX!PZO3WYEw0~%Y7gIx7_+&ihCJKVM3H~e z!y4w={voj;qO*d6SsUmb%^LWESDMCq`LpA+=pUpm3tn1&lv@tZJ-S9zkf1J(@At1m zv+uT-@xtqzSv7{x+o}gM(HoOu;tc%{ftjUs`m8+Yw4)FI6E2 zHtP-)WRWKJA|`@EBm_uqu#h5;Xo7g%CW|Ai(3By?`G>R;_v_+%!O2HoVt)){h!=vf zs;LtQpvVUg{$)ODEkSpusvzxzZ$+tjdMt>w?BWFVj-9U0`NBGTEyoHY_Z+CdEvsLX zh290$UX)|uy=;Li4oUN#mU2YCCklVQEm#(;F-AAi*15N#?Xt#k@7mQoQzt}!dUZO0 zgMpmBmc-?1;ZVFCM;||Lu2ODbJ|MNEKp~_0aiQU%uOiUy@2I+xuC(%~t9e*BFRYa$ zlK%7Q2&$K)x7haxqzR6qDzxi5s6pfEbk_i%E@N=t)wYr$+>=ASfs~#J0_fw(0ubUi zK%Pj{_O`Vgj*K`>UhbGw9Pd7YjOq=FuqrH7uLmDUVBK?PI{JDpY#%paZ6A~2#O;)>Jf#y+Rbp1#p8woi-C;ViVC^=--B8q&6sQX9EkWX!A}o zGP0rJ1pk9$=Y0r%JJ#?M2BY6vfVD3VQ_mRNNENnW{3pg~5?#Xxj>5n6+K9YQ07tmZ zX63!a^MoXyOT|p5LQn%^R>3%BDBCq`c zw*zRso6O7curoxBgIi{+6)&-B80RU_q&w3Ow|Rq6{dF;jknEX;J4rbyh?X<<*3M8v zdni{_09VY8ABnPhw=k0w&(7X<8*lXBiRkY`sQo(7p_>rR?c7gP=1;9&X8wP%NSsiMAsv} z+CPqC>dywF`<*1^jymfs99z|4Rb;-s*)V8Y@K0CcsqdO-QujAK466}Uj;^U|c)hE} z4|v+d^v6qSE-L(3kdkw8fdd;<>w&Ef-2u}`(*RnNNf*r9N!vqsO(hfTC4rigeQz*% zk#CE3%}YS-w+3G~17afAl77T1qac%#&JPyG>W&;+Xu9uMaEhOVJ)6Qy#w$*ah?`9D zonF2i(%UXpYyq+9&DKO9^bz;Lj9{`rcyN!mmYa(scBlhkOBEH^*IkZLyU+$kiFA3` z@$V*e(=&^XRRG>l2#PcG))J&h45Z5jd7B78U!6Hg>Bf(4d#Z3A@#UG}5xf93I1u$` zhw5Z)M`JB;mz(+;eKwOr8TDffBDHTu189vV*@@%bXhU|Cn@#!P(XAa3H{@ZOAMB7* z=e95hT9tpehdrZqAhl_`lyOi>DKWfPDfW3r|4ETM-TA^O1iN{M=_S4za7z&>DnUZ* z>F|PXxh-hu|83sL!(E;d=8u~bDiGR z=|wJbAYoK2iYx^jAsRR~V>Fqc^L;8jRC$~FK|XcP1MaLx= zk}LHBg+)$%!QUFN{~D@3J1PFp$k@!O&aw!+>rNeXG84B^EqZ> zKdBCSVpD|i)Cu>ID1PYQU_|)g((S-R)%-@9vhg~H3F7i#eM#98)TcE){5F=eSZLAc zos279;XBjNyXc;?Or?QtcQJ+SlbH}Vk1rVYx&x>fLjdU^Y7Y*U@R~_Ljb=10?zVo5 zady7?nT&-0L%-@&BHy#>u}jB~OAD>s=iY#^QS5IiwNIl>|({%T+#QPo}ciE4bl$E4R|V%r!UiT1Y(ovVK9 z$sB?Uw7(_5xZO^N-r5aOA9UY_LhKaL0UGh?)-Mf?#NS3FsJpXU=9gXHosmosgYbXBrga}K>v)wiQKCVcT#c7erS?n7w=SC;q zw7vJ_UO+HX{a+p6SQ1{sBGgO` zsX5Ck&-A_{g(I7d)qtr#6g{XI=7$e~ovbJYK$La2_~BW7Lld(!^ffxlx@QTgacIVq2_fa!WXh^vA_C_pZkBn{@0bV^w52YIxIR9 z@?(D&3Hr($8dJ7m;-x^AvcbqF>^VP|h&2BP`m|OdPoS~}wi<;>Nyq8=Jn^9ZZqw#9 z)N1gNW8FWgL;gEa%U=_Fv1TeH&kI66HW_+BtYKf7qm^;>Y0}4#&;#8CFC}9p`1*ga zA8mtd3HZmkbD2J=L1?|KO#(@DH|u_+6E3rtMGNq*8YC@{9Bq1o1&&qjtk*r zhN_$HyLR0H)gc6ES-E+XzGG%DYn?=3BNv#rPGarCd1>rB0yYIjh*2l;O?NHxSev>a zXQ#x>&p6ZG-t8l5KyZ_G4I7-#fVH-Ov-5VHU>!Ldg|J>LaU(&xOfv?AY|frs@zoP_ z;a6|Knx1{T3l5P+vCHUqlOwX^CJeWH53`9ueArXiRv^64i0*X4gzW;j!q!`aqz!h_ zBlc`rZ(t7K7Q}Av%!6OQaY0>A;p1}z2N}kE>x_Jv0lR@s6gL67pjZ3FirnKj%IfVw zeFguyp65gzI)_j3AH}QFM+O%+qQbl+`cpqXI?IxNCip%E*x?tsS7N1&6*X;0op^LP3X-yM+XokOVA()(FJKOJiX2T&+ z=-pDRPDVBfcnqDZ`}Tumo!Q_p2YH;Q5B>=W-5DhvwTrY;Q%|fpMRy~_w6}+^xdNWszZ;KSu&?I_)5ST_7Fx~~HzX_Q#8!u;dJd8`9 zNpFY{L5P41fxb~6N}HK)KEs&m5DXsI=5fXuY@i)%5PH%Bc(>jyJ#K*MPH9dC7=d{# zlFwJs#a^f3GO>UP41e%X=vs38D1(5E(R9^xbz=93{a5l=+yDe#)}~P)y8W;9pdqxYVhBzd#!mEWxmWl4^gR=Gy?Tt_ofC?yZ zD6xN7JK6C*=59ZBz=){+TXYA3Qt}7q4zUYp8+2sdnTN>b6i=#muXydc%`|AQl6>|( z+pJ{a(_dKfBNiKBLOzU^s~6Af*L=eZJ1m*(-3_N6z%)tX!?+5mX^j=SFcg|lsQkJ# zJls5^>$Pj#&Ajf+soHXn#grXWiJsbFho43>fqC8)f_9pA3CQPy&wrn}>}vCN<>60K zM@TT7D6miDF#yaV>}Ge8)TE(T7(-s8qs<;g~{eqVP(WC&lbd zT8={YT=MT6uic3(aNSbgM$l}M-tJLsm4bUgJ(ecjXR|mI&gZ9oC=R2i$HyoL3$9yt zs{87GAKf2b@K6u*olY1~dn9(O=$Et3;n%&G(v&9TGw-Pb*L-(HGu{s+{#z^7pCu+O z;`65SGpofHO@Te{PH;`B{V2hc@B$c-ig#GQr{$6M!vHSi%xME7-(F?hJd75Zz&?qBw9rQSWw(OX)aMr#l8)Z@Lv%8Qj7b41 zMWWQ=Tb|HL8{!S$)JAi1cdzPHvgep$In3s{=Gf*OqY}Lhx@*$g*ND!m1-+hyRFezL zDTksI191(O2&0mdqZ<=O^~JRxV>?4Z;OV2#TeCAW@<0C8u8=d5I)@qke3=U4m?F!99kLx@YbcXm1OFl=>(B3X#n;iUWtG=Tl4~m5y6UA~ApE|_u)7Hlw zk@kp{C#|h>20!Ic^a1w>KZ|Htw)78uz%LwhYcpV7SHzTx55f4{AL5g&CwYVPSP}u|5T|6 zhd}Le@K}<#xf8RJ`KeOSN}!S7)I#7)SGCtL<7@ZY>sp5KHz2!QdoSD3aqz9Tzhxwd z%{+UyXHc|@BUKrA<+S+dL9@bgTHre49hzDp?R3{3>;1!lNm_*B^UB@drs(EM?_9NA zWASHFGs;ep(AUvUDh1w!G`hQl?_&zNtbJoD#UpEA`sk)L4JIQb2iNuR8RLg>m!#Mz z)QqQ4G!FsJn2XNg!52)&o$PIKfsoHftE6JzRJW z=Nn@YtzA?Y(ANt}jli&+w>1Xsab+ZjxiMHBVjwbXn5t#};3L&563 z)^SYeE!tuf+1VP@KV{^r4ONW}T5E5E99nWE8PsZb3&`>xd^M2d*9B6$v>Y}dp3&aM zu50xXY%Obc{h2Ri#@~!p*?CKQ*0k<@K(RB8yr!|!q15moJH4xcd)*8jR(;U&N@rIf zy@G0Wt(vJ$v6NrjTWAiQpq2-v@&n_KQXXru@z1OOTUw%um84)FGU+Z3zq^$1AX<^P zGyTWS<3uz>m$yLWH?!hEn>UBx#~@+qFPl9d%TDqcGo>A(ZeS5BvR0;+G$8CUjLVtn zc;IN^-AmDf{6s@vSi=IXmm~qS8Vs-gUG<^Zo}ab;?9k%hSt1T123*F!%R;>=)cunq zb4jd(x~MQuG-~+H>FXU?eaPDe6vJ*kQ7e2*qfIHXrFw@RNAW!xOBn9C-aIHX^(|t8K{7tihA*Iq!4v& z(ZSil+~e*eim%DdzSNJ{eU2y#s^t623!#yojh$)QU^K@$_(uyM5jn1(j(EsaavdLO z#zOiLSma&+mw!?(ePwtnIAaN^1 z-}HX#ayFy3FTba;66hiJ4Z($n#hYtpxhP(OIS536fk_NPTE-{6UmP3OctOZjg&C`s z0x9%m5itu8p~|l=xZFCT`e7YHP~95zC<)}|j1AQ)FcM5kTDCGGiVUUw!M=@5XwN_b zW^C&7{cF%i*?j*DWB={SRosJr?0S3?%c>)!nuZKLaCc(0)R>@RHaqhIDp>0Vbv7YJ zZ8P`OZPTYicim6vvvH8n4MM~-4Y((Ql}(_^4yr*E>+&ulS%Z*r+QUv1zzmhD2CnaW zX0~XetjSH^pCyt3u(n-10tPZb5Agf-lngkdwLwT(T{#rsuO|iNIIXfJ3qfzmdfJ2SgUJElGPFf?!nSUj{*pVxbSPRV zo4LsriqH=yk>X1(I!yByyF|zzPTZ4^`D6GrF>VU4e98fd_9X zgj|8>A>`%pMOLQLrAdmNceRhdGsV7FW78ry znENe5TuU&x_JawgG5Bt4x>A*IZ!r=$Bqjb)Q54e_yNE>~Nh-D+=P!tZ;H4Evz_MAj zL%(j~0YIXu-$g{f922QOn5c!qcfobt|3pU$4PUugnXirr7%)Xqw#0sLNjRb~dG&Js zVuJ1I{)?Ww^=Q~(Es-xg*$K-^}h~% z(S&6G6XCgh8PNA%KMG8N|F5t-|B|-9L8qLFUabOh1pg{PAd-y#?gDhx=_CGcL}wkt z%^Oz_3fTVOaPGzXu7M8-wWRtY7!ThrfSw;h&-uyqMfjaa59T(!-cXU~iy$UP?2xG$ z-Y=Y3VlCAu$~ufWluUrk3QmURwcr%7NMwuu@w*2)URuEL@)bB~gGhOcwuHaqj~pf~ z^-Lx?RlimA_^ldxPB5Kw^%`W<~+Bg|p>D$_FO*Zd0L|4^`hQW3+_kTsHIu zKiAjy4>f(LU5lc#%HKBPyfJa{Ifqwh%9gO5E`fqo@A%_0I@Bq`39ZLPZr8jvQsaQf8c7(b+(j(6A`t3ba9{~m*ijWB%vw?h02+&ICH0LM}j zkygJeY1u6WbB4lIQUBtqEknI$i1QIew3!2Cd&8 zh58-3T#f6*c0J!vnaR9R$VF@c(;f|Lw)Slr7YRPh(H|T|=x^3y6fA_00R~P19s$r6 zKLOouTqt?jAIs9b!T6~tYCJp!wOrlBbH@_Ki#-Qq8%p>X%4(AVsLlEA$qjqCwte035=AM zr`o{NrVh!2ml_a>uBJ@EDsE*Gb_9#ZwKhyNsp=xZ!Gny}ETXF{_ZboRtt4(@(qaL+AGZ8{Q&7v9<}}_h{KYYE*E0=kUY- z05()CZi*S+JahtE$`lL`%6-)&Z)OKQeQOnXwW1kbks2w^wF7x>D@$Z}$Cr|O~{-XP%@+Cw{nLd~Y=&b6oMQe{w*hAiF`J<*O>3JYyy zG4L}b^Osf{Z!Ai7Q|eAA0Pdni#Z~b66T{U~Lh{#(8;aMcxR2`!YMJ($LtdLUnf8KO zeP!~mv}UZ44L$z_U4=dd`rXRZ*>;2+(+0H;>ldtGBs9cocFqORf__DVH|Y0^>N3Cw)uwF$|)in4$+=>6Qe=1!nsjoW^iBE2@u+SVOq&e13VTLGCyB*Qb9%`r5Se(|<>; zAwN&T88rF(M1SXgNd`+(efHR>t2@ZwEimab6g8-eXl$c+Un=kJx#F9pE=oNG4}ly1yU>6S(U724*^;D{}4isE1EiXl6PH*E?z^>9}ti8P;wq zVJe%oe8=1BH;*Hb2Y=lb6U&a*S90K?SQHx(g~Sn2PD7W8Fwg$6F;g0@LGl3ScwP}O zyLJ{t?EdN_X~}ThC;>E0ewUb_bPT6F7h1s!Bl2Rdyxe!Ld6?G_N1S2JCygd^)edQH2ifCUWnS7c7b+V~ z8Q1kMo6ZZp`F%mx;FzDVT5}STGIH-~8=tWYL+G+MHs$HP4VM&Cp|%rVO+$f;xGEyn+@shuYo zZ>gXcrXS2={xc~n0ymK9=T8A`N(7pC!IN*caH#VXX7+Aju#91QCf!5|MT|w~L~+v^>aqy;H0RU>i!IESLxvvPm6Mwvk)q zbV7zg&DTenkKVp;+vOOO9W5!`_5FX0Q*=`h1r0Q;)qQRALYO%m*bEzvt?%aja*iN z&9uA{YpA%qe-mdy)o>fS)44@;S7mL=vB+iKO@&9`tlV-r^ClsxjC^2t@HLLEX~SeH z;T^KH`+Ya+!ixfq2is`i|G|YC{s#>)Qc$`1)0oZBVAArOcF)#g16vV0EXh6wH)y1dmnPD?BFT3-w9${8_uR0(zBGNm+Tjpakn7}?hFK8?^_M6`px=sM!^fl47N zvWr}?uIDsL%c+!n6?>W3wd7?cMM9DULG7&%y354vY+iL20JB~hJE`6bDu$}UolNq# z%u^9OP_*Ls@Ci1(V7X8A0$4v%yB@o+Jp z118KP@Bx!+5;97)hEyDHnU=@txjCCLf^K786%pr>O%jn{TN203HF;TP8|mPh z@+D8{oJx;Xp5YM{`9oy#shC;uS0;*9vJg_4?2cnJZjI>D&kfEK{vsoB=c)@31_I3m zTx3)k`(RX-B!K)a`>#D5AITU;zY^{|B^J9p;rA0!l6x;7Uwv#1c89e32_kSvxKK{> ztoBS3x7x}tR4!jTl38~j#)%B!J2-rsw^QfucIrv`ym>A@G})xbXxRSyKSuc>63Ev8 zMhHE)i?Oo5zH_pTKKIf6bNJvSE1c^A>J%3`=AM7YpX*+l9BrCXL4Q(y-Y)e^T#f&@ zaj>U%DQ)i=8XO>?7ryYgQpfs#HNYXo{dHsN< zOjsU%2R|ew&2%3rn_q^Zt^GkYXc}61E+>!Q`!~4k6y9p^j!j@=zByve-nCZ2IC`pz zg30A6WrwUr-Z2p+IrieN{NiR*c8LT>He1Mwmm$}VV-AP4icC#ezKWDj-M+Y5OqTfm zzT808xd{y1@Z)w_2dCQ+W;Zgm7?;{JV`iVMbkO?NrK3lugMa)v{Js<$B}Dw}f!ynE z(*{~sirjfOe{g5H#1{d3kH-{@EF70+)S$PaYuYi5J+fi*y*VI>HolPgQQu_bgQy=U zHSTRdqu%~OGx6RjOx4L;iD&r6OxBvpYq8`s61q;ZI~q43QS8jU5(4_u3MrxL456|` z7^$CEB3{nB6bi1j9UHuPdswKa(IXZ#iiwqg|9*!p1Q9Si|7*egs1tysL)EH~k1I*t z%sDrmMtZq|eDb4YU)>)G4J&bgi9pev)su_ZIn%hS3AHL{6O*J|Vy#Bp(dN1}r&q>@^F+arZX&Y9X zS%F(L%`~QEO#=dBxeLq6#2a$!VY$J{YJzN-M0Ip!^hjCiEp)bz>$oHJRIilIeKPDv zbE;$nCL{H0*%*RuG>n|ep{kPG1hdO>pLMWhvrl96hGJzl&nuhr!LfgOr~8$ZZD~kp zBT=J;F@8cjsi@MlLj8Y#(ly^`cJOr6ruVX#8;$!ykuvt~aYDG6h(p?Y%AC2iU+(ii zahlH-Sr0o^WR=4Yy^>3BC;9WT+<$H`I&|W`#Y$^-zU~&)ekPlq^V^D*ySa#hdA17V z0F-cRdLjo~v+P@Nay_0^k_xwxVyTP!N}9@G3oizE)IPNE;JLL?{j2|*f=Y~Ap{`M( zYOidf_kEvLT=d~V{cLZAk5j_-Sbu)j`sfw&HJdb~KU+@APQT7(_HE)zKn5>g3p=nqQ@`0 zE;xr2<&*avLc@OJMpt~;NQh?B%1rljK%BCIB0(!93lm@3yJVeoy$eT)lTW|6aW@ ziksF0B_$nE!2#=yEKb^`@ zUktaS^M?6UPT5v)`V2jzFy4|9NCT?F8(-SG7)7NmT4%XszRVqYMldtzu#!RJwOi%Z z=_z~55W4YbTINi@7dD5qZpp2&_Ll=0E(ajZC8d-`B9vi+=d2AA`tGv-h)g&+zJ2;3 z3qjL+pXmico~h#|-jejC7V|Z{+cau76crYUqHe*+LM0jE9A-^N;;nUw@cWu3rLsgu z`8k^$D4n$lTB#k}KF+F(F}<1PPV^~?O*j*j3@%*>Wc8Kz(JkdNM&h?Zw$e$^BX@{DfvcSnQFm;)$kR@X~CFN`&q zqiC^e51Nc%o0D5dE81~5%+M*BavgR|>%Xi$w3)15;15FTH_M#SkRkWouAC+`V_pM( zP9?ThmB%IRqvmV$|uB$M@&!-%~kH zftDzgZ~Du97;)cnM}xD)N37KR$B@orWJH<)y@gPbW2F&5 z%P!@PtH&nWn*#sB^0UQQ-NH$#A38589l~uh9;|O{7plsgF|e3?P^r|(?@C#bu$U`b zbEj#(A}81sz%>>N`F!HZdjziU0#`S9^xsUMHw1n2U6*Jm`1BhW@0eCx>K2HCnkrz$_2m%g4ZV!8P2Ye_tFeDW3G1*IOiy|VDWkE2g&DY>;M>OxX7 zw6jW6av^#njp7Hv5=}iA`vZ(WSAC>P!AO^&r5&||jDevO#&awx%SHO+OhL73uU>*e zbyHe_QcP1dU?s2bw%x;)wtk3%A<@IcUA%*Wwa#bhTiNbo~7Rk-Ezh z`uz7tP16yPf&XgT*cVbQ8~_??g%*})K*f_ z?9YWs>E>V9l)LPb6V9z?;;u$3JBLD0nr_n>?{e-by@tVjREB znR&h){q1=qew9;>6eRu*%iEQfD`NipCccppSR)O)p1`^&eyWIdHi5I%ZyiYa=Wuj# z6@lP+_T$e22TA+v5eQ0%msx)$?5++UKEA9W^gG0hH~f~9CT5oDp6(2lgXC21oL9~0 zQDWvk9FCxTfHTZm6yF`e+0nW6xs`eW4t87mWDOl{;66vB;eo7lZAEK7Ld3nM%}`#} z4EXeo%KlKdh^EjV+-bI{spUblWJ60gIR!$)2Frq%k**S$JFK$_NnHPi{$ui(b!czc zA6J@Dh!^*L6W?@7)p%V@KkCXfeKW|Ykjp-Omwx-mbfvGtAcWyEaruf_#=#SO$mQk) R{Eij$SxP~&THGk${{VzR0!sh@ diff --git a/previews/PR2578/assets/search.js b/previews/PR2578/assets/search.js deleted file mode 100644 index c133f74101b1..000000000000 --- a/previews/PR2578/assets/search.js +++ /dev/null @@ -1,267 +0,0 @@ -// Generated by Documenter.jl -requirejs.config({ - paths: { - 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.9/lunr.min', - 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min', - 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min', - } -}); -//////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'lunr', 'lodash'], function($, lunr, _) { - -$(document).ready(function() { - // parseUri 1.2.2 - // (c) Steven Levithan - // MIT License - function parseUri (str) { - var o = parseUri.options, - m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), - uri = {}, - i = 14; - - while (i--) uri[o.key[i]] = m[i] || ""; - - uri[o.q.name] = {}; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) uri[o.q.name][$1] = $2; - }); - - return uri; - }; - parseUri.options = { - strictMode: false, - key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], - q: { - name: "queryKey", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } - }; - - $("#search-form").submit(function(e) { - e.preventDefault() - }) - - // list below is the lunr 2.1.3 list minus the intersect with names(Base) - // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) - // ideally we'd just filter the original list but it's not available as a variable - lunr.stopWordFilter = lunr.generateStopWordFilter([ - 'a', - 'able', - 'about', - 'across', - 'after', - 'almost', - 'also', - 'am', - 'among', - 'an', - 'and', - 'are', - 'as', - 'at', - 'be', - 'because', - 'been', - 'but', - 'by', - 'can', - 'cannot', - 'could', - 'dear', - 'did', - 'does', - 'either', - 'ever', - 'every', - 'from', - 'got', - 'had', - 'has', - 'have', - 'he', - 'her', - 'hers', - 'him', - 'his', - 'how', - 'however', - 'i', - 'if', - 'into', - 'it', - 'its', - 'just', - 'least', - 'like', - 'likely', - 'may', - 'me', - 'might', - 'most', - 'must', - 'my', - 'neither', - 'no', - 'nor', - 'not', - 'of', - 'off', - 'often', - 'on', - 'or', - 'other', - 'our', - 'own', - 'rather', - 'said', - 'say', - 'says', - 'she', - 'should', - 'since', - 'so', - 'some', - 'than', - 'that', - 'the', - 'their', - 'them', - 'then', - 'there', - 'these', - 'they', - 'this', - 'tis', - 'to', - 'too', - 'twas', - 'us', - 'wants', - 'was', - 'we', - 'were', - 'what', - 'when', - 'who', - 'whom', - 'why', - 'will', - 'would', - 'yet', - 'you', - 'your' - ]) - - // add . as a separator, because otherwise "title": "Documenter.Anchors.add!" - // would not find anything if searching for "add!", only for the entire qualification - lunr.tokenizer.separator = /[\s\-\.]+/ - - // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names - lunr.trimmer = function (token) { - return token.update(function (s) { - return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '') - }) - } - - lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter') - lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer') - - var index = lunr(function () { - this.ref('location') - this.field('title',{boost: 100}) - this.field('text') - documenterSearchIndex['docs'].forEach(function(e) { - this.add(e) - }, this) - }) - var store = {} - - documenterSearchIndex['docs'].forEach(function(e) { - store[e.location] = {title: e.title, category: e.category, page: e.page} - }) - - $(function(){ - searchresults = $('#documenter-search-results'); - searchinfo = $('#documenter-search-info'); - searchbox = $('#documenter-search-query'); - searchform = $('.docs-search'); - sidebar = $('.docs-sidebar'); - function update_search(querystring) { - tokens = lunr.tokenizer(querystring) - results = index.query(function (q) { - tokens.forEach(function (t) { - q.term(t.toString(), { - fields: ["title"], - boost: 100, - usePipeline: true, - editDistance: 0, - wildcard: lunr.Query.wildcard.NONE - }) - q.term(t.toString(), { - fields: ["title"], - boost: 10, - usePipeline: true, - editDistance: 2, - wildcard: lunr.Query.wildcard.NONE - }) - q.term(t.toString(), { - fields: ["text"], - boost: 1, - usePipeline: true, - editDistance: 0, - wildcard: lunr.Query.wildcard.NONE - }) - }) - }) - searchinfo.text("Number of results: " + results.length) - searchresults.empty() - results.forEach(function(result) { - data = store[result.ref] - link = $(''+data.title+'') - link.attr('href', documenterBaseURL+'/'+result.ref) - if (data.category != "page"){ - cat = $('('+data.category+', '+data.page+')') - } else { - cat = $('('+data.category+')') - } - li = $('
  • ').append(link).append(" ").append(cat) - searchresults.append(li) - }) - } - - function update_search_box() { - querystring = searchbox.val() - update_search(querystring) - } - - searchbox.keyup(_.debounce(update_search_box, 250)) - searchbox.change(update_search_box) - - // Disable enter-key form submission for the searchbox on the search page - // and just re-run search rather than refresh the whole page. - searchform.keypress( - function(event){ - if (event.which == '13') { - if (sidebar.hasClass('visible')) { - sidebar.removeClass('visible'); - } - update_search_box(); - event.preventDefault(); - } - } - ); - - search_query_uri = parseUri(window.location).queryKey["q"] - if(search_query_uri !== undefined) { - search_query = decodeURIComponent(search_query_uri.replace(/\+/g, '%20')) - searchbox.val(search_query) - } - update_search_box(); - }) -}) - -}) diff --git a/previews/PR2578/assets/themes/documenter-dark.css b/previews/PR2578/assets/themes/documenter-dark.css deleted file mode 100644 index c94a294dcf84..000000000000 --- a/previews/PR2578/assets/themes/documenter-dark.css +++ /dev/null @@ -1,7 +0,0 @@ -@keyframes spinAround{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}html.theme--documenter-dark .tabs,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .breadcrumb,html.theme--documenter-dark .file,html.theme--documenter-dark .button,.is-unselectable,html.theme--documenter-dark .modal-close,html.theme--documenter-dark .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after,html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--documenter-dark .admonition:not(:last-child),html.theme--documenter-dark .tabs:not(:last-child),html.theme--documenter-dark .message:not(:last-child),html.theme--documenter-dark .list:not(:last-child),html.theme--documenter-dark .level:not(:last-child),html.theme--documenter-dark .breadcrumb:not(:last-child),html.theme--documenter-dark .highlight:not(:last-child),html.theme--documenter-dark .block:not(:last-child),html.theme--documenter-dark .title:not(:last-child),html.theme--documenter-dark .subtitle:not(:last-child),html.theme--documenter-dark .table-container:not(:last-child),html.theme--documenter-dark .table:not(:last-child),html.theme--documenter-dark .progress:not(:last-child),html.theme--documenter-dark .notification:not(:last-child),html.theme--documenter-dark .content:not(:last-child),html.theme--documenter-dark .box:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .modal-close,html.theme--documenter-dark .delete{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:290486px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before,html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before{height:2px;width:50%}html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{height:50%;width:2px}html.theme--documenter-dark .modal-close:hover,html.theme--documenter-dark .delete:hover,html.theme--documenter-dark .modal-close:focus,html.theme--documenter-dark .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--documenter-dark .modal-close:active,html.theme--documenter-dark .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--documenter-dark .is-small.modal-close,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--documenter-dark .is-small.delete,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--documenter-dark .is-medium.modal-close,html.theme--documenter-dark .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--documenter-dark .is-large.modal-close,html.theme--documenter-dark .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--documenter-dark .control.is-loading::after,html.theme--documenter-dark .select.is-loading::after,html.theme--documenter-dark .loader,html.theme--documenter-dark .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdee0;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--documenter-dark .hero-video,html.theme--documenter-dark .modal-background,html.theme--documenter-dark .modal,html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:15px;height:2.25em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.375em - 1px);padding-left:calc(0.625em - 1px);padding-right:calc(0.625em - 1px);padding-top:calc(0.375em - 1px);position:relative;vertical-align:top}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus,html.theme--documenter-dark .pagination-ellipsis:focus,html.theme--documenter-dark .file-cta:focus,html.theme--documenter-dark .file-name:focus,html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .button:focus,html.theme--documenter-dark .is-focused.pagination-previous,html.theme--documenter-dark .is-focused.pagination-next,html.theme--documenter-dark .is-focused.pagination-link,html.theme--documenter-dark .is-focused.pagination-ellipsis,html.theme--documenter-dark .is-focused.file-cta,html.theme--documenter-dark .is-focused.file-name,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-focused.button,html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active,html.theme--documenter-dark .pagination-ellipsis:active,html.theme--documenter-dark .file-cta:active,html.theme--documenter-dark .file-name:active,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .button:active,html.theme--documenter-dark .is-active.pagination-previous,html.theme--documenter-dark .is-active.pagination-next,html.theme--documenter-dark .is-active.pagination-link,html.theme--documenter-dark .is-active.pagination-ellipsis,html.theme--documenter-dark .is-active.file-cta,html.theme--documenter-dark .is-active.file-name,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .is-active.button{outline:none}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-ellipsis[disabled],html.theme--documenter-dark .file-cta[disabled],html.theme--documenter-dark .file-name[disabled],html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--documenter-dark .pagination-next,html.theme--documenter-dark fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--documenter-dark .pagination-link,html.theme--documenter-dark fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--documenter-dark .file-cta,html.theme--documenter-dark fieldset[disabled] .file-cta,fieldset[disabled] html.theme--documenter-dark .file-name,html.theme--documenter-dark fieldset[disabled] .file-name,fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark fieldset[disabled] .select select,html.theme--documenter-dark .select fieldset[disabled] select,html.theme--documenter-dark fieldset[disabled] .textarea,html.theme--documenter-dark fieldset[disabled] .input,html.theme--documenter-dark fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--documenter-dark .button,html.theme--documenter-dark fieldset[disabled] .button{cursor:not-allowed}/*! minireset.css v0.0.4 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,embed,iframe,object,video{height:auto;max-width:100%}audio{max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:left}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-clipped{overflow:hidden !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:15px !important}.is-size-7,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{font-size:.85em !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:15px !important}.is-size-7-mobile{font-size:.85em !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:15px !important}.is-size-7-tablet{font-size:.85em !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:15px !important}.is-size-7-touch{font-size:.85em !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:15px !important}.is-size-7-desktop{font-size:.85em !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:15px !important}.is-size-7-widescreen{font-size:.85em !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:15px !important}.is-size-7-fullhd{font-size:.85em !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#ecf0f1 !important}a.has-text-light:hover,a.has-text-light:focus{color:#cfd9db !important}.has-background-light{background-color:#ecf0f1 !important}.has-text-dark{color:#282f2f !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#111414 !important}.has-background-dark{background-color:#282f2f !important}.has-text-primary{color:#375a7f !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#28415b !important}.has-background-primary{background-color:#375a7f !important}.has-text-link{color:#1abc9c !important}a.has-text-link:hover,a.has-text-link:focus{color:#148f77 !important}.has-background-link{background-color:#1abc9c !important}.has-text-info{color:#024c7d !important}a.has-text-info:hover,a.has-text-info:focus{color:#012d4b !important}.has-background-info{background-color:#024c7d !important}.has-text-success{color:#008438 !important}a.has-text-success:hover,a.has-text-success:focus{color:#005122 !important}.has-background-success{background-color:#008438 !important}.has-text-warning{color:#ad8100 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#7a5b00 !important}.has-background-warning{background-color:#ad8100 !important}.has-text-danger{color:#9e1b0d !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#6f1309 !important}.has-background-danger{background-color:#9e1b0d !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#282f2f !important}.has-background-grey-darker{background-color:#282f2f !important}.has-text-grey-dark{color:#343c3d !important}.has-background-grey-dark{background-color:#343c3d !important}.has-text-grey{color:#5e6d6f !important}.has-background-grey{background-color:#5e6d6f !important}.has-text-grey-light{color:#8c9b9d !important}.has-background-grey-light{background-color:#8c9b9d !important}.has-text-grey-lighter{color:#dbdee0 !important}.has-background-grey-lighter{background-color:#dbdee0 !important}.has-text-white-ter{color:#ecf0f1 !important}.has-background-white-ter{background-color:#ecf0f1 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-relative{position:relative !important}html.theme--documenter-dark{/*! - Theme: a11y-dark - Author: @ericwbailey - Maintainer: @ericwbailey - - Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css -*/}html.theme--documenter-dark html{background-color:#1f2424;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark article,html.theme--documenter-dark aside,html.theme--documenter-dark figure,html.theme--documenter-dark footer,html.theme--documenter-dark header,html.theme--documenter-dark hgroup,html.theme--documenter-dark section{display:block}html.theme--documenter-dark body,html.theme--documenter-dark button,html.theme--documenter-dark input,html.theme--documenter-dark select,html.theme--documenter-dark textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--documenter-dark code,html.theme--documenter-dark pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark body{color:#fff;font-size:1em;font-weight:400;line-height:1.5}html.theme--documenter-dark a{color:#1abc9c;cursor:pointer;text-decoration:none}html.theme--documenter-dark a strong{color:currentColor}html.theme--documenter-dark a:hover{color:#1dd2af}html.theme--documenter-dark code{background-color:rgba(255,255,255,0.05);color:#ececec;font-size:.875em;font-weight:normal;padding:.1em}html.theme--documenter-dark hr{background-color:#282f2f;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--documenter-dark img{height:auto;max-width:100%}html.theme--documenter-dark input[type="checkbox"],html.theme--documenter-dark input[type="radio"]{vertical-align:baseline}html.theme--documenter-dark small{font-size:.875em}html.theme--documenter-dark span{font-style:inherit;font-weight:inherit}html.theme--documenter-dark strong{color:#f2f2f2;font-weight:700}html.theme--documenter-dark fieldset{border:none}html.theme--documenter-dark pre{-webkit-overflow-scrolling:touch;background-color:#282f2f;color:#fff;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--documenter-dark pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--documenter-dark table td,html.theme--documenter-dark table th{vertical-align:top}html.theme--documenter-dark table td:not([align]),html.theme--documenter-dark table th:not([align]){text-align:left}html.theme--documenter-dark table th{color:#f2f2f2}html.theme--documenter-dark .box{background-color:#343c3d;border-radius:8px;box-shadow:none;color:#fff;display:block;padding:1.25rem}html.theme--documenter-dark a.box:hover,html.theme--documenter-dark a.box:focus{box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px #1abc9c}html.theme--documenter-dark a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #1abc9c}html.theme--documenter-dark .button{background-color:#282f2f;border-color:#4c5759;border-width:1px;color:#375a7f;cursor:pointer;justify-content:center;padding-bottom:calc(0.375em - 1px);padding-left:.75em;padding-right:.75em;padding-top:calc(0.375em - 1px);text-align:center;white-space:nowrap}html.theme--documenter-dark .button strong{color:inherit}html.theme--documenter-dark .button .icon,html.theme--documenter-dark .button .icon.is-small,html.theme--documenter-dark .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--documenter-dark #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--documenter-dark .button .icon.is-medium,html.theme--documenter-dark .button .icon.is-large{height:1.5em;width:1.5em}html.theme--documenter-dark .button .icon:first-child:not(:last-child){margin-left:calc(-0.375em - 1px);margin-right:0.1875em}html.theme--documenter-dark .button .icon:last-child:not(:first-child){margin-left:0.1875em;margin-right:calc(-0.375em - 1px)}html.theme--documenter-dark .button .icon:first-child:last-child{margin-left:calc(-0.375em - 1px);margin-right:calc(-0.375em - 1px)}html.theme--documenter-dark .button:hover,html.theme--documenter-dark .button.is-hovered{border-color:#8c9b9d;color:#f2f2f2}html.theme--documenter-dark .button:focus,html.theme--documenter-dark .button.is-focused{border-color:#8c9b9d;color:#17a689}html.theme--documenter-dark .button:focus:not(:active),html.theme--documenter-dark .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button:active,html.theme--documenter-dark .button.is-active{border-color:#343c3d;color:#f2f2f2}html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;color:#fff;text-decoration:underline}html.theme--documenter-dark .button.is-text:hover,html.theme--documenter-dark .button.is-text.is-hovered,html.theme--documenter-dark .button.is-text:focus,html.theme--documenter-dark .button.is-text.is-focused{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .button.is-text:active,html.theme--documenter-dark .button.is-text.is-active{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .button.is-text[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:hover,html.theme--documenter-dark .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus,html.theme--documenter-dark .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus:not(:active),html.theme--documenter-dark .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--documenter-dark .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-white.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:hover,html.theme--documenter-dark .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus,html.theme--documenter-dark .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus:not(:active),html.theme--documenter-dark .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:transparent;color:#282f2f}html.theme--documenter-dark .button.is-light:hover,html.theme--documenter-dark .button.is-light.is-hovered{background-color:#e5eaec;border-color:transparent;color:#282f2f}html.theme--documenter-dark .button.is-light:focus,html.theme--documenter-dark .button.is-light.is-focused{border-color:transparent;color:#282f2f}html.theme--documenter-dark .button.is-light:focus:not(:active),html.theme--documenter-dark .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light.is-active{background-color:#dde4e6;border-color:transparent;color:#282f2f}html.theme--documenter-dark .button.is-light[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-light.is-inverted{background-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-hovered{background-color:#1d2122}html.theme--documenter-dark .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted{background-color:#282f2f;border-color:transparent;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-loading::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-outlined.is-focused{background-color:#ecf0f1;border-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#282f2f;color:#282f2f}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-focused{background-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#282f2f;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark,html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:transparent;color:#ecf0f1}html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover,html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered{background-color:#232829;border-color:transparent;color:#ecf0f1}html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused{border-color:transparent;color:#ecf0f1}html.theme--documenter-dark .button.is-dark:focus:not(:active),html.theme--documenter-dark .content kbd.button:focus:not(:active),html.theme--documenter-dark .button.is-dark.is-focused:not(:active),html.theme--documenter-dark .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active{background-color:#1d2122;border-color:transparent;color:#ecf0f1}html.theme--documenter-dark .button.is-dark[disabled],html.theme--documenter-dark .content kbd.button[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark,fieldset[disabled] html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-dark.is-inverted,html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted:hover,html.theme--documenter-dark .content kbd.button.is-inverted:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-hovered{background-color:#dde4e6}html.theme--documenter-dark .button.is-dark.is-inverted[disabled],html.theme--documenter-dark .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#ecf0f1;border-color:transparent;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-loading::after,html.theme--documenter-dark .content kbd.button.is-loading::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-dark.is-outlined,html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-outlined.is-focused{background-color:#282f2f;border-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-dark.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#ecf0f1;color:#ecf0f1}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#ecf0f1;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-primary,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus:not(:active),html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--documenter-dark .button.is-primary.is-focused:not(:active),html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary[disabled],html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-primary.is-inverted,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--documenter-dark .button.is-primary.is-inverted[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:hover,html.theme--documenter-dark .button.is-link.is-hovered{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus,html.theme--documenter-dark .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus:not(:active),html.theme--documenter-dark .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link.is-active{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-outlined.is-focused{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:hover,html.theme--documenter-dark .button.is-info.is-hovered{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus,html.theme--documenter-dark .button.is-info.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus:not(:active),html.theme--documenter-dark .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info.is-active{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;color:#024c7d}html.theme--documenter-dark .button.is-info.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-outlined.is-focused{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:hover,html.theme--documenter-dark .button.is-success.is-hovered{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus,html.theme--documenter-dark .button.is-success.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus:not(:active),html.theme--documenter-dark .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success.is-active{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;color:#008438}html.theme--documenter-dark .button.is-success.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-outlined.is-focused{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:hover,html.theme--documenter-dark .button.is-warning.is-hovered{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus,html.theme--documenter-dark .button.is-warning.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus:not(:active),html.theme--documenter-dark .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning.is-active{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-outlined.is-focused{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-focused{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:hover,html.theme--documenter-dark .button.is-danger.is-hovered{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus,html.theme--documenter-dark .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus:not(:active),html.theme--documenter-dark .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger.is-active{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-outlined.is-focused{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{border-radius:3px;font-size:.85em}html.theme--documenter-dark .button.is-normal{font-size:15px}html.theme--documenter-dark .button.is-medium{font-size:1.25rem}html.theme--documenter-dark .button.is-large{font-size:1.5rem}html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .button{background-color:#8c9b9d;border-color:#dbdee0;box-shadow:none;opacity:.5}html.theme--documenter-dark .button.is-fullwidth{display:flex;width:100%}html.theme--documenter-dark .button.is-loading{color:transparent !important;pointer-events:none}html.theme--documenter-dark .button.is-loading::after{position:absolute;left:calc(50% - (1em / 2));top:calc(50% - (1em / 2));position:absolute !important}html.theme--documenter-dark .button.is-static{background-color:#282f2f;border-color:#5e6d6f;color:#dbdee0;box-shadow:none;pointer-events:none}html.theme--documenter-dark .button.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{border-radius:290486px;padding-left:1em;padding-right:1em}html.theme--documenter-dark .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .buttons .button{margin-bottom:0.5rem}html.theme--documenter-dark .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:0.5rem}html.theme--documenter-dark .buttons:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .buttons:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){border-radius:3px;font-size:.85em}html.theme--documenter-dark .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--documenter-dark .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--documenter-dark .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--documenter-dark .buttons.has-addons .button:last-child{margin-right:0}html.theme--documenter-dark .buttons.has-addons .button:hover,html.theme--documenter-dark .buttons.has-addons .button.is-hovered{z-index:2}html.theme--documenter-dark .buttons.has-addons .button:focus,html.theme--documenter-dark .buttons.has-addons .button.is-focused,html.theme--documenter-dark .buttons.has-addons .button:active,html.theme--documenter-dark .buttons.has-addons .button.is-active,html.theme--documenter-dark .buttons.has-addons .button.is-selected{z-index:3}html.theme--documenter-dark .buttons.has-addons .button:focus:hover,html.theme--documenter-dark .buttons.has-addons .button.is-focused:hover,html.theme--documenter-dark .buttons.has-addons .button:active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--documenter-dark .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .buttons.is-centered{justify-content:center}html.theme--documenter-dark .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--documenter-dark .buttons.is-right{justify-content:flex-end}html.theme--documenter-dark .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--documenter-dark .container{flex-grow:1;margin:0 auto;position:relative;width:auto}@media screen and (min-width: 1056px){html.theme--documenter-dark .container{max-width:992px}html.theme--documenter-dark .container.is-fluid{margin-left:32px;margin-right:32px;max-width:none}}@media screen and (max-width: 1215px){html.theme--documenter-dark .container.is-widescreen{max-width:1152px}}@media screen and (max-width: 1407px){html.theme--documenter-dark .container.is-fullhd{max-width:1344px}}@media screen and (min-width: 1216px){html.theme--documenter-dark .container{max-width:1152px}}@media screen and (min-width: 1408px){html.theme--documenter-dark .container{max-width:1344px}}html.theme--documenter-dark .content li+li{margin-top:0.25em}html.theme--documenter-dark .content p:not(:last-child),html.theme--documenter-dark .content dl:not(:last-child),html.theme--documenter-dark .content ol:not(:last-child),html.theme--documenter-dark .content ul:not(:last-child),html.theme--documenter-dark .content blockquote:not(:last-child),html.theme--documenter-dark .content pre:not(:last-child),html.theme--documenter-dark .content table:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .content h1,html.theme--documenter-dark .content h2,html.theme--documenter-dark .content h3,html.theme--documenter-dark .content h4,html.theme--documenter-dark .content h5,html.theme--documenter-dark .content h6{color:#f2f2f2;font-weight:600;line-height:1.125}html.theme--documenter-dark .content h1{font-size:2em;margin-bottom:0.5em}html.theme--documenter-dark .content h1:not(:first-child){margin-top:1em}html.theme--documenter-dark .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--documenter-dark .content h2:not(:first-child){margin-top:1.1428em}html.theme--documenter-dark .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--documenter-dark .content h3:not(:first-child){margin-top:1.3333em}html.theme--documenter-dark .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--documenter-dark .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--documenter-dark .content h6{font-size:1em;margin-bottom:1em}html.theme--documenter-dark .content blockquote{background-color:#282f2f;border-left:5px solid #5e6d6f;padding:1.25em 1.5em}html.theme--documenter-dark .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ol:not([type]){list-style-type:decimal}html.theme--documenter-dark .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--documenter-dark .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--documenter-dark .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--documenter-dark .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--documenter-dark .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--documenter-dark .content ul ul ul{list-style-type:square}html.theme--documenter-dark .content dd{margin-left:2em}html.theme--documenter-dark .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--documenter-dark .content figure:not(:first-child){margin-top:2em}html.theme--documenter-dark .content figure:not(:last-child){margin-bottom:2em}html.theme--documenter-dark .content figure img{display:inline-block}html.theme--documenter-dark .content figure figcaption{font-style:italic}html.theme--documenter-dark .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--documenter-dark .content sup,html.theme--documenter-dark .content sub{font-size:75%}html.theme--documenter-dark .content table{width:100%}html.theme--documenter-dark .content table td,html.theme--documenter-dark .content table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .content table th{color:#f2f2f2}html.theme--documenter-dark .content table th:not([align]){text-align:left}html.theme--documenter-dark .content table thead td,html.theme--documenter-dark .content table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .content table tfoot td,html.theme--documenter-dark .content table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .content table tbody tr:last-child td,html.theme--documenter-dark .content table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .content .tabs li+li{margin-top:0}html.theme--documenter-dark .content.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.content{font-size:.85em}html.theme--documenter-dark .content.is-medium{font-size:1.25rem}html.theme--documenter-dark .content.is-large{font-size:1.5rem}html.theme--documenter-dark .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--documenter-dark .icon.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--documenter-dark .icon.is-medium{height:2rem;width:2rem}html.theme--documenter-dark .icon.is-large{height:3rem;width:3rem}html.theme--documenter-dark .image,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--documenter-dark .image img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--documenter-dark .image img.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:290486px}html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--documenter-dark .image.is-square,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--documenter-dark .image.is-1by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--documenter-dark .image.is-5by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--documenter-dark .image.is-4by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--documenter-dark .image.is-3by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--documenter-dark .image.is-5by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--documenter-dark .image.is-16by9,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--documenter-dark .image.is-2by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--documenter-dark .image.is-3by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--documenter-dark .image.is-4by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--documenter-dark .image.is-3by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--documenter-dark .image.is-2by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--documenter-dark .image.is-3by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--documenter-dark .image.is-9by16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--documenter-dark .image.is-1by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--documenter-dark .image.is-1by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--documenter-dark .image.is-16x16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--documenter-dark .image.is-24x24,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--documenter-dark .image.is-32x32,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--documenter-dark .image.is-48x48,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--documenter-dark .image.is-64x64,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--documenter-dark .image.is-96x96,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--documenter-dark .image.is-128x128,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--documenter-dark .notification{background-color:#282f2f;border-radius:.4em;padding:1.25rem 2.5rem 1.25rem 1.5rem;position:relative}html.theme--documenter-dark .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .notification strong{color:currentColor}html.theme--documenter-dark .notification code,html.theme--documenter-dark .notification pre{background:#fff}html.theme--documenter-dark .notification pre code{background:transparent}html.theme--documenter-dark .notification>.delete{position:absolute;right:0.5rem;top:0.5rem}html.theme--documenter-dark .notification .title,html.theme--documenter-dark .notification .subtitle,html.theme--documenter-dark .notification .content{color:currentColor}html.theme--documenter-dark .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .notification.is-light{background-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .notification.is-dark,html.theme--documenter-dark .content kbd.notification{background-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .notification.is-primary,html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .notification.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .notification.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .notification.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .notification.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .notification.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:290486px;display:block;height:15px;overflow:hidden;padding:0;width:100%}html.theme--documenter-dark .progress::-webkit-progress-bar{background-color:#5e6d6f}html.theme--documenter-dark .progress::-webkit-progress-value{background-color:#dbdee0}html.theme--documenter-dark .progress::-moz-progress-bar{background-color:#dbdee0}html.theme--documenter-dark .progress::-ms-fill{background-color:#dbdee0;border:none}html.theme--documenter-dark .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--documenter-dark .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--documenter-dark .progress.is-white::-ms-fill{background-color:#fff}html.theme--documenter-dark .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-light::-webkit-progress-value{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-moz-progress-bar{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-ms-fill{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light:indeterminate{background-image:linear-gradient(to right, #ecf0f1 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-dark::-webkit-progress-value,html.theme--documenter-dark .content kbd.progress::-webkit-progress-value{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-moz-progress-bar,html.theme--documenter-dark .content kbd.progress::-moz-progress-bar{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-ms-fill,html.theme--documenter-dark .content kbd.progress::-ms-fill{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark:indeterminate,html.theme--documenter-dark .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #282f2f 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-primary::-webkit-progress-value,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-moz-progress-bar,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-ms-fill,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary:indeterminate,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #375a7f 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-link::-webkit-progress-value{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-moz-progress-bar{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-ms-fill{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link:indeterminate{background-image:linear-gradient(to right, #1abc9c 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-info::-webkit-progress-value{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-moz-progress-bar{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-ms-fill{background-color:#024c7d}html.theme--documenter-dark .progress.is-info:indeterminate{background-image:linear-gradient(to right, #024c7d 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-success::-webkit-progress-value{background-color:#008438}html.theme--documenter-dark .progress.is-success::-moz-progress-bar{background-color:#008438}html.theme--documenter-dark .progress.is-success::-ms-fill{background-color:#008438}html.theme--documenter-dark .progress.is-success:indeterminate{background-image:linear-gradient(to right, #008438 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-warning::-webkit-progress-value{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-moz-progress-bar{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-ms-fill{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ad8100 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress.is-danger::-webkit-progress-value{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-moz-progress-bar{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-ms-fill{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #9e1b0d 30%, #5e6d6f 30%)}html.theme--documenter-dark .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#5e6d6f;background-image:linear-gradient(to right, #fff 30%, #5e6d6f 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--documenter-dark .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--documenter-dark .progress.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.progress{height:.85em}html.theme--documenter-dark .progress.is-medium{height:1.25rem}html.theme--documenter-dark .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--documenter-dark .table{background-color:#343c3d;color:#fff}html.theme--documenter-dark .table td,html.theme--documenter-dark .table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .table td.is-white,html.theme--documenter-dark .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .table td.is-black,html.theme--documenter-dark .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .table td.is-light,html.theme--documenter-dark .table th.is-light{background-color:#ecf0f1;border-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .table td.is-dark,html.theme--documenter-dark .table th.is-dark{background-color:#282f2f;border-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .table td.is-primary,html.theme--documenter-dark .table th.is-primary{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-link,html.theme--documenter-dark .table th.is-link{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .table td.is-info,html.theme--documenter-dark .table th.is-info{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .table td.is-success,html.theme--documenter-dark .table th.is-success{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .table td.is-warning,html.theme--documenter-dark .table th.is-warning{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .table td.is-danger,html.theme--documenter-dark .table th.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .table td.is-narrow,html.theme--documenter-dark .table th.is-narrow{white-space:nowrap;width:1%}html.theme--documenter-dark .table td.is-selected,html.theme--documenter-dark .table th.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-selected a,html.theme--documenter-dark .table td.is-selected strong,html.theme--documenter-dark .table th.is-selected a,html.theme--documenter-dark .table th.is-selected strong{color:currentColor}html.theme--documenter-dark .table th{color:#f2f2f2}html.theme--documenter-dark .table th:not([align]){text-align:left}html.theme--documenter-dark .table tr.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table tr.is-selected a,html.theme--documenter-dark .table tr.is-selected strong{color:currentColor}html.theme--documenter-dark .table tr.is-selected td,html.theme--documenter-dark .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--documenter-dark .table thead{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table thead td,html.theme--documenter-dark .table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .table tfoot{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tfoot td,html.theme--documenter-dark .table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .table tbody{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tbody tr:last-child td,html.theme--documenter-dark .table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .table.is-bordered td,html.theme--documenter-dark .table.is-bordered th{border-width:1px}html.theme--documenter-dark .table.is-bordered tr:last-child td,html.theme--documenter-dark .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--documenter-dark .table.is-fullwidth{width:100%}html.theme--documenter-dark .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#2d3435}html.theme--documenter-dark .table.is-narrow td,html.theme--documenter-dark .table.is-narrow th{padding:0.25em 0.5em}html.theme--documenter-dark .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#282f2f}html.theme--documenter-dark .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--documenter-dark .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .tags .tag,html.theme--documenter-dark .tags .content kbd,html.theme--documenter-dark .content .tags kbd,html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--documenter-dark .tags .tag:not(:last-child),html.theme--documenter-dark .tags .content kbd:not(:last-child),html.theme--documenter-dark .content .tags kbd:not(:last-child),html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0.5rem}html.theme--documenter-dark .tags:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .tags:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:15px}html.theme--documenter-dark .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--documenter-dark .tags.is-centered{justify-content:center}html.theme--documenter-dark .tags.is-centered .tag,html.theme--documenter-dark .tags.is-centered .content kbd,html.theme--documenter-dark .content .tags.is-centered kbd,html.theme--documenter-dark .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--documenter-dark .tags.is-right{justify-content:flex-end}html.theme--documenter-dark .tags.is-right .tag:not(:first-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:first-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--documenter-dark .tags.is-right .tag:not(:last-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:last-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--documenter-dark .tags.has-addons .tag,html.theme--documenter-dark .tags.has-addons .content kbd,html.theme--documenter-dark .content .tags.has-addons kbd,html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--documenter-dark .tags.has-addons .tag:not(:first-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:first-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .tags.has-addons .tag:not(:last-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:last-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .tag:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#282f2f;border-radius:.4em;color:#fff;display:inline-flex;font-size:.85em;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--documenter-dark .tag:not(body) .delete,html.theme--documenter-dark .content kbd:not(body) .delete,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:0.25rem;margin-right:-0.375rem}html.theme--documenter-dark .tag.is-white:not(body),html.theme--documenter-dark .content kbd.is-white:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .tag.is-black:not(body),html.theme--documenter-dark .content kbd.is-black:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .tag.is-light:not(body),html.theme--documenter-dark .content kbd.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .tag.is-dark:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--documenter-dark .content .docstring>section>kbd:not(body){background-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .tag.is-primary:not(body),html.theme--documenter-dark .content kbd.is-primary:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){background-color:#375a7f;color:#fff}html.theme--documenter-dark .tag.is-link:not(body),html.theme--documenter-dark .content kbd.is-link:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#1abc9c;color:#fff}html.theme--documenter-dark .tag.is-info:not(body),html.theme--documenter-dark .content kbd.is-info:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#024c7d;color:#fff}html.theme--documenter-dark .tag.is-success:not(body),html.theme--documenter-dark .content kbd.is-success:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#008438;color:#fff}html.theme--documenter-dark .tag.is-warning:not(body),html.theme--documenter-dark .content kbd.is-warning:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ad8100;color:#fff}html.theme--documenter-dark .tag.is-danger:not(body),html.theme--documenter-dark .content kbd.is-danger:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .tag.is-normal:not(body),html.theme--documenter-dark .content kbd.is-normal:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.85em}html.theme--documenter-dark .tag.is-medium:not(body),html.theme--documenter-dark .content kbd.is-medium:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:15px}html.theme--documenter-dark .tag.is-large:not(body),html.theme--documenter-dark .content kbd.is-large:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--documenter-dark .tag:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-0.375em;margin-right:0.1875em}html.theme--documenter-dark .tag:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:0.1875em;margin-right:-0.375em}html.theme--documenter-dark .tag:not(body) .icon:first-child:last-child,html.theme--documenter-dark .content kbd:not(body) .icon:first-child:last-child,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-0.375em;margin-right:-0.375em}html.theme--documenter-dark .tag.is-delete:not(body),html.theme--documenter-dark .content kbd.is-delete:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--documenter-dark .tag.is-delete:not(body):hover,html.theme--documenter-dark .content kbd.is-delete:not(body):hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--documenter-dark .tag.is-delete:not(body):focus,html.theme--documenter-dark .content kbd.is-delete:not(body):focus,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#1d2122}html.theme--documenter-dark .tag.is-delete:not(body):active,html.theme--documenter-dark .content kbd.is-delete:not(body):active,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#111414}html.theme--documenter-dark .tag.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--documenter-dark .content kbd.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:290486px}html.theme--documenter-dark a.tag:hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--documenter-dark .title,html.theme--documenter-dark .subtitle{word-break:break-word}html.theme--documenter-dark .title em,html.theme--documenter-dark .title span,html.theme--documenter-dark .subtitle em,html.theme--documenter-dark .subtitle span{font-weight:inherit}html.theme--documenter-dark .title sub,html.theme--documenter-dark .subtitle sub{font-size:.75em}html.theme--documenter-dark .title sup,html.theme--documenter-dark .subtitle sup{font-size:.75em}html.theme--documenter-dark .title .tag,html.theme--documenter-dark .title .content kbd,html.theme--documenter-dark .content .title kbd,html.theme--documenter-dark .title .docstring>section>a.docs-sourcelink,html.theme--documenter-dark .subtitle .tag,html.theme--documenter-dark .subtitle .content kbd,html.theme--documenter-dark .content .subtitle kbd,html.theme--documenter-dark .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--documenter-dark .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--documenter-dark .title strong{color:inherit;font-weight:inherit}html.theme--documenter-dark .title+.highlight{margin-top:-0.75rem}html.theme--documenter-dark .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--documenter-dark .title.is-1{font-size:3rem}html.theme--documenter-dark .title.is-2{font-size:2.5rem}html.theme--documenter-dark .title.is-3{font-size:2rem}html.theme--documenter-dark .title.is-4{font-size:1.5rem}html.theme--documenter-dark .title.is-5{font-size:1.25rem}html.theme--documenter-dark .title.is-6{font-size:15px}html.theme--documenter-dark .title.is-7{font-size:.85em}html.theme--documenter-dark .subtitle{color:#8c9b9d;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--documenter-dark .subtitle strong{color:#8c9b9d;font-weight:600}html.theme--documenter-dark .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--documenter-dark .subtitle.is-1{font-size:3rem}html.theme--documenter-dark .subtitle.is-2{font-size:2.5rem}html.theme--documenter-dark .subtitle.is-3{font-size:2rem}html.theme--documenter-dark .subtitle.is-4{font-size:1.5rem}html.theme--documenter-dark .subtitle.is-5{font-size:1.25rem}html.theme--documenter-dark .subtitle.is-6{font-size:15px}html.theme--documenter-dark .subtitle.is-7{font-size:.85em}html.theme--documenter-dark .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--documenter-dark .highlight{font-weight:400;max-width:100%;overflow:hidden;padding:0}html.theme--documenter-dark .highlight pre{overflow:auto;max-width:100%}html.theme--documenter-dark .number{align-items:center;background-color:#282f2f;border-radius:290486px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#1f2424;border-color:#5e6d6f;border-radius:.4em;color:#dbdee0}html.theme--documenter-dark .select select::-moz-placeholder,html.theme--documenter-dark .textarea::-moz-placeholder,html.theme--documenter-dark .input::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(219,222,224,0.3)}html.theme--documenter-dark .select select::-webkit-input-placeholder,html.theme--documenter-dark .textarea::-webkit-input-placeholder,html.theme--documenter-dark .input::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(219,222,224,0.3)}html.theme--documenter-dark .select select:-moz-placeholder,html.theme--documenter-dark .textarea:-moz-placeholder,html.theme--documenter-dark .input:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(219,222,224,0.3)}html.theme--documenter-dark .select select:-ms-input-placeholder,html.theme--documenter-dark .textarea:-ms-input-placeholder,html.theme--documenter-dark .input:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(219,222,224,0.3)}html.theme--documenter-dark .select select:hover,html.theme--documenter-dark .textarea:hover,html.theme--documenter-dark .input:hover,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:hover,html.theme--documenter-dark .select select.is-hovered,html.theme--documenter-dark .is-hovered.textarea,html.theme--documenter-dark .is-hovered.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#8c9b9d}html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#1abc9c;box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#8c9b9d;border-color:#282f2f;box-shadow:none;color:#fff}html.theme--documenter-dark .select select[disabled]::-moz-placeholder,html.theme--documenter-dark .textarea[disabled]::-moz-placeholder,html.theme--documenter-dark .input[disabled]::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .textarea[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .input[disabled]::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-moz-placeholder,html.theme--documenter-dark .textarea[disabled]:-moz-placeholder,html.theme--documenter-dark .input[disabled]:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-ms-input-placeholder,html.theme--documenter-dark .textarea[disabled]:-ms-input-placeholder,html.theme--documenter-dark .input[disabled]:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 1px 2px rgba(10,10,10,0.1);max-width:100%;width:100%}html.theme--documenter-dark .textarea[readonly],html.theme--documenter-dark .input[readonly],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--documenter-dark .is-white.textarea,html.theme--documenter-dark .is-white.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--documenter-dark .is-white.textarea:focus,html.theme--documenter-dark .is-white.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--documenter-dark .is-white.is-focused.textarea,html.theme--documenter-dark .is-white.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-white.textarea:active,html.theme--documenter-dark .is-white.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--documenter-dark .is-white.is-active.textarea,html.theme--documenter-dark .is-white.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .is-black.textarea,html.theme--documenter-dark .is-black.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--documenter-dark .is-black.textarea:focus,html.theme--documenter-dark .is-black.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--documenter-dark .is-black.is-focused.textarea,html.theme--documenter-dark .is-black.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-black.textarea:active,html.theme--documenter-dark .is-black.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--documenter-dark .is-black.is-active.textarea,html.theme--documenter-dark .is-black.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .is-light.textarea,html.theme--documenter-dark .is-light.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#ecf0f1}html.theme--documenter-dark .is-light.textarea:focus,html.theme--documenter-dark .is-light.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--documenter-dark .is-light.is-focused.textarea,html.theme--documenter-dark .is-light.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-light.textarea:active,html.theme--documenter-dark .is-light.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--documenter-dark .is-light.is-active.textarea,html.theme--documenter-dark .is-light.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .is-dark.textarea,html.theme--documenter-dark .content kbd.textarea,html.theme--documenter-dark .is-dark.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--documenter-dark .content kbd.input{border-color:#282f2f}html.theme--documenter-dark .is-dark.textarea:focus,html.theme--documenter-dark .content kbd.textarea:focus,html.theme--documenter-dark .is-dark.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--documenter-dark .content kbd.input:focus,html.theme--documenter-dark .is-dark.is-focused.textarea,html.theme--documenter-dark .content kbd.is-focused.textarea,html.theme--documenter-dark .is-dark.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .content kbd.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--documenter-dark .is-dark.textarea:active,html.theme--documenter-dark .content kbd.textarea:active,html.theme--documenter-dark .is-dark.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--documenter-dark .content kbd.input:active,html.theme--documenter-dark .is-dark.is-active.textarea,html.theme--documenter-dark .content kbd.is-active.textarea,html.theme--documenter-dark .is-dark.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .content kbd.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .is-primary.textarea,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink{border-color:#375a7f}html.theme--documenter-dark .is-primary.textarea:focus,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.is-focused.textarea,html.theme--documenter-dark .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--documenter-dark .is-primary.textarea:active,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:active,html.theme--documenter-dark .is-primary.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:active,html.theme--documenter-dark .is-primary.is-active.textarea,html.theme--documenter-dark .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .is-link.textarea,html.theme--documenter-dark .is-link.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#1abc9c}html.theme--documenter-dark .is-link.textarea:focus,html.theme--documenter-dark .is-link.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--documenter-dark .is-link.is-focused.textarea,html.theme--documenter-dark .is-link.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-link.textarea:active,html.theme--documenter-dark .is-link.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--documenter-dark .is-link.is-active.textarea,html.theme--documenter-dark .is-link.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .is-info.textarea,html.theme--documenter-dark .is-info.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#024c7d}html.theme--documenter-dark .is-info.textarea:focus,html.theme--documenter-dark .is-info.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--documenter-dark .is-info.is-focused.textarea,html.theme--documenter-dark .is-info.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-info.textarea:active,html.theme--documenter-dark .is-info.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--documenter-dark .is-info.is-active.textarea,html.theme--documenter-dark .is-info.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .is-success.textarea,html.theme--documenter-dark .is-success.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#008438}html.theme--documenter-dark .is-success.textarea:focus,html.theme--documenter-dark .is-success.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--documenter-dark .is-success.is-focused.textarea,html.theme--documenter-dark .is-success.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-success.textarea:active,html.theme--documenter-dark .is-success.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--documenter-dark .is-success.is-active.textarea,html.theme--documenter-dark .is-success.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .is-warning.textarea,html.theme--documenter-dark .is-warning.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ad8100}html.theme--documenter-dark .is-warning.textarea:focus,html.theme--documenter-dark .is-warning.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--documenter-dark .is-warning.is-focused.textarea,html.theme--documenter-dark .is-warning.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-warning.textarea:active,html.theme--documenter-dark .is-warning.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--documenter-dark .is-warning.is-active.textarea,html.theme--documenter-dark .is-warning.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .is-danger.textarea,html.theme--documenter-dark .is-danger.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#9e1b0d}html.theme--documenter-dark .is-danger.textarea:focus,html.theme--documenter-dark .is-danger.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--documenter-dark .is-danger.is-focused.textarea,html.theme--documenter-dark .is-danger.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-danger.textarea:active,html.theme--documenter-dark .is-danger.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--documenter-dark .is-danger.is-active.textarea,html.theme--documenter-dark .is-danger.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .is-small.textarea,html.theme--documenter-dark .is-small.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.85em}html.theme--documenter-dark .is-medium.textarea,html.theme--documenter-dark .is-medium.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--documenter-dark .is-large.textarea,html.theme--documenter-dark .is-large.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--documenter-dark .is-fullwidth.textarea,html.theme--documenter-dark .is-fullwidth.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--documenter-dark .is-inline.textarea,html.theme--documenter-dark .is-inline.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--documenter-dark .input.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:290486px;padding-left:1em;padding-right:1em}html.theme--documenter-dark .input.is-static,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--documenter-dark .textarea{display:block;max-width:100%;min-width:100%;padding:0.625em;resize:vertical}html.theme--documenter-dark .textarea:not([rows]){max-height:600px;min-height:120px}html.theme--documenter-dark .textarea[rows]{height:initial}html.theme--documenter-dark .textarea.has-fixed-size{resize:none}html.theme--documenter-dark .radio,html.theme--documenter-dark .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--documenter-dark .radio input,html.theme--documenter-dark .checkbox input{cursor:pointer}html.theme--documenter-dark .radio:hover,html.theme--documenter-dark .checkbox:hover{color:#8c9b9d}html.theme--documenter-dark .radio[disabled],html.theme--documenter-dark .checkbox[disabled],fieldset[disabled] html.theme--documenter-dark .radio,fieldset[disabled] html.theme--documenter-dark .checkbox{color:#fff;cursor:not-allowed}html.theme--documenter-dark .radio+.radio{margin-left:0.5em}html.theme--documenter-dark .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--documenter-dark .select:not(.is-multiple){height:2.25em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border-color:#1abc9c;right:1.125em;z-index:4}html.theme--documenter-dark .select.is-rounded select,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select select{border-radius:290486px;padding-left:1em}html.theme--documenter-dark .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--documenter-dark .select select::-ms-expand{display:none}html.theme--documenter-dark .select select[disabled]:hover,fieldset[disabled] html.theme--documenter-dark .select select:hover{border-color:#282f2f}html.theme--documenter-dark .select select:not([multiple]){padding-right:2.5em}html.theme--documenter-dark .select select[multiple]{height:auto;padding:0}html.theme--documenter-dark .select select[multiple] option{padding:0.5em 1em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#8c9b9d}html.theme--documenter-dark .select.is-white:not(:hover)::after{border-color:#fff}html.theme--documenter-dark .select.is-white select{border-color:#fff}html.theme--documenter-dark .select.is-white select:hover,html.theme--documenter-dark .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--documenter-dark .select.is-white select:focus,html.theme--documenter-dark .select.is-white select.is-focused,html.theme--documenter-dark .select.is-white select:active,html.theme--documenter-dark .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select:hover,html.theme--documenter-dark .select.is-black select.is-hovered{border-color:#000}html.theme--documenter-dark .select.is-black select:focus,html.theme--documenter-dark .select.is-black select.is-focused,html.theme--documenter-dark .select.is-black select:active,html.theme--documenter-dark .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .select.is-light:not(:hover)::after{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select:hover,html.theme--documenter-dark .select.is-light select.is-hovered{border-color:#dde4e6}html.theme--documenter-dark .select.is-light select:focus,html.theme--documenter-dark .select.is-light select.is-focused,html.theme--documenter-dark .select.is-light select:active,html.theme--documenter-dark .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .select.is-dark:not(:hover)::after,html.theme--documenter-dark .content kbd.select:not(:hover)::after{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select,html.theme--documenter-dark .content kbd.select select{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select:hover,html.theme--documenter-dark .content kbd.select select:hover,html.theme--documenter-dark .select.is-dark select.is-hovered,html.theme--documenter-dark .content kbd.select select.is-hovered{border-color:#1d2122}html.theme--documenter-dark .select.is-dark select:focus,html.theme--documenter-dark .content kbd.select select:focus,html.theme--documenter-dark .select.is-dark select.is-focused,html.theme--documenter-dark .content kbd.select select.is-focused,html.theme--documenter-dark .select.is-dark select:active,html.theme--documenter-dark .content kbd.select select:active,html.theme--documenter-dark .select.is-dark select.is-active,html.theme--documenter-dark .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .select.is-primary:not(:hover)::after,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select:hover,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:hover,html.theme--documenter-dark .select.is-primary select.is-hovered,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#2f4d6d}html.theme--documenter-dark .select.is-primary select:focus,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:focus,html.theme--documenter-dark .select.is-primary select.is-focused,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--documenter-dark .select.is-primary select:active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:active,html.theme--documenter-dark .select.is-primary select.is-active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .select.is-link:not(:hover)::after{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select:hover,html.theme--documenter-dark .select.is-link select.is-hovered{border-color:#17a689}html.theme--documenter-dark .select.is-link select:focus,html.theme--documenter-dark .select.is-link select.is-focused,html.theme--documenter-dark .select.is-link select:active,html.theme--documenter-dark .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select.is-info:not(:hover)::after{border-color:#024c7d}html.theme--documenter-dark .select.is-info select{border-color:#024c7d}html.theme--documenter-dark .select.is-info select:hover,html.theme--documenter-dark .select.is-info select.is-hovered{border-color:#023d64}html.theme--documenter-dark .select.is-info select:focus,html.theme--documenter-dark .select.is-info select.is-focused,html.theme--documenter-dark .select.is-info select:active,html.theme--documenter-dark .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .select.is-success:not(:hover)::after{border-color:#008438}html.theme--documenter-dark .select.is-success select{border-color:#008438}html.theme--documenter-dark .select.is-success select:hover,html.theme--documenter-dark .select.is-success select.is-hovered{border-color:#006b2d}html.theme--documenter-dark .select.is-success select:focus,html.theme--documenter-dark .select.is-success select.is-focused,html.theme--documenter-dark .select.is-success select:active,html.theme--documenter-dark .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .select.is-warning:not(:hover)::after{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select:hover,html.theme--documenter-dark .select.is-warning select.is-hovered{border-color:#946e00}html.theme--documenter-dark .select.is-warning select:focus,html.theme--documenter-dark .select.is-warning select.is-focused,html.theme--documenter-dark .select.is-warning select:active,html.theme--documenter-dark .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .select.is-danger:not(:hover)::after{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select:hover,html.theme--documenter-dark .select.is-danger select.is-hovered{border-color:#86170b}html.theme--documenter-dark .select.is-danger select:focus,html.theme--documenter-dark .select.is-danger select.is-focused,html.theme--documenter-dark .select.is-danger select:active,html.theme--documenter-dark .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .select.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.85em}html.theme--documenter-dark .select.is-medium{font-size:1.25rem}html.theme--documenter-dark .select.is-large{font-size:1.5rem}html.theme--documenter-dark .select.is-disabled::after{border-color:#fff}html.theme--documenter-dark .select.is-fullwidth{width:100%}html.theme--documenter-dark .select.is-fullwidth select{width:100%}html.theme--documenter-dark .select.is-loading::after{margin-top:0;position:absolute;right:0.625em;top:0.625em;transform:none}html.theme--documenter-dark .select.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.85em}html.theme--documenter-dark .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .select.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--documenter-dark .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:hover .file-cta,html.theme--documenter-dark .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:focus .file-cta,html.theme--documenter-dark .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--documenter-dark .file.is-white:active .file-cta,html.theme--documenter-dark .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:hover .file-cta,html.theme--documenter-dark .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:focus .file-cta,html.theme--documenter-dark .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--documenter-dark .file.is-black:active .file-cta,html.theme--documenter-dark .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-light .file-cta{background-color:#ecf0f1;border-color:transparent;color:#282f2f}html.theme--documenter-dark .file.is-light:hover .file-cta,html.theme--documenter-dark .file.is-light.is-hovered .file-cta{background-color:#e5eaec;border-color:transparent;color:#282f2f}html.theme--documenter-dark .file.is-light:focus .file-cta,html.theme--documenter-dark .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(236,240,241,0.25);color:#282f2f}html.theme--documenter-dark .file.is-light:active .file-cta,html.theme--documenter-dark .file.is-light.is-active .file-cta{background-color:#dde4e6;border-color:transparent;color:#282f2f}html.theme--documenter-dark .file.is-dark .file-cta,html.theme--documenter-dark .content kbd.file .file-cta{background-color:#282f2f;border-color:transparent;color:#ecf0f1}html.theme--documenter-dark .file.is-dark:hover .file-cta,html.theme--documenter-dark .content kbd.file:hover .file-cta,html.theme--documenter-dark .file.is-dark.is-hovered .file-cta,html.theme--documenter-dark .content kbd.file.is-hovered .file-cta{background-color:#232829;border-color:transparent;color:#ecf0f1}html.theme--documenter-dark .file.is-dark:focus .file-cta,html.theme--documenter-dark .content kbd.file:focus .file-cta,html.theme--documenter-dark .file.is-dark.is-focused .file-cta,html.theme--documenter-dark .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(40,47,47,0.25);color:#ecf0f1}html.theme--documenter-dark .file.is-dark:active .file-cta,html.theme--documenter-dark .content kbd.file:active .file-cta,html.theme--documenter-dark .file.is-dark.is-active .file-cta,html.theme--documenter-dark .content kbd.file.is-active .file-cta{background-color:#1d2122;border-color:transparent;color:#ecf0f1}html.theme--documenter-dark .file.is-primary .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:hover .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--documenter-dark .file.is-primary.is-hovered .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:focus .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--documenter-dark .file.is-primary.is-focused .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(55,90,127,0.25);color:#fff}html.theme--documenter-dark .file.is-primary:active .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--documenter-dark .file.is-primary.is-active .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link .file-cta{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:hover .file-cta,html.theme--documenter-dark .file.is-link.is-hovered .file-cta{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:focus .file-cta,html.theme--documenter-dark .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(26,188,156,0.25);color:#fff}html.theme--documenter-dark .file.is-link:active .file-cta,html.theme--documenter-dark .file.is-link.is-active .file-cta{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info .file-cta{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:hover .file-cta,html.theme--documenter-dark .file.is-info.is-hovered .file-cta{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:focus .file-cta,html.theme--documenter-dark .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(2,76,125,0.25);color:#fff}html.theme--documenter-dark .file.is-info:active .file-cta,html.theme--documenter-dark .file.is-info.is-active .file-cta{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success .file-cta{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:hover .file-cta,html.theme--documenter-dark .file.is-success.is-hovered .file-cta{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:focus .file-cta,html.theme--documenter-dark .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(0,132,56,0.25);color:#fff}html.theme--documenter-dark .file.is-success:active .file-cta,html.theme--documenter-dark .file.is-success.is-active .file-cta{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning .file-cta{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:hover .file-cta,html.theme--documenter-dark .file.is-warning.is-hovered .file-cta{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:focus .file-cta,html.theme--documenter-dark .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(173,129,0,0.25);color:#fff}html.theme--documenter-dark .file.is-warning:active .file-cta,html.theme--documenter-dark .file.is-warning.is-active .file-cta{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger .file-cta{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:hover .file-cta,html.theme--documenter-dark .file.is-danger.is-hovered .file-cta{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:focus .file-cta,html.theme--documenter-dark .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(158,27,13,0.25);color:#fff}html.theme--documenter-dark .file.is-danger:active .file-cta,html.theme--documenter-dark .file.is-danger.is-active .file-cta{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.file{font-size:.85em}html.theme--documenter-dark .file.is-medium{font-size:1.25rem}html.theme--documenter-dark .file.is-medium .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-large{font-size:1.5rem}html.theme--documenter-dark .file.is-large .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--documenter-dark .file.has-name.is-empty .file-name{display:none}html.theme--documenter-dark .file.is-boxed .file-label{flex-direction:column}html.theme--documenter-dark .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--documenter-dark .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--documenter-dark .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--documenter-dark .file.is-boxed .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-boxed.is-small .file-icon .fa,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--documenter-dark .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--documenter-dark .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--documenter-dark .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--documenter-dark .file.is-centered{justify-content:center}html.theme--documenter-dark .file.is-fullwidth .file-label{width:100%}html.theme--documenter-dark .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--documenter-dark .file.is-right{justify-content:flex-end}html.theme--documenter-dark .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--documenter-dark .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--documenter-dark .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--documenter-dark .file-label:hover .file-cta{background-color:#e5eaec;color:#282f2f}html.theme--documenter-dark .file-label:hover .file-name{border-color:#596668}html.theme--documenter-dark .file-label:active .file-cta{background-color:#dde4e6;color:#282f2f}html.theme--documenter-dark .file-label:active .file-name{border-color:#535f61}html.theme--documenter-dark .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--documenter-dark .file-cta{background-color:#ecf0f1;color:#343c3d}html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:left;text-overflow:ellipsis}html.theme--documenter-dark .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:0.5em;width:1em}html.theme--documenter-dark .file-icon .fa{font-size:14px}html.theme--documenter-dark .label{color:#282f2f;display:block;font-size:15px;font-weight:700}html.theme--documenter-dark .label:not(:last-child){margin-bottom:0.5em}html.theme--documenter-dark .label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.label{font-size:.85em}html.theme--documenter-dark .label.is-medium{font-size:1.25rem}html.theme--documenter-dark .label.is-large{font-size:1.5rem}html.theme--documenter-dark .help{display:block;font-size:.85em;margin-top:0.25rem}html.theme--documenter-dark .help.is-white{color:#fff}html.theme--documenter-dark .help.is-black{color:#0a0a0a}html.theme--documenter-dark .help.is-light{color:#ecf0f1}html.theme--documenter-dark .help.is-dark,html.theme--documenter-dark .content kbd.help{color:#282f2f}html.theme--documenter-dark .help.is-primary,html.theme--documenter-dark .docstring>section>a.help.docs-sourcelink{color:#375a7f}html.theme--documenter-dark .help.is-link{color:#1abc9c}html.theme--documenter-dark .help.is-info{color:#024c7d}html.theme--documenter-dark .help.is-success{color:#008438}html.theme--documenter-dark .help.is-warning{color:#ad8100}html.theme--documenter-dark .help.is-danger{color:#9e1b0d}html.theme--documenter-dark .field:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.has-addons{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--documenter-dark .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.has-addons.has-addons-centered{justify-content:center}html.theme--documenter-dark .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--documenter-dark .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .field.is-grouped{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.is-grouped>.control{flex-shrink:0}html.theme--documenter-dark .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:0.75rem}html.theme--documenter-dark .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--documenter-dark .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field.is-horizontal{display:flex}}html.theme--documenter-dark .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--documenter-dark .field-label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.85em;padding-top:0.375em}html.theme--documenter-dark .field-label.is-normal{padding-top:0.375em}html.theme--documenter-dark .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--documenter-dark .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--documenter-dark .field-body .field{margin-bottom:0}html.theme--documenter-dark .field-body>.field{flex-shrink:1}html.theme--documenter-dark .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--documenter-dark .field-body>.field:not(:last-child){margin-right:0.75rem}}html.theme--documenter-dark .control{box-sizing:border-box;clear:both;font-size:15px;position:relative;text-align:left}html.theme--documenter-dark .control.has-icons-left .input:focus~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-left .select:focus~.icon,html.theme--documenter-dark .control.has-icons-right .input:focus~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-right .select:focus~.icon{color:#5e6d6f}html.theme--documenter-dark .control.has-icons-left .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-small~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-small~.icon{font-size:.85em}html.theme--documenter-dark .control.has-icons-left .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--documenter-dark .control.has-icons-left .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon{color:#dbdee0;height:2.25em;pointer-events:none;position:absolute;top:0;width:2.25em;z-index:4}html.theme--documenter-dark .control.has-icons-left .input,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--documenter-dark .control.has-icons-left .select select{padding-left:2.25em}html.theme--documenter-dark .control.has-icons-left .icon.is-left{left:0}html.theme--documenter-dark .control.has-icons-right .input,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--documenter-dark .control.has-icons-right .select select{padding-right:2.25em}html.theme--documenter-dark .control.has-icons-right .icon.is-right{right:0}html.theme--documenter-dark .control.is-loading::after{position:absolute !important;right:0.625em;top:0.625em;z-index:4}html.theme--documenter-dark .control.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.85em}html.theme--documenter-dark .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .control.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .breadcrumb{font-size:15px;white-space:nowrap}html.theme--documenter-dark .breadcrumb a{align-items:center;color:#1abc9c;display:flex;justify-content:center;padding:0 .75em}html.theme--documenter-dark .breadcrumb a:hover{color:#1dd2af}html.theme--documenter-dark .breadcrumb li{align-items:center;display:flex}html.theme--documenter-dark .breadcrumb li:first-child a{padding-left:0}html.theme--documenter-dark .breadcrumb li.is-active a{color:#f2f2f2;cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb li+li::before{color:#8c9b9d;content:"\0002f"}html.theme--documenter-dark .breadcrumb ul,html.theme--documenter-dark .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .breadcrumb .icon:first-child{margin-right:0.5em}html.theme--documenter-dark .breadcrumb .icon:last-child{margin-left:0.5em}html.theme--documenter-dark .breadcrumb.is-centered ol,html.theme--documenter-dark .breadcrumb.is-centered ul{justify-content:center}html.theme--documenter-dark .breadcrumb.is-right ol,html.theme--documenter-dark .breadcrumb.is-right ul{justify-content:flex-end}html.theme--documenter-dark .breadcrumb.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.85em}html.theme--documenter-dark .breadcrumb.is-medium{font-size:1.25rem}html.theme--documenter-dark .breadcrumb.is-large{font-size:1.5rem}html.theme--documenter-dark .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--documenter-dark .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--documenter-dark .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--documenter-dark .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--documenter-dark .card{background-color:#fff;box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px rgba(10,10,10,0.1);color:#fff;max-width:100%;position:relative}html.theme--documenter-dark .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 1px 2px rgba(10,10,10,0.1);display:flex}html.theme--documenter-dark .card-header-title{align-items:center;color:#f2f2f2;display:flex;flex-grow:1;font-weight:700;padding:.75rem}html.theme--documenter-dark .card-header-title.is-centered{justify-content:center}html.theme--documenter-dark .card-header-icon{align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem}html.theme--documenter-dark .card-image{display:block;position:relative}html.theme--documenter-dark .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--documenter-dark .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #5e6d6f;align-items:stretch;display:flex}html.theme--documenter-dark .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--documenter-dark .card-footer-item:not(:last-child){border-right:1px solid #5e6d6f}html.theme--documenter-dark .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--documenter-dark .dropdown.is-active .dropdown-menu,html.theme--documenter-dark .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--documenter-dark .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--documenter-dark .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--documenter-dark .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .dropdown-content{background-color:#282f2f;border-radius:.4em;box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px rgba(10,10,10,0.1);padding-bottom:.5rem;padding-top:.5rem}html.theme--documenter-dark .dropdown-item{color:#fff;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--documenter-dark a.dropdown-item,html.theme--documenter-dark button.dropdown-item{padding-right:3rem;text-align:left;white-space:nowrap;width:100%}html.theme--documenter-dark a.dropdown-item:hover,html.theme--documenter-dark button.dropdown-item:hover{background-color:#282f2f;color:#0a0a0a}html.theme--documenter-dark a.dropdown-item.is-active,html.theme--documenter-dark button.dropdown-item.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .dropdown-divider{background-color:#5e6d6f;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--documenter-dark .level{align-items:center;justify-content:space-between}html.theme--documenter-dark .level code{border-radius:.4em}html.theme--documenter-dark .level img{display:inline-block;vertical-align:top}html.theme--documenter-dark .level.is-mobile{display:flex}html.theme--documenter-dark .level.is-mobile .level-left,html.theme--documenter-dark .level.is-mobile .level-right{display:flex}html.theme--documenter-dark .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--documenter-dark .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level{display:flex}html.theme--documenter-dark .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--documenter-dark .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--documenter-dark .level-item .title,html.theme--documenter-dark .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--documenter-dark .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--documenter-dark .level-left,html.theme--documenter-dark .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .level-left .level-item.is-flexible,html.theme--documenter-dark .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left .level-item:not(:last-child),html.theme--documenter-dark .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--documenter-dark .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left{display:flex}}html.theme--documenter-dark .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-right{display:flex}}html.theme--documenter-dark .list{background-color:#fff;border-radius:.4em;box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px rgba(10,10,10,0.1)}html.theme--documenter-dark .list-item{display:block;padding:0.5em 1em}html.theme--documenter-dark .list-item:not(a){color:#fff}html.theme--documenter-dark .list-item:first-child{border-top-left-radius:.4em;border-top-right-radius:.4em}html.theme--documenter-dark .list-item:last-child{border-bottom-left-radius:.4em;border-bottom-right-radius:.4em}html.theme--documenter-dark .list-item:not(:last-child){border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .list-item.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark a.list-item{background-color:#282f2f;cursor:pointer}html.theme--documenter-dark .media{align-items:flex-start;display:flex;text-align:left}html.theme--documenter-dark .media .content:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .media .media{border-top:1px solid rgba(94,109,111,0.5);display:flex;padding-top:0.75rem}html.theme--documenter-dark .media .media .content:not(:last-child),html.theme--documenter-dark .media .media .control:not(:last-child){margin-bottom:0.5rem}html.theme--documenter-dark .media .media .media{padding-top:0.5rem}html.theme--documenter-dark .media .media .media+.media{margin-top:0.5rem}html.theme--documenter-dark .media+.media{border-top:1px solid rgba(94,109,111,0.5);margin-top:1rem;padding-top:1rem}html.theme--documenter-dark .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--documenter-dark .media-left,html.theme--documenter-dark .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .media-left{margin-right:1rem}html.theme--documenter-dark .media-right{margin-left:1rem}html.theme--documenter-dark .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:left}@media screen and (max-width: 768px){html.theme--documenter-dark .media-content{overflow-x:auto}}html.theme--documenter-dark .menu{font-size:15px}html.theme--documenter-dark .menu.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.menu{font-size:.85em}html.theme--documenter-dark .menu.is-medium{font-size:1.25rem}html.theme--documenter-dark .menu.is-large{font-size:1.5rem}html.theme--documenter-dark .menu-list{line-height:1.25}html.theme--documenter-dark .menu-list a{border-radius:3px;color:#fff;display:block;padding:0.5em 0.75em}html.theme--documenter-dark .menu-list a:hover{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .menu-list a.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .menu-list li ul{border-left:1px solid #5e6d6f;margin:.75em;padding-left:.75em}html.theme--documenter-dark .menu-label{color:#fff;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--documenter-dark .menu-label:not(:first-child){margin-top:1em}html.theme--documenter-dark .menu-label:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .message{background-color:#282f2f;border-radius:.4em;font-size:15px}html.theme--documenter-dark .message strong{color:currentColor}html.theme--documenter-dark .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .message.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.message{font-size:.85em}html.theme--documenter-dark .message.is-medium{font-size:1.25rem}html.theme--documenter-dark .message.is-large{font-size:1.5rem}html.theme--documenter-dark .message.is-white{background-color:#fff}html.theme--documenter-dark .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .message.is-white .message-body{border-color:#fff;color:#4d4d4d}html.theme--documenter-dark .message.is-black{background-color:#fafafa}html.theme--documenter-dark .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .message.is-black .message-body{border-color:#0a0a0a;color:#090909}html.theme--documenter-dark .message.is-light{background-color:#f9fafb}html.theme--documenter-dark .message.is-light .message-header{background-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .message.is-light .message-body{border-color:#ecf0f1;color:#505050}html.theme--documenter-dark .message.is-dark,html.theme--documenter-dark .content kbd.message{background-color:#f9fafa}html.theme--documenter-dark .message.is-dark .message-header,html.theme--documenter-dark .content kbd.message .message-header{background-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .message.is-dark .message-body,html.theme--documenter-dark .content kbd.message .message-body{border-color:#282f2f;color:#212526}html.theme--documenter-dark .message.is-primary,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink{background-color:#f8fafc}html.theme--documenter-dark .message.is-primary .message-header,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-header{background-color:#375a7f;color:#fff}html.theme--documenter-dark .message.is-primary .message-body,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-body{border-color:#375a7f;color:#2b4159}html.theme--documenter-dark .message.is-link{background-color:#f6fefc}html.theme--documenter-dark .message.is-link .message-header{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .message.is-link .message-body{border-color:#1abc9c;color:#0b2f28}html.theme--documenter-dark .message.is-info{background-color:#f5fbff}html.theme--documenter-dark .message.is-info .message-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .message.is-info .message-body{border-color:#024c7d;color:#033659}html.theme--documenter-dark .message.is-success{background-color:#f5fff9}html.theme--documenter-dark .message.is-success .message-header{background-color:#008438;color:#fff}html.theme--documenter-dark .message.is-success .message-body{border-color:#008438;color:#023518}html.theme--documenter-dark .message.is-warning{background-color:#fffcf5}html.theme--documenter-dark .message.is-warning .message-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .message.is-warning .message-body{border-color:#ad8100;color:#3d2e03}html.theme--documenter-dark .message.is-danger{background-color:#fef6f6}html.theme--documenter-dark .message.is-danger .message-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .message.is-danger .message-body{border-color:#9e1b0d;color:#7a170c}html.theme--documenter-dark .message-header{align-items:center;background-color:#fff;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--documenter-dark .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:0.75em}html.theme--documenter-dark .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--documenter-dark .message-body{border-color:#5e6d6f;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#fff;padding:1.25em 1.5em}html.theme--documenter-dark .message-body code,html.theme--documenter-dark .message-body pre{background-color:#fff}html.theme--documenter-dark .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--documenter-dark .modal.is-active{display:flex}html.theme--documenter-dark .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px),print{html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--documenter-dark .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--documenter-dark .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--documenter-dark .modal-card-head,html.theme--documenter-dark .modal-card-foot{align-items:center;background-color:#282f2f;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--documenter-dark .modal-card-head{border-bottom:1px solid #5e6d6f;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--documenter-dark .modal-card-title{color:#f2f2f2;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--documenter-dark .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #5e6d6f}html.theme--documenter-dark .modal-card-foot .button:not(:last-child){margin-right:0.5em}html.theme--documenter-dark .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--documenter-dark .navbar{background-color:#375a7f;min-height:4rem;position:relative;z-index:30}html.theme--documenter-dark .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-white .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--documenter-dark .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-black .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--documenter-dark .navbar.is-light{background-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link{color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#dde4e6;color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link::after{border-color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-burger{color:#282f2f}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-light .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link{color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#dde4e6;color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link::after{border-color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#dde4e6;color:#282f2f}html.theme--documenter-dark .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#ecf0f1;color:#282f2f}}html.theme--documenter-dark .navbar.is-dark,html.theme--documenter-dark .content kbd.navbar{background-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-brand>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link{color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#1d2122;color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-burger,html.theme--documenter-dark .content kbd.navbar .navbar-burger{color:#ecf0f1}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-dark .navbar-start>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-end>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link{color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#1d2122;color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link::after{border-color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1d2122;color:#ecf0f1}html.theme--documenter-dark .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#282f2f;color:#ecf0f1}}html.theme--documenter-dark .navbar.is-primary,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-burger,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-primary .navbar-start>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-end>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#375a7f;color:#fff}}html.theme--documenter-dark .navbar.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-link .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c;color:#fff}}html.theme--documenter-dark .navbar.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-info .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#024c7d;color:#fff}}html.theme--documenter-dark .navbar.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-success .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#008438;color:#fff}}html.theme--documenter-dark .navbar.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-warning .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ad8100;color:#fff}}html.theme--documenter-dark .navbar.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-danger .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#9e1b0d;color:#fff}}html.theme--documenter-dark .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--documenter-dark .navbar.has-shadow{box-shadow:0 2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-bottom,html.theme--documenter-dark .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-top{top:0}html.theme--documenter-dark html.has-navbar-fixed-top,html.theme--documenter-dark body.has-navbar-fixed-top{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom,html.theme--documenter-dark body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--documenter-dark .navbar-brand,html.theme--documenter-dark .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--documenter-dark .navbar-brand a.navbar-item:focus,html.theme--documenter-dark .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--documenter-dark .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--documenter-dark .navbar-burger{color:#fff;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--documenter-dark .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--documenter-dark .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--documenter-dark .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--documenter-dark .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--documenter-dark .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--documenter-dark .navbar-menu{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{color:#fff;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--documenter-dark .navbar-item .icon:only-child,html.theme--documenter-dark .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--documenter-dark a.navbar-item,html.theme--documenter-dark .navbar-link{cursor:pointer}html.theme--documenter-dark a.navbar-item:focus,html.theme--documenter-dark a.navbar-item:focus-within,html.theme--documenter-dark a.navbar-item:hover,html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link:focus,html.theme--documenter-dark .navbar-link:focus-within,html.theme--documenter-dark .navbar-link:hover,html.theme--documenter-dark .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-item{display:block;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .navbar-item img{max-height:1.75rem}html.theme--documenter-dark .navbar-item.has-dropdown{padding:0}html.theme--documenter-dark .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--documenter-dark .navbar-item.is-tab:focus,html.theme--documenter-dark .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c}html.theme--documenter-dark .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c;border-bottom-style:solid;border-bottom-width:3px;color:#1abc9c;padding-bottom:calc(0.5rem - 3px)}html.theme--documenter-dark .navbar-content{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--documenter-dark .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--documenter-dark .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar>.container{display:block}html.theme--documenter-dark .navbar-brand .navbar-item,html.theme--documenter-dark .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--documenter-dark .navbar-link::after{display:none}html.theme--documenter-dark .navbar-menu{background-color:#375a7f;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--documenter-dark .navbar-menu.is-active{display:block}html.theme--documenter-dark .navbar.is-fixed-bottom-touch,html.theme--documenter-dark .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-touch{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-touch{top:0}html.theme--documenter-dark .navbar.is-fixed-top .navbar-menu,html.theme--documenter-dark .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--documenter-dark html.has-navbar-fixed-top-touch,html.theme--documenter-dark body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-touch,html.theme--documenter-dark body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar,html.theme--documenter-dark .navbar-menu,html.theme--documenter-dark .navbar-start,html.theme--documenter-dark .navbar-end{align-items:stretch;display:flex}html.theme--documenter-dark .navbar{min-height:4rem}html.theme--documenter-dark .navbar.is-spaced{padding:1rem 2rem}html.theme--documenter-dark .navbar.is-spaced .navbar-start,html.theme--documenter-dark .navbar.is-spaced .navbar-end{align-items:center}html.theme--documenter-dark .navbar.is-spaced a.navbar-item,html.theme--documenter-dark .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent a.navbar-item:hover,html.theme--documenter-dark .navbar.is-transparent a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-transparent .navbar-link:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-link:hover,html.theme--documenter-dark .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-burger{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{align-items:center;display:flex}html.theme--documenter-dark .navbar-item{display:flex}html.theme--documenter-dark .navbar-item.has-dropdown{align-items:stretch}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--documenter-dark .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--documenter-dark .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--documenter-dark .navbar-dropdown{background-color:#375a7f;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--documenter-dark .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--documenter-dark .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}.navbar.is-spaced html.theme--documenter-dark .navbar-dropdown,html.theme--documenter-dark .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--documenter-dark .navbar-dropdown.is-right{left:auto;right:0}html.theme--documenter-dark .navbar-divider{display:block}html.theme--documenter-dark .navbar>.container .navbar-brand,html.theme--documenter-dark .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--documenter-dark .navbar>.container .navbar-menu,html.theme--documenter-dark .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop,html.theme--documenter-dark .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-desktop{top:0}html.theme--documenter-dark html.has-navbar-fixed-top-desktop,html.theme--documenter-dark body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-desktop,html.theme--documenter-dark body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-top,html.theme--documenter-dark body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-bottom,html.theme--documenter-dark body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link.is-active{color:#1abc9c}html.theme--documenter-dark a.navbar-item.is-active:not(:focus):not(:hover),html.theme--documenter-dark .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--documenter-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--documenter-dark .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--documenter-dark .pagination{font-size:15px;margin:-.25rem}html.theme--documenter-dark .pagination.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.85em}html.theme--documenter-dark .pagination.is-medium{font-size:1.25rem}html.theme--documenter-dark .pagination.is-large{font-size:1.5rem}html.theme--documenter-dark .pagination.is-rounded .pagination-previous,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--documenter-dark .pagination.is-rounded .pagination-next,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:290486px}html.theme--documenter-dark .pagination.is-rounded .pagination-link,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:290486px}html.theme--documenter-dark .pagination,html.theme--documenter-dark .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link{border-color:#5e6d6f;color:#1abc9c;min-width:2.25em}html.theme--documenter-dark .pagination-previous:hover,html.theme--documenter-dark .pagination-next:hover,html.theme--documenter-dark .pagination-link:hover{border-color:#8c9b9d;color:#1dd2af}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus{border-color:#8c9b9d}html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-link[disabled]{background-color:#dbdee0;border-color:#dbdee0;box-shadow:none;color:#5e6d6f;opacity:0.5}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--documenter-dark .pagination-link.is-current{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .pagination-ellipsis{color:#8c9b9d;pointer-events:none}html.theme--documenter-dark .pagination-list{flex-wrap:wrap}@media screen and (max-width: 768px){html.theme--documenter-dark .pagination{flex-wrap:wrap}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--documenter-dark .pagination-previous{order:2}html.theme--documenter-dark .pagination-next{order:3}html.theme--documenter-dark .pagination{justify-content:space-between}html.theme--documenter-dark .pagination.is-centered .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--documenter-dark .pagination.is-centered .pagination-next{order:3}html.theme--documenter-dark .pagination.is-right .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-right .pagination-next{order:2}html.theme--documenter-dark .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--documenter-dark .panel{font-size:15px}html.theme--documenter-dark .panel:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .panel-heading,html.theme--documenter-dark .panel-tabs,html.theme--documenter-dark .panel-block{border-bottom:1px solid #5e6d6f;border-left:1px solid #5e6d6f;border-right:1px solid #5e6d6f}html.theme--documenter-dark .panel-heading:first-child,html.theme--documenter-dark .panel-tabs:first-child,html.theme--documenter-dark .panel-block:first-child{border-top:1px solid #5e6d6f}html.theme--documenter-dark .panel-heading{background-color:#282f2f;border-radius:.4em .4em 0 0;color:#f2f2f2;font-size:1.25em;font-weight:300;line-height:1.25;padding:0.5em 0.75em}html.theme--documenter-dark .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--documenter-dark .panel-tabs a{border-bottom:1px solid #5e6d6f;margin-bottom:-1px;padding:0.5em}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#343c3d;color:#17a689}html.theme--documenter-dark .panel-list a{color:#fff}html.theme--documenter-dark .panel-list a:hover{color:#1abc9c}html.theme--documenter-dark .panel-block{align-items:center;color:#f2f2f2;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--documenter-dark .panel-block input[type="checkbox"]{margin-right:0.75em}html.theme--documenter-dark .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--documenter-dark .panel-block.is-wrapped{flex-wrap:wrap}html.theme--documenter-dark .panel-block.is-active{border-left-color:#1abc9c;color:#17a689}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark a.panel-block,html.theme--documenter-dark label.panel-block{cursor:pointer}html.theme--documenter-dark a.panel-block:hover,html.theme--documenter-dark label.panel-block:hover{background-color:#282f2f}html.theme--documenter-dark .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#fff;margin-right:0.75em}html.theme--documenter-dark .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--documenter-dark .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:15px;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--documenter-dark .tabs a{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;color:#fff;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--documenter-dark .tabs a:hover{border-bottom-color:#f2f2f2;color:#f2f2f2}html.theme--documenter-dark .tabs li{display:block}html.theme--documenter-dark .tabs li.is-active a{border-bottom-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .tabs ul{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--documenter-dark .tabs ul.is-left{padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--documenter-dark .tabs .icon:first-child{margin-right:0.5em}html.theme--documenter-dark .tabs .icon:last-child{margin-left:0.5em}html.theme--documenter-dark .tabs.is-centered ul{justify-content:center}html.theme--documenter-dark .tabs.is-right ul{justify-content:flex-end}html.theme--documenter-dark .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--documenter-dark .tabs.is-boxed a:hover{background-color:#282f2f;border-bottom-color:#5e6d6f}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#5e6d6f;border-bottom-color:rgba(0,0,0,0) !important}html.theme--documenter-dark .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .tabs.is-toggle a{border-color:#5e6d6f;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--documenter-dark .tabs.is-toggle a:hover{background-color:#282f2f;border-color:#8c9b9d;z-index:2}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .tabs.is-toggle li:first-child a{border-radius:.4em 0 0 .4em}html.theme--documenter-dark .tabs.is-toggle li:last-child a{border-radius:0 .4em .4em 0}html.theme--documenter-dark .tabs.is-toggle li.is-active a{background-color:#1abc9c;border-color:#1abc9c;color:#fff;z-index:1}html.theme--documenter-dark .tabs.is-toggle ul{border-bottom:none}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:290486px;border-top-left-radius:290486px;padding-left:1.25em}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:290486px;border-top-right-radius:290486px;padding-right:1.25em}html.theme--documenter-dark .tabs.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.85em}html.theme--documenter-dark .tabs.is-medium{font-size:1.25rem}html.theme--documenter-dark .tabs.is-large{font-size:1.5rem}html.theme--documenter-dark .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--documenter-dark .column.is-narrow{flex:none}.columns.is-mobile>html.theme--documenter-dark .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-1{flex:none;width:8.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-1{margin-left:8.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-2{flex:none;width:16.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-2{margin-left:16.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-4{flex:none;width:33.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-4{margin-left:33.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-5{flex:none;width:41.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-5{margin-left:41.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-7{flex:none;width:58.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-7{margin-left:58.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-8{flex:none;width:66.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-8{margin-left:66.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-10{flex:none;width:83.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-10{margin-left:83.3333333333%}.columns.is-mobile>html.theme--documenter-dark .column.is-11{flex:none;width:91.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-11{margin-left:91.6666666667%}.columns.is-mobile>html.theme--documenter-dark .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--documenter-dark .column.is-narrow-mobile{flex:none}html.theme--documenter-dark .column.is-full-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-mobile{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--documenter-dark .column.is-0-mobile{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-mobile{margin-left:0%}html.theme--documenter-dark .column.is-1-mobile{flex:none;width:8.3333333333%}html.theme--documenter-dark .column.is-offset-1-mobile{margin-left:8.3333333333%}html.theme--documenter-dark .column.is-2-mobile{flex:none;width:16.6666666667%}html.theme--documenter-dark .column.is-offset-2-mobile{margin-left:16.6666666667%}html.theme--documenter-dark .column.is-3-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-mobile{margin-left:25%}html.theme--documenter-dark .column.is-4-mobile{flex:none;width:33.3333333333%}html.theme--documenter-dark .column.is-offset-4-mobile{margin-left:33.3333333333%}html.theme--documenter-dark .column.is-5-mobile{flex:none;width:41.6666666667%}html.theme--documenter-dark .column.is-offset-5-mobile{margin-left:41.6666666667%}html.theme--documenter-dark .column.is-6-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-mobile{margin-left:50%}html.theme--documenter-dark .column.is-7-mobile{flex:none;width:58.3333333333%}html.theme--documenter-dark .column.is-offset-7-mobile{margin-left:58.3333333333%}html.theme--documenter-dark .column.is-8-mobile{flex:none;width:66.6666666667%}html.theme--documenter-dark .column.is-offset-8-mobile{margin-left:66.6666666667%}html.theme--documenter-dark .column.is-9-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-mobile{margin-left:75%}html.theme--documenter-dark .column.is-10-mobile{flex:none;width:83.3333333333%}html.theme--documenter-dark .column.is-offset-10-mobile{margin-left:83.3333333333%}html.theme--documenter-dark .column.is-11-mobile{flex:none;width:91.6666666667%}html.theme--documenter-dark .column.is-offset-11-mobile{margin-left:91.6666666667%}html.theme--documenter-dark .column.is-12-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .column.is-narrow,html.theme--documenter-dark .column.is-narrow-tablet{flex:none}html.theme--documenter-dark .column.is-full,html.theme--documenter-dark .column.is-full-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters,html.theme--documenter-dark .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds,html.theme--documenter-dark .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half,html.theme--documenter-dark .column.is-half-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third,html.theme--documenter-dark .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter,html.theme--documenter-dark .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth,html.theme--documenter-dark .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths,html.theme--documenter-dark .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths,html.theme--documenter-dark .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths,html.theme--documenter-dark .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters,html.theme--documenter-dark .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds,html.theme--documenter-dark .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half,html.theme--documenter-dark .column.is-offset-half-tablet{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third,html.theme--documenter-dark .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter,html.theme--documenter-dark .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth,html.theme--documenter-dark .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths,html.theme--documenter-dark .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths,html.theme--documenter-dark .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths,html.theme--documenter-dark .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--documenter-dark .column.is-0,html.theme--documenter-dark .column.is-0-tablet{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0,html.theme--documenter-dark .column.is-offset-0-tablet{margin-left:0%}html.theme--documenter-dark .column.is-1,html.theme--documenter-dark .column.is-1-tablet{flex:none;width:8.3333333333%}html.theme--documenter-dark .column.is-offset-1,html.theme--documenter-dark .column.is-offset-1-tablet{margin-left:8.3333333333%}html.theme--documenter-dark .column.is-2,html.theme--documenter-dark .column.is-2-tablet{flex:none;width:16.6666666667%}html.theme--documenter-dark .column.is-offset-2,html.theme--documenter-dark .column.is-offset-2-tablet{margin-left:16.6666666667%}html.theme--documenter-dark .column.is-3,html.theme--documenter-dark .column.is-3-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3,html.theme--documenter-dark .column.is-offset-3-tablet{margin-left:25%}html.theme--documenter-dark .column.is-4,html.theme--documenter-dark .column.is-4-tablet{flex:none;width:33.3333333333%}html.theme--documenter-dark .column.is-offset-4,html.theme--documenter-dark .column.is-offset-4-tablet{margin-left:33.3333333333%}html.theme--documenter-dark .column.is-5,html.theme--documenter-dark .column.is-5-tablet{flex:none;width:41.6666666667%}html.theme--documenter-dark .column.is-offset-5,html.theme--documenter-dark .column.is-offset-5-tablet{margin-left:41.6666666667%}html.theme--documenter-dark .column.is-6,html.theme--documenter-dark .column.is-6-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6,html.theme--documenter-dark .column.is-offset-6-tablet{margin-left:50%}html.theme--documenter-dark .column.is-7,html.theme--documenter-dark .column.is-7-tablet{flex:none;width:58.3333333333%}html.theme--documenter-dark .column.is-offset-7,html.theme--documenter-dark .column.is-offset-7-tablet{margin-left:58.3333333333%}html.theme--documenter-dark .column.is-8,html.theme--documenter-dark .column.is-8-tablet{flex:none;width:66.6666666667%}html.theme--documenter-dark .column.is-offset-8,html.theme--documenter-dark .column.is-offset-8-tablet{margin-left:66.6666666667%}html.theme--documenter-dark .column.is-9,html.theme--documenter-dark .column.is-9-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9,html.theme--documenter-dark .column.is-offset-9-tablet{margin-left:75%}html.theme--documenter-dark .column.is-10,html.theme--documenter-dark .column.is-10-tablet{flex:none;width:83.3333333333%}html.theme--documenter-dark .column.is-offset-10,html.theme--documenter-dark .column.is-offset-10-tablet{margin-left:83.3333333333%}html.theme--documenter-dark .column.is-11,html.theme--documenter-dark .column.is-11-tablet{flex:none;width:91.6666666667%}html.theme--documenter-dark .column.is-offset-11,html.theme--documenter-dark .column.is-offset-11-tablet{margin-left:91.6666666667%}html.theme--documenter-dark .column.is-12,html.theme--documenter-dark .column.is-12-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12,html.theme--documenter-dark .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--documenter-dark .column.is-narrow-touch{flex:none}html.theme--documenter-dark .column.is-full-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-touch{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-touch{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-touch{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-touch{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-touch{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--documenter-dark .column.is-0-touch{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-touch{margin-left:0%}html.theme--documenter-dark .column.is-1-touch{flex:none;width:8.3333333333%}html.theme--documenter-dark .column.is-offset-1-touch{margin-left:8.3333333333%}html.theme--documenter-dark .column.is-2-touch{flex:none;width:16.6666666667%}html.theme--documenter-dark .column.is-offset-2-touch{margin-left:16.6666666667%}html.theme--documenter-dark .column.is-3-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-touch{margin-left:25%}html.theme--documenter-dark .column.is-4-touch{flex:none;width:33.3333333333%}html.theme--documenter-dark .column.is-offset-4-touch{margin-left:33.3333333333%}html.theme--documenter-dark .column.is-5-touch{flex:none;width:41.6666666667%}html.theme--documenter-dark .column.is-offset-5-touch{margin-left:41.6666666667%}html.theme--documenter-dark .column.is-6-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-touch{margin-left:50%}html.theme--documenter-dark .column.is-7-touch{flex:none;width:58.3333333333%}html.theme--documenter-dark .column.is-offset-7-touch{margin-left:58.3333333333%}html.theme--documenter-dark .column.is-8-touch{flex:none;width:66.6666666667%}html.theme--documenter-dark .column.is-offset-8-touch{margin-left:66.6666666667%}html.theme--documenter-dark .column.is-9-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-touch{margin-left:75%}html.theme--documenter-dark .column.is-10-touch{flex:none;width:83.3333333333%}html.theme--documenter-dark .column.is-offset-10-touch{margin-left:83.3333333333%}html.theme--documenter-dark .column.is-11-touch{flex:none;width:91.6666666667%}html.theme--documenter-dark .column.is-offset-11-touch{margin-left:91.6666666667%}html.theme--documenter-dark .column.is-12-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--documenter-dark .column.is-narrow-desktop{flex:none}html.theme--documenter-dark .column.is-full-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-desktop{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--documenter-dark .column.is-0-desktop{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-desktop{margin-left:0%}html.theme--documenter-dark .column.is-1-desktop{flex:none;width:8.3333333333%}html.theme--documenter-dark .column.is-offset-1-desktop{margin-left:8.3333333333%}html.theme--documenter-dark .column.is-2-desktop{flex:none;width:16.6666666667%}html.theme--documenter-dark .column.is-offset-2-desktop{margin-left:16.6666666667%}html.theme--documenter-dark .column.is-3-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-desktop{margin-left:25%}html.theme--documenter-dark .column.is-4-desktop{flex:none;width:33.3333333333%}html.theme--documenter-dark .column.is-offset-4-desktop{margin-left:33.3333333333%}html.theme--documenter-dark .column.is-5-desktop{flex:none;width:41.6666666667%}html.theme--documenter-dark .column.is-offset-5-desktop{margin-left:41.6666666667%}html.theme--documenter-dark .column.is-6-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-desktop{margin-left:50%}html.theme--documenter-dark .column.is-7-desktop{flex:none;width:58.3333333333%}html.theme--documenter-dark .column.is-offset-7-desktop{margin-left:58.3333333333%}html.theme--documenter-dark .column.is-8-desktop{flex:none;width:66.6666666667%}html.theme--documenter-dark .column.is-offset-8-desktop{margin-left:66.6666666667%}html.theme--documenter-dark .column.is-9-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-desktop{margin-left:75%}html.theme--documenter-dark .column.is-10-desktop{flex:none;width:83.3333333333%}html.theme--documenter-dark .column.is-offset-10-desktop{margin-left:83.3333333333%}html.theme--documenter-dark .column.is-11-desktop{flex:none;width:91.6666666667%}html.theme--documenter-dark .column.is-offset-11-desktop{margin-left:91.6666666667%}html.theme--documenter-dark .column.is-12-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--documenter-dark .column.is-narrow-widescreen{flex:none}html.theme--documenter-dark .column.is-full-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--documenter-dark .column.is-0-widescreen{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-widescreen{margin-left:0%}html.theme--documenter-dark .column.is-1-widescreen{flex:none;width:8.3333333333%}html.theme--documenter-dark .column.is-offset-1-widescreen{margin-left:8.3333333333%}html.theme--documenter-dark .column.is-2-widescreen{flex:none;width:16.6666666667%}html.theme--documenter-dark .column.is-offset-2-widescreen{margin-left:16.6666666667%}html.theme--documenter-dark .column.is-3-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-4-widescreen{flex:none;width:33.3333333333%}html.theme--documenter-dark .column.is-offset-4-widescreen{margin-left:33.3333333333%}html.theme--documenter-dark .column.is-5-widescreen{flex:none;width:41.6666666667%}html.theme--documenter-dark .column.is-offset-5-widescreen{margin-left:41.6666666667%}html.theme--documenter-dark .column.is-6-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-7-widescreen{flex:none;width:58.3333333333%}html.theme--documenter-dark .column.is-offset-7-widescreen{margin-left:58.3333333333%}html.theme--documenter-dark .column.is-8-widescreen{flex:none;width:66.6666666667%}html.theme--documenter-dark .column.is-offset-8-widescreen{margin-left:66.6666666667%}html.theme--documenter-dark .column.is-9-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-10-widescreen{flex:none;width:83.3333333333%}html.theme--documenter-dark .column.is-offset-10-widescreen{margin-left:83.3333333333%}html.theme--documenter-dark .column.is-11-widescreen{flex:none;width:91.6666666667%}html.theme--documenter-dark .column.is-offset-11-widescreen{margin-left:91.6666666667%}html.theme--documenter-dark .column.is-12-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--documenter-dark .column.is-narrow-fullhd{flex:none}html.theme--documenter-dark .column.is-full-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--documenter-dark .column.is-0-fullhd{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-fullhd{margin-left:0%}html.theme--documenter-dark .column.is-1-fullhd{flex:none;width:8.3333333333%}html.theme--documenter-dark .column.is-offset-1-fullhd{margin-left:8.3333333333%}html.theme--documenter-dark .column.is-2-fullhd{flex:none;width:16.6666666667%}html.theme--documenter-dark .column.is-offset-2-fullhd{margin-left:16.6666666667%}html.theme--documenter-dark .column.is-3-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-4-fullhd{flex:none;width:33.3333333333%}html.theme--documenter-dark .column.is-offset-4-fullhd{margin-left:33.3333333333%}html.theme--documenter-dark .column.is-5-fullhd{flex:none;width:41.6666666667%}html.theme--documenter-dark .column.is-offset-5-fullhd{margin-left:41.6666666667%}html.theme--documenter-dark .column.is-6-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-7-fullhd{flex:none;width:58.3333333333%}html.theme--documenter-dark .column.is-offset-7-fullhd{margin-left:58.3333333333%}html.theme--documenter-dark .column.is-8-fullhd{flex:none;width:66.6666666667%}html.theme--documenter-dark .column.is-offset-8-fullhd{margin-left:66.6666666667%}html.theme--documenter-dark .column.is-9-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-10-fullhd{flex:none;width:83.3333333333%}html.theme--documenter-dark .column.is-offset-10-fullhd{margin-left:83.3333333333%}html.theme--documenter-dark .column.is-11-fullhd{flex:none;width:91.6666666667%}html.theme--documenter-dark .column.is-offset-11-fullhd{margin-left:91.6666666667%}html.theme--documenter-dark .column.is-12-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-fullhd{margin-left:100%}}html.theme--documenter-dark .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .columns:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--documenter-dark .columns.is-centered{justify-content:center}html.theme--documenter-dark .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--documenter-dark .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--documenter-dark .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .columns.is-gapless:last-child{margin-bottom:0}html.theme--documenter-dark .columns.is-mobile{display:flex}html.theme--documenter-dark .columns.is-multiline{flex-wrap:wrap}html.theme--documenter-dark .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-desktop{display:flex}}html.theme--documenter-dark .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--documenter-dark .columns.is-variable .column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--documenter-dark .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--documenter-dark .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--documenter-dark .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--documenter-dark .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--documenter-dark .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--documenter-dark .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--documenter-dark .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--documenter-dark .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--documenter-dark .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--documenter-dark .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--documenter-dark .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .tile.is-child{margin:0 !important}html.theme--documenter-dark .tile.is-parent{padding:.75rem}html.theme--documenter-dark .tile.is-vertical{flex-direction:column}html.theme--documenter-dark .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--documenter-dark .tile:not(.is-child){display:flex}html.theme--documenter-dark .tile.is-1{flex:none;width:8.3333333333%}html.theme--documenter-dark .tile.is-2{flex:none;width:16.6666666667%}html.theme--documenter-dark .tile.is-3{flex:none;width:25%}html.theme--documenter-dark .tile.is-4{flex:none;width:33.3333333333%}html.theme--documenter-dark .tile.is-5{flex:none;width:41.6666666667%}html.theme--documenter-dark .tile.is-6{flex:none;width:50%}html.theme--documenter-dark .tile.is-7{flex:none;width:58.3333333333%}html.theme--documenter-dark .tile.is-8{flex:none;width:66.6666666667%}html.theme--documenter-dark .tile.is-9{flex:none;width:75%}html.theme--documenter-dark .tile.is-10{flex:none;width:83.3333333333%}html.theme--documenter-dark .tile.is-11{flex:none;width:91.6666666667%}html.theme--documenter-dark .tile.is-12{flex:none;width:100%}}html.theme--documenter-dark .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--documenter-dark .hero .navbar{background:none}html.theme--documenter-dark .hero .tabs ul{border-bottom:none}html.theme--documenter-dark .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-white strong{color:inherit}html.theme--documenter-dark .hero.is-white .title{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--documenter-dark .hero.is-white .subtitle a:not(.button),html.theme--documenter-dark .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-white .navbar-menu{background-color:#fff}}html.theme--documenter-dark .hero.is-white .navbar-item,html.theme--documenter-dark .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--documenter-dark .hero.is-white a.navbar-item:hover,html.theme--documenter-dark .hero.is-white a.navbar-item.is-active,html.theme--documenter-dark .hero.is-white .navbar-link:hover,html.theme--documenter-dark .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--documenter-dark .hero.is-white .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-white .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--documenter-dark .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-black strong{color:inherit}html.theme--documenter-dark .hero.is-black .title{color:#fff}html.theme--documenter-dark .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-black .subtitle a:not(.button),html.theme--documenter-dark .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--documenter-dark .hero.is-black .navbar-item,html.theme--documenter-dark .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-black a.navbar-item:hover,html.theme--documenter-dark .hero.is-black a.navbar-item.is-active,html.theme--documenter-dark .hero.is-black .navbar-link:hover,html.theme--documenter-dark .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-black .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-black .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--documenter-dark .hero.is-light{background-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-light strong{color:inherit}html.theme--documenter-dark .hero.is-light .title{color:#282f2f}html.theme--documenter-dark .hero.is-light .subtitle{color:rgba(40,47,47,0.9)}html.theme--documenter-dark .hero.is-light .subtitle a:not(.button),html.theme--documenter-dark .hero.is-light .subtitle strong{color:#282f2f}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-light .navbar-menu{background-color:#ecf0f1}}html.theme--documenter-dark .hero.is-light .navbar-item,html.theme--documenter-dark .hero.is-light .navbar-link{color:rgba(40,47,47,0.7)}html.theme--documenter-dark .hero.is-light a.navbar-item:hover,html.theme--documenter-dark .hero.is-light a.navbar-item.is-active,html.theme--documenter-dark .hero.is-light .navbar-link:hover,html.theme--documenter-dark .hero.is-light .navbar-link.is-active{background-color:#dde4e6;color:#282f2f}html.theme--documenter-dark .hero.is-light .tabs a{color:#282f2f;opacity:0.9}html.theme--documenter-dark .hero.is-light .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-light .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a{color:#282f2f}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:#282f2f;border-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .hero.is-light.is-bold{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}}html.theme--documenter-dark .hero.is-dark,html.theme--documenter-dark .content kbd.hero{background-color:#282f2f;color:#ecf0f1}html.theme--documenter-dark .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-dark strong,html.theme--documenter-dark .content kbd.hero strong{color:inherit}html.theme--documenter-dark .hero.is-dark .title,html.theme--documenter-dark .content kbd.hero .title{color:#ecf0f1}html.theme--documenter-dark .hero.is-dark .subtitle,html.theme--documenter-dark .content kbd.hero .subtitle{color:rgba(236,240,241,0.9)}html.theme--documenter-dark .hero.is-dark .subtitle a:not(.button),html.theme--documenter-dark .content kbd.hero .subtitle a:not(.button),html.theme--documenter-dark .hero.is-dark .subtitle strong,html.theme--documenter-dark .content kbd.hero .subtitle strong{color:#ecf0f1}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-dark .navbar-menu,html.theme--documenter-dark .content kbd.hero .navbar-menu{background-color:#282f2f}}html.theme--documenter-dark .hero.is-dark .navbar-item,html.theme--documenter-dark .content kbd.hero .navbar-item,html.theme--documenter-dark .hero.is-dark .navbar-link,html.theme--documenter-dark .content kbd.hero .navbar-link{color:rgba(236,240,241,0.7)}html.theme--documenter-dark .hero.is-dark a.navbar-item:hover,html.theme--documenter-dark .content kbd.hero a.navbar-item:hover,html.theme--documenter-dark .hero.is-dark a.navbar-item.is-active,html.theme--documenter-dark .content kbd.hero a.navbar-item.is-active,html.theme--documenter-dark .hero.is-dark .navbar-link:hover,html.theme--documenter-dark .content kbd.hero .navbar-link:hover,html.theme--documenter-dark .hero.is-dark .navbar-link.is-active,html.theme--documenter-dark .content kbd.hero .navbar-link.is-active{background-color:#1d2122;color:#ecf0f1}html.theme--documenter-dark .hero.is-dark .tabs a,html.theme--documenter-dark .content kbd.hero .tabs a{color:#ecf0f1;opacity:0.9}html.theme--documenter-dark .hero.is-dark .tabs a:hover,html.theme--documenter-dark .content kbd.hero .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-dark .tabs li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a{color:#ecf0f1}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#ecf0f1;border-color:#ecf0f1;color:#282f2f}html.theme--documenter-dark .hero.is-dark.is-bold,html.theme--documenter-dark .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-dark.is-bold .navbar-menu,html.theme--documenter-dark .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}}html.theme--documenter-dark .hero.is-primary,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-primary strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--documenter-dark .hero.is-primary .title,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--documenter-dark .hero.is-primary .subtitle,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-primary .subtitle a:not(.button),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--documenter-dark .hero.is-primary .subtitle strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-primary .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#375a7f}}html.theme--documenter-dark .hero.is-primary .navbar-item,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--documenter-dark .hero.is-primary .navbar-link,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-primary a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--documenter-dark .hero.is-primary a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--documenter-dark .hero.is-primary .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--documenter-dark .hero.is-primary .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .hero.is-primary .tabs a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-primary .tabs a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-primary .tabs li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#375a7f}html.theme--documenter-dark .hero.is-primary.is-bold,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-primary.is-bold .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}}html.theme--documenter-dark .hero.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-link strong{color:inherit}html.theme--documenter-dark .hero.is-link .title{color:#fff}html.theme--documenter-dark .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-link .subtitle a:not(.button),html.theme--documenter-dark .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-link .navbar-menu{background-color:#1abc9c}}html.theme--documenter-dark .hero.is-link .navbar-item,html.theme--documenter-dark .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-link a.navbar-item:hover,html.theme--documenter-dark .hero.is-link a.navbar-item.is-active,html.theme--documenter-dark .hero.is-link .navbar-link:hover,html.theme--documenter-dark .hero.is-link .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-link .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-link .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1abc9c}html.theme--documenter-dark .hero.is-link.is-bold{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}}html.theme--documenter-dark .hero.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-info strong{color:inherit}html.theme--documenter-dark .hero.is-info .title{color:#fff}html.theme--documenter-dark .hero.is-info .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-info .subtitle a:not(.button),html.theme--documenter-dark .hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-info .navbar-menu{background-color:#024c7d}}html.theme--documenter-dark .hero.is-info .navbar-item,html.theme--documenter-dark .hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-info a.navbar-item:hover,html.theme--documenter-dark .hero.is-info a.navbar-item.is-active,html.theme--documenter-dark .hero.is-info .navbar-link:hover,html.theme--documenter-dark .hero.is-info .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .hero.is-info .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-info .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-info .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#024c7d}html.theme--documenter-dark .hero.is-info.is-bold{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}}html.theme--documenter-dark .hero.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-success strong{color:inherit}html.theme--documenter-dark .hero.is-success .title{color:#fff}html.theme--documenter-dark .hero.is-success .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-success .subtitle a:not(.button),html.theme--documenter-dark .hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-success .navbar-menu{background-color:#008438}}html.theme--documenter-dark .hero.is-success .navbar-item,html.theme--documenter-dark .hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-success a.navbar-item:hover,html.theme--documenter-dark .hero.is-success a.navbar-item.is-active,html.theme--documenter-dark .hero.is-success .navbar-link:hover,html.theme--documenter-dark .hero.is-success .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .hero.is-success .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-success .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-success .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#008438}html.theme--documenter-dark .hero.is-success.is-bold{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}}html.theme--documenter-dark .hero.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-warning strong{color:inherit}html.theme--documenter-dark .hero.is-warning .title{color:#fff}html.theme--documenter-dark .hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-warning .subtitle a:not(.button),html.theme--documenter-dark .hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-warning .navbar-menu{background-color:#ad8100}}html.theme--documenter-dark .hero.is-warning .navbar-item,html.theme--documenter-dark .hero.is-warning .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-warning a.navbar-item:hover,html.theme--documenter-dark .hero.is-warning a.navbar-item.is-active,html.theme--documenter-dark .hero.is-warning .navbar-link:hover,html.theme--documenter-dark .hero.is-warning .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .hero.is-warning .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-warning .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-warning .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ad8100}html.theme--documenter-dark .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}}html.theme--documenter-dark .hero.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-danger strong{color:inherit}html.theme--documenter-dark .hero.is-danger .title{color:#fff}html.theme--documenter-dark .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-danger .subtitle a:not(.button),html.theme--documenter-dark .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-danger .navbar-menu{background-color:#9e1b0d}}html.theme--documenter-dark .hero.is-danger .navbar-item,html.theme--documenter-dark .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-danger a.navbar-item:hover,html.theme--documenter-dark .hero.is-danger a.navbar-item.is-active,html.theme--documenter-dark .hero.is-danger .navbar-link:hover,html.theme--documenter-dark .hero.is-danger .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-danger .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-danger .tabs li.is-active a{opacity:1}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#9e1b0d}html.theme--documenter-dark .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}}html.theme--documenter-dark .hero.is-small .hero-body,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding-bottom:1.5rem;padding-top:1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-medium .hero-body{padding-bottom:9rem;padding-top:9rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-large .hero-body{padding-bottom:18rem;padding-top:18rem}}html.theme--documenter-dark .hero.is-halfheight .hero-body,html.theme--documenter-dark .hero.is-fullheight .hero-body,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--documenter-dark .hero.is-halfheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .hero.is-halfheight{min-height:50vh}html.theme--documenter-dark .hero.is-fullheight{min-height:100vh}html.theme--documenter-dark .hero-video{overflow:hidden}html.theme--documenter-dark .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--documenter-dark .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-video{display:none}}html.theme--documenter-dark .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-buttons .button{display:flex}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-buttons{display:flex;justify-content:center}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--documenter-dark .hero-head,html.theme--documenter-dark .hero-foot{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}html.theme--documenter-dark .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--documenter-dark .section.is-medium{padding:9rem 1.5rem}html.theme--documenter-dark .section.is-large{padding:18rem 1.5rem}}html.theme--documenter-dark .footer{background-color:#282f2f;padding:3rem 1.5rem 6rem}html.theme--documenter-dark hr{height:1px}html.theme--documenter-dark h6{text-transform:uppercase;letter-spacing:0.5px}html.theme--documenter-dark .hero{background-color:#343c3d}html.theme--documenter-dark a{transition:all 200ms ease}html.theme--documenter-dark .button{transition:all 200ms ease;border-width:1px;color:#fff}html.theme--documenter-dark .button.is-active,html.theme--documenter-dark .button.is-focused,html.theme--documenter-dark .button:active,html.theme--documenter-dark .button:focus{box-shadow:0 0 0 2px rgba(140,155,157,0.5)}html.theme--documenter-dark .button.is-white.is-hovered,html.theme--documenter-dark .button.is-white:hover{background-color:#fff}html.theme--documenter-dark .button.is-white.is-active,html.theme--documenter-dark .button.is-white.is-focused,html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white:focus{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,0.5)}html.theme--documenter-dark .button.is-black.is-hovered,html.theme--documenter-dark .button.is-black:hover{background-color:#1d1d1d}html.theme--documenter-dark .button.is-black.is-active,html.theme--documenter-dark .button.is-black.is-focused,html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black:focus{border-color:#0a0a0a;box-shadow:0 0 0 2px rgba(10,10,10,0.5)}html.theme--documenter-dark .button.is-light.is-hovered,html.theme--documenter-dark .button.is-light:hover{background-color:#fff}html.theme--documenter-dark .button.is-light.is-active,html.theme--documenter-dark .button.is-light.is-focused,html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light:focus{border-color:#ecf0f1;box-shadow:0 0 0 2px rgba(236,240,241,0.5)}html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered,html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover{background-color:#3a4344}html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused,html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus{border-color:#282f2f;box-shadow:0 0 0 2px rgba(40,47,47,0.5)}html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover{background-color:#436d9a}html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink,html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus{border-color:#375a7f;box-shadow:0 0 0 2px rgba(55,90,127,0.5)}html.theme--documenter-dark .button.is-link.is-hovered,html.theme--documenter-dark .button.is-link:hover{background-color:#1fdeb8}html.theme--documenter-dark .button.is-link.is-active,html.theme--documenter-dark .button.is-link.is-focused,html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link:focus{border-color:#1abc9c;box-shadow:0 0 0 2px rgba(26,188,156,0.5)}html.theme--documenter-dark .button.is-info.is-hovered,html.theme--documenter-dark .button.is-info:hover{background-color:#0363a3}html.theme--documenter-dark .button.is-info.is-active,html.theme--documenter-dark .button.is-info.is-focused,html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info:focus{border-color:#024c7d;box-shadow:0 0 0 2px rgba(2,76,125,0.5)}html.theme--documenter-dark .button.is-success.is-hovered,html.theme--documenter-dark .button.is-success:hover{background-color:#00aa48}html.theme--documenter-dark .button.is-success.is-active,html.theme--documenter-dark .button.is-success.is-focused,html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success:focus{border-color:#008438;box-shadow:0 0 0 2px rgba(0,132,56,0.5)}html.theme--documenter-dark .button.is-warning.is-hovered,html.theme--documenter-dark .button.is-warning:hover{background-color:#d39e00}html.theme--documenter-dark .button.is-warning.is-active,html.theme--documenter-dark .button.is-warning.is-focused,html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning:focus{border-color:#ad8100;box-shadow:0 0 0 2px rgba(173,129,0,0.5)}html.theme--documenter-dark .button.is-danger.is-hovered,html.theme--documenter-dark .button.is-danger:hover{background-color:#c12110}html.theme--documenter-dark .button.is-danger.is-active,html.theme--documenter-dark .button.is-danger.is-focused,html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger:focus{border-color:#9e1b0d;box-shadow:0 0 0 2px rgba(158,27,13,0.5)}html.theme--documenter-dark .label{color:#dbdee0}html.theme--documenter-dark .button,html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .select,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea{height:2.5em}html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em}html.theme--documenter-dark .select:after,html.theme--documenter-dark .select select{border-width:1px}html.theme--documenter-dark .control.has-addons .button,html.theme--documenter-dark .control.has-addons .input,html.theme--documenter-dark .control.has-addons #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-addons form.docs-search>input,html.theme--documenter-dark .control.has-addons .select{margin-right:-1px}html.theme--documenter-dark .notification{background-color:#343c3d}html.theme--documenter-dark .card{box-shadow:none;border:1px solid #343c3d;background-color:#282f2f;border-radius:.4em}html.theme--documenter-dark .card .card-image img{border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-header{box-shadow:none;background-color:rgba(18,18,18,0.2);border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-footer{background-color:rgba(18,18,18,0.2)}html.theme--documenter-dark .card .card-footer,html.theme--documenter-dark .card .card-footer-item{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .notification.is-white a:not(.button){color:#0a0a0a;text-decoration:underline}html.theme--documenter-dark .notification.is-black a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-light a:not(.button){color:#282f2f;text-decoration:underline}html.theme--documenter-dark .notification.is-dark a:not(.button),html.theme--documenter-dark .content kbd.notification a:not(.button){color:#ecf0f1;text-decoration:underline}html.theme--documenter-dark .notification.is-primary a:not(.button),html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-link a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-info a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-success a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-warning a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-danger a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .tag,html.theme--documenter-dark .content kbd,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{border-radius:.4em}html.theme--documenter-dark .menu-list a{transition:all 300ms ease}html.theme--documenter-dark .modal-card-body{background-color:#282f2f}html.theme--documenter-dark .modal-card-foot,html.theme--documenter-dark .modal-card-head{border-color:#343c3d}html.theme--documenter-dark .message-header{font-weight:700;background-color:#343c3d;color:#fff}html.theme--documenter-dark .message-body{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .navbar{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent{background:none}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar .navbar-menu{background-color:#375a7f;border-radius:0 0 .4em .4em}}html.theme--documenter-dark .hero .navbar,html.theme--documenter-dark body>.navbar{border-radius:0}html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous{border-width:1px}html.theme--documenter-dark .panel-block,html.theme--documenter-dark .panel-heading,html.theme--documenter-dark .panel-tabs{border-width:1px}html.theme--documenter-dark .panel-block:first-child,html.theme--documenter-dark .panel-heading:first-child,html.theme--documenter-dark .panel-tabs:first-child{border-top-width:1px}html.theme--documenter-dark .panel-heading{font-weight:700}html.theme--documenter-dark .panel-tabs a{border-width:1px;margin-bottom:-1px}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#17a689}html.theme--documenter-dark .panel-block:hover{color:#1dd2af}html.theme--documenter-dark .panel-block:hover .panel-icon{color:#1dd2af}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#17a689}html.theme--documenter-dark .tabs a{border-bottom-width:1px;margin-bottom:-1px}html.theme--documenter-dark .tabs ul{border-bottom-width:1px}html.theme--documenter-dark .tabs.is-boxed a{border-width:1px}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#1f2424}html.theme--documenter-dark .tabs.is-toggle li a{border-width:1px;margin-bottom:0}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .hero.is-white .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-black .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-light .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-dark .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .content kbd.hero .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-primary .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-link .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-info .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-success .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-warning .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-danger .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark h1 .docs-heading-anchor,html.theme--documenter-dark h1 .docs-heading-anchor:hover,html.theme--documenter-dark h1 .docs-heading-anchor:visited,html.theme--documenter-dark h2 .docs-heading-anchor,html.theme--documenter-dark h2 .docs-heading-anchor:hover,html.theme--documenter-dark h2 .docs-heading-anchor:visited,html.theme--documenter-dark h3 .docs-heading-anchor,html.theme--documenter-dark h3 .docs-heading-anchor:hover,html.theme--documenter-dark h3 .docs-heading-anchor:visited,html.theme--documenter-dark h4 .docs-heading-anchor,html.theme--documenter-dark h4 .docs-heading-anchor:hover,html.theme--documenter-dark h4 .docs-heading-anchor:visited,html.theme--documenter-dark h5 .docs-heading-anchor,html.theme--documenter-dark h5 .docs-heading-anchor:hover,html.theme--documenter-dark h5 .docs-heading-anchor:visited,html.theme--documenter-dark h6 .docs-heading-anchor,html.theme--documenter-dark h6 .docs-heading-anchor:hover,html.theme--documenter-dark h6 .docs-heading-anchor:visited{color:#f2f2f2}html.theme--documenter-dark h1 .docs-heading-anchor-permalink,html.theme--documenter-dark h2 .docs-heading-anchor-permalink,html.theme--documenter-dark h3 .docs-heading-anchor-permalink,html.theme--documenter-dark h4 .docs-heading-anchor-permalink,html.theme--documenter-dark h5 .docs-heading-anchor-permalink,html.theme--documenter-dark h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--documenter-dark h1 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h2 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h3 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h4 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h5 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 5 Free";font-weight:900;content:"\f0c1"}html.theme--documenter-dark h1:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h2:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h3:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h4:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h5:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--documenter-dark .docs-light-only{display:none !important}html.theme--documenter-dark pre{position:relative;overflow:hidden}html.theme--documenter-dark pre code,html.theme--documenter-dark pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--documenter-dark pre code:first-of-type,html.theme--documenter-dark pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--documenter-dark pre code:last-of-type,html.theme--documenter-dark pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--documenter-dark pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 5 Free";color:#fff;cursor:pointer;text-align:center}html.theme--documenter-dark pre .copy-button:focus,html.theme--documenter-dark pre .copy-button:hover{opacity:1;background:rgba(255,255,255,0.1);color:#1abc9c}html.theme--documenter-dark pre .copy-button.success{color:#259a12;opacity:1}html.theme--documenter-dark pre .copy-button.error{color:#cb3c33;opacity:1}html.theme--documenter-dark pre:hover .copy-button{opacity:1}html.theme--documenter-dark .admonition{background-color:#282f2f;border-style:solid;border-width:1px;border-color:#5e6d6f;border-radius:.4em;font-size:15px}html.theme--documenter-dark .admonition strong{color:currentColor}html.theme--documenter-dark .admonition.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.85em}html.theme--documenter-dark .admonition.is-medium{font-size:1.25rem}html.theme--documenter-dark .admonition.is-large{font-size:1.5rem}html.theme--documenter-dark .admonition.is-default{background-color:#282f2f;border-color:#5e6d6f}html.theme--documenter-dark .admonition.is-default>.admonition-header{background-color:#5e6d6f;color:#fff}html.theme--documenter-dark .admonition.is-default>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-info{background-color:#282f2f;border-color:#024c7d}html.theme--documenter-dark .admonition.is-info>.admonition-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .admonition.is-info>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-success{background-color:#282f2f;border-color:#008438}html.theme--documenter-dark .admonition.is-success>.admonition-header{background-color:#008438;color:#fff}html.theme--documenter-dark .admonition.is-success>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-warning{background-color:#282f2f;border-color:#ad8100}html.theme--documenter-dark .admonition.is-warning>.admonition-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .admonition.is-warning>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-danger{background-color:#282f2f;border-color:#9e1b0d}html.theme--documenter-dark .admonition.is-danger>.admonition-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .admonition.is-danger>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-compat{background-color:#282f2f;border-color:#137886}html.theme--documenter-dark .admonition.is-compat>.admonition-header{background-color:#137886;color:#fff}html.theme--documenter-dark .admonition.is-compat>.admonition-body{color:#fff}html.theme--documenter-dark .admonition-header{color:#fff;background-color:#5e6d6f;align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--documenter-dark .admonition-header:before{font-family:"Font Awesome 5 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--documenter-dark .admonition-body{color:#fff;padding:0.5rem .75rem}html.theme--documenter-dark .admonition-body pre{background-color:#282f2f}html.theme--documenter-dark .admonition-body code{background-color:rgba(255,255,255,0.05)}html.theme--documenter-dark .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:1px solid #5e6d6f;box-shadow:none;max-width:100%}html.theme--documenter-dark .docstring>header{display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#282f2f;box-shadow:0 1px 2px rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>header code{background-color:transparent}html.theme--documenter-dark .docstring>header .docstring-binding{margin-right:0.3em}html.theme--documenter-dark .docstring>header .docstring-category{margin-left:0.3em}html.theme--documenter-dark .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>section:last-child{border-bottom:none}html.theme--documenter-dark .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--documenter-dark .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--documenter-dark .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--documenter-dark .documenter-example-output{background-color:#1f2424}html.theme--documenter-dark .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#282f2f;color:#fff;border-bottom:3px solid #9e1b0d;padding:10px 35px;text-align:center;font-size:15px}html.theme--documenter-dark .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--documenter-dark .outdated-warning-overlay a{color:#1abc9c}html.theme--documenter-dark .outdated-warning-overlay a:hover{color:#1dd2af}html.theme--documenter-dark .content pre{border:1px solid #5e6d6f}html.theme--documenter-dark .content code{font-weight:inherit}html.theme--documenter-dark .content a code{color:#1abc9c}html.theme--documenter-dark .content h1 code,html.theme--documenter-dark .content h2 code,html.theme--documenter-dark .content h3 code,html.theme--documenter-dark .content h4 code,html.theme--documenter-dark .content h5 code,html.theme--documenter-dark .content h6 code{color:#f2f2f2}html.theme--documenter-dark .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--documenter-dark .content blockquote>ul:first-child,html.theme--documenter-dark .content blockquote>ol:first-child,html.theme--documenter-dark .content .admonition-body>ul:first-child,html.theme--documenter-dark .content .admonition-body>ol:first-child{margin-top:0}html.theme--documenter-dark pre,html.theme--documenter-dark code{font-variant-ligatures:no-contextual}html.theme--documenter-dark .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb a.is-disabled,html.theme--documenter-dark .breadcrumb a.is-disabled:hover{color:#f2f2f2}html.theme--documenter-dark .hljs{background:initial !important}html.theme--documenter-dark .katex .katex-mathml{top:0;right:0}html.theme--documenter-dark .katex-display,html.theme--documenter-dark mjx-container,html.theme--documenter-dark .MathJax_Display{margin:0.5em 0 !important}html.theme--documenter-dark html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--documenter-dark li.no-marker{list-style:none}html.theme--documenter-dark #documenter .docs-main>article{overflow-wrap:break-word}html.theme--documenter-dark #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main{width:100%}html.theme--documenter-dark #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-main>header,html.theme--documenter-dark #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar{background-color:#1f2424;border-bottom:1px solid #5e6d6f;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label,html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button{display:inline-block}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-settings-button{margin:auto 0 auto 1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button{font-size:1.5rem;margin:auto 0 auto 1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--documenter-dark #documenter .docs-main section.footnotes{border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-main section.footnotes li .tag:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--documenter-dark .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--documenter-dark #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5e6d6f;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--documenter-dark #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--documenter-dark #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--documenter-dark #documenter .docs-sidebar{display:flex;flex-direction:column;color:#fff;background-color:#282f2f;border-right:1px solid #5e6d6f;padding:0;flex:0 0 18rem;z-index:5;font-size:15px;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--documenter-dark #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar{left:0;top:0}}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a,html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a:hover{color:#fff}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5e6d6f;display:none;padding:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5e6d6f;padding-bottom:1.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li li{font-size:14.25px;margin-left:1em;border-left:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:11.25px;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 5 Free";font-weight:900;content:"\f054"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#fff;background:#282f2f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#fff;background-color:#32393a}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5e6d6f;border-bottom:1px solid #5e6d6f;background-color:#1f2424}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#1f2424;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#32393a;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:12.75px;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{width:14.4rem}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}html.theme--documenter-dark #documenter .docs-main #documenter-search-info{margin-bottom:1rem}html.theme--documenter-dark #documenter .docs-main #documenter-search-results{list-style-type:circle;list-style-position:outside}html.theme--documenter-dark #documenter .docs-main #documenter-search-results li{margin-left:2rem}html.theme--documenter-dark #documenter .docs-main #documenter-search-results .docs-highlight{background-color:yellow}html.theme--documenter-dark{background-color:#1f2424;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark .ansi span.sgr1{font-weight:bolder}html.theme--documenter-dark .ansi span.sgr2{font-weight:lighter}html.theme--documenter-dark .ansi span.sgr3{font-style:italic}html.theme--documenter-dark .ansi span.sgr4{text-decoration:underline}html.theme--documenter-dark .ansi span.sgr7{color:#1f2424;background-color:#fff}html.theme--documenter-dark .ansi span.sgr8{color:transparent}html.theme--documenter-dark .ansi span.sgr8 span{color:transparent}html.theme--documenter-dark .ansi span.sgr9{text-decoration:line-through}html.theme--documenter-dark .ansi span.sgr30{color:#242424}html.theme--documenter-dark .ansi span.sgr31{color:#f6705f}html.theme--documenter-dark .ansi span.sgr32{color:#4fb43a}html.theme--documenter-dark .ansi span.sgr33{color:#f4c72f}html.theme--documenter-dark .ansi span.sgr34{color:#7587f0}html.theme--documenter-dark .ansi span.sgr35{color:#bc89d3}html.theme--documenter-dark .ansi span.sgr36{color:#49b6ca}html.theme--documenter-dark .ansi span.sgr37{color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr40{background-color:#242424}html.theme--documenter-dark .ansi span.sgr41{background-color:#f6705f}html.theme--documenter-dark .ansi span.sgr42{background-color:#4fb43a}html.theme--documenter-dark .ansi span.sgr43{background-color:#f4c72f}html.theme--documenter-dark .ansi span.sgr44{background-color:#7587f0}html.theme--documenter-dark .ansi span.sgr45{background-color:#bc89d3}html.theme--documenter-dark .ansi span.sgr46{background-color:#49b6ca}html.theme--documenter-dark .ansi span.sgr47{background-color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr90{color:#92a0a2}html.theme--documenter-dark .ansi span.sgr91{color:#ff8674}html.theme--documenter-dark .ansi span.sgr92{color:#79d462}html.theme--documenter-dark .ansi span.sgr93{color:#ffe76b}html.theme--documenter-dark .ansi span.sgr94{color:#8a98ff}html.theme--documenter-dark .ansi span.sgr95{color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr96{color:#6bc8db}html.theme--documenter-dark .ansi span.sgr97{color:#ecf0f1}html.theme--documenter-dark .ansi span.sgr100{background-color:#92a0a2}html.theme--documenter-dark .ansi span.sgr101{background-color:#ff8674}html.theme--documenter-dark .ansi span.sgr102{background-color:#79d462}html.theme--documenter-dark .ansi span.sgr103{background-color:#ffe76b}html.theme--documenter-dark .ansi span.sgr104{background-color:#8a98ff}html.theme--documenter-dark .ansi span.sgr105{background-color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr106{background-color:#6bc8db}html.theme--documenter-dark .ansi span.sgr107{background-color:#ecf0f1}html.theme--documenter-dark code.language-julia-repl>span.hljs-meta{color:#4fb43a;font-weight:bolder}html.theme--documenter-dark .hljs{background:#2b2b2b;color:#f8f8f2}html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-quote{color:#d4d0ab}html.theme--documenter-dark .hljs-variable,html.theme--documenter-dark .hljs-template-variable,html.theme--documenter-dark .hljs-tag,html.theme--documenter-dark .hljs-name,html.theme--documenter-dark .hljs-selector-id,html.theme--documenter-dark .hljs-selector-class,html.theme--documenter-dark .hljs-regexp,html.theme--documenter-dark .hljs-deletion{color:#ffa07a}html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-link{color:#f5ab35}html.theme--documenter-dark .hljs-attribute{color:#ffd700}html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-addition{color:#abe338}html.theme--documenter-dark .hljs-title,html.theme--documenter-dark .hljs-section{color:#00e0e0}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{color:#dcc6e0}html.theme--documenter-dark .hljs-emphasis{font-style:italic}html.theme--documenter-dark .hljs-strong{font-weight:bold}@media screen and (-ms-high-contrast: active){html.theme--documenter-dark .hljs-addition,html.theme--documenter-dark .hljs-attribute,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-link,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-quote{color:highlight}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{font-weight:bold}}html.theme--documenter-dark .hljs-subst{color:#f8f8f2} diff --git a/previews/PR2578/assets/themes/documenter-light.css b/previews/PR2578/assets/themes/documenter-light.css deleted file mode 100644 index 9b9a14b04312..000000000000 --- a/previews/PR2578/assets/themes/documenter-light.css +++ /dev/null @@ -1,9 +0,0 @@ -@keyframes spinAround{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.tabs,.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.breadcrumb,.file,.button,.is-unselectable,.modal-close,.delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}.admonition:not(:last-child),.tabs:not(:last-child),.message:not(:last-child),.list:not(:last-child),.level:not(:last-child),.breadcrumb:not(:last-child),.highlight:not(:last-child),.block:not(:last-child),.title:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.progress:not(:last-child),.notification:not(:last-child),.content:not(:last-child),.box:not(:last-child){margin-bottom:1.5rem}.modal-close,.delete{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:290486px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}.modal-close::before,.delete::before,.modal-close::after,.delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.modal-close::before,.delete::before{height:2px;width:50%}.modal-close::after,.delete::after{height:50%;width:2px}.modal-close:hover,.delete:hover,.modal-close:focus,.delete:focus{background-color:rgba(10,10,10,0.3)}.modal-close:active,.delete:active{background-color:rgba(10,10,10,0.4)}.is-small.modal-close,#documenter .docs-sidebar form.docs-search>input.modal-close,.is-small.delete,#documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.modal-close,.is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.modal-close,.is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.control.is-loading::after,.select.is-loading::after,.loader,.button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdbdb;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.modal-background,.modal,.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.file-cta,.file-name,.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input,.button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.25em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.375em - 1px);padding-left:calc(0.625em - 1px);padding-right:calc(0.625em - 1px);padding-top:calc(0.375em - 1px);position:relative;vertical-align:top}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus,.pagination-ellipsis:focus,.file-cta:focus,.file-name:focus,.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.button:focus,.is-focused.pagination-previous,.is-focused.pagination-next,.is-focused.pagination-link,.is-focused.pagination-ellipsis,.is-focused.file-cta,.is-focused.file-name,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-focused.button,.pagination-previous:active,.pagination-next:active,.pagination-link:active,.pagination-ellipsis:active,.file-cta:active,.file-name:active,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.button:active,.is-active.pagination-previous,.is-active.pagination-next,.is-active.pagination-link,.is-active.pagination-ellipsis,.is-active.file-cta,.is-active.file-name,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.is-active.button{outline:none}.pagination-previous[disabled],.pagination-next[disabled],.pagination-link[disabled],.pagination-ellipsis[disabled],.file-cta[disabled],.file-name[disabled],.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],.button[disabled],fieldset[disabled] .pagination-previous,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] .button{cursor:not-allowed}/*! minireset.css v0.0.4 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,embed,iframe,object,video{height:auto;max-width:100%}audio{max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:left}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,select,textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}body{color:#222;font-size:1em;font-weight:400;line-height:1.5}a{color:#2e63b8;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:rgba(0,0,0,0.05);color:#000;font-size:.875em;font-weight:normal;padding:.1em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type="checkbox"],input[type="radio"]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#222;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#222;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:left}table th{color:#222}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-clipped{overflow:hidden !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,.docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#363636 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#1c1c1c !important}.has-background-dark{background-color:#363636 !important}.has-text-primary{color:#4eb5de !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#27a1d2 !important}.has-background-primary{background-color:#4eb5de !important}.has-text-link{color:#2e63b8 !important}a.has-text-link:hover,a.has-text-link:focus{color:#244d8f !important}.has-background-link{background-color:#2e63b8 !important}.has-text-info{color:#209cee !important}a.has-text-info:hover,a.has-text-info:focus{color:#1081cb !important}.has-background-info{background-color:#209cee !important}.has-text-success{color:#22c35b !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a9847 !important}.has-background-success{background-color:#22c35b !important}.has-text-warning{color:#ffdd57 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#ffd324 !important}.has-background-warning{background-color:#ffdd57 !important}.has-text-danger{color:#da0b00 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a70800 !important}.has-background-danger{background-color:#da0b00 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#363636 !important}.has-background-grey-darker{background-color:#363636 !important}.has-text-grey-dark{color:#4a4a4a !important}.has-background-grey-dark{background-color:#4a4a4a !important}.has-text-grey{color:#6b6b6b !important}.has-background-grey{background-color:#6b6b6b !important}.has-text-grey-light{color:#b5b5b5 !important}.has-background-grey-light{background-color:#b5b5b5 !important}.has-text-grey-lighter{color:#dbdbdb !important}.has-background-grey-lighter{background-color:#dbdbdb !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-relative{position:relative !important}.box{background-color:#fff;border-radius:6px;box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px rgba(10,10,10,0.1);color:#222;display:block;padding:1.25rem}a.box:hover,a.box:focus{box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px #2e63b8}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #2e63b8}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(0.375em - 1px);padding-left:.75em;padding-right:.75em;padding-top:calc(0.375em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-small,.button #documenter .docs-sidebar form.docs-search>input.icon,#documenter .docs-sidebar .button form.docs-search>input.icon,.button .icon.is-medium,.button .icon.is-large{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-0.375em - 1px);margin-right:0.1875em}.button .icon:last-child:not(:first-child){margin-left:0.1875em;margin-right:calc(-0.375em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-0.375em - 1px);margin-right:calc(-0.375em - 1px)}.button:hover,.button.is-hovered{border-color:#b5b5b5;color:#363636}.button:focus,.button.is-focused{border-color:#3c5dcd;color:#363636}.button:focus:not(:active),.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button:active,.button.is-active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#222;text-decoration:underline}.button.is-text:hover,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text.is-focused{background-color:#f5f5f5;color:#222}.button.is-text:active,.button.is-text.is-active{background-color:#e8e8e8;color:#222}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white:hover,.button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white:focus,.button.is-white.is-focused{border-color:transparent;color:#0a0a0a}.button.is-white:focus:not(:active),.button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.button.is-white:active,.button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:transparent;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted:hover,.button.is-white.is-inverted.is-hovered{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined:hover,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-outlined.is-loading:hover::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined:hover,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading:hover::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black:hover,.button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}.button.is-black:focus,.button.is-black.is-focused{border-color:transparent;color:#fff}.button.is-black:focus:not(:active),.button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.button.is-black:active,.button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:transparent;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted:hover,.button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined:hover,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-outlined.is-loading:hover::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined:hover,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading:hover::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:#363636}.button.is-light:hover,.button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:#363636}.button.is-light:focus,.button.is-light.is-focused{border-color:transparent;color:#363636}.button.is-light:focus:not(:active),.button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.button.is-light:active,.button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:#363636}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:transparent;box-shadow:none}.button.is-light.is-inverted{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted:hover,.button.is-light.is-inverted.is-hovered{background-color:#292929}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:#363636;border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent #363636 #363636 !important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined:hover,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-outlined.is-loading:hover::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #363636 #363636 !important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-light.is-inverted.is-outlined:hover,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined.is-focused{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading:hover::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark,.content kbd.button{background-color:#363636;border-color:transparent;color:#f5f5f5}.button.is-dark:hover,.content kbd.button:hover,.button.is-dark.is-hovered,.content kbd.button.is-hovered{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.button.is-dark:focus,.content kbd.button:focus,.button.is-dark.is-focused,.content kbd.button.is-focused{border-color:transparent;color:#f5f5f5}.button.is-dark:focus:not(:active),.content kbd.button:focus:not(:active),.button.is-dark.is-focused:not(:active),.content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.button.is-dark:active,.content kbd.button:active,.button.is-dark.is-active,.content kbd.button.is-active{background-color:#292929;border-color:transparent;color:#f5f5f5}.button.is-dark[disabled],.content kbd.button[disabled],fieldset[disabled] .button.is-dark,fieldset[disabled] .content kbd.button,.content fieldset[disabled] kbd.button{background-color:#363636;border-color:transparent;box-shadow:none}.button.is-dark.is-inverted,.content kbd.button.is-inverted{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted:hover,.content kbd.button.is-inverted:hover,.button.is-dark.is-inverted.is-hovered,.content kbd.button.is-inverted.is-hovered{background-color:#e8e8e8}.button.is-dark.is-inverted[disabled],.content kbd.button.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted,fieldset[disabled] .content kbd.button.is-inverted,.content fieldset[disabled] kbd.button.is-inverted{background-color:#f5f5f5;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after,.content kbd.button.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-dark.is-outlined,.content kbd.button.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined:hover,.content kbd.button.is-outlined:hover,.button.is-dark.is-outlined.is-hovered,.content kbd.button.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.content kbd.button.is-outlined:focus,.button.is-dark.is-outlined.is-focused,.content kbd.button.is-outlined.is-focused{background-color:#363636;border-color:#363636;color:#f5f5f5}.button.is-dark.is-outlined.is-loading::after,.content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-outlined.is-loading:hover::after,.content kbd.button.is-outlined.is-loading:hover::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.content kbd.button.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading.is-focused::after,.content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-dark.is-outlined[disabled],.content kbd.button.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined,fieldset[disabled] .content kbd.button.is-outlined,.content fieldset[disabled] kbd.button.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined,.content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-dark.is-inverted.is-outlined:hover,.content kbd.button.is-inverted.is-outlined:hover,.button.is-dark.is-inverted.is-outlined.is-hovered,.content kbd.button.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.content kbd.button.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined.is-focused,.content kbd.button.is-inverted.is-outlined.is-focused{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading:hover::after,.content kbd.button.is-inverted.is-outlined.is-loading:hover::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.content kbd.button.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-inverted.is-outlined[disabled],.content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined,fieldset[disabled] .content kbd.button.is-inverted.is-outlined,.content fieldset[disabled] kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-primary,.docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:transparent;color:#fff}.button.is-primary:hover,.docstring>section>a.button.docs-sourcelink:hover,.button.is-primary.is-hovered,.docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#43b1dc;border-color:transparent;color:#fff}.button.is-primary:focus,.docstring>section>a.button.docs-sourcelink:focus,.button.is-primary.is-focused,.docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}.button.is-primary:focus:not(:active),.docstring>section>a.button.docs-sourcelink:focus:not(:active),.button.is-primary.is-focused:not(:active),.docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.button.is-primary:active,.docstring>section>a.button.docs-sourcelink:active,.button.is-primary.is-active,.docstring>section>a.button.is-active.docs-sourcelink{background-color:#39acda;border-color:transparent;color:#fff}.button.is-primary[disabled],.docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary,fieldset[disabled] .docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:transparent;box-shadow:none}.button.is-primary.is-inverted,.docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted:hover,.docstring>section>a.button.is-inverted.docs-sourcelink:hover,.button.is-primary.is-inverted.is-hovered,.docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],.docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted,fieldset[disabled] .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#4eb5de}.button.is-primary.is-loading::after,.docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined,.docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;color:#4eb5de}.button.is-primary.is-outlined:hover,.docstring>section>a.button.is-outlined.docs-sourcelink:hover,.button.is-primary.is-outlined.is-hovered,.docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-outlined:focus,.docstring>section>a.button.is-outlined.docs-sourcelink:focus,.button.is-primary.is-outlined.is-focused,.docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.button.is-primary.is-outlined.is-loading::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined[disabled],.docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-outlined,fieldset[disabled] .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;box-shadow:none;color:#4eb5de}.button.is-primary.is-inverted.is-outlined,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined:hover,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,.button.is-primary.is-inverted.is-outlined.is-hovered,.docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-inverted.is-outlined:focus,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,.button.is-primary.is-inverted.is-outlined.is-focused,.docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-inverted.is-outlined[disabled],.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined,fieldset[disabled] .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link{background-color:#2e63b8;border-color:transparent;color:#fff}.button.is-link:hover,.button.is-link.is-hovered{background-color:#2b5eae;border-color:transparent;color:#fff}.button.is-link:focus,.button.is-link.is-focused{border-color:transparent;color:#fff}.button.is-link:focus:not(:active),.button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button.is-link:active,.button.is-link.is-active{background-color:#2958a4;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#2e63b8;border-color:transparent;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted:hover,.button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#2e63b8}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;color:#2e63b8}.button.is-link.is-outlined:hover,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined.is-focused{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-outlined.is-loading:hover::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;box-shadow:none;color:#2e63b8}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined:hover,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted.is-outlined.is-loading:hover::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info{background-color:#209cee;border-color:transparent;color:#fff}.button.is-info:hover,.button.is-info.is-hovered{background-color:#1497ed;border-color:transparent;color:#fff}.button.is-info:focus,.button.is-info.is-focused{border-color:transparent;color:#fff}.button.is-info:focus:not(:active),.button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.button.is-info:active,.button.is-info.is-active{background-color:#1190e3;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#209cee;border-color:transparent;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#209cee}.button.is-info.is-inverted:hover,.button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#209cee}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined{background-color:transparent;border-color:#209cee;color:#209cee}.button.is-info.is-outlined:hover,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined.is-focused{background-color:#209cee;border-color:#209cee;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #209cee #209cee !important}.button.is-info.is-outlined.is-loading:hover::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#209cee;box-shadow:none;color:#209cee}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined:hover,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#209cee}.button.is-info.is-inverted.is-outlined.is-loading:hover::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #209cee #209cee !important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success{background-color:#22c35b;border-color:transparent;color:#fff}.button.is-success:hover,.button.is-success.is-hovered{background-color:#20b856;border-color:transparent;color:#fff}.button.is-success:focus,.button.is-success.is-focused{border-color:transparent;color:#fff}.button.is-success:focus:not(:active),.button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.button.is-success:active,.button.is-success.is-active{background-color:#1ead51;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#22c35b;border-color:transparent;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#22c35b}.button.is-success.is-inverted:hover,.button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#22c35b}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined{background-color:transparent;border-color:#22c35b;color:#22c35b}.button.is-success.is-outlined:hover,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined.is-focused{background-color:#22c35b;border-color:#22c35b;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #22c35b #22c35b !important}.button.is-success.is-outlined.is-loading:hover::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#22c35b;box-shadow:none;color:#22c35b}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined:hover,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#22c35b}.button.is-success.is-inverted.is-outlined.is-loading:hover::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #22c35b #22c35b !important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:hover,.button.is-warning.is-hovered{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus,.button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus:not(:active),.button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.button.is-warning:active,.button.is-warning.is-active{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:transparent;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#ffdd57}.button.is-warning.is-inverted:hover,.button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined:hover,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined.is-focused{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffdd57 #ffdd57 !important}.button.is-warning.is-outlined.is-loading:hover::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;box-shadow:none;color:#ffdd57}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}.button.is-warning.is-inverted.is-outlined:hover,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined.is-loading:hover::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ffdd57 #ffdd57 !important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}.button.is-danger{background-color:#da0b00;border-color:transparent;color:#fff}.button.is-danger:hover,.button.is-danger.is-hovered{background-color:#cd0a00;border-color:transparent;color:#fff}.button.is-danger:focus,.button.is-danger.is-focused{border-color:transparent;color:#fff}.button.is-danger:focus:not(:active),.button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.button.is-danger:active,.button.is-danger.is-active{background-color:#c10a00;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#da0b00;border-color:transparent;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#da0b00}.button.is-danger.is-inverted:hover,.button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#da0b00}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined{background-color:transparent;border-color:#da0b00;color:#da0b00}.button.is-danger.is-outlined:hover,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined.is-focused{background-color:#da0b00;border-color:#da0b00;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #da0b00 #da0b00 !important}.button.is-danger.is-outlined.is-loading:hover::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#da0b00;box-shadow:none;color:#da0b00}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined:hover,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#da0b00}.button.is-danger.is-inverted.is-outlined.is-loading:hover::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #da0b00 #da0b00 !important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-small,#documenter .docs-sidebar form.docs-search>input.button{border-radius:2px;font-size:.75rem}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent !important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em / 2));top:calc(50% - (1em / 2));position:absolute !important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#6b6b6b;box-shadow:none;pointer-events:none}.button.is-rounded,#documenter .docs-sidebar form.docs-search>input.button{border-radius:290486px;padding-left:1em;padding-right:1em}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:0.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:0.5rem}.buttons:last-child{margin-bottom:-0.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){border-radius:2px;font-size:.75rem}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button:hover,.buttons.has-addons .button.is-hovered{z-index:2}.buttons.has-addons .button:focus,.buttons.has-addons .button.is-focused,.buttons.has-addons .button:active,.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-selected{z-index:3}.buttons.has-addons .button:focus:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-selected:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}@media screen and (min-width: 1056px){.container{max-width:992px}.container.is-fluid{margin-left:32px;margin-right:32px;max-width:none}}@media screen and (max-width: 1215px){.container.is-widescreen{max-width:1152px}}@media screen and (max-width: 1407px){.container.is-fullhd{max-width:1344px}}@media screen and (min-width: 1216px){.container{max-width:1152px}}@media screen and (min-width: 1408px){.container{max-width:1344px}}.content li+li{margin-top:0.25em}.content p:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content ul:not(:last-child),.content blockquote:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#222;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:0.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:0.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:0.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:0.8em}.content h5{font-size:1.125em;margin-bottom:0.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}.content ol.is-lower-roman:not([type]){list-style-type:lower-roman}.content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}.content ol.is-upper-roman:not([type]){list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:0.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}.content sup,.content sub{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.content table th{color:#222}.content table th:not([align]){text-align:left}.content table thead td,.content table thead th{border-width:0 0 2px;color:#222}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#222}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small,#documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small,#documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.image,#documenter .docs-sidebar .docs-logo>img{display:block;position:relative}.image img,#documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}.image img.is-rounded,#documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:290486px}.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}.image.is-square,#documenter .docs-sidebar .docs-logo>img.is-square,.image.is-1by1,#documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}.image.is-5by4,#documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}.image.is-4by3,#documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}.image.is-3by2,#documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}.image.is-5by3,#documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}.image.is-16by9,#documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}.image.is-2by1,#documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}.image.is-3by1,#documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}.image.is-4by5,#documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}.image.is-3by4,#documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}.image.is-2by3,#documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}.image.is-3by5,#documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}.image.is-9by16,#documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}.image.is-1by2,#documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}.image.is-1by3,#documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}.image.is-16x16,#documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}.image.is-24x24,#documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}.image.is-32x32,#documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}.image.is-48x48,#documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}.image.is-64x64,#documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}.image.is-96x96,#documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}.image.is-128x128,#documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;padding:1.25rem 2.5rem 1.25rem 1.5rem;position:relative}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:transparent}.notification>.delete{position:absolute;right:0.5rem;top:0.5rem}.notification .title,.notification .subtitle,.notification .content{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:#363636}.notification.is-dark,.content kbd.notification{background-color:#363636;color:#f5f5f5}.notification.is-primary,.docstring>section>a.notification.docs-sourcelink{background-color:#4eb5de;color:#fff}.notification.is-link{background-color:#2e63b8;color:#fff}.notification.is-info{background-color:#209cee;color:#fff}.notification.is-success{background-color:#22c35b;color:#fff}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.notification.is-danger{background-color:#da0b00;color:#fff}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:290486px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#dbdbdb}.progress::-webkit-progress-value{background-color:#222}.progress::-moz-progress-bar{background-color:#222}.progress::-ms-fill{background-color:#222;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #dbdbdb 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #dbdbdb 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #dbdbdb 30%)}.progress.is-dark::-webkit-progress-value,.content kbd.progress::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar,.content kbd.progress::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill,.content kbd.progress::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate,.content kbd.progress:indeterminate{background-image:linear-gradient(to right, #363636 30%, #dbdbdb 30%)}.progress.is-primary::-webkit-progress-value,.docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#4eb5de}.progress.is-primary::-moz-progress-bar,.docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#4eb5de}.progress.is-primary::-ms-fill,.docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#4eb5de}.progress.is-primary:indeterminate,.docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #4eb5de 30%, #dbdbdb 30%)}.progress.is-link::-webkit-progress-value{background-color:#2e63b8}.progress.is-link::-moz-progress-bar{background-color:#2e63b8}.progress.is-link::-ms-fill{background-color:#2e63b8}.progress.is-link:indeterminate{background-image:linear-gradient(to right, #2e63b8 30%, #dbdbdb 30%)}.progress.is-info::-webkit-progress-value{background-color:#209cee}.progress.is-info::-moz-progress-bar{background-color:#209cee}.progress.is-info::-ms-fill{background-color:#209cee}.progress.is-info:indeterminate{background-image:linear-gradient(to right, #209cee 30%, #dbdbdb 30%)}.progress.is-success::-webkit-progress-value{background-color:#22c35b}.progress.is-success::-moz-progress-bar{background-color:#22c35b}.progress.is-success::-ms-fill{background-color:#22c35b}.progress.is-success:indeterminate{background-image:linear-gradient(to right, #22c35b 30%, #dbdbdb 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffdd57}.progress.is-warning::-moz-progress-bar{background-color:#ffdd57}.progress.is-warning::-ms-fill{background-color:#ffdd57}.progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ffdd57 30%, #dbdbdb 30%)}.progress.is-danger::-webkit-progress-value{background-color:#da0b00}.progress.is-danger::-moz-progress-bar{background-color:#da0b00}.progress.is-danger::-ms-fill{background-color:#da0b00}.progress.is-danger:indeterminate{background-image:linear-gradient(to right, #da0b00 30%, #dbdbdb 30%)}.progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#dbdbdb;background-image:linear-gradient(to right, #222 30%, #dbdbdb 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress.is-small,#documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#363636}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#f5f5f5}.table td.is-primary,.table th.is-primary{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.table td.is-link,.table th.is-link{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.table td.is-info,.table th.is-info{background-color:#209cee;border-color:#209cee;color:#fff}.table td.is-success,.table th.is-success{background-color:#22c35b;border-color:#22c35b;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.table td.is-danger,.table th.is-danger{background-color:#da0b00;border-color:#da0b00;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#4eb5de;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table th{color:#222}.table th:not([align]){text-align:left}.table tr.is-selected{background-color:#4eb5de;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:rgba(0,0,0,0)}.table thead td,.table thead th{border-width:0 0 2px;color:#222}.table tfoot{background-color:rgba(0,0,0,0)}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#222}.table tbody{background-color:rgba(0,0,0,0)}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:0.25em 0.5em}.table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag,.tags .content kbd,.content .tags kbd,.tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}.tags .tag:not(:last-child),.tags .content kbd:not(:last-child),.content .tags kbd:not(:last-child),.tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0.5rem}.tags:last-child{margin-bottom:-0.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large),.tags.are-medium .content kbd:not(.is-normal):not(.is-large),.content .tags.are-medium kbd:not(.is-normal):not(.is-large),.tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium),.tags.are-large .content kbd:not(.is-normal):not(.is-medium),.content .tags.are-large kbd:not(.is-normal):not(.is-medium),.tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag,.tags.is-centered .content kbd,.content .tags.is-centered kbd,.tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child),.tags.is-right .content kbd:not(:first-child),.content .tags.is-right kbd:not(:first-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}.tags.is-right .tag:not(:last-child),.tags.is-right .content kbd:not(:last-child),.content .tags.is-right kbd:not(:last-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}.tags.has-addons .tag,.tags.has-addons .content kbd,.content .tags.has-addons kbd,.tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}.tags.has-addons .tag:not(:first-child),.tags.has-addons .content kbd:not(:first-child),.content .tags.has-addons kbd:not(:first-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.tags.has-addons .tag:not(:last-child),.tags.has-addons .content kbd:not(:last-child),.content .tags.has-addons kbd:not(:last-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.tag:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#222;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}.tag:not(body) .delete,.content kbd:not(body) .delete,.docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:0.25rem;margin-right:-0.375rem}.tag.is-white:not(body),.content kbd.is-white:not(body),.docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}.tag.is-black:not(body),.content kbd.is-black:not(body),.docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}.tag.is-light:not(body),.content kbd.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:#363636}.tag.is-dark:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink.is-dark:not(body),.content .docstring>section>kbd:not(body){background-color:#363636;color:#f5f5f5}.tag.is-primary:not(body),.content kbd.is-primary:not(body),.docstring>section>a.docs-sourcelink:not(body){background-color:#4eb5de;color:#fff}.tag.is-link:not(body),.content kbd.is-link:not(body),.docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#2e63b8;color:#fff}.tag.is-info:not(body),.content kbd.is-info:not(body),.docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#209cee;color:#fff}.tag.is-success:not(body),.content kbd.is-success:not(body),.docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#22c35b;color:#fff}.tag.is-warning:not(body),.content kbd.is-warning:not(body),.docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ffdd57;color:rgba(0,0,0,0.7)}.tag.is-danger:not(body),.content kbd.is-danger:not(body),.docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#da0b00;color:#fff}.tag.is-normal:not(body),.content kbd.is-normal:not(body),.docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}.tag.is-medium:not(body),.content kbd.is-medium:not(body),.docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}.tag.is-large:not(body),.content kbd.is-large:not(body),.docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child),.content kbd:not(body) .icon:first-child:not(:last-child),.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-0.375em;margin-right:0.1875em}.tag:not(body) .icon:last-child:not(:first-child),.content kbd:not(body) .icon:last-child:not(:first-child),.docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:0.1875em;margin-right:-0.375em}.tag:not(body) .icon:first-child:last-child,.content kbd:not(body) .icon:first-child:last-child,.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-0.375em;margin-right:-0.375em}.tag.is-delete:not(body),.content kbd.is-delete:not(body),.docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before,.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}.tag.is-delete:not(body):hover,.content kbd.is-delete:not(body):hover,.docstring>section>a.docs-sourcelink.is-delete:not(body):hover,.tag.is-delete:not(body):focus,.content kbd.is-delete:not(body):focus,.docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#e8e8e8}.tag.is-delete:not(body):active,.content kbd.is-delete:not(body):active,.docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#dbdbdb}.tag.is-rounded:not(body),#documenter .docs-sidebar form.docs-search>input:not(body),.content kbd.is-rounded:not(body),#documenter .docs-sidebar .content form.docs-search>input:not(body),.docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:290486px}a.tag:hover,.docstring>section>a.docs-sourcelink:hover{text-decoration:underline}.title,.subtitle{word-break:break-word}.title em,.title span,.subtitle em,.subtitle span{font-weight:inherit}.title sub,.subtitle sub{font-size:.75em}.title sup,.subtitle sup{font-size:.75em}.title .tag,.title .content kbd,.content .title kbd,.title .docstring>section>a.docs-sourcelink,.subtitle .tag,.subtitle .content kbd,.content .subtitle kbd,.subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}.title{color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title+.highlight{margin-top:-0.75rem}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#4a4a4a;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#363636;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.highlight{font-weight:400;max-width:100%;overflow:hidden;padding:0}.highlight pre{overflow:auto;max-width:100%}.number{align-items:center;background-color:#f5f5f5;border-radius:290486px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#363636}.select select::-moz-placeholder,.textarea::-moz-placeholder,.input::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(54,54,54,0.3)}.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder,.input::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(54,54,54,0.3)}.select select:-moz-placeholder,.textarea:-moz-placeholder,.input:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(54,54,54,0.3)}.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder,.input:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(54,54,54,0.3)}.select select:hover,.textarea:hover,.input:hover,#documenter .docs-sidebar form.docs-search>input:hover,.select select.is-hovered,.is-hovered.textarea,.is-hovered.input,#documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#b5b5b5}.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{border-color:#2e63b8;box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#6b6b6b}.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,.input[disabled]::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,.input[disabled]::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-webkit-input-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,.input[disabled]:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,.input[disabled]:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-ms-input-placeholder{color:rgba(107,107,107,0.3)}.textarea,.input,#documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 1px 2px rgba(10,10,10,0.1);max-width:100%;width:100%}.textarea[readonly],.input[readonly],#documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}.is-white.textarea,.is-white.input,#documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}.is-white.textarea:focus,.is-white.input:focus,#documenter .docs-sidebar form.docs-search>input.is-white:focus,.is-white.is-focused.textarea,.is-white.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-white.textarea:active,.is-white.input:active,#documenter .docs-sidebar form.docs-search>input.is-white:active,.is-white.is-active.textarea,.is-white.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.is-black.textarea,.is-black.input,#documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}.is-black.textarea:focus,.is-black.input:focus,#documenter .docs-sidebar form.docs-search>input.is-black:focus,.is-black.is-focused.textarea,.is-black.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-black.textarea:active,.is-black.input:active,#documenter .docs-sidebar form.docs-search>input.is-black:active,.is-black.is-active.textarea,.is-black.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.is-light.textarea,.is-light.input,#documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}.is-light.textarea:focus,.is-light.input:focus,#documenter .docs-sidebar form.docs-search>input.is-light:focus,.is-light.is-focused.textarea,.is-light.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-light.textarea:active,.is-light.input:active,#documenter .docs-sidebar form.docs-search>input.is-light:active,.is-light.is-active.textarea,.is-light.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.is-dark.textarea,.content kbd.textarea,.is-dark.input,#documenter .docs-sidebar form.docs-search>input.is-dark,.content kbd.input{border-color:#363636}.is-dark.textarea:focus,.content kbd.textarea:focus,.is-dark.input:focus,#documenter .docs-sidebar form.docs-search>input.is-dark:focus,.content kbd.input:focus,.is-dark.is-focused.textarea,.content kbd.is-focused.textarea,.is-dark.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.content kbd.is-focused.input,#documenter .docs-sidebar .content form.docs-search>input.is-focused,.is-dark.textarea:active,.content kbd.textarea:active,.is-dark.input:active,#documenter .docs-sidebar form.docs-search>input.is-dark:active,.content kbd.input:active,.is-dark.is-active.textarea,.content kbd.is-active.textarea,.is-dark.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.content kbd.is-active.input,#documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.is-primary.textarea,.docstring>section>a.textarea.docs-sourcelink,.is-primary.input,#documenter .docs-sidebar form.docs-search>input.is-primary,.docstring>section>a.input.docs-sourcelink{border-color:#4eb5de}.is-primary.textarea:focus,.docstring>section>a.textarea.docs-sourcelink:focus,.is-primary.input:focus,#documenter .docs-sidebar form.docs-search>input.is-primary:focus,.docstring>section>a.input.docs-sourcelink:focus,.is-primary.is-focused.textarea,.docstring>section>a.is-focused.textarea.docs-sourcelink,.is-primary.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.docstring>section>a.is-focused.input.docs-sourcelink,.is-primary.textarea:active,.docstring>section>a.textarea.docs-sourcelink:active,.is-primary.input:active,#documenter .docs-sidebar form.docs-search>input.is-primary:active,.docstring>section>a.input.docs-sourcelink:active,.is-primary.is-active.textarea,.docstring>section>a.is-active.textarea.docs-sourcelink,.is-primary.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.is-link.textarea,.is-link.input,#documenter .docs-sidebar form.docs-search>input.is-link{border-color:#2e63b8}.is-link.textarea:focus,.is-link.input:focus,#documenter .docs-sidebar form.docs-search>input.is-link:focus,.is-link.is-focused.textarea,.is-link.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-link.textarea:active,.is-link.input:active,#documenter .docs-sidebar form.docs-search>input.is-link:active,.is-link.is-active.textarea,.is-link.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.is-info.textarea,.is-info.input,#documenter .docs-sidebar form.docs-search>input.is-info{border-color:#209cee}.is-info.textarea:focus,.is-info.input:focus,#documenter .docs-sidebar form.docs-search>input.is-info:focus,.is-info.is-focused.textarea,.is-info.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-info.textarea:active,.is-info.input:active,#documenter .docs-sidebar form.docs-search>input.is-info:active,.is-info.is-active.textarea,.is-info.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.is-success.textarea,.is-success.input,#documenter .docs-sidebar form.docs-search>input.is-success{border-color:#22c35b}.is-success.textarea:focus,.is-success.input:focus,#documenter .docs-sidebar form.docs-search>input.is-success:focus,.is-success.is-focused.textarea,.is-success.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-success.textarea:active,.is-success.input:active,#documenter .docs-sidebar form.docs-search>input.is-success:active,.is-success.is-active.textarea,.is-success.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.is-warning.textarea,.is-warning.input,#documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ffdd57}.is-warning.textarea:focus,.is-warning.input:focus,#documenter .docs-sidebar form.docs-search>input.is-warning:focus,.is-warning.is-focused.textarea,.is-warning.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-warning.textarea:active,.is-warning.input:active,#documenter .docs-sidebar form.docs-search>input.is-warning:active,.is-warning.is-active.textarea,.is-warning.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.is-danger.textarea,.is-danger.input,#documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#da0b00}.is-danger.textarea:focus,.is-danger.input:focus,#documenter .docs-sidebar form.docs-search>input.is-danger:focus,.is-danger.is-focused.textarea,.is-danger.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-danger.textarea:active,.is-danger.input:active,#documenter .docs-sidebar form.docs-search>input.is-danger:active,.is-danger.is-active.textarea,.is-danger.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.is-small.textarea,.is-small.input,#documenter .docs-sidebar form.docs-search>input{border-radius:2px;font-size:.75rem}.is-medium.textarea,.is-medium.input,#documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}.is-large.textarea,.is-large.input,#documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}.is-fullwidth.textarea,.is-fullwidth.input,#documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}.is-inline.textarea,.is-inline.input,#documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}.input.is-rounded,#documenter .docs-sidebar form.docs-search>input{border-radius:290486px;padding-left:1em;padding-right:1em}.input.is-static,#documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:0.625em;resize:vertical}.textarea:not([rows]){max-height:600px;min-height:120px}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.radio,.checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.radio input,.checkbox input{cursor:pointer}.radio:hover,.checkbox:hover{color:#363636}.radio[disabled],.checkbox[disabled],fieldset[disabled] .radio,fieldset[disabled] .checkbox{color:#6b6b6b;cursor:not-allowed}.radio+.radio{margin-left:0.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.25em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#2e63b8;right:1.125em;z-index:4}.select.is-rounded select,#documenter .docs-sidebar form.docs-search>input.select select{border-radius:290486px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:0.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#363636}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select:hover,.select.is-white select.is-hovered{border-color:#f2f2f2}.select.is-white select:focus,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select:hover,.select.is-black select.is-hovered{border-color:#000}.select.is-black select:focus,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select:hover,.select.is-light select.is-hovered{border-color:#e8e8e8}.select.is-light select:focus,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.select.is-dark:not(:hover)::after,.content kbd.select:not(:hover)::after{border-color:#363636}.select.is-dark select,.content kbd.select select{border-color:#363636}.select.is-dark select:hover,.content kbd.select select:hover,.select.is-dark select.is-hovered,.content kbd.select select.is-hovered{border-color:#292929}.select.is-dark select:focus,.content kbd.select select:focus,.select.is-dark select.is-focused,.content kbd.select select.is-focused,.select.is-dark select:active,.content kbd.select select:active,.select.is-dark select.is-active,.content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.select.is-primary:not(:hover)::after,.docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#4eb5de}.select.is-primary select,.docstring>section>a.select.docs-sourcelink select{border-color:#4eb5de}.select.is-primary select:hover,.docstring>section>a.select.docs-sourcelink select:hover,.select.is-primary select.is-hovered,.docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#39acda}.select.is-primary select:focus,.docstring>section>a.select.docs-sourcelink select:focus,.select.is-primary select.is-focused,.docstring>section>a.select.docs-sourcelink select.is-focused,.select.is-primary select:active,.docstring>section>a.select.docs-sourcelink select:active,.select.is-primary select.is-active,.docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.select.is-link:not(:hover)::after{border-color:#2e63b8}.select.is-link select{border-color:#2e63b8}.select.is-link select:hover,.select.is-link select.is-hovered{border-color:#2958a4}.select.is-link select:focus,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select.is-info:not(:hover)::after{border-color:#209cee}.select.is-info select{border-color:#209cee}.select.is-info select:hover,.select.is-info select.is-hovered{border-color:#1190e3}.select.is-info select:focus,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.select.is-success:not(:hover)::after{border-color:#22c35b}.select.is-success select{border-color:#22c35b}.select.is-success select:hover,.select.is-success select.is-hovered{border-color:#1ead51}.select.is-success select:focus,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select:hover,.select.is-warning select.is-hovered{border-color:#ffd83e}.select.is-warning select:focus,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.select.is-danger:not(:hover)::after{border-color:#da0b00}.select.is-danger select{border-color:#da0b00}.select.is-danger select:hover,.select.is-danger select.is-hovered{border-color:#c10a00}.select.is-danger select:focus,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.select.is-small,#documenter .docs-sidebar form.docs-search>input.select{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#6b6b6b}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:0.625em;top:0.625em;transform:none}.select.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white:hover .file-cta,.file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white:focus .file-cta,.file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}.file.is-white:active .file-cta,.file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black:hover .file-cta,.file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black:focus .file-cta,.file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}.file.is-black:active .file-cta,.file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:#363636}.file.is-light:hover .file-cta,.file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:#363636}.file.is-light:focus .file-cta,.file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:#363636}.file.is-light:active .file-cta,.file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:#363636}.file.is-dark .file-cta,.content kbd.file .file-cta{background-color:#363636;border-color:transparent;color:#f5f5f5}.file.is-dark:hover .file-cta,.content kbd.file:hover .file-cta,.file.is-dark.is-hovered .file-cta,.content kbd.file.is-hovered .file-cta{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.file.is-dark:focus .file-cta,.content kbd.file:focus .file-cta,.file.is-dark.is-focused .file-cta,.content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(54,54,54,0.25);color:#f5f5f5}.file.is-dark:active .file-cta,.content kbd.file:active .file-cta,.file.is-dark.is-active .file-cta,.content kbd.file.is-active .file-cta{background-color:#292929;border-color:transparent;color:#f5f5f5}.file.is-primary .file-cta,.docstring>section>a.file.docs-sourcelink .file-cta{background-color:#4eb5de;border-color:transparent;color:#fff}.file.is-primary:hover .file-cta,.docstring>section>a.file.docs-sourcelink:hover .file-cta,.file.is-primary.is-hovered .file-cta,.docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#43b1dc;border-color:transparent;color:#fff}.file.is-primary:focus .file-cta,.docstring>section>a.file.docs-sourcelink:focus .file-cta,.file.is-primary.is-focused .file-cta,.docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(78,181,222,0.25);color:#fff}.file.is-primary:active .file-cta,.docstring>section>a.file.docs-sourcelink:active .file-cta,.file.is-primary.is-active .file-cta,.docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#39acda;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#2e63b8;border-color:transparent;color:#fff}.file.is-link:hover .file-cta,.file.is-link.is-hovered .file-cta{background-color:#2b5eae;border-color:transparent;color:#fff}.file.is-link:focus .file-cta,.file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(46,99,184,0.25);color:#fff}.file.is-link:active .file-cta,.file.is-link.is-active .file-cta{background-color:#2958a4;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#209cee;border-color:transparent;color:#fff}.file.is-info:hover .file-cta,.file.is-info.is-hovered .file-cta{background-color:#1497ed;border-color:transparent;color:#fff}.file.is-info:focus .file-cta,.file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(32,156,238,0.25);color:#fff}.file.is-info:active .file-cta,.file.is-info.is-active .file-cta{background-color:#1190e3;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#22c35b;border-color:transparent;color:#fff}.file.is-success:hover .file-cta,.file.is-success.is-hovered .file-cta{background-color:#20b856;border-color:transparent;color:#fff}.file.is-success:focus .file-cta,.file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(34,195,91,0.25);color:#fff}.file.is-success:active .file-cta,.file.is-success.is-active .file-cta{background-color:#1ead51;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:hover .file-cta,.file.is-warning.is-hovered .file-cta{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:focus .file-cta,.file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,221,87,0.25);color:rgba(0,0,0,0.7)}.file.is-warning:active .file-cta,.file.is-warning.is-active .file-cta{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-danger .file-cta{background-color:#da0b00;border-color:transparent;color:#fff}.file.is-danger:hover .file-cta,.file.is-danger.is-hovered .file-cta{background-color:#cd0a00;border-color:transparent;color:#fff}.file.is-danger:focus .file-cta,.file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(218,11,0,0.25);color:#fff}.file.is-danger:active .file-cta,.file.is-danger.is-active .file-cta{background-color:#c10a00;border-color:transparent;color:#fff}.file.is-small,#documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa,#documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#363636}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#363636}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#4a4a4a}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:left;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:0.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#363636;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:0.5em}.label.is-small,#documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:0.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark,.content kbd.help{color:#363636}.help.is-primary,.docstring>section>a.help.docs-sourcelink{color:#4eb5de}.help.is-link{color:#2e63b8}.help.is-info{color:#209cee}.help.is-success{color:#22c35b}.help.is-warning{color:#ffdd57}.help.is-danger{color:#da0b00}.field:not(:last-child){margin-bottom:0.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .button.is-hovered:not([disabled]),.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,.field.has-addons .control .input.is-hovered:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),.field.has-addons .control .select select:not([disabled]):hover,.field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .button.is-focused:not([disabled]),.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button.is-active:not([disabled]),.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,.field.has-addons .control .input.is-focused:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,.field.has-addons .control .input.is-active:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),.field.has-addons .control .select select:not([disabled]):focus,.field.has-addons .control .select select.is-focused:not([disabled]),.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select.is-active:not([disabled]){z-index:3}.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .button.is-focused:not([disabled]):hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button.is-active:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,.field.has-addons .control .input.is-focused:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,.field.has-addons .control .input.is-active:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):focus:hover,.field.has-addons .control .select select.is-focused:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:0.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width: 768px){.field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small,#documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}.field-label.is-normal{padding-top:0.375em}.field-label.is-medium{font-size:1.25rem;padding-top:0.375em}.field-label.is-large{font-size:1.5rem;padding-top:0.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:0.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:left}.control.has-icons-left .input:focus~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#6b6b6b}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.25em;pointer-events:none;position:absolute;top:0;width:2.25em;z-index:4}.control.has-icons-left .input,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input,.control.has-icons-left .select select{padding-left:2.25em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input,.control.has-icons-right .select select{padding-right:2.25em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute !important;right:0.625em;top:0.625em;z-index:4}.control.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#2e63b8;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#222;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ul,.breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:0.5em}.breadcrumb .icon:last-child{margin-left:0.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small,#documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px rgba(10,10,10,0.1);color:#222;max-width:100%;position:relative}.card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 1px 2px rgba(10,10,10,0.1);display:flex}.card-header-title{align-items:center;color:#222;display:flex;flex-grow:1;font-weight:700;padding:.75rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem}.card-image{display:block;position:relative}.card-content{background-color:rgba(0,0,0,0);padding:1.5rem}.card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #dbdbdb;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #dbdbdb}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px rgba(10,10,10,0.1);padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#4a4a4a;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:left;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#2e63b8;color:#fff}.dropdown-divider{background-color:#dbdbdb;border:none;display:block;height:1px;margin:0.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .title,.level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{.level-right{display:flex}}.list{background-color:#fff;border-radius:4px;box-shadow:0 2px 3px rgba(10,10,10,0.1),0 0 0 1px rgba(10,10,10,0.1)}.list-item{display:block;padding:0.5em 1em}.list-item:not(a){color:#222}.list-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-item:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px}.list-item:not(:last-child){border-bottom:1px solid #dbdbdb}.list-item.is-active{background-color:#2e63b8;color:#fff}a.list-item{background-color:#f5f5f5;cursor:pointer}.media{align-items:flex-start;display:flex;text-align:left}.media .content:not(:last-child){margin-bottom:0.75rem}.media .media{border-top:1px solid rgba(219,219,219,0.5);display:flex;padding-top:0.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:0.5rem}.media .media .media{padding-top:0.5rem}.media .media .media+.media{margin-top:0.5rem}.media+.media{border-top:1px solid rgba(219,219,219,0.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:left}@media screen and (max-width: 768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small,#documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#222;display:block;padding:0.5em 0.75em}.menu-list a:hover{background-color:#f5f5f5;color:#222}.menu-list a.is-active{background-color:#2e63b8;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#6b6b6b;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small,#documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff;color:#4d4d4d}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a;color:#090909}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:#363636}.message.is-light .message-body{border-color:#f5f5f5;color:#505050}.message.is-dark,.content kbd.message{background-color:#fafafa}.message.is-dark .message-header,.content kbd.message .message-header{background-color:#363636;color:#f5f5f5}.message.is-dark .message-body,.content kbd.message .message-body{border-color:#363636;color:#2a2a2a}.message.is-primary,.docstring>section>a.message.docs-sourcelink{background-color:#f6fbfd}.message.is-primary .message-header,.docstring>section>a.message.docs-sourcelink .message-header{background-color:#4eb5de;color:#fff}.message.is-primary .message-body,.docstring>section>a.message.docs-sourcelink .message-body{border-color:#4eb5de;color:#1f556a}.message.is-link{background-color:#f7f9fd}.message.is-link .message-header{background-color:#2e63b8;color:#fff}.message.is-link .message-body{border-color:#2e63b8;color:#264981}.message.is-info{background-color:#f6fbfe}.message.is-info .message-header{background-color:#209cee;color:#fff}.message.is-info .message-body{border-color:#209cee;color:#12537d}.message.is-success{background-color:#f6fdf9}.message.is-success .message-header{background-color:#22c35b;color:#fff}.message.is-success .message-body{border-color:#22c35b;color:#0f361d}.message.is-warning{background-color:#fffdf5}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#3c3108}.message.is-danger{background-color:#fff5f5}.message.is-danger .message-header{background-color:#da0b00;color:#fff}.message.is-danger .message-body{border-color:#da0b00;color:#9b0c04}.message-header{align-items:center;background-color:#222;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:0.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#222;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:rgba(0,0,0,0)}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,0.86)}.modal-content,.modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px),print{.modal-content,.modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-head,.modal-card-foot{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#222;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:0.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand>.navbar-item,.navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){.navbar.is-white .navbar-start>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-start .navbar-link::after,.navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand>.navbar-item,.navbar.is-black .navbar-brand .navbar-link{color:#fff}.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-black .navbar-start>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-end .navbar-link{color:#fff}.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-start .navbar-link::after,.navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:#363636}.navbar.is-light .navbar-brand>.navbar-item,.navbar.is-light .navbar-brand .navbar-link{color:#363636}.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-brand .navbar-link::after{border-color:#363636}.navbar.is-light .navbar-burger{color:#363636}@media screen and (min-width: 1056px){.navbar.is-light .navbar-start>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-end .navbar-link{color:#363636}.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-start .navbar-link::after,.navbar.is-light .navbar-end .navbar-link::after{border-color:#363636}.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#363636}}.navbar.is-dark,.content kbd.navbar{background-color:#363636;color:#f5f5f5}.navbar.is-dark .navbar-brand>.navbar-item,.content kbd.navbar .navbar-brand>.navbar-item,.navbar.is-dark .navbar-brand .navbar-link,.content kbd.navbar .navbar-brand .navbar-link{color:#f5f5f5}.navbar.is-dark .navbar-brand>a.navbar-item:focus,.content kbd.navbar .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover,.content kbd.navbar .navbar-brand>a.navbar-item:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.content kbd.navbar .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.content kbd.navbar .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.content kbd.navbar .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand .navbar-link.is-active,.content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-brand .navbar-link::after,.content kbd.navbar .navbar-brand .navbar-link::after{border-color:#f5f5f5}.navbar.is-dark .navbar-burger,.content kbd.navbar .navbar-burger{color:#f5f5f5}@media screen and (min-width: 1056px){.navbar.is-dark .navbar-start>.navbar-item,.content kbd.navbar .navbar-start>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.content kbd.navbar .navbar-start .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.content kbd.navbar .navbar-end>.navbar-item,.navbar.is-dark .navbar-end .navbar-link,.content kbd.navbar .navbar-end .navbar-link{color:#f5f5f5}.navbar.is-dark .navbar-start>a.navbar-item:focus,.content kbd.navbar .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover,.content kbd.navbar .navbar-start>a.navbar-item:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.content kbd.navbar .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.content kbd.navbar .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.content kbd.navbar .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.content kbd.navbar .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.content kbd.navbar .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.content kbd.navbar .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.content kbd.navbar .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.content kbd.navbar .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.content kbd.navbar .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end .navbar-link.is-active,.content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-start .navbar-link::after,.content kbd.navbar .navbar-start .navbar-link::after,.navbar.is-dark .navbar-end .navbar-link::after,.content kbd.navbar .navbar-end .navbar-link::after{border-color:#f5f5f5}.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active,.content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#f5f5f5}}.navbar.is-primary,.docstring>section>a.navbar.docs-sourcelink{background-color:#4eb5de;color:#fff}.navbar.is-primary .navbar-brand>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,.navbar.is-primary .navbar-brand .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}.navbar.is-primary .navbar-brand>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger,.docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-primary .navbar-start>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,.navbar.is-primary .navbar-end .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}.navbar.is-primary .navbar-start>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-start .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,.navbar.is-primary .navbar-end .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#4eb5de;color:#fff}}.navbar.is-link{background-color:#2e63b8;color:#fff}.navbar.is-link .navbar-brand>.navbar-item,.navbar.is-link .navbar-brand .navbar-link{color:#fff}.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-link .navbar-start>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-end .navbar-link{color:#fff}.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-start .navbar-link::after,.navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#2e63b8;color:#fff}}.navbar.is-info{background-color:#209cee;color:#fff}.navbar.is-info .navbar-brand>.navbar-item,.navbar.is-info .navbar-brand .navbar-link{color:#fff}.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-info .navbar-start>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-end .navbar-link{color:#fff}.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end .navbar-link.is-active{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-start .navbar-link::after,.navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#209cee;color:#fff}}.navbar.is-success{background-color:#22c35b;color:#fff}.navbar.is-success .navbar-brand>.navbar-item,.navbar.is-success .navbar-brand .navbar-link{color:#fff}.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-success .navbar-start>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-end .navbar-link{color:#fff}.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end .navbar-link.is-active{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-start .navbar-link::after,.navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#22c35b;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand>.navbar-item,.navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){.navbar.is-warning .navbar-start>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-start .navbar-link::after,.navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,0.7)}}.navbar.is-danger{background-color:#da0b00;color:#fff}.navbar.is-danger .navbar-brand>.navbar-item,.navbar.is-danger .navbar-brand .navbar-link{color:#fff}.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-danger .navbar-start>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-end .navbar-link{color:#fff}.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-start .navbar-link::after,.navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#da0b00;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}html.has-navbar-fixed-top,body.has-navbar-fixed-top{padding-top:3.25rem}html.has-navbar-fixed-bottom,body.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#4a4a4a;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,0.05)}.navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#4a4a4a;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}a.navbar-item,.navbar-link{cursor:pointer}a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover,a.navbar-item.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,.navbar-link.is-active{background-color:#fafafa;color:#2e63b8}.navbar-item{display:block;flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(0.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8}.navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8;border-bottom-style:solid;border-bottom-width:3px;color:#2e63b8;padding-bottom:calc(0.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#2e63b8;margin-top:-0.375em;right:1.125em}.navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}html.has-navbar-fixed-top-touch,body.has-navbar-fixed-top-touch{padding-top:3.25rem}html.has-navbar-fixed-bottom-touch,body.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width: 1056px){.navbar,.navbar-menu,.navbar-start,.navbar-end{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-start,.navbar.is-spaced .navbar-end{align-items:center}.navbar.is-spaced a.navbar-item,.navbar.is-spaced .navbar-link{border-radius:4px}.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item{display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar.is-spaced .navbar-dropdown,.navbar-dropdown.is-boxed{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.navbar>.container .navbar-brand,.container>.navbar .navbar-brand{margin-left:-.75rem}.navbar>.container .navbar-menu,.container>.navbar .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-desktop{top:0}html.has-navbar-fixed-top-desktop,body.has-navbar-fixed-top-desktop{padding-top:3.25rem}html.has-navbar-fixed-bottom-desktop,body.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}html.has-spaced-navbar-fixed-top,body.has-spaced-navbar-fixed-top{padding-top:5.25rem}html.has-spaced-navbar-fixed-bottom,body.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}a.navbar-item.is-active,.navbar-link.is-active{color:#0a0a0a}a.navbar-item.is-active:not(:focus):not(:hover),.navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link,.navbar-item.has-dropdown.is-active .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small,#documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-previous,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,.pagination.is-rounded .pagination-next,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:290486px}.pagination.is-rounded .pagination-link,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:290486px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-previous,.pagination-next,.pagination-link{border-color:#dbdbdb;color:#363636;min-width:2.25em}.pagination-previous:hover,.pagination-next:hover,.pagination-link:hover{border-color:#b5b5b5;color:#363636}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus{border-color:#3c5dcd}.pagination-previous:active,.pagination-next:active,.pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}.pagination-previous[disabled],.pagination-next[disabled],.pagination-link[disabled]{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#6b6b6b;opacity:0.5}.pagination-previous,.pagination-next{padding-left:0.75em;padding-right:0.75em;white-space:nowrap}.pagination-link.is-current{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}@media screen and (max-width: 768px){.pagination{flex-wrap:wrap}.pagination-previous,.pagination-next{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel-heading,.panel-tabs,.panel-block{border-bottom:1px solid #dbdbdb;border-left:1px solid #dbdbdb;border-right:1px solid #dbdbdb}.panel-heading:first-child,.panel-tabs:first-child,.panel-block:first-child{border-top:1px solid #dbdbdb}.panel-heading{background-color:#f5f5f5;border-radius:4px 4px 0 0;color:#222;font-size:1.25em;font-weight:300;line-height:1.25;padding:0.5em 0.75em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:0.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#222}.panel-list a:hover{color:#2e63b8}.panel-block{align-items:center;color:#222;display:flex;justify-content:flex-start;padding:0.5em 0.75em}.panel-block input[type="checkbox"]{margin-right:0.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#2e63b8;color:#363636}.panel-block.is-active .panel-icon{color:#2e63b8}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#6b6b6b;margin-right:0.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#222;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#222;color:#222}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#2e63b8;color:#2e63b8}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:0.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}.tabs .icon:first-child{margin-right:0.5em}.tabs .icon:last-child{margin-left:0.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:rgba(0,0,0,0) !important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-radius:4px 0 0 4px}.tabs.is-toggle li:last-child a{border-radius:0 4px 4px 0}.tabs.is-toggle li.is-active a{background-color:#2e63b8;border-color:#2e63b8;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:290486px;border-top-left-radius:290486px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:290486px;border-top-right-radius:290486px;padding-right:1.25em}.tabs.is-small,#documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0%}.columns.is-mobile>.column.is-1{flex:none;width:8.3333333333%}.columns.is-mobile>.column.is-offset-1{margin-left:8.3333333333%}.columns.is-mobile>.column.is-2{flex:none;width:16.6666666667%}.columns.is-mobile>.column.is-offset-2{margin-left:16.6666666667%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.3333333333%}.columns.is-mobile>.column.is-offset-4{margin-left:33.3333333333%}.columns.is-mobile>.column.is-5{flex:none;width:41.6666666667%}.columns.is-mobile>.column.is-offset-5{margin-left:41.6666666667%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.3333333333%}.columns.is-mobile>.column.is-offset-7{margin-left:58.3333333333%}.columns.is-mobile>.column.is-8{flex:none;width:66.6666666667%}.columns.is-mobile>.column.is-offset-8{margin-left:66.6666666667%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.3333333333%}.columns.is-mobile>.column.is-offset-10{margin-left:83.3333333333%}.columns.is-mobile>.column.is-11{flex:none;width:91.6666666667%}.columns.is-mobile>.column.is-offset-11{margin-left:91.6666666667%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){.column.is-narrow-mobile{flex:none}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0%}.column.is-1-mobile{flex:none;width:8.3333333333%}.column.is-offset-1-mobile{margin-left:8.3333333333%}.column.is-2-mobile{flex:none;width:16.6666666667%}.column.is-offset-2-mobile{margin-left:16.6666666667%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.3333333333%}.column.is-offset-4-mobile{margin-left:33.3333333333%}.column.is-5-mobile{flex:none;width:41.6666666667%}.column.is-offset-5-mobile{margin-left:41.6666666667%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.3333333333%}.column.is-offset-7-mobile{margin-left:58.3333333333%}.column.is-8-mobile{flex:none;width:66.6666666667%}.column.is-offset-8-mobile{margin-left:66.6666666667%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.3333333333%}.column.is-offset-10-mobile{margin-left:83.3333333333%}.column.is-11-mobile{flex:none;width:91.6666666667%}.column.is-offset-11-mobile{margin-left:91.6666666667%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0%}.column.is-1,.column.is-1-tablet{flex:none;width:8.3333333333%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.3333333333%}.column.is-2,.column.is-2-tablet{flex:none;width:16.6666666667%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.6666666667%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.3333333333%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.3333333333%}.column.is-5,.column.is-5-tablet{flex:none;width:41.6666666667%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.6666666667%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.3333333333%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.3333333333%}.column.is-8,.column.is-8-tablet{flex:none;width:66.6666666667%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.6666666667%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.3333333333%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.3333333333%}.column.is-11,.column.is-11-tablet{flex:none;width:91.6666666667%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.6666666667%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){.column.is-narrow-touch{flex:none}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0%}.column.is-1-touch{flex:none;width:8.3333333333%}.column.is-offset-1-touch{margin-left:8.3333333333%}.column.is-2-touch{flex:none;width:16.6666666667%}.column.is-offset-2-touch{margin-left:16.6666666667%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.3333333333%}.column.is-offset-4-touch{margin-left:33.3333333333%}.column.is-5-touch{flex:none;width:41.6666666667%}.column.is-offset-5-touch{margin-left:41.6666666667%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.3333333333%}.column.is-offset-7-touch{margin-left:58.3333333333%}.column.is-8-touch{flex:none;width:66.6666666667%}.column.is-offset-8-touch{margin-left:66.6666666667%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.3333333333%}.column.is-offset-10-touch{margin-left:83.3333333333%}.column.is-11-touch{flex:none;width:91.6666666667%}.column.is-offset-11-touch{margin-left:91.6666666667%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){.column.is-narrow-desktop{flex:none}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0%}.column.is-1-desktop{flex:none;width:8.3333333333%}.column.is-offset-1-desktop{margin-left:8.3333333333%}.column.is-2-desktop{flex:none;width:16.6666666667%}.column.is-offset-2-desktop{margin-left:16.6666666667%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.3333333333%}.column.is-offset-4-desktop{margin-left:33.3333333333%}.column.is-5-desktop{flex:none;width:41.6666666667%}.column.is-offset-5-desktop{margin-left:41.6666666667%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.3333333333%}.column.is-offset-7-desktop{margin-left:58.3333333333%}.column.is-8-desktop{flex:none;width:66.6666666667%}.column.is-offset-8-desktop{margin-left:66.6666666667%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.3333333333%}.column.is-offset-10-desktop{margin-left:83.3333333333%}.column.is-11-desktop{flex:none;width:91.6666666667%}.column.is-offset-11-desktop{margin-left:91.6666666667%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){.column.is-narrow-widescreen{flex:none}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0%}.column.is-1-widescreen{flex:none;width:8.3333333333%}.column.is-offset-1-widescreen{margin-left:8.3333333333%}.column.is-2-widescreen{flex:none;width:16.6666666667%}.column.is-offset-2-widescreen{margin-left:16.6666666667%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.3333333333%}.column.is-offset-4-widescreen{margin-left:33.3333333333%}.column.is-5-widescreen{flex:none;width:41.6666666667%}.column.is-offset-5-widescreen{margin-left:41.6666666667%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.3333333333%}.column.is-offset-7-widescreen{margin-left:58.3333333333%}.column.is-8-widescreen{flex:none;width:66.6666666667%}.column.is-offset-8-widescreen{margin-left:66.6666666667%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.3333333333%}.column.is-offset-10-widescreen{margin-left:83.3333333333%}.column.is-11-widescreen{flex:none;width:91.6666666667%}.column.is-offset-11-widescreen{margin-left:91.6666666667%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){.column.is-narrow-fullhd{flex:none}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0%}.column.is-1-fullhd{flex:none;width:8.3333333333%}.column.is-offset-1-fullhd{margin-left:8.3333333333%}.column.is-2-fullhd{flex:none;width:16.6666666667%}.column.is-offset-2-fullhd{margin-left:16.6666666667%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.3333333333%}.column.is-offset-4-fullhd{margin-left:33.3333333333%}.column.is-5-fullhd{flex:none;width:41.6666666667%}.column.is-offset-5-fullhd{margin-left:41.6666666667%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.3333333333%}.column.is-offset-7-fullhd{margin-left:58.3333333333%}.column.is-8-fullhd{flex:none;width:66.6666666667%}.column.is-offset-8-fullhd{margin-left:66.6666666667%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.3333333333%}.column.is-offset-10-fullhd{margin-left:83.3333333333%}.column.is-11-fullhd{flex:none;width:91.6666666667%}.column.is-offset-11-fullhd{margin-left:91.6666666667%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0 !important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable .column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){.columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-0-fullhd{--columnGap: 0rem}}.columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){.columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-1-fullhd{--columnGap: .25rem}}.columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){.columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-2-fullhd{--columnGap: .5rem}}.columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){.columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-3-fullhd{--columnGap: .75rem}}.columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){.columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-4-fullhd{--columnGap: 1rem}}.columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){.columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}.columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){.columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}.columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){.columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}.columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){.columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-8-fullhd{--columnGap: 2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0 !important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.3333333333%}.tile.is-2{flex:none;width:16.6666666667%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.3333333333%}.tile.is-5{flex:none;width:41.6666666667%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.3333333333%}.tile.is-8{flex:none;width:66.6666666667%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.3333333333%}.tile.is-11{flex:none;width:91.6666666667%}.tile.is-12{flex:none;width:100%}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:none}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,0.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}.hero.is-white a.navbar-item:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white .navbar-link:hover,.hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,0.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-black a.navbar-item:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black .navbar-link:hover,.hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:0.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:#363636}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:#363636}.hero.is-light .subtitle{color:rgba(54,54,54,0.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:#363636}@media screen and (max-width: 1055px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(54,54,54,0.7)}.hero.is-light a.navbar-item:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light .navbar-link:hover,.hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:#363636}.hero.is-light .tabs a{color:#363636;opacity:0.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:#363636}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:#363636;border-color:#363636;color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}.hero.is-dark,.content kbd.hero{background-color:#363636;color:#f5f5f5}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong,.content kbd.hero strong{color:inherit}.hero.is-dark .title,.content kbd.hero .title{color:#f5f5f5}.hero.is-dark .subtitle,.content kbd.hero .subtitle{color:rgba(245,245,245,0.9)}.hero.is-dark .subtitle a:not(.button),.content kbd.hero .subtitle a:not(.button),.hero.is-dark .subtitle strong,.content kbd.hero .subtitle strong{color:#f5f5f5}@media screen and (max-width: 1055px){.hero.is-dark .navbar-menu,.content kbd.hero .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.content kbd.hero .navbar-item,.hero.is-dark .navbar-link,.content kbd.hero .navbar-link{color:rgba(245,245,245,0.7)}.hero.is-dark a.navbar-item:hover,.content kbd.hero a.navbar-item:hover,.hero.is-dark a.navbar-item.is-active,.content kbd.hero a.navbar-item.is-active,.hero.is-dark .navbar-link:hover,.content kbd.hero .navbar-link:hover,.hero.is-dark .navbar-link.is-active,.content kbd.hero .navbar-link.is-active{background-color:#292929;color:#f5f5f5}.hero.is-dark .tabs a,.content kbd.hero .tabs a{color:#f5f5f5;opacity:0.9}.hero.is-dark .tabs a:hover,.content kbd.hero .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a,.content kbd.hero .tabs li.is-active a{opacity:1}.hero.is-dark .tabs.is-boxed a,.content kbd.hero .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a,.content kbd.hero .tabs.is-toggle a{color:#f5f5f5}.hero.is-dark .tabs.is-boxed a:hover,.content kbd.hero .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover,.content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.content kbd.hero .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.content kbd.hero .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.hero.is-dark.is-bold,.content kbd.hero.is-bold{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}@media screen and (max-width: 768px){.hero.is-dark.is-bold .navbar-menu,.content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}}.hero.is-primary,.docstring>section>a.hero.docs-sourcelink{background-color:#4eb5de;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong,.docstring>section>a.hero.docs-sourcelink strong{color:inherit}.hero.is-primary .title,.docstring>section>a.hero.docs-sourcelink .title{color:#fff}.hero.is-primary .subtitle,.docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}.hero.is-primary .subtitle a:not(.button),.docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),.hero.is-primary .subtitle strong,.docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-primary .navbar-menu,.docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#4eb5de}}.hero.is-primary .navbar-item,.docstring>section>a.hero.docs-sourcelink .navbar-item,.hero.is-primary .navbar-link,.docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-primary a.navbar-item:hover,.docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,.hero.is-primary a.navbar-item.is-active,.docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,.hero.is-primary .navbar-link:hover,.docstring>section>a.hero.docs-sourcelink .navbar-link:hover,.hero.is-primary .navbar-link.is-active,.docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#39acda;color:#fff}.hero.is-primary .tabs a,.docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}.hero.is-primary .tabs a:hover,.docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{opacity:1}.hero.is-primary .tabs.is-boxed a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#4eb5de}.hero.is-primary.is-bold,.docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}@media screen and (max-width: 768px){.hero.is-primary.is-bold .navbar-menu,.docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}}.hero.is-link{background-color:#2e63b8;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,0.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-link .navbar-menu{background-color:#2e63b8}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-link a.navbar-item:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link .navbar-link:hover,.hero.is-link .navbar-link.is-active{background-color:#2958a4;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:0.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#2e63b8}.hero.is-link.is-bold{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}@media screen and (max-width: 768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}}.hero.is-info{background-color:#209cee;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,0.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-info .navbar-menu{background-color:#209cee}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-info a.navbar-item:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info .navbar-link:hover,.hero.is-info .navbar-link.is-active{background-color:#1190e3;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:0.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#209cee}.hero.is-info.is-bold{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}@media screen and (max-width: 768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}}.hero.is-success{background-color:#22c35b;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,0.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-success .navbar-menu{background-color:#22c35b}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-success a.navbar-item:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success .navbar-link:hover,.hero.is-success .navbar-link.is-active{background-color:#1ead51;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:0.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#22c35b}.hero.is-success.is-bold{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}@media screen and (max-width: 768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,0.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}.hero.is-warning a.navbar-item:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}@media screen and (max-width: 768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}}.hero.is-danger{background-color:#da0b00;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-danger .navbar-menu{background-color:#da0b00}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-danger a.navbar-item:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger .navbar-link.is-active{background-color:#c10a00;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:0.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#da0b00}.hero.is-danger.is-bold{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 100%)}@media screen and (max-width: 768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 100%)}}.hero.is-small .hero-body,#documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding-bottom:1.5rem;padding-top:1.5rem}@media screen and (min-width: 769px),print{.hero.is-medium .hero-body{padding-bottom:9rem;padding-top:9rem}}@media screen and (min-width: 769px),print{.hero.is-large .hero-body{padding-bottom:18rem;padding-top:18rem}}.hero.is-halfheight .hero-body,.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}.hero.is-halfheight .hero-body>.container,.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}.hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-head,.hero-foot{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}.section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){.section.is-medium{padding:9rem 1.5rem}.section.is-large{padding:18rem 1.5rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem}h1 .docs-heading-anchor,h1 .docs-heading-anchor:hover,h1 .docs-heading-anchor:visited,h2 .docs-heading-anchor,h2 .docs-heading-anchor:hover,h2 .docs-heading-anchor:visited,h3 .docs-heading-anchor,h3 .docs-heading-anchor:hover,h3 .docs-heading-anchor:visited,h4 .docs-heading-anchor,h4 .docs-heading-anchor:hover,h4 .docs-heading-anchor:visited,h5 .docs-heading-anchor,h5 .docs-heading-anchor:hover,h5 .docs-heading-anchor:visited,h6 .docs-heading-anchor,h6 .docs-heading-anchor:hover,h6 .docs-heading-anchor:visited{color:#222}h1 .docs-heading-anchor-permalink,h2 .docs-heading-anchor-permalink,h3 .docs-heading-anchor-permalink,h4 .docs-heading-anchor-permalink,h5 .docs-heading-anchor-permalink,h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}h1 .docs-heading-anchor-permalink::before,h2 .docs-heading-anchor-permalink::before,h3 .docs-heading-anchor-permalink::before,h4 .docs-heading-anchor-permalink::before,h5 .docs-heading-anchor-permalink::before,h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 5 Free";font-weight:900;content:"\f0c1"}h1:hover .docs-heading-anchor-permalink,h2:hover .docs-heading-anchor-permalink,h3:hover .docs-heading-anchor-permalink,h4:hover .docs-heading-anchor-permalink,h5:hover .docs-heading-anchor-permalink,h6:hover .docs-heading-anchor-permalink{visibility:visible}.docs-dark-only{display:none !important}pre{position:relative;overflow:hidden}pre code,pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}pre code:first-of-type,pre code.hljs:first-of-type{padding-top:0.5rem !important}pre code:last-of-type,pre code.hljs:last-of-type{padding-bottom:0.5rem !important}pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 5 Free";color:#222;cursor:pointer;text-align:center}pre .copy-button:focus,pre .copy-button:hover{opacity:1;background:rgba(34,34,34,0.1);color:#2e63b8}pre .copy-button.success{color:#259a12;opacity:1}pre .copy-button.error{color:#cb3c33;opacity:1}pre:hover .copy-button{opacity:1}.admonition{background-color:#b5b5b5;border-style:solid;border-width:1px;border-color:#363636;border-radius:4px;font-size:1rem}.admonition strong{color:currentColor}.admonition.is-small,#documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}.admonition.is-medium{font-size:1.25rem}.admonition.is-large{font-size:1.5rem}.admonition.is-default{background-color:#b5b5b5;border-color:#363636}.admonition.is-default>.admonition-header{background-color:#363636;color:#fff}.admonition.is-default>.admonition-body{color:#fff}.admonition.is-info{background-color:#def0fc;border-color:#209cee}.admonition.is-info>.admonition-header{background-color:#209cee;color:#fff}.admonition.is-info>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-success{background-color:#bdf4d1;border-color:#22c35b}.admonition.is-success>.admonition-header{background-color:#22c35b;color:#fff}.admonition.is-success>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-warning{background-color:#fff3c5;border-color:#ffdd57}.admonition.is-warning>.admonition-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.admonition.is-warning>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-danger{background-color:#ffaba7;border-color:#da0b00}.admonition.is-danger>.admonition-header{background-color:#da0b00;color:#fff}.admonition.is-danger>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-compat{background-color:#bdeff5;border-color:#1db5c9}.admonition.is-compat>.admonition-header{background-color:#1db5c9;color:#fff}.admonition.is-compat>.admonition-body{color:rgba(0,0,0,0.7)}.admonition-header{color:#fff;background-color:#363636;align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}.admonition-header:before{font-family:"Font Awesome 5 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}.admonition-body{color:#222;padding:0.5rem .75rem}.admonition-body pre{background-color:#f5f5f5}.admonition-body code{background-color:rgba(0,0,0,0.05)}.docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:1px solid #dbdbdb;box-shadow:2px 2px 3px rgba(10,10,10,0.1);max-width:100%}.docstring>header{display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#f5f5f5;box-shadow:0 1px 2px rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #dbdbdb}.docstring>header code{background-color:transparent}.docstring>header .docstring-binding{margin-right:0.3em}.docstring>header .docstring-category{margin-left:0.3em}.docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #dbdbdb}.docstring>section:last-child{border-bottom:none}.docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}.docstring>section>a.docs-sourcelink:focus{opacity:1 !important}.docstring:hover>section>a.docs-sourcelink{opacity:0.2}.docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}.docstring>section:hover a.docs-sourcelink{opacity:1}.documenter-example-output{background-color:#fff}.outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#ffaba7;color:rgba(0,0,0,0.7);border-bottom:3px solid #da0b00;padding:10px 35px;text-align:center;font-size:15px}.outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}.outdated-warning-overlay a{color:#2e63b8}.outdated-warning-overlay a:hover{color:#363636}.content pre{border:1px solid #dbdbdb}.content code{font-weight:inherit}.content a code{color:#2e63b8}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code,.content h6 code{color:#222}.content table{display:block;width:initial;max-width:100%;overflow-x:auto}.content blockquote>ul:first-child,.content blockquote>ol:first-child,.content .admonition-body>ul:first-child,.content .admonition-body>ol:first-child{margin-top:0}pre,code{font-variant-ligatures:no-contextual}.breadcrumb a.is-disabled{cursor:default;pointer-events:none}.breadcrumb a.is-disabled,.breadcrumb a.is-disabled:hover{color:#222}.hljs{background:initial !important}.katex .katex-mathml{top:0;right:0}.katex-display,mjx-container,.MathJax_Display{margin:0.5em 0 !important}html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}li.no-marker{list-style:none}#documenter .docs-main>article{overflow-wrap:break-word}#documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){#documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){#documenter .docs-main{width:100%}#documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}#documenter .docs-main>header,#documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}#documenter .docs-main header.docs-navbar{background-color:#fff;border-bottom:1px solid #dbdbdb;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}#documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1}#documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap}#documenter .docs-main header.docs-navbar .docs-right .docs-icon,#documenter .docs-main header.docs-navbar .docs-right .docs-label,#documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button{display:inline-block}#documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}#documenter .docs-main header.docs-navbar .docs-right .docs-settings-button{margin:auto 0 auto 1rem}#documenter .docs-main header.docs-navbar .docs-right .docs-sidebar-button{font-size:1.5rem;margin:auto 0 auto 1rem}#documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}#documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #bbb;transition-duration:0.7s;-webkit-transition-duration:0.7s}#documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}#documenter .docs-main section.footnotes{border-top:1px solid #dbdbdb}#documenter .docs-main section.footnotes li .tag:first-child,#documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,#documenter .docs-main section.footnotes li .content kbd:first-child,.content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}#documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #dbdbdb;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){#documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}#documenter .docs-main .docs-footer .docs-footer-nextpage,#documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}#documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}#documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}#documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}#documenter .docs-sidebar{display:flex;flex-direction:column;color:#0a0a0a;background-color:#f5f5f5;border-right:1px solid #dbdbdb;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}#documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #bbb}@media screen and (min-width: 1056px){#documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){#documenter .docs-sidebar{left:0;top:0}}#documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}#documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}#documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}#documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}#documenter .docs-sidebar .docs-package-name a,#documenter .docs-sidebar .docs-package-name a:hover{color:#0a0a0a}#documenter .docs-sidebar .docs-version-selector{border-top:1px solid #dbdbdb;display:none;padding:0.5rem}#documenter .docs-sidebar .docs-version-selector.visible{display:flex}#documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #dbdbdb;padding-bottom:1.5rem}#documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}#documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}#documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}#documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}#documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 5 Free";font-weight:900;content:"\f054"}#documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}#documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}#documenter .docs-sidebar ul.docs-menu .tocitem,#documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#0a0a0a;background:#f5f5f5}#documenter .docs-sidebar ul.docs-menu a.tocitem:hover,#documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#0a0a0a;background-color:#ebebeb}#documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #dbdbdb;border-bottom:1px solid #dbdbdb;background-color:#fff}#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#fff;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#ebebeb;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}#documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}#documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}#documenter .docs-sidebar form.docs-search>input{width:14.4rem}@media screen and (min-width: 1056px){#documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#ccc}}@media screen and (max-width: 1055px){#documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#ccc}}#documenter .docs-main #documenter-search-info{margin-bottom:1rem}#documenter .docs-main #documenter-search-results{list-style-type:circle;list-style-position:outside}#documenter .docs-main #documenter-search-results li{margin-left:2rem}#documenter .docs-main #documenter-search-results .docs-highlight{background-color:yellow}.ansi span.sgr1{font-weight:bolder}.ansi span.sgr2{font-weight:lighter}.ansi span.sgr3{font-style:italic}.ansi span.sgr4{text-decoration:underline}.ansi span.sgr7{color:#fff;background-color:#222}.ansi span.sgr8{color:transparent}.ansi span.sgr8 span{color:transparent}.ansi span.sgr9{text-decoration:line-through}.ansi span.sgr30{color:#242424}.ansi span.sgr31{color:#a7201f}.ansi span.sgr32{color:#066f00}.ansi span.sgr33{color:#856b00}.ansi span.sgr34{color:#2149b0}.ansi span.sgr35{color:#7d4498}.ansi span.sgr36{color:#007989}.ansi span.sgr37{color:gray}.ansi span.sgr40{background-color:#242424}.ansi span.sgr41{background-color:#a7201f}.ansi span.sgr42{background-color:#066f00}.ansi span.sgr43{background-color:#856b00}.ansi span.sgr44{background-color:#2149b0}.ansi span.sgr45{background-color:#7d4498}.ansi span.sgr46{background-color:#007989}.ansi span.sgr47{background-color:gray}.ansi span.sgr90{color:#616161}.ansi span.sgr91{color:#cb3c33}.ansi span.sgr92{color:#0e8300}.ansi span.sgr93{color:#a98800}.ansi span.sgr94{color:#3c5dcd}.ansi span.sgr95{color:#9256af}.ansi span.sgr96{color:#008fa3}.ansi span.sgr97{color:#f5f5f5}.ansi span.sgr100{background-color:#616161}.ansi span.sgr101{background-color:#cb3c33}.ansi span.sgr102{background-color:#0e8300}.ansi span.sgr103{background-color:#a98800}.ansi span.sgr104{background-color:#3c5dcd}.ansi span.sgr105{background-color:#9256af}.ansi span.sgr106{background-color:#008fa3}.ansi span.sgr107{background-color:#f5f5f5}code.language-julia-repl>span.hljs-meta{color:#066f00;font-weight:bolder}/*! - Theme: Default - Description: Original highlight.js style - Author: (c) Ivan Sagalaev - Maintainer: @highlightjs/core-team - Website: https://highlightjs.org/ - License: see project LICENSE - Touched: 2021 -*/pre code.hljs{display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{background:#F0F0F0;color:#444}.hljs-comment{color:#888888}.hljs-tag,.hljs-punctuation{color:#444a}.hljs-tag .hljs-name,.hljs-tag .hljs-attr{color:#444}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-operator,.hljs-selector-pseudo{color:#BC6060}.hljs-literal{color:#78A960}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} diff --git a/previews/PR2578/assets/themeswap.js b/previews/PR2578/assets/themeswap.js deleted file mode 100644 index c58e993e3e13..000000000000 --- a/previews/PR2578/assets/themeswap.js +++ /dev/null @@ -1,66 +0,0 @@ -// Small function to quickly swap out themes. Gets put into the tag.. -function set_theme_from_local_storage() { - // Intialize the theme to null, which means default - var theme = null; - // If the browser supports the localstorage and is not disabled then try to get the - // documenter theme - if(window.localStorage != null) { - // Get the user-picked theme from localStorage. May be `null`, which means the default - // theme. - theme = window.localStorage.getItem("documenter-theme"); - } - // Check if the browser supports user color preference - var darkPreference = false; - // Check if the users preference is for dark color scheme - if(window.matchMedia('(prefers-color-scheme: dark)').matches === true) { - darkPreference = true; - } - // Initialize a few variables for the loop: - // - // - active: will contain the index of the theme that should be active. Note that there - // is no guarantee that localStorage contains sane values. If `active` stays `null` - // we either could not find the theme or it is the default (primary) theme anyway. - // Either way, we then need to stick to the primary theme. - // - // - disabled: style sheets that should be disabled (i.e. all the theme style sheets - // that are not the currently active theme) - var active = null; var disabled = []; var darkTheme = null; - for (var i = 0; i < document.styleSheets.length; i++) { - var ss = document.styleSheets[i]; - // The tag of each style sheet is expected to have a data-theme-name attribute - // which must contain the name of the theme. The names in localStorage much match this. - var themename = ss.ownerNode.getAttribute("data-theme-name"); - // attribute not set => non-theme stylesheet => ignore - if(themename === null) continue; - // To distinguish the default (primary) theme, it needs to have the data-theme-primary - // attribute set. - var isprimary = (ss.ownerNode.getAttribute("data-theme-primary") !== null); - // Check if the theme is primary dark theme - var isDarkTheme = (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null); - // If ss is for dark theme then set the value of darkTheme to the name of the theme - if(isDarkTheme) darkTheme = themename; - // If we find a matching theme (and it's not the default), we'll set active to non-null - if(themename === theme) active = i; - // Store the style sheets of inactive themes so that we could disable them - if(themename !== theme) disabled.push(ss); - } - if(active !== null) { - // If we did find an active theme, we'll (1) add the theme--$(theme) class to - document.getElementsByTagName('html')[0].className = "theme--" + theme; - // and (2) disable all the other theme stylesheets - disabled.forEach(function(ss){ - ss.disabled = true; - }); - } - else if(darkTheme !== null && darkPreference === true) { - // If we did find an active theme, we'll (1) add the theme--$(theme) class to - document.getElementsByTagName('html')[0].className = "theme--" + darkTheme; - // and (2) disable all the other theme stylesheets - disabled.forEach(function(ss){ - if (ss.ownerNode.getAttribute("data-theme-name") !== darkTheme) { - ss.disabled = true; - } - }); - } -} -set_theme_from_local_storage(); diff --git a/previews/PR2578/assets/warner.js b/previews/PR2578/assets/warner.js deleted file mode 100644 index 5531c8851b9d..000000000000 --- a/previews/PR2578/assets/warner.js +++ /dev/null @@ -1,49 +0,0 @@ -function maybeAddWarning () { - // DOCUMENTER_NEWEST is defined in versions.js, DOCUMENTER_CURRENT_VERSION and DOCUMENTER_STABLE - // in siteinfo.js. - // If either of these are undefined something went horribly wrong, so we abort. - if ( - window.DOCUMENTER_NEWEST === undefined || - window.DOCUMENTER_CURRENT_VERSION === undefined || - window.DOCUMENTER_STABLE === undefined - ) { - return - }; - - // Current version is not a version number, so we can't tell if it's the newest version. Abort. - if (!/v(\d+\.)*\d+/.test(window.DOCUMENTER_CURRENT_VERSION)) { - return - }; - - // Current version is newest version, so no need to add a warning. - if (window.DOCUMENTER_NEWEST === window.DOCUMENTER_CURRENT_VERSION) { - return - }; - - // Add a noindex meta tag (unless one exists) so that search engines don't index this version of the docs. - if (document.body.querySelector('meta[name="robots"]') === null) { - const meta = document.createElement('meta'); - meta.name = 'robots'; - meta.content = 'noindex'; - - document.getElementsByTagName('head')[0].appendChild(meta); - }; - - const div = document.createElement('div'); - div.classList.add('outdated-warning-overlay'); - const closer = document.createElement('button'); - closer.classList.add('outdated-warning-closer', 'delete'); - closer.addEventListener('click', function () { - document.body.removeChild(div); - }); - const href = window.documenterBaseURL + '/../' + window.DOCUMENTER_STABLE; - div.innerHTML = 'This documentation is not for the latest stable release, but for either the development version or an older release.
    Click here to go to the documentation for the latest stable release.'; - div.appendChild(closer); - document.body.appendChild(div); -}; - -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', maybeAddWarning); -} else { - maybeAddWarning(); -}; diff --git a/previews/PR2578/index.html b/previews/PR2578/index.html deleted file mode 100644 index 95c0ccabfd41..000000000000 --- a/previews/PR2578/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Welcome to OSCAR · Oscar.jl

    Welcome to OSCAR

    OSCAR is a new computer algebra system. OSCAR features functions for groups, rings, and fields as well as linear and commutative algebra, number theory, algebraic and polyhedral geometry, and more. It is built upon several well established systems for mathematical research joined via the Julia programming language. Have a look at our Architecture page for a detailed overview and at our installation instructions for installing OSCAR.

    If you have questions about OSCAR, please have a look at our Frequently Asked Questions and feel free to contact us under the channels mentioned on our community page. Our main communication channels are Slack and Github.

    If you are a new developer or interested in developing OSCAR, have a look at our Introduction for new developers.

    diff --git a/previews/PR2578/manualindex/index.html b/previews/PR2578/manualindex/index.html deleted file mode 100644 index ab7e376da282..000000000000 --- a/previews/PR2578/manualindex/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Index · Oscar.jl
    diff --git a/previews/PR2578/references/index.html b/previews/PR2578/references/index.html deleted file mode 100644 index 401957b769ef..000000000000 --- a/previews/PR2578/references/index.html +++ /dev/null @@ -1,450 +0,0 @@ - -References · Oscar.jl
    AL94
    -
    -
    William W. Adams, Philippe Loustaunau, An Introduction to Gröbner Bases, American Mathematical Society, 1994.
    -
    AHK18
    -
    -
    Karim Adiprasito, June Huh, Eric Katz, Hodge theory for combinatorial geometries, Ann. of Math. (2), 188(2), 381–452, 2018.
    -
    AG10
    -
    -
    Ivan V. Arzhantsev, Sergei A. Gaǐfullin, Cox rings, semigroups, and automorphisms of affine varieties, Mat. Sb., 201(1), 3–24, 2010.
    -
    BES19
    -
    -
    Spencer Backman, Christopher Eur, Connor Simpson, Simplicial generation of Chow rings of matroids, 2019.
    -
    BN07
    -
    -
    Matthew Baker, Serguei Norine, Riemann-Roch and Abel-Jacobi theory on a finite graph, Adv. Math., 215(2), 766–788, 2007.
    -
    Ben93
    -
    -
    David J. Benson, Polynomial invariants of finite groups, Cambridge University Press, Cambridge, 1993.
    -
    BDEPS04
    -
    -
    Neil Berry, Artūras Dubickas, Noam D. Elkies, Bjorn Poonen, Chris Smyth, The conjugate dimension of algebraic numbers, Q. J. Math., 55(3), 237–252, 2004.
    -
    BES-E-D21
    -
    -
    Jérémy Berthomieu, Christian Eder, Mohab Safey El Din, Msolve: A Library for Solving Polynomial Systems, In Proceedings of the 2021 on International Symposium on Symbolic and Algebraic Computation, ISSAC '21, 51–58, New York, NY, USA, 2021. Association for Computing Machinery.
    -
    Bie18
    -
    -
    Martin Bies, Cohomologies of coherent sheaves and massless spectra in F-theory, PhD thesis, Heidelberg U., 2018.
    -
    BL81
    -
    -
    Louis J. Billera, Carl W. Lee, A proof of the sufficiency of McMullen's conditions for {$f$}-vectors of simplicial convex - polytopes, J. Combin. Theory Ser. A, 31(3), 237–255, 1981.
    -
    BJRR10
    -
    -
    Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy, Cohomology of line bundles: A computational algorithm, Journal of Mathematical Physics, 51(10), 103525, 2010.
    -
    BJRR10*1
    -
    -
    Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy, cohomCalg package, 2010, High-performance line bundle cohomology computation based on BJRR10.
    -
    BJRR12
    -
    -
    Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy, Cohomology of line bundles: Applications, Journal of Mathematical Physics, 53(1), 012302, 2012.
    -
    BHMPW20
    -
    -
    Tom Braden, June Huh, Jacob P. Matherne, Nicholas Proudfoot, Botong Wang, A semi-small decomposition of the Chow ring of a matroid, 2020.
    -
    BH23
    -
    -
    Simon Brandhorst, Tommy Hofmann, Finite subgroups of automorphisms of K3 surfaces, Forum of Mathematics, Sigma, 11, e54 1–57, 2023.
    -
    BH09
    -
    -
    Winfried Bruns, Jürgen Herzog, Cohen-Macaulay rings, Cambridge University Press, Cambridge, 2009.
    -
    BGV03
    -
    -
    José Bueso, José Gómez-Torrecillas, Alain Verschoren, Algorithmic methods in non-commutative algebra. Applications to quantum groups., Dordrecht: Kluwer Academic Publishers, 2003.
    -
    Bhm99
    -
    -
    Janko Böhm, Parametrisierung rationaler Kurven, Master's thesis, Universität Bayreuth, 1999.
    -
    BDLP17
    -
    -
    Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Local to global algorithms for the Gorenstein adjoint ideal of a curve, In Algorithmic and experimental methods in algebra, geometry, and number theory, editors, 51–96. Springer, Cham, 2017.
    -
    BDLP19
    -
    -
    Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Computing integral bases via localization and Hensel lifting, In MEGA 2019 - International Conference on Effective Methods in Algebraic Geometry, Madrid, Spain, 2019.
    -
    BDLPSS13
    -
    -
    Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Andreas Steenpaß, Stefan Steidel, Parallel algorithms for normalization, Journal of Symbolic Computation, 51, 99-114, 2013.
    -
    BKR20
    -
    -
    Janko Böhm, Simon Keicher, Yue Ren, Computing GIT-fans with symmetry and the Mori chamber decomposition of $\overline M_{0,6}$, Math. Comp., 89(326), 3003–3021, 2020.
    -
    Cam99
    -
    -
    Peter J. Cameron, Permutation groups, Cambridge University Press, Cambridge, 1999.
    -
    OMdCS00
    -
    -
    Ignacio Ojeda Martínez de Castilla, Ramón Peidra Sánchez, Cellular binomial ideals. Primary decomposition of binomial ideals, J. Symbolic Comput., 30(4), 383–400, 2000.
    -
    Chr91
    -
    -
    Jan Arthur Christophersen, On the components and discriminant of the versal base space of cyclic quotient singularities, In Singularity theory and its applications, Part I (Coventry, 1988/1989), editors, 81–92. Springer, Berlin, 1991.
    -
    C-MLS20
    -
    -
    Jose Luis Cisneros Molina, Dung Trang Le, Jose Seade, Handbook of Geometry and Topology of Singularities I, Springer-Verlag, Cham, 2020.
    -
    C-MLS21
    -
    -
    Jose Luis Cisneros Molina, Dung Trang Le, Jose Seade, Handbook of Geometry and Topology of Singularities II, Springer-Verlag, Cham, 2021.
    -
    Coh93
    -
    -
    Henri Cohen, A course in computational algebraic number theory, Springer-Verlag, Berlin, 1993.
    -
    Coh00
    -
    -
    Henri Cohen, Advanced topics in computational number theory, Springer-Verlag, New York, 2000.
    -
    CCNPW85
    -
    -
    J. H. Conway, R. T. Curtis, S. P. Norton, R. A. Parker, R. A. Wilson, Atlas of finite groups, Oxford University Press, Eynsham, 1985.
    -
    CS99
    -
    -
    J. H. Conway, N. J. A. Sloane, Sphere packings, lattices and groups, Springer-Verlag, New York, 1999.
    -
    CHM98
    -
    -
    John H. Conway, Alexander Hulpke, John McKay, On transitive permutation groups, LMS J. Comput. Math., 1, 1–8, 1998.
    -
    Cor21
    -
    -
    D. Corey, Initial degenerations of Grassmannians, Sel. Math. New Ser., 27(57), 2021.
    -
    CLS11
    -
    -
    David A. Cox, John B. Little, Henry K. Schenck, Toric varieties, Providence, RI: American Mathematical Society (AMS), 2011.
    -
    DF20
    -
    - -
    DLRS10
    -
    -
    Jesús A. De Loera, Jörg Rambau, Francisco Santos, Triangulations. Structures for algorithms and applications, Springer-Verlag, Berlin, 2010.
    -
    DES93
    -
    -
    Wolfram Decker, Lawrence Ein, Frank-Olaf Schreyer, Construction of surfaces in ${\mathbb P}_4$, J. Algebr. Geom., 2(2), 185–237, 1993.
    -
    DGP99
    -
    -
    Wolfram Decker, Gert-Martin Greuel, Gerhard Pfister, Primary decomposition: algorithms and comparisons, In Algorithmic algebra and number theory. Selected papers from a conference, Heidelberg, Germany, - October 1997, editors, 187–220. Springer, Berlin, 1999.
    -
    DHS98
    -
    -
    Wolfram Decker, Agnes Eileen Heydtmann, Frank-Olaf Schreyer, Generating a Noetherian normalization of the invariant ring of a finite group, J. Symbolic Comput., 25(6), 727–731, 1998.
    -
    DJ98
    -
    -
    Wolfram Decker, Theo de Jong, Gröbner bases and invariant theory, In Gröbner bases and applications. Based on a course for young researchers, January 1998, and the - conference "33 years of Gröbner bases", Linz, Austria, February 2–4, 1998, editors, 61–89. Cambridge Univ. Press, Cambridge, 1998.
    -
    DL06
    -
    -
    Wolfram Decker, Christoph Lossen, Computing in algebraic geometry. A quick start using SINGULAR, Springer-Verlag, Berlin; Hindustan Book Agency, New Delhi, 2006.
    -
    DP13
    -
    -
    Wolfram Decker, Gerhard Pfister, A first course in computational algebraic geometry, Cambridge University Press, Cambridge, 2013.
    -
    DS00
    -
    -
    Wolfram Decker, Frank-Olaf Schreyer, Non-general type surfaces in ${\mathbb P}^4$: Some remarks on bounds and constructions, J. Symb. Comput., 29(4-5), 545–582, 2000.
    -
    Der99
    -
    -
    Harm Derksen, Computation of invariants for reductive groups, Adv. Math., 141(2), 366–384, 1999.
    -
    DK15
    -
    - -
    DFO13
    -
    -
    A. S. Detinko, D. L. Flannery, E. A. O'Brien, Recognizing finite matrix groups over infinite fields, J. Symbolic Comput., 50, 100–109, 2013.
    -
    DH00
    -
    -
    Mátyás Domokos, Pál Hegedűs, Noether's bound for polynomial invariants of finite groups, Arch. Math. (Basel), 74(3), 161–167, 2000.
    -
    DK17
    -
    -
    Maria Donten-Bury, Simon Keicher, Computing resolutions of quotient singularities, J. Algebra, 472, 546–572, 2017.
    -
    Eis95
    -
    -
    David Eisenbud, Commutative algebra. With a view toward algebraic geometry, Berlin: Springer-Verlag, 1995.
    -
    EHU03
    -
    -
    David Eisenbud, Craig Huneke, Bernd Ulrich, What is the Rees algebra of a module?, Proc. Am. Math. Soc., 131(3), 701–708, 2003.
    -
    EHV92
    -
    -
    David Eisenbud, Craig Huneke, Wolmer Vasconcelos, Direct methods for primary decomposition, Invent. Math., 110(2), 207–235, 1992.
    -
    ES96
    -
    -
    David Eisenbud, Bernd Sturmfels, Binomial ideals, Duke Math. J., 84(1), 1–45, 1996.
    -
    EM16
    -
    -
    Zekiye Sahin Eser, Laura Felicia Matusevich, Decompositions of cellular binomial ideals, J. Lond. Math. Soc. (2), 94(2), 409–426, 2016.
    -
    EM19
    -
    -
    Zekiye Sahin Eser, Laura Felicia Matusevich, Corrigendum: Decompositions of cellular binomial ideals: (J. Lond. Math. Soc. 94 (2016) 409–426), J. Lond. Math. Soc. (2), 100(2), 717–719, 2019.
    -
    FJR17
    -
    -
    Huijun Fan, Tyler Jarvis, Yongbin Ruan, A mathematical theory of the gauged linear sigma model, Geometry & Topology, 22(1), 235-303, 2017.
    -
    FGLM93
    -
    -
    J.C. Faugère, P. Gianni, D. Lazard, T. Mora, Efficient Computation of Zero-dimensional Gröbner Bases by Change of Ordering, Journal of Symbolic Computation, 16(4), 329-344, 1993.
    -
    Fau99
    -
    -
    Jean-Charles Faugère, A new efficient algorithm for computing Gröbner bases (F4), Journal of Pure and Applied Algebra, 139(1–3), 61–88, 1999.
    -
    FY04
    -
    -
    Eva Maria Feichtner, Sergey Yuzvinsky, Chow rings of toric varieties defined by atomic lattices, Inventiones Mathematicae, 155(3), 515–536, 2004.
    -
    Ful69
    -
    -
    William Fulton, Algebraic curves. An introduction to algebraic geometry, W. A. Benjamin, Inc., New York-Amsterdam, 1969.
    -
    Ful97
    -
    -
    William Fulton, Young tableaux, Cambridge University Press, Cambridge, 1997.
    -
    Ful98
    -
    -
    William Fulton, Intersection theory, Springer-Verlag, Berlin, 1998.
    -
    Gat96
    -
    -
    Karin Gatermann, Semi-invariants, equivariants and algorithms, Appl. Algebra Engrg. Comm. Comput., 7(2), 105–124, 1996.
    -
    Gat18
    -
    - -
    GHJ16
    -
    -
    Ewgenij Gawrilow, Simon Hampe, Michael Joswig, The polymake XML File Format, In Mathematical Software – ICMS 2016, 403–410, Cham, 2016. Springer International Publishing.
    -
    GJ00
    -
    -
    Ewgenij Gawrilow, Michael Joswig, polymake: a Framework for Analyzing Convex Polytopes, In Polytopes — Combinatorics and Computation, editors, Gil Kalai, Günter M. Ziegler, 43–74. Birkhäuser, 2000.
    -
    GJRW10
    -
    -
    Ewgenij Gawrilow, Michael Joswig, Thilo Rörig, Nikolaus Witte, Drawing polytopal graphs with polymake, Comput. Vis. Sci., 13(2), 99–110, 2010.
    -
    GTZ88
    -
    -
    Patrizia Gianni, Barry Trager, Gail Zacharias, Gröbner bases and primary decomposition of polynomial ideals, In Computational aspects of commutative algebra, editors, 149–167. Elsevier Ltd, Oxford, 1988.
    -
    Gru03
    -
    -
    Branko Grünbaum, Convex polytopes, Springer-Verlag, New York, 2003.
    -
    GLS07
    -
    -
    G.-M. Greuel, C. Lossen, E. Shustin, Introduction to Singularities and Deformations, Springer-Verlag, Berlin, 2007.
    -
    GLS10
    -
    -
    Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch, Normalization of rings, J. Symbolic Comput., 45(9), 887–901, 2010.
    -
    GP08
    -
    - -
    FLINT
    -
    -
    W. B. Hart, Fast Library for Number Theory: An Introduction, In Proceedings of the Third International Congress on Mathematical Software, ICMS'10, 88–91, Berlin, Heidelberg, 2010. Springer-Verlag.
    -
    Har77
    -
    -
    Robin Hartshorne, Algebraic Geometry, Springer-Verlag, New York, 1977.
    -
    HEO05
    -
    -
    Derek F. Holt, Bettina Eick, Eamonn A. O'Brien, Handbook of computational group theory, Chapman & Hall/CRC, Boca Raton, FL, 2005.
    -
    HP89
    -
    -
    Derek F. Holt, W. Plesken, Perfect groups, The Clarendon Press, Oxford University Press, New York, 1989.
    -
    Hum72
    -
    -
    James E. Humphreys, Introduction to Lie Algebras and Representation Theory, Springer-Verlag, New York, 1972.
    -
    Hup67
    -
    -
    B. Huppert, Endliche Gruppen. I, Springer-Verlag, Berlin-New York, 1967.
    -
    Huy16
    -
    -
    Daniel Huybrechts, Lectures on K3 surfaces, Cambridge University Press, Cambridge, 2016.
    -
    OEIS
    -
    -
    OEIS Foundation Inc., The On-Line Encyclopedia of Integer Sequences, 2023, Published electronically at \url{http://oeis.org}.
    -
    IR96
    -
    -
    Yukari Ito, Miles Reid, The McKay correspondence for finite subgroups of ${\rm SL}(3,\mathbb C)$, In Higher-dimensional complex varieties (Trento, 1994), editors, 221-240. de Gruyter, 1996.
    -
    JLPW95
    -
    -
    C. Jansen, K. Lux, R. Parker, R. Wilson, An atlas of Brauer characters, The Clarendon Press Oxford University Press, New York, 1995.
    -
    Joh12
    -
    -
    Fredrik Johansson, Efficient implementation of the Hardy-Ramanujan-Rademacher formula, LMS J. Comput. Math., 15, 341–359, 2012.
    -
    JP00
    -
    -
    Theo de Jong, Gerhard Pfister, Local Analytic Geometry, Vieweg+Teubner Verlag, 2000.
    -
    Jos21
    -
    -
    Michael Joswig, Essentials of tropical combinatorics, American Mathematical Society, Providence, RI, 2021.
    -
    JT13
    -
    -
    Michael Joswig, Thorsten Theobald, Polyhedral and algebraic methods in computational geometry, Springer, London, 2013.
    -
    Jow11
    -
    -
    Shin-Yao Jow, Cohomology of toric line bundles via simplicial Alexander duality, Journal of Mathematical Physics, 52(3), 033506, 2011.
    -
    Kah10
    -
    -
    Thomas Kahle, Decompositions of binomial ideals, Ann. Inst. Statist. Math., 62(4), 727–745, 2010.
    -
    KLT20
    -
    -
    Marek Kaluba, Benjamin Lorenz, Sascha Timme, Polymake.jl: A New Interface to polymake, In Mathematical Software – ICMS 2020, 377–385, Cham, 2020. Springer International Publishing.
    -
    KMSS11
    -
    -
    Sheldon Katz, David R. Morrison, Sakura Schafer-Nameki, James Sully, Tate's algorithm and F-theory, arXiv:1106.3854 [hep-th].
    -
    KO14
    -
    - -
    Kem99
    -
    -
    Gregor Kemper, An algorithm to calculate optimal homogeneous systems of parameters, J. Symbolic Comput., 27(2), 171–184, 1999.
    -
    Kem02
    -
    -
    Gregor Kemper, The calculation of radical ideals in positive characteristic, J. Symbolic Comput., 34(3), 229–238, 2002.
    -
    KS99
    -
    -
    Gregor Kemper, Allan Steel, Some algorithms in invariant theory of finite groups, In Computational methods for representations of groups and algebras (Essen, 1997), editors, 267–285. Birkhäuser, Basel, 1999.
    -
    Kin07
    -
    -
    Simon King, Fast computation of secondary invariants, arXiv:math/0701270, 2007.
    -
    Kin13
    -
    -
    Simon King, Minimal generating sets of non-modular invariant rings of finite groups, J. Symb. Comput., 48, 101–109, 2013.
    -
    KM-POPR15
    -
    -
    Denis Klevers, Damian Kaloni Mayorga Pena, Paul-Konstantin Oehlmann, Hernan Piragua, Jonas Reuter, F-Theory on all Toric Hypersurface Fibrations and its Higgs Branches, arXiv:1408.4808 [hep-th].
    -
    Knu11
    -
    -
    Donald E. Knuth, The art of computer programming. Vol. 4A. Combinatorial algorithms. Part 1, Addison-Wesley, Upper Saddle River, NJ, 2011.
    -
    Kol13
    -
    -
    János Kollár, Singularities of the minimal model program, Cambridge University Press, 2013.
    -
    Koz08
    -
    -
    Dmitry Kozlov, Combinatorial algebraic topology, Springer, Berlin, 2008.
    -
    KR05
    -
    -
    Martin Kreuzer, Lorenzo Robbiano, Computational commutative algebra. II, Berlin: Springer, 2005.
    -
    KL91
    -
    -
    Teresa Krick, Alessandro Logar, An algorithm for the computation of the radical of an ideal in the ring of polynomials, In Applied algebra, algebraic algorithms and error-correcting codes (New Orleans, LA, 1991), editors, 195–205. Springer, Berlin, 1991.
    -
    Lev05
    -
    -
    Viktor Levandovskyy, Non-commutative Computer Algebra for polynomial algebras: Gröbner bases, applications and - implementation, PhD thesis, Technische Universität Kaiserslautern, 2005.
    -
    LS03
    -
    -
    Viktor Levandovskyy, Hans Schönemann, Plural – a computer algebra system for noncommutative polynomial algebras, In Proceedings of the 2003 international symposium on symbolic and algebraic computation, ISSAC 2003, - Philadelphia, PA, USA, August 3–6, 2003., editors, 176–183. New York, NY: ACM Press, 2003.
    -
    LN97
    -
    -
    Rudolf Lidl, Harald Niederreiter, Finite fields, Cambridge University Press, Cambridge, 1997.
    -
    Loo84
    -
    -
    Eduard Looijenga, Isolated Singular Points on Complete Intersections, Cambridge University Press, Cambridge, 1984.
    -
    MS15
    -
    -
    Diane Maclagan, Bernd Sturmfels, Introduction to tropical geometry, Providence, RI: American Mathematical Society (AMS), 2015.
    -
    Mar18
    -
    -
    Daniel A. Marcus, Number fields, Springer, Cham, 2018.
    -
    Mer12
    -
    -
    M Merca, Fast algorithm for generating ascending compositions, J. Math. Model. Algorithms, 11(1), 89–104, 2012.
    -
    MS21
    -
    -
    Mateusz Michałek, Bernd Sturmfels, Invitation to nonlinear algebra, Providence, RI: American Mathematical Society (AMS), 2021.
    -
    MS05
    -
    -
    Ezra Miller, Bernd Sturmfels, Combinatorial commutative algebra, New York, NY: Springer, 2005.
    -
    Nik79
    -
    -
    V. V. Nikulin, Integer symmetric bilinear forms and some of their geometric applications, Izv. Akad. Nauk SSSR Ser. Mat., 43(1), 111–177, 238, 1979.
    -
    Oxl11
    -
    -
    James Oxley, Matroid theory, Oxford University Press, Oxford, 2011.
    -
    Pol56
    -
    -
    G. Pólya, On picture-writing, Amer. Math. Monthly, 63, 689–697, 1956.
    -
    Peg14
    -
    -
    Christoph Pegel, Chow Rings of Toric Varieties, Master's thesis, University of Bremen, Faculty of Mathematics, 2014.
    -
    PSS11
    -
    -
    Gerhard Pfister, Afshan Sadiq, Stefan Steidel, An algorithm for primary decomposition in polynomial rings over the integers, Cent. Eur. J. Math., 9(4), 897–904, 2011.
    -
    PZ97
    -
    -
    M. Pohst, H. Zassenhaus, Algorithmic algebraic number theory, Cambridge University Press, Cambridge, 1997.
    -
    Pop93
    -
    -
    Sorin Popescu, On smooth surfaces of degree $\geq 11$ in the projective fourspace, PhD thesis, Universität des Saarlandes, Saarbrücken, 1993.
    -
    PS09
    -
    -
    Alexander Postnikov, Richard P. Stanley, Chains in the Bruhat order, J. Algebraic Combin., 29(2), 133–174, 2009.
    -
    Pos18
    -
    -
    Sebastian Posur, Linear systems over localizations of rings, Archiv der Mathematik, 111, 23–32, 2018.
    -
    RJ76
    -
    -
    W. Riha, K. R. James, Algorithm 29 efficient algorithms for doubly and multiply restricted partitions, Computing, 16, 163–168, 1976.
    -
    RR10
    -
    -
    Helmut Roschy, Thorsten Rahn, Cohomology of line bundles: Proof of the algorithm, Journal of Mathematical Physics, 51(10), 103520, 2010.
    -
    Sch23
    -
    -
    Johannes Schmitt, {On $\mathbb Q$-factorial terminalizations of symplectic linear quotient singularities}, PhD thesis, RPTU Kaiserslautern-Landau, 2023.
    -
    Ser03
    -
    -
    Ákos Seress, Permutation group algorithms, Cambridge University Press, Cambridge, 2003.
    -
    Sez02
    -
    - -
    Shi15
    -
    - -
    Shi18
    -
    -
    Ichiro Shimada, Connected Components of the Moduli of Elliptic $K3$ Surfaces, Michigan Mathematical Journal, 67(3), 511 – 559, 2018.
    -
    SY96
    -
    -
    Takeshi Shimoyama, Kazuhiro Yokoyama, Localization and primary decomposition of polynomial ideals, J. Symbolic Comput., 22(3), 247–277, 1996.
    -
    Sta79
    -
    -
    Richard P. Stanley, Invariants of finite groups and their applications to combinatorics, Bull. Amer. Math. Soc. (N.S.), 1(3), 475–511, 1979.
    -
    Ste91
    -
    -
    Jan Stevens, On the versal deformation of cyclic quotient singularities, In Singularity theory and its applications, Part I (Coventry, 1988/1989), editors, 302–319. Springer, Berlin, 1991.
    -
    Stu93
    -
    -
    Bernd Sturmfels, Algorithms in invariant theory, Springer-Verlag, Vienna, 1993.
    -
    Sym11
    -
    -
    Peter Symonds, On the Castelnuovo-Mumford regularity of rings of polynomial invariants, Ann. of Math. (2), 174(1), 499–517, 2011.
    -
    Tay87
    -
    -
    D. E. Taylor, Pairs of Generators for Matrix Groups. I, The Cayley Bulletin, 3, 76–85, 1987.
    -
    Was08
    -
    -
    Lawrence C. Washington, Elliptic curves, Chapman & Hall/CRC, Boca Raton, FL, 2008.
    -
    Wei18
    -
    -
    Timo Weigand, TASI Lectures on F-theory, arXiv:1806.01854 [hep-th].
    -
    Wei10
    -
    -
    Timo Weigand, Lectures on F-theory compactifications and model building, arXiv:1009.3497 [hep-th].
    -
    Wil13
    -
    -
    James B. Wilson, Optimal algorithms of Gram-Schmidt type, Linear Algebra Appl., 438(12), 4573–4583, 2013.
    -
    WWTSPNNLBA
    -
    -
    R. A. Wilson, P. Walsh, J. Tripp, I. Suleiman, R. A. Parker, S. P. Norton, S. Nickerson, S. Linton, J. Bray, R. Abbott, ATLAS of Finite Group Representations,
    -
    Wit88
    -
    -
    Edward Witten, Topological Sigma Models, Commun. Math. Phys., 118, 411, 1988.
    -
    Yam18
    -
    -
    Ryo Yamagishi, On smoothness of minimal models of quotient singularities by finite subgroups of ${\rm SL}_n(\mathbb - C)$, Glasg. Math. J., 60(3), 603–634, 2018.
    -
    Zie95
    -
    -
    Günter M. Ziegler, Lectures on polytopes, Springer-Verlag, New York, 1995.
    -
    ZS98
    -
    -
    A. Zoghbi, I. Stojmenovic, Fast algorithms for generating integer partitions, Int. J. Comput. Math., 70(2), 319–332, 1998.
    -
    Aut00
    -
    -
    The Stacks Project Authors, Stacks Project, 0000.
    -
    -
    diff --git a/previews/PR2578/search/index.html b/previews/PR2578/search/index.html deleted file mode 100644 index 35d00689972a..000000000000 --- a/previews/PR2578/search/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Search · Oscar.jl

    Loading search...

      diff --git a/previews/PR2578/search_index.js b/previews/PR2578/search_index.js deleted file mode 100644 index f88e32c1dbf8..000000000000 --- a/previews/PR2578/search_index.js +++ /dev/null @@ -1,3 +0,0 @@ -var documenterSearchIndex = {"docs": -[{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/subgroups/#subgroups","page":"Subgroups","title":"Subgroups","text":"","category":"section"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"The following functions are available in OSCAR for subgroup properties:","category":"page"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"sub(G::GAPGroup, gens::AbstractVector{<:GAPGroupElem}; check::Bool = true)\nis_subset(H::T, G::T) where T <: GAPGroup\nis_subgroup(H::T, G::T) where T <: GAPGroup\nembedding(H::T, G::T) where T <: GAPGroup\nindex(G::T, H::T) where T <: Union{GAPGroup, GrpAbFinGen}\nis_maximal_subgroup(H::T, G::T) where T <: GAPGroup\nis_normalized_by(H::T, G::T) where T <: GAPGroup\nis_normal_subgroup(H::T, G::T) where T <: GAPGroup\nis_characteristic_subgroup(H::T, G::T) where T <: GAPGroup","category":"page"},{"location":"Groups/subgroups/#sub-Tuple{Oscar.GAPGroup, AbstractVector{<:GAPGroupElem}}","page":"Subgroups","title":"sub","text":"sub(G::GAPGroup, gens::AbstractVector{<:GAPGroupElem}; check::Bool = true)\nsub(gens::GAPGroupElem...)\n\nReturn two objects: a group H, that is the subgroup of G generated by the elements x,y,..., and the embedding homomorphism of H into G. The object H has the same type of G, and it has no memory of the \"parent\" group G: it is an independent group.\n\nIf check is set to false then it is not checked whether each element of gens is an element of G.\n\nExamples\n\njulia> G = symmetric_group(4); H, _ = sub(G,[cperm([1,2,3]),cperm([2,3,4])]);\n\njulia> H == alternating_group(4)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_subset-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"is_subset","text":"is_subset(H::T, G::T) where T <: GAPGroup\n\nReturn true if H is a subset of G, otherwise return false.\n\nExamples\n\njulia> g = symmetric_group(300); h = derived_subgroup(g)[1];\n\njulia> is_subset(h, g)\ntrue\n\njulia> is_subset(g, h)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_subgroup-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"is_subgroup","text":"is_subgroup(H::T, G::T) where T <: GAPGroup\n\nReturn (true,f) if H is a subgroup of G, where f is the embedding homomorphism of H into G, otherwise return (false,nothing).\n\nIf you do not need the embedding then better call is_subset(H::T, G::T) where T <: GAPGroup.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#embedding-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"embedding","text":"embedding(H::T, G::T) where T <: GAPGroup\n\nReturn the embedding morphism of H into G. An exception is thrown if H is not a subgroup of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#index-Union{Tuple{T}, Tuple{T, T}} where T<:Union{GrpAbFinGen, Oscar.GAPGroup}","page":"Subgroups","title":"index","text":"index(::Type{I} = ZZRingElem, G::T, H::T) where I <: IntegerUnion where T <: Union{GAPGroup, GrpAbFinGen}\n\nReturn the index of H in G, as an instance of I.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_maximal_subgroup-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"is_maximal_subgroup","text":"is_maximal_subgroup(H::T, G::T; check::Bool = true) where T <: GAPGroup\n\nReturn whether H is a maximal subgroup of G, i. e., whether H is a proper subgroup of G and there is no proper subgroup of G that properly contains H.\n\nIf check is set to false then it is not checked whether H is a subgroup of G. If check is not set to false then an exception is thrown if H is not a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> is_maximal_subgroup(sylow_subgroup(G, 2)[1], G)\ntrue\n\njulia> is_maximal_subgroup(sylow_subgroup(G, 3)[1], G)\nfalse\n\njulia> is_maximal_subgroup(sylow_subgroup(G, 3)[1], sylow_subgroup(G, 2)[1])\nERROR: ArgumentError: H is not a subgroup of G\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_normalized_by-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"is_normalized_by","text":"is_normalized_by(H::T, G::T) where T <: GAPGroup\n\nReturn whether the group H is normalized by G, i.e., whether H is invariant under conjugation with elements of G.\n\nNote that H need not be a subgroup of G. To test whether H is a normal subgroup of G, use is_normal_subgroup.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> is_normalized_by(sylow_subgroup(G, 2)[1], G)\nfalse\n\njulia> is_normalized_by(derived_subgroup(G)[1], G)\ntrue\n\njulia> is_normalized_by(derived_subgroup(G)[1], sylow_subgroup(G, 2)[1])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_normal_subgroup-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"is_normal_subgroup","text":"is_normal_subgroup(H::T, G::T) where T <: GAPGroup\n\nReturn whether the group H is a normal subgroup of G, i.e., whether H is a subgroup of G that is invariant under conjugation with elements of G.\n\n(See is_normalized_by for an invariance check only.)\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> is_normal_subgroup(sylow_subgroup(G, 2)[1], G)\nfalse\n\njulia> is_normal_subgroup(derived_subgroup(G)[1], G)\ntrue\n\njulia> is_normal_subgroup(derived_subgroup(G)[1], sylow_subgroup(G, 2)[1])\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_characteristic_subgroup-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"is_characteristic_subgroup","text":"is_characteristic_subgroup(H::T, G::T; check::Bool = true) where T <: GAPGroup\n\nReturn whether the subgroup H of G is characteristic in G, i.e., H is invariant under all automorphisms of G.\n\nIf check is set to false then it is not checked whether H is a subgroup of G. If check is not set to false then an exception is thrown if H is not a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> is_characteristic_subgroup(derived_subgroup(G)[1], G)\ntrue\n\njulia> is_characteristic_subgroup(sylow_subgroup(G, 3)[1], G)\nfalse\n\njulia> is_characteristic_subgroup(sylow_subgroup(G, 3)[1], sylow_subgroup(G, 2)[1])\nERROR: ArgumentError: H is not a subgroup of G\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#Standard-subgroups","page":"Subgroups","title":"Standard subgroups","text":"","category":"section"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"The following functions are available in OSCAR to obtain standard subgroups of a group G. Every such function returns a tuple (H,f), where H is a group of the same type of G and f is the embedding homomorphism of H into G.","category":"page"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"trivial_subgroup\ncenter(G::GAPGroup)\nsylow_subgroup(G::GAPGroup, p::IntegerUnion)\nderived_subgroup\nfitting_subgroup\nfrattini_subgroup\nsocle\nsolvable_radical\npcore(G::GAPGroup, p::IntegerUnion)\nintersect(V::T...) where T<:GAPGroup","category":"page"},{"location":"Groups/subgroups/#trivial_subgroup","page":"Subgroups","title":"trivial_subgroup","text":"trivial_subgroup(G::GAPGroup)\n\nReturn the trivial subgroup of G, together with its embedding morphism into G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#center-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"center","text":"center(G::Group)\n\nReturn the center of G, i.e., the subgroup of all x in G such that x y equals y x for every y in G, together with its embedding morphism into G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#sylow_subgroup-Tuple{Oscar.GAPGroup, Union{Integer, ZZRingElem}}","page":"Subgroups","title":"sylow_subgroup","text":"sylow_subgroup(G::Group, p::IntegerUnion)\n\nReturn a Sylow p-subgroup of the finite group G, for a prime p. This is a subgroup of p-power order in G whose index in G is coprime to p.\n\nExamples\n\njulia> g = symmetric_group(4); order(g)\n24\n\njulia> s = sylow_subgroup(g, 2); order(s[1])\n8\n\njulia> s = sylow_subgroup(g, 3); order(s[1])\n3\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#derived_subgroup","page":"Subgroups","title":"derived_subgroup","text":"derived_subgroup(G::GAPGroup)\n\nReturn the derived subgroup of G, i.e., the subgroup generated by all commutators of G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#fitting_subgroup","page":"Subgroups","title":"fitting_subgroup","text":"fitting_subgroup(G::GAPGroup)\n\nReturn the Fitting subgroup of G, i.e., the largest nilpotent normal subgroup of G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#frattini_subgroup","page":"Subgroups","title":"frattini_subgroup","text":"frattini_subgroup(G::GAPGroup)\n\nReturn the Frattini subgroup of G, i.e., the intersection of all maximal subgroups of G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#socle","page":"Subgroups","title":"socle","text":"socle(G::GAPGroup)\n\nReturn the socle of G, i.e., the subgroup generated by all minimal normal subgroups of G, see minimal_normal_subgroups.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#solvable_radical","page":"Subgroups","title":"solvable_radical","text":"solvable_radical(G::GAPGroup)\n\nReturn the solvable radical of G, i.e., the largest solvable normal subgroup of G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#pcore-Tuple{Oscar.GAPGroup, Union{Integer, ZZRingElem}}","page":"Subgroups","title":"pcore","text":"pcore(G::Group, p::IntegerUnion)\n\nReturn C, f, where C is the p-core (i.e. the largest normal p-subgroup) of G and f is the embedding morphism of C into G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#intersect-Union{Tuple{Vararg{T}}, Tuple{T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"intersect","text":"intersect(V::T...) where T <: Group\nintersect(V::AbstractVector{T}) where T <: Group\n\nIf V is G_1 G_2 ldots G_n , return the intersection K of the groups G_1 G_2 ldots G_n, together with the embeddings of K into G_i.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"The following functions return a vector of subgroups.","category":"page"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"subgroups(G::GAPGroup)\nnormal_subgroups\nmaximal_subgroups\nmaximal_normal_subgroups\nminimal_normal_subgroups\ncharacteristic_subgroups\nderived_series\nsylow_system\nhall_subgroup_reps\nhall_system\ncomplement_class_reps\ncomplement_system","category":"page"},{"location":"Groups/subgroups/#subgroups-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"subgroups","text":"subgroups(G::Group)\n\nReturn the vector of all subgroups of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#normal_subgroups","page":"Subgroups","title":"normal_subgroups","text":"normal_subgroups(G::Group)\n\nReturn the vector of normal subgroups of G (see is_normal).\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#maximal_subgroups","page":"Subgroups","title":"maximal_subgroups","text":"maximal_subgroups(G::Group)\n\nReturn the vector of maximal subgroups of G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#maximal_normal_subgroups","page":"Subgroups","title":"maximal_normal_subgroups","text":"maximal_normal_subgroups(G::Group)\n\nReturn the vector of maximal normal subgroups of G, i.e., of those proper normal subgroups of G that are maximal among the proper normal subgroups.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#minimal_normal_subgroups","page":"Subgroups","title":"minimal_normal_subgroups","text":"minimal_normal_subgroups(G::Group)\n\nReturn the vector of minimal normal subgroups of G, i.e., of those nontrivial normal subgroups of G that are minimal among the nontrivial normal subgroups.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#characteristic_subgroups","page":"Subgroups","title":"characteristic_subgroups","text":"characteristic_subgroups(G::Group)\n\nReturn the list of characteristic subgroups of G, i.e., those subgroups that are invariant under all automorphisms of G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#derived_series","page":"Subgroups","title":"derived_series","text":"derived_series(G::GAPGroup)\n\nReturn the vector G_1 G_2 ldots , where G_1 = G and G_i+1 = derived_subgroup(G_i).\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#sylow_system","page":"Subgroups","title":"sylow_system","text":"sylow_system(G::Group)\n\nReturn a vector of Sylow p-subgroups of the finite group G, where p runs over the prime factors of the order of G, such that every two such subgroups commute with each other (as subgroups).\n\nSylow systems exist only for solvable groups, an exception is thrown if G is not solvable.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#hall_subgroup_reps","page":"Subgroups","title":"hall_subgroup_reps","text":"hall_subgroup_reps(G::Group, P::AbstractVector{<:IntegerUnion})\n\nReturn a vector that contains representatives of conjugacy classes of Hall P-subgroups of the finite group G, for a vector P of primes. A Hall P-subgroup of G is a subgroup the order of which is only divisible by primes in P and whose index in G is coprime to all primes in P.\n\nFor solvable G, Hall P-subgroups exist and are unique up to conjugacy. For nonsolvable G, Hall P-subgroups may not exist or may not be unique up to conjugacy.\n\nExamples\n\njulia> g = dihedral_group(30);\n\njulia> h = hall_subgroup_reps(g, [2, 3]);\n\njulia> (length(h), order(h[1]))\n(1, 6)\n\njulia> g = GL(3, 2)\nGL(3,2)\n\njulia> h = hall_subgroup_reps(g, [2, 3]);\n\njulia> (length(h), order(h[1]))\n(2, 24)\n\njulia> h = hall_subgroup_reps(g, [2, 7]); length(h)\n0\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#hall_system","page":"Subgroups","title":"hall_system","text":"hall_system(G::Group)\n\nReturn a vector of Hall P-subgroups of the finite group G, where P runs over the subsets of prime factors of the order of G.\n\nHall systems exist only for solvable groups, an exception is thrown if G is not solvable.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#complement_class_reps","page":"Subgroups","title":"complement_class_reps","text":"complement_class_reps(G::T, N::T) where T <: GAPGroup\n\nReturn a vector of representatives of the conjugacy classes of complements of the normal subgroup N in G. This function may throw an error exception if both N and G/N are nonsolvable.\n\nA complement is a subgroup of G which intersects trivially with N and together with N generates G.\n\nExamples\n\njulia> G = symmetric_group(3);\n\njulia> complement_class_reps(G, derived_subgroup(G)[1])\n1-element Vector{PermGroup}:\n Group([ (2,3) ])\n\njulia> G = dihedral_group(8)\n\n\njulia> complement_class_reps(G, center(G)[1])\nPcGroup[]\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#complement_system","page":"Subgroups","title":"complement_system","text":"complement_system(G::Group)\n\nReturn a vector of Hall p-subgroups of the finite group G, where p runs over the prime factors of the order of G.\n\nComplement systems exist only for solvable groups, an exception is thrown if G is not solvable.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"note: Note\nWhen a function returns a vector of subgroups, the output consists in the subgroups only; the embeddings are not returned as well. To get the embedding homomorphism of the subgroup H in G, one can type embedding(G,H).","category":"page"},{"location":"Groups/subgroups/#Conjugation-action-of-elements-and-subgroups","page":"Subgroups","title":"Conjugation action of elements and subgroups","text":"","category":"section"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"is_conjugate(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem)\nis_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup)\nis_conjugate_with_data(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem)\nis_conjugate_with_data(G::GAPGroup, H::GAPGroup, K::GAPGroup)\ncentralizer(G::GAPGroup, x::GAPGroupElem)\ncentralizer(G::T, H::T) where T <: GAPGroup\nnormalizer(G::GAPGroup, x::GAPGroupElem)\nnormalizer(G::T, H::T) where T<:GAPGroup\ncore(G::T, H::T) where T<:GAPGroup\nnormal_closure(G::T, H::T) where T<:GAPGroup","category":"page"},{"location":"Groups/subgroups/#is_conjugate-Tuple{Oscar.GAPGroup, GAPGroupElem, GAPGroupElem}","page":"Subgroups","title":"is_conjugate","text":"is_conjugate(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem)\n\nReturn whether x and y are conjugate elements in G, i.e., there is an element z in G such that x^z equals y.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_conjugate-Tuple{Oscar.GAPGroup, Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_conjugate","text":"is_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup)\n\nReturn whether H and K are conjugate subgroups in G.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> H = sub(G, [G([2, 1, 3, 4])])[1]\nGroup([ (1,2) ])\n\njulia> K = sub(G, [G([1, 2, 4, 3])])[1]\nGroup([ (3,4) ])\n\njulia> is_conjugate(G, H, K)\ntrue\n\njulia> K = sub(G, [G([2, 1, 4, 3])])[1]\nGroup([ (1,2)(3,4) ])\n\njulia> is_conjugate(G, H, K)\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_conjugate_with_data-Tuple{Oscar.GAPGroup, GAPGroupElem, GAPGroupElem}","page":"Subgroups","title":"is_conjugate_with_data","text":"is_conjugate_with_data(G::Group, x::GAPGroupElem, y::GAPGroupElem)\n\nIf x and y are conjugate in G, return (true, z), where x^z == y holds; otherwise, return (false, nothing).\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_conjugate_with_data-Tuple{Oscar.GAPGroup, Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_conjugate_with_data","text":"is_conjugate_with_data(G::Group, H::Group, K::Group)\n\nIf H and K are conjugate subgroups in G, return true, z where H^z = K; otherwise, return false, nothing.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> H = sub(G, [G([2, 1, 3, 4])])[1]\nGroup([ (1,2) ])\n\njulia> K = sub(G, [G([1, 2, 4, 3])])[1]\nGroup([ (3,4) ])\n\njulia> is_conjugate_with_data(G, H, K)\n(true, (1,3)(2,4))\n\njulia> K = sub(G, [G([2, 1, 4, 3])])[1]\nGroup([ (1,2)(3,4) ])\n\njulia> is_conjugate_with_data(G, H, K)\n(false, nothing)\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#centralizer-Tuple{Oscar.GAPGroup, GAPGroupElem}","page":"Subgroups","title":"centralizer","text":"centralizer(G::Group, x::GroupElem)\n\nReturn the centralizer of x in G, i.e., the subgroup of all g in G such that g x equals x g, together with its embedding morphism into G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#centralizer-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"centralizer","text":"centralizer(G::Group, H::Group)\n\nReturn the centralizer of H in G, i.e., the subgroup of all g in G such that g h equals h g for every h in H, together with its embedding morphism into G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#normalizer-Tuple{Oscar.GAPGroup, GAPGroupElem}","page":"Subgroups","title":"normalizer","text":"normalizer(G::Group, x::GAPGroupElem)\n\nReturn N, f, where N is the normalizer of the cyclic subgroup generated by x in G and f is the embedding morphism of N into G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#normalizer-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"normalizer","text":"normalizer(G::Group, H::Group)\n\nReturn N, f, where N is the normalizer of H in G, i.e., the largest subgroup of G in which H is normal, and f is the embedding morphism of N into G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#core-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"core","text":"core(G::Group, H::Group)\n\nReturn C, f, where C is the normal core of H in G, that is, the largest normal subgroup of G that is contained in H, and f is the embedding morphism of C into G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#normal_closure-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"normal_closure","text":"normal_closure(G::Group, H::Group)\n\nReturn N, f, where N is the normal closure of H in G, that is, the smallest normal subgroup of G that contains H, and f is the embedding morphism of N into G.\n\nNote that H must be a subgroup of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"GroupConjClass{T<:GAPGroup, S<:Union{GAPGroupElem,GAPGroup}}\nrepresentative(G::GroupConjClass)\nacting_group(G::GroupConjClass)\nnumber_conjugacy_classes(G::GAPGroup)\nconjugacy_class(G::GAPGroup, g::GAPGroupElem)\nconjugacy_class(G::T, g::T) where T<:GAPGroup\nconjugacy_classes(G::GAPGroup)\nconjugacy_classes_subgroups(G::GAPGroup)\nconjugacy_classes_maximal_subgroups(G::GAPGroup)","category":"page"},{"location":"Groups/subgroups/#GroupConjClass","page":"Subgroups","title":"GroupConjClass","text":"GroupConjClass{T, S}\n\nIt can be either the conjugacy class of an element or of a subgroup of type S in a group G of type T. It is displayed as\n\n cc = x ^ G\n\nwhere G is a group and x = representative(cc) is either an element or a subgroup of G.\n\n\n\n\n\n","category":"type"},{"location":"Groups/subgroups/#representative-Tuple{GroupConjClass}","page":"Subgroups","title":"representative","text":"representative(C::GroupConjClass)\n\nReturn a representative of the conjugacy class C.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> C = conjugacy_class(G, G([2, 1, 3, 4]))\n(1,2) ^ Sym( [ 1 .. 4 ] )\n\njulia> representative(C)\n(1,2)\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#acting_group-Tuple{GroupConjClass}","page":"Subgroups","title":"acting_group","text":"acting_group(C::GroupConjClass)\n\nReturn the acting group of C.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> C = conjugacy_class(G, G([2, 1, 3, 4]))\n(1,2) ^ Sym( [ 1 .. 4 ] )\n\njulia> acting_group(C) === G\ntrue\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#number_conjugacy_classes-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"number_conjugacy_classes","text":"number_conjugacy_classes(G::GAPGroup)\n\nReturn the number of conjugacy classes of elements in G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#conjugacy_class-Tuple{Oscar.GAPGroup, GAPGroupElem}","page":"Subgroups","title":"conjugacy_class","text":"conjugacy_class(G::Group, g::GAPGroupElem) -> GroupConjClass\n\nReturn the conjugacy class cc of g in G, where g = representative(cc).\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> C = conjugacy_class(G, G([2, 1, 3, 4]))\n(1,2) ^ Sym( [ 1 .. 4 ] )\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#conjugacy_class-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"conjugacy_class","text":"conjugacy_class(G::T, H::T) where T<:Group -> GroupConjClass\n\nReturn the subgroup conjugacy class cc of H in G, where H = representative(cc).\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#conjugacy_classes-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"conjugacy_classes","text":"conjugacy_classes(G::Group)\n\nReturn the vector of all conjugacy classes of elements in G. It is guaranteed that the class of the identity is in the first position.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#conjugacy_classes_subgroups-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"conjugacy_classes_subgroups","text":"conjugacy_classes_subgroups(G::Group)\n\nReturn the vector of all conjugacy classes of subgroups of G.\n\nExamples\n\njulia> G = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> conjugacy_classes_subgroups(G)\n4-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:\n Group(()) ^ Sym( [ 1 .. 3 ] )\n Group([ (2,3) ]) ^ Sym( [ 1 .. 3 ] )\n Group([ (1,2,3) ]) ^ Sym( [ 1 .. 3 ] )\n Group([ (1,2,3), (2,3) ]) ^ Sym( [ 1 .. 3 ] )\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#conjugacy_classes_maximal_subgroups-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"conjugacy_classes_maximal_subgroups","text":"conjugacy_classes_maximal_subgroups(G::Group)\n\nReturn the vector of all conjugacy classes of maximal subgroups of G.\n\nExamples\n\njulia> G = symmetric_group(3);\n\njulia> conjugacy_classes_maximal_subgroups(G)\n2-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:\n Group([ (1,2,3) ]) ^ Sym( [ 1 .. 3 ] )\n Group([ (2,3) ]) ^ Sym( [ 1 .. 3 ] )\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#Cosets-(left/right/double)","page":"Subgroups","title":"Cosets (left/right/double)","text":"","category":"section"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"GroupCoset\nright_coset(H::GAPGroup, g::GAPGroupElem)\nleft_coset(H::GAPGroup, g::GAPGroupElem)\nis_right(c::GroupCoset)\nis_left(c::GroupCoset)\nis_bicoset(C::GroupCoset)\nacting_domain(C::GroupCoset)\nrepresentative(C::GroupCoset)\nright_cosets(G::T, H::T; check::Bool=true) where T<: GAPGroup\nleft_cosets(G::T, H::T; check::Bool=true) where T<: GAPGroup\nright_transversal(G::T, H::T; check::Bool=true) where T<: GAPGroup\nleft_transversal(G::T, H::T; check::Bool=true) where T<: GAPGroup\nGroupDoubleCoset{T <: GAPGroup, S <: GAPGroupElem}\ndouble_coset(G::T, g::GAPGroupElem{T}, H::T) where T<: GAPGroup\ndouble_cosets(G::T, H::T, K::T; check::Bool) where T<: GAPGroup\nleft_acting_group(C::GroupDoubleCoset)\nright_acting_group(C::GroupDoubleCoset)\nrepresentative(C::GroupDoubleCoset)\norder(C::Union{GroupCoset,GroupDoubleCoset})\nBase.rand(C::Union{GroupCoset,GroupDoubleCoset})\nintersect(V::AbstractVector{Union{T, GroupCoset, GroupDoubleCoset}}) where T <: GAPGroup","category":"page"},{"location":"Groups/subgroups/#GroupCoset","page":"Subgroups","title":"GroupCoset","text":"GroupCoset{T<: Group, S <: GAPGroupElem}\n\nType of group cosets. It is displayed as H * x (right cosets) or x * H (left cosets), where H is a subgroup of a group G and x is an element of G. Two cosets are equal if, and only if, they are both left (resp. right) and they contain the same elements.\n\n\n\n\n\n","category":"type"},{"location":"Groups/subgroups/#right_coset-Tuple{Oscar.GAPGroup, GAPGroupElem}","page":"Subgroups","title":"right_coset","text":"right_coset(H::Group, g::GAPGroupElem)\n*(H::Group, g::GAPGroupElem)\n\nReturn the coset Hg.\n\nExamples\n\njulia> G = symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> g = perm(G,[3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#left_coset-Tuple{Oscar.GAPGroup, GAPGroupElem}","page":"Subgroups","title":"left_coset","text":"left_coset(H::Group, g::GAPGroupElem)\n*(g::GAPGroupElem, H::Group)\n\nReturn the coset gH.\n\nnote: Note\nSince GAP supports right cosets only, the underlying GAP object of left_coset(H,g) is the right coset H^(g^-1) * g.\n\nExamples\n\njulia> g = perm([3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> gH = left_coset(H,g)\nLeft coset (1,3)(2,4,5) * Sym( [ 1 .. 3 ] )\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_right-Tuple{GroupCoset}","page":"Subgroups","title":"is_right","text":"is_right(c::GroupCoset)\n\nReturn whether the coset c is a right coset of its acting domain.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_left-Tuple{GroupCoset}","page":"Subgroups","title":"is_left","text":"is_left(c::GroupCoset)\n\nReturn whether the coset c is a left coset of its acting domain.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_bicoset-Tuple{GroupCoset}","page":"Subgroups","title":"is_bicoset","text":"is_bicoset(C::GroupCoset)\n\nReturn whether C is simultaneously a right coset and a left coset for the same subgroup H. This is the case if and only if the coset representative normalizes the acting domain subgroup.\n\nExamples\n\njulia> G = symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> H = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> g = perm(G,[3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> gH = left_coset(H,g)\nLeft coset (1,3)(2,4,5) * Sym( [ 1 .. 4 ] )\n\njulia> is_bicoset(gH)\nfalse\n\njulia> f = perm(G,[2,1,4,3,5])\n(1,2)(3,4)\n\njulia> fH = left_coset(H,f)\nLeft coset (1,2)(3,4) * Sym( [ 1 .. 4 ] )\n\njulia> is_bicoset(fH)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#acting_domain-Tuple{GroupCoset}","page":"Subgroups","title":"acting_domain","text":"acting_domain(C::GroupCoset)\n\nIf C = Hx or xH, return H.\n\nExamples\n\njulia> G = symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> g = perm(G,[3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> gH = left_coset(H,g)\nLeft coset (1,3)(2,4,5) * Sym( [ 1 .. 3 ] )\n\njulia> acting_domain(gH)\nSym( [ 1 .. 3 ] )\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#representative-Tuple{GroupCoset}","page":"Subgroups","title":"representative","text":"representative(C::GroupCoset)\n\nIf C = Hx or xH, return x.\n\nExamples\n\njulia> G = symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> g = perm(G,[3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> gH = left_coset(H,g)\nLeft coset (1,3)(2,4,5) * Sym( [ 1 .. 3 ] )\n\njulia> representative(gH)\n(1,3)(2,4,5)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#right_cosets-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"right_cosets","text":"right_cosets(G::T, H::T; check::Bool=true) where T<: GAPGroup\n\nReturn the vector of the right cosets of H in G.\n\nIf check == false, do not check whether H is a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> right_cosets(G,H)\n4-element Vector{GroupCoset{PermGroup, PermGroupElem}}:\n Right coset Sym( [ 1 .. 3 ] ) * ()\n Right coset Sym( [ 1 .. 3 ] ) * (1,4)\n Right coset Sym( [ 1 .. 3 ] ) * (1,4,2)\n Right coset Sym( [ 1 .. 3 ] ) * (1,4,3)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#left_cosets-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"left_cosets","text":"left_cosets(G::T, H::T; check::Bool=true) where T<: GAPGroup\n\nReturn the vector of the left cosets of H in G.\n\nIf check == false, do not check whether H is a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> left_cosets(G,H)\n4-element Vector{GroupCoset{PermGroup, PermGroupElem}}:\n Left coset () * Sym( [ 1 .. 3 ] )\n Left coset (1,4) * Sym( [ 1 .. 3 ] )\n Left coset (1,2,4) * Sym( [ 1 .. 3 ] )\n Left coset (1,3,4) * Sym( [ 1 .. 3 ] )\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#right_transversal-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"right_transversal","text":"right_transversal(G::T, H::T; check::Bool=true) where T<: GAPGroup\n\nReturn a vector containing a complete set of representatives for the right cosets of H in G.\n\nIf check == false, do not check whether H is a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> right_transversal(G,H)\n4-element Vector{PermGroupElem}:\n ()\n (1,4)\n (1,4,2)\n (1,4,3)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#left_transversal-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"left_transversal","text":"left_transversal(G::T, H::T; check::Bool=true) where T<: Group\n\nReturn a vector containing a complete set of representatives for the left cosets for H in G.\n\nIf check == false, do not check whether H is a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> left_transversal(G,H)\n4-element Vector{PermGroupElem}:\n ()\n (1,4)\n (1,2,4)\n (1,3,4)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#GroupDoubleCoset","page":"Subgroups","title":"GroupDoubleCoset","text":"GroupDoubleCoset{T<: Group, S <: GAPGroupElem}\n\nGroup double coset. It is displayed as H * x * K, where H and K are subgroups of a group G and x is an element of G. Two double cosets are equal if, and only if, they contain the same elements.\n\n\n\n\n\n","category":"type"},{"location":"Groups/subgroups/#double_coset-Union{Tuple{T}, Tuple{T, GAPGroupElem{T}, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"double_coset","text":"double_coset(H::Group, x::GAPGroupElem, K::Group)\n*(H::Group, x::GAPGroupElem, K::Group)\n\nReturn the double coset HxK.\n\nExamples\n\njulia> G = symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> g = perm(G,[3,4,5,1,2])\n(1,3,5,2,4)\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> K = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> double_coset(H,g,K)\nSym( [ 1 .. 3 ] ) * (1,3,5,2,4) * Sym( [ 1 .. 2 ] )\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#double_cosets-Union{Tuple{T}, Tuple{T, T, T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"double_cosets","text":"double_cosets(G::T, H::T, K::T; check::Bool=true) where T<: GAPGroup\n\nReturn the vector of all the double cosets HxK for x in G. If check == false, do not check whether H and K are subgroups of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> K = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> double_cosets(G,H,K)\n3-element Vector{GroupDoubleCoset{PermGroup, PermGroupElem}}:\n Sym( [ 1 .. 3 ] ) * () * Sym( [ 1 .. 2 ] )\n Sym( [ 1 .. 3 ] ) * (1,4) * Sym( [ 1 .. 2 ] )\n Sym( [ 1 .. 3 ] ) * (1,4,3) * Sym( [ 1 .. 2 ] )\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#left_acting_group-Tuple{GroupDoubleCoset}","page":"Subgroups","title":"left_acting_group","text":"left_acting_group(C::GroupDoubleCoset)\n\nGiven a double coset C = HxK, return H.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#right_acting_group-Tuple{GroupDoubleCoset}","page":"Subgroups","title":"right_acting_group","text":"right_acting_group(C::GroupDoubleCoset)\n\nGiven a double coset C = HxK, return K.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#representative-Tuple{GroupDoubleCoset}","page":"Subgroups","title":"representative","text":"representative(C::GroupDoubleCoset)\n\nReturn a representative x of the double coset C = HxK.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#order-Tuple{Union{GroupCoset, GroupDoubleCoset}}","page":"Subgroups","title":"order","text":"order(C::Union{GroupCoset,GroupDoubleCoset})\n\nReturn the cardinality of the (double) coset C.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#rand-Tuple{Union{GroupCoset, GroupDoubleCoset}}","page":"Subgroups","title":"rand","text":"rand(rng::Random.AbstractRNG = Random.GLOBAL_RNG, C::Union{GroupCoset,GroupDoubleCoset})\n\nReturn a random element of the (double) coset C, using the random number generator rng.\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#intersect-Union{Tuple{AbstractArray{Union{GroupCoset, GroupDoubleCoset, T}, 1}}, Tuple{T}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"intersect","text":"intersect(V::AbstractVector{Union{T, GroupCoset, GroupDoubleCoset}}) where T <: GAPGroup\n\nReturn a vector containing all elements belonging to all groups and cosets in V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#Normal-Toric-Schemes","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"","category":"section"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#Constructors","page":"Normal Toric Schemes","title":"Constructors","text":"","category":"section"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"We provide the following constructors for toric covered schemes:","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"toric_covered_scheme(antv::AffineNormalToricVariety)\ntoric_covered_scheme(ntv::NormalToricVariety)","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#toric_covered_scheme-Tuple{AffineNormalToricVariety}","page":"Normal Toric Schemes","title":"toric_covered_scheme","text":"toric_covered_scheme(antv::AffineNormalToricVariety)\n\nConstructs the toric covered scheme associated to an affine toric variety.\n\nExamples\n\njulia> C = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> antv = affine_normal_toric_variety(C)\nNormal, affine toric variety\n\njulia> toric_covered_scheme(antv)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#toric_covered_scheme-Tuple{NormalToricVariety}","page":"Normal Toric Schemes","title":"toric_covered_scheme","text":"toric_covered_scheme(ntv::NormalToricVariety)\n\nConstructs the toric covered scheme associated to a normal toric variety.\n\nExamples\n\njulia> ntv = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> toric_covered_scheme(ntv)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#Special-constructors","page":"Normal Toric Schemes","title":"Special constructors","text":"","category":"section"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"We support constructors for a couple of famous geometries:","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"affine_space(::Type{ToricCoveredScheme}, d::Int; set_attributes::Bool = true)\nprojective_space(::Type{ToricCoveredScheme}, d::Int; set_attributes::Bool = true)\nweighted_projective_space(::Type{ToricCoveredScheme}, w::Vector{T}; set_attributes::Bool = true) where {T <: IntegerUnion}\nhirzebruch_surface(::Type{ToricCoveredScheme}, r::Int; set_attributes::Bool = true)\ndel_pezzo_surface(::Type{ToricCoveredScheme}, b::Int; set_attributes::Bool = true)","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#affine_space-Tuple{Type{ToricCoveredScheme}, Int64}","page":"Normal Toric Schemes","title":"affine_space","text":"affine_space(::Type{ToricCoveredScheme}, d::Int; set_attributes::Bool = true)\n\nConstructs the affine space of dimension d as toric (covered) scheme.\n\nExamples\n\njulia> affine_space(ToricCoveredScheme, 2)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#projective_space-Tuple{Type{ToricCoveredScheme}, Int64}","page":"Normal Toric Schemes","title":"projective_space","text":"projective_space(::Type{ToricCoveredScheme}, d::Int; set_attributes::Bool = true)\n\nConstruct the projective space of dimension d as toric (covered) scheme.\n\nExamples\n\njulia> projective_space(ToricCoveredScheme, 2)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#weighted_projective_space-Union{Tuple{T}, Tuple{Type{ToricCoveredScheme}, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Normal Toric Schemes","title":"weighted_projective_space","text":"weighted_projective_space(::Type{ToricCoveredScheme}, w::Vector{T}; set_attributes::Bool = true) where {T <: IntegerUnion}\n\nConstruct the weighted projective space corresponding to the weights w as toric (covered) scheme.\n\nExamples\n\njulia> weighted_projective_space(ToricCoveredScheme, [2,3,1])\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#hirzebruch_surface-Tuple{Type{ToricCoveredScheme}, Int64}","page":"Normal Toric Schemes","title":"hirzebruch_surface","text":"hirzebruch_surface(::Type{ToricCoveredScheme}, r::Int; set_attributes::Bool = true)\n\nConstructs the r-th Hirzebruch surface as toric (covered) scheme.\n\nExamples\n\njulia> hirzebruch_surface(ToricCoveredScheme, 5)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#del_pezzo_surface-Tuple{Type{ToricCoveredScheme}, Int64}","page":"Normal Toric Schemes","title":"del_pezzo_surface","text":"del_pezzo_surface(::Type{ToricCoveredScheme}, b::Int; set_attributes::Bool = true)\n\nConstructs the del Pezzo surface with b blowups for b at most 3 as toric (covered) scheme.\n\nExamples\n\njulia> del_pezzo_surface(ToricCoveredScheme, 3)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#Attributes","page":"Normal Toric Schemes","title":"Attributes","text":"","category":"section"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"We overload the following attributes from the underlying toric variety:","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"affine_open_covering(XToricCoveredScheme),\ncharacter_lattice(XToricCoveredScheme),\ncharacter_to_rational_function(RMPolyRing XToricCoveredScheme characterVectorZZRingElem),\ncharacter_to_rational_function(XToricCoveredScheme characterVectorZZRingElem),\nclass_group(XToricCoveredScheme),\ncoefficient_ring(XToricCoveredScheme),\ncoordinate_names(XToricCoveredScheme),\ncoordinate_names_of_torus(XToricCoveredScheme),\ncoordinate_ring_of_torus(RMPolyRing XToricCoveredScheme),\ncoordinate_ring_of_torus(XToricCoveredScheme),\ncox_ring(RMPolyRing XToricCoveredScheme),\ncox_ring(XToricCoveredScheme),\ndim(XToricCoveredScheme),\ndim_of_torusfactor(XToricCoveredScheme),\neuler_characteristic(XToricCoveredScheme),\npolyhedral_fan(XToricCoveredScheme),\nideal_of_linear_relations(RMPolyRing XToricCoveredScheme),\nideal_of_linear_relations(XToricCoveredScheme),\nirrelevant_ideal(RMPolyRing XToricCoveredScheme),\nirrelevant_ideal(XToricCoveredScheme),\nmap_from_character_lattice_to_torusinvariant_weil_divisor_group(XToricCoveredScheme),\nmap_from_torusinvariant_cartier_divisor_group_to_picard_group(XToricCoveredScheme),\nmap_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(XToricCoveredScheme),\nmap_from_torusinvariant_weil_divisor_group_to_class_group(XToricCoveredScheme),\nmori_cone(XToricCoveredScheme),\nnef_cone(XToricCoveredScheme),\npicard_group(XToricCoveredScheme),\nset_coordinate_names(XToricCoveredScheme),\nset_coordinate_names_of_torus(XToricCoveredScheme),\nstanley_reisner_ideal(RMPolyRing XToricCoveredScheme),\nstanley_reisner_ideal(XToricCoveredScheme),\ntorusinvariant_cartier_divisor_group(XToricCoveredScheme),\ntorusinvariant_prime_divisors(XToricCoveredScheme),\ntorusinvariant_weil_divisor_group(XToricCoveredScheme),\nunderlying_toric_variety(XToricCoveredScheme).","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"It is possible to forget the toric origin, i.e. one can turn a toric scheme into a scheme. This is achieved with the following method:","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"underlying_scheme(X::ToricCoveredScheme)","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#underlying_scheme-Tuple{ToricCoveredScheme}","page":"Normal Toric Schemes","title":"underlying_scheme","text":"underlying_scheme(X::ToricCoveredScheme)\n\nFor a toric covered scheme X, this returns the underlying scheme. In other words, by applying this method, you obtain a scheme that has forgotten its toric origin.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> toric_scheme = ToricCoveredScheme(P2)\nScheme of a toric variety\n\njulia> underlying_scheme(toric_scheme)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of an affine toric variety\n 2: spec of an affine toric variety\n 3: spec of an affine toric variety\n in the coordinate(s)\n 1: [x1, x2]\n 2: [x1, x2]\n 3: [x1, x2]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/#Properties","page":"Normal Toric Schemes","title":"Properties","text":"","category":"section"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"The following properties are overloaded from the underlying toric variety:","category":"page"},{"location":"Experimental/ToricSchemes/normal_toric_schemes/","page":"Normal Toric Schemes","title":"Normal Toric Schemes","text":"is_finalized(XToricCoveredScheme),\nis_normal(XToricCoveredScheme),\nis_affine(XToricCoveredScheme),\nis_projective(XToricCoveredScheme),\nis_projective_space(XToricCoveredScheme),\nis_smooth(XToricCoveredScheme),\nis_complete(XToricCoveredScheme),\nhas_torusfactor(XToricCoveredScheme),\nis_orbifold(XToricCoveredScheme),\nis_simplicial(XToricCoveredScheme),\nis_gorenstein(XToricCoveredScheme),\nis_q_gorenstein(XToricCoveredScheme),\nis_fano(XToricCoveredScheme).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Ideals-in-PBW-algebras","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Types","page":"Ideals in PBW-algebras","title":"Types","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"The OSCAR type for ideals in PBW-algebras is of parametrized form PBWAlgIdeal{D, T, S}, where D encodes the direction left, right, or two-sided, and T is the element type of the field over which the PBW-algebra is defined (the type S is added for internal use).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Constructors","page":"Ideals in PBW-algebras","title":"Constructors","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"left_ideal(g::Vector{<:PBWAlgElem})\nright_ideal(g::Vector{<:PBWAlgElem})\ntwo_sided_ideal(g::Vector{<:PBWAlgElem})","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#left_ideal-Tuple{Vector{<:PBWAlgElem}}","page":"Ideals in PBW-algebras","title":"left_ideal","text":"left_ideal(g::Vector{<:PBWAlgElem})\n\nGiven a vector g of elements in a PBW-algebra A, say, return the left ideal of A generated by these elements.\n\nleft_ideal(A::PBWAlgRing, g::AbstractVector)\n\nGiven a vector g of elements of A, return the left ideal of A generated by these elements.\n\nExamples\n\njulia> R, (x, y, z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [x*y, x*z, y*z + 1];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)))\n(PBW-algebra over Rational field in x, y, z with relations y*x = x*y, z*x = x*z, z*y = y*z + 1, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z])\n\njulia> I = left_ideal(A, [x^2*y^2, x*z+y*z])\nleft_ideal(x^2*y^2, x*z + y*z)\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#right_ideal-Tuple{Vector{<:PBWAlgElem}}","page":"Ideals in PBW-algebras","title":"right_ideal","text":"right_ideal(g::Vector{<:PBWAlgElem})\n\nGiven a vector g of elements in a PBW-algebra A, say, return the right ideal of A generated by these elements.\n\nright_ideal(A::PBWAlgRing, g::AbstractVector)\n\nGiven a vector g of elements of A, return the right ideal of A generated by these elements.\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#two_sided_ideal-Tuple{Vector{<:PBWAlgElem}}","page":"Ideals in PBW-algebras","title":"two_sided_ideal","text":"two_sided_ideal(g::Vector{<:PBWAlgElem})\n\nGiven a vector g of elements in a PBW-algebra A, say, return the two-sided ideal of A generated by these elements.\n\ntwo_sided_ideal(A::PBWAlgRing, g::AbstractVector)\n\nGiven a vector g of elements of A, return the two-sided ideal of A generated by these elements.\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Gröbner-bases","page":"Ideals in PBW-algebras","title":"Gröbner bases","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Data-Associated-to-Ideals","page":"Ideals in PBW-algebras","title":"Data Associated to Ideals","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"If I is an ideal of a PBW-algebra A, then","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"base_ring(I) refers to A,\ngens(I) to the generators of I,\nngens(I) to the number of these generators, and\ngen(I, k) as well as I[k] to the k-th such generator.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Examples","page":"Ideals in PBW-algebras","title":"Examples","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"julia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"])\n(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])\n\njulia> I = left_ideal(D, [x, dx])\nleft_ideal(x, dx)\n\njulia> base_ring(I)\nWeyl-algebra over Rational field in variables (x, y)\n\njulia> gens(I)\n2-element Vector{PBWAlgElem{QQFieldElem, Singular.n_Q}}:\n x\n dx\n\njulia> ngens(I)\n2\n\njulia> gen(I, 2)\ndx\n","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Operations-on-Ideals","page":"Ideals in PBW-algebras","title":"Operations on Ideals","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Simple-Ideal-Operations","page":"Ideals in PBW-algebras","title":"Simple Ideal Operations","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Powers-of-Ideal","page":"Ideals in PBW-algebras","title":"Powers of Ideal","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"^(I::PBWAlgIdeal{D, T, S}, k::Int) where {D, T, S}","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#^-Union{Tuple{S}, Tuple{T}, Tuple{D}, Tuple{Oscar.PBWAlgIdeal{D, T, S}, Int64}} where {D, T, S}","page":"Ideals in PBW-algebras","title":"^","text":"^(I::PBWAlgIdeal{D, T, S}, k::Int) where {D, T, S}\n\nGiven a two_sided ideal I, return the k-th power of I.\n\nExamples\n\njulia> D, (x, dx) = weyl_algebra(GF(3), [\"x\"]);\n\njulia> I = two_sided_ideal(D, [x^3])\ntwo_sided_ideal(x^3)\n\njulia> I^2\ntwo_sided_ideal(x^6)\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Sum-of-Ideals","page":"Ideals in PBW-algebras","title":"Sum of Ideals","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"+(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#+-Union{Tuple{S}, Tuple{T}, Tuple{D}, Tuple{Oscar.PBWAlgIdeal{D, T, S}, Oscar.PBWAlgIdeal{D, T, S}}} where {D, T, S}","page":"Ideals in PBW-algebras","title":"+","text":"+(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}\n\nReturn the sum of I and J.\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Product-of-Ideals","page":"Ideals in PBW-algebras","title":"Product of Ideals","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"*(I::PBWAlgIdeal{DI, T, S}, J::PBWAlgIdeal{DJ, T, S}) where {DI, DJ, T, S}","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#*-Union{Tuple{S}, Tuple{T}, Tuple{DJ}, Tuple{DI}, Tuple{Oscar.PBWAlgIdeal{DI, T, S}, Oscar.PBWAlgIdeal{DJ, T, S}}} where {DI, DJ, T, S}","page":"Ideals in PBW-algebras","title":"*","text":"*(I::PBWAlgIdeal{DI, T, S}, J::PBWAlgIdeal{DJ, T, S}) where {DI, DJ, T, S}\n\nGiven two ideals I and J such that both I and J are two-sided ideals or I and J are a left and a right ideal, respectively, return the product of I and J.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(GF(3), [\"x\", \"y\"]);\n\njulia> I = left_ideal(D, [x^3+y^3, x*y^2])\nleft_ideal(x^3 + y^3, x*y^2)\n\njulia> J = right_ideal(D, [dx^3, dy^5])\nright_ideal(dx^3, dy^5)\n\njulia> I*J\ntwo_sided_ideal(x^3*dx^3 + y^3*dx^3, x^3*dy^5 + y^3*dy^5, x*y^2*dx^3, x*y^2*dy^5)\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Intersection-of-Ideals","page":"Ideals in PBW-algebras","title":"Intersection of Ideals","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"intersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}\nintersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#intersect-Union{Tuple{S}, Tuple{T}, Tuple{D}, Tuple{Oscar.PBWAlgIdeal{D, T, S}, Vararg{Oscar.PBWAlgIdeal{D, T, S}}}} where {D, T, S}","page":"Ideals in PBW-algebras","title":"intersect","text":"intersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}\nintersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"]);\n\njulia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))\nleft_ideal(-x^3 + dy^2 + x)\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#intersect-Union{Tuple{Array{Oscar.PBWAlgIdeal{D, T, S}, 1}}, Tuple{S}, Tuple{T}, Tuple{D}} where {D, T, S}","page":"Ideals in PBW-algebras","title":"intersect","text":"intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T\nintersect(V::Vector{MPolyIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2;\n\njulia> J = ideal(R, [y^2-x^3+x]);\n\njulia> intersect(I, J)\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> intersect([I, J])\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\n\n\n\n\nintersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T\nintersect(V::Vector{MPolyQuoIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));\n\njulia> a = ideal(A, [y^2])\nideal(y^2)\n\njulia> b = ideal(A, [x])\nideal(x)\n\njulia> intersect(a,b)\nideal(x*y)\n\njulia> intersect([a,b])\nideal(x*y)\n\n\n\n\n\nintersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}\nintersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"]);\n\njulia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))\nleft_ideal(-x^3 + dy^2 + x)\n\n\n\n\n\nintersect(M::SubquoModule{T}, N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.\n\nAdditionally, return the inclusion maps M cap N to M and M cap N to N.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[y;]\n[y]\n\njulia> BN = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Subquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n, Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n)\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> AM = Rg[x;];\n\njulia> BM = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, AM, BM)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = Rg[y;];\n\njulia> BN = Rg[x^2; y^3; z^4];\n\njulia> N = SubquoModule(F, AN, BN)\nGraded subquotient of submodule of F generated by\n1 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> M\n-x*y*e[1] -> -x*y*e[1]\nx*z^4*e[1] -> x*z^4*e[1]\nHomogeneous module homomorphism, Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> N\n-x*y*e[1] -> x*y*e[1]\nx*z^4*e[1] -> 0\nHomogeneous module homomorphism)\n\n\n\n\n\n\nintersect(T1, T2)\n\nIntersect two tropical varieties.\n\nExamples\n\njulia> RR = TropicalSemiring(min)\nTropical semiring (min)\n\njulia> S,(x,y) = RR[\"x\",\"y\"]\n(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])\n\njulia> f1 = x+y+1\nx + y + (1)\n\njulia> f2 = x^2+y^2+RR(-6)\nx^2 + y^2 + (-6)\n\njulia> hyp1 = TropicalHypersurface(f1)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> hyp2 = TropicalHypersurface(f2)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> tv12 = intersect(hyp1, hyp2)\nmin tropical variety of dimension 1 embedded in 2-dimensional Euclidean space\n\n\n\n\n\nintersect(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl\n\nReturns a cap b.\n\n\n\n\n\nintersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl\n\nReturns a cap b.\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Elimination","page":"Ideals in PBW-algebras","title":"Elimination","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"Let","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"A = Klangle x_1 dots x_n mid x_jx_i = c_ijx_ix_j+d_ij 1leq ij leq n rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"be a PBW-algebra. Fix a subset sigmasubset 1dots n, write x_sigma for the set of variables x_i with iinsigma, and let A_sigma be the K-linear subspace of A which is generated by the standard monomials in langle x_sigma rangle. Suppose there exists a global monomial ordering on A which is both admissible for A and an elimination ordering for xsmallsetminus x_sigma. Then A_sigma is a subalgebra of A with d_ijin A_sigma for each pair of indices 1leq ij leq n with ijinsigma. In particular, A_sigma is a PBW-algebra with admissible ordering _sigma, where _sigma is the restriction of to the set of standard monomials in langle x_sigmarangle. Moreover, if Isubset A is a nonzero (left, right, two-sided) ideal, and mathcal G is a (left, right, two-sided) Gröbner basis for I with respect to , then mathcal Gcap A_sigma is a (left, right, two-sided) Gröbner basis for Icap A_sigma with respect to _sigma. We refer to computing Icap A_sigma as eliminating the variables in xsmallsetminus x_sigma from I","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"note: Note\nIf the relevant d_ij are all contained in A_sigma, we also say that A_sigma is admissible for elimination.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"note: Note\nA monomial ordering which is both admissible for A and an elimination ordering for xsmallsetminus x_sigma may not exist. ","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"eliminate(I::PBWAlgIdeal, V::Vector{<:PBWAlgElem}; ordering = nothing)","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#eliminate-Tuple{Oscar.PBWAlgIdeal, Vector{<:PBWAlgElem}}","page":"Ideals in PBW-algebras","title":"eliminate","text":"eliminate(I::PBWAlgIdeal, V::Vector{<:PBWAlgElem}; ordering = nothing)\n\nGiven a vector V of variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.\n\neliminate(I::PBWAlgIdeal, V::Vector{Int}; ordering = nothing)\n\nGiven a vector V of indices which specify variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.\n\nnote: Note\nThe return value is an ideal of the original algebra.\n\nnote: Note\nIf provided, the ordering must be an admissible elimination ordering (this is checked by the function). If not provided, finding an admissible elimination ordering may involve solving a particular linear programming problem. Here, the function is implemented so that it searches for solutions in a certain range only. If no solution is found in that range, the function will throw an error.\n\nExamples\n\njulia> R, (x, y, z, a) = QQ[\"x\", \"y\", \"z\", \"a\"];\n\njulia> L = [x*y-z, x*z+2*x, x*a, y*z-2*y, y*a, z*a];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x, y, z, a) = pbw_algebra(R, REL, deglex(gens(R)))\n(PBW-algebra over Rational field in x, y, z, a with relations y*x = x*y - z, z*x = x*z + 2*x, a*x = x*a, z*y = y*z - 2*y, a*y = y*a, a*z = z*a, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z, a])\n\njulia> f = 4*x*y+z^2-2*z-a;\n\njulia> I = left_ideal(A, [x^2, y^2, z^2-1, f])\nleft_ideal(x^2, y^2, z^2 - 1, 4*x*y + z^2 - 2*z - a)\n\njulia> eliminate(I, [x, y, z])\nleft_ideal(a - 3)\n\njulia> eliminate(I, [1, 2 ,3])\nleft_ideal(a - 3)\n\njulia> try eliminate(I, [z, a]); catch e; e; end\nErrorException(\"no elimination is possible: subalgebra is not admissible\")\n\njulia> R, (p, q) = QQ[\"p\", \"q\"];\n\njulia> L = [p*q+q^2];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (p, q) = pbw_algebra(R, REL, lex(gens(R)))\n(PBW-algebra over Rational field in p, q with relations q*p = p*q + q^2, PBWAlgElem{QQFieldElem, Singular.n_Q}[p, q])\n\njulia> I = left_ideal(A, [p, q])\nleft_ideal(p, q)\n\njulia> try eliminate(I, [q]); catch e; e; end # in fact, no elimination ordering exists\nErrorException(\"could not find elimination ordering\")\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#Tests-on-Ideals","page":"Ideals in PBW-algebras","title":"Tests on Ideals","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"is_zero(I:: PBWAlgIdeal)","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#is_zero-Tuple{Oscar.PBWAlgIdeal}","page":"Ideals in PBW-algebras","title":"is_zero","text":"is_zero(I::PBWAlgIdeal)\n\nReturn true if I is the zero ideal, false otherwise.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"])\n(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])\n\njulia> I = left_ideal(D, [x, dx])\nleft_ideal(x, dx)\n\njulia> is_zero(I)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"is_one(I:: PBWAlgIdeal)","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#is_one-Tuple{Oscar.PBWAlgIdeal}","page":"Ideals in PBW-algebras","title":"is_one","text":"is_one(I::PBWAlgIdeal{D}) where D\n\nReturn true if I is generated by 1, false otherwise.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"])\n(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])\n\njulia> I = left_ideal(D, [x, dx])\nleft_ideal(x, dx)\n\njulia> is_one(I)\ntrue\n\njulia> J = left_ideal(D, [y*x])\nleft_ideal(x*y)\n\njulia> is_one(J)\nfalse\n\njulia> K = two_sided_ideal(D, [y*x])\ntwo_sided_ideal(x*y)\n\njulia> is_one(K)\ntrue\n\njulia> D, (x, y, dx, dy) = weyl_algebra(GF(3), [\"x\", \"y\"]);\n\njulia> I = two_sided_ideal(D, [x^3])\ntwo_sided_ideal(x^3)\n\njulia> is_one(I)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"is_subset(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#is_subset-Union{Tuple{S}, Tuple{T}, Tuple{D}, Tuple{Oscar.PBWAlgIdeal{D, T, S}, Oscar.PBWAlgIdeal{D, T, S}}} where {D, T, S}","page":"Ideals in PBW-algebras","title":"is_subset","text":"is_subset(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}\n\nReturn true if I is contained in J, false otherwise.\n\nExamples\n\njulia> D, (x, dx) = weyl_algebra(QQ, [\"x\"]);\n\njulia> I = left_ideal(D, [dx^2])\nleft_ideal(dx^2)\n\njulia> J = left_ideal(D, [x*dx^4, x^3*dx^2])\nleft_ideal(x*dx^4, x^3*dx^2)\n\njulia> is_subset(I, J)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"==(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#==-Union{Tuple{S}, Tuple{T}, Tuple{D}, Tuple{Oscar.PBWAlgIdeal{D, T, S}, Oscar.PBWAlgIdeal{D, T, S}}} where {D, T, S}","page":"Ideals in PBW-algebras","title":"==","text":"==(I::PBWAlgIdeal{D, T, S}, J::PBWAlgIdeal{D, T, S}) where {D, T, S}\n\nReturn true if I is equal to J, false otherwise.\n\nExamples\n\njulia> D, (x, dx) = weyl_algebra(QQ, [\"x\"]);\n\njulia> I = left_ideal(D, [dx^2])\nleft_ideal(dx^2)\n\njulia> J = left_ideal(D, [x*dx^4, x^3*dx^2])\nleft_ideal(x*dx^4, x^3*dx^2)\n\njulia> I == J\ntrue\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"ideal_membership(f::PBWAlgElem{T, S}, I::PBWAlgIdeal{D, T, S}) where {D, T, S}","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/#ideal_membership-Union{Tuple{S}, Tuple{T}, Tuple{D}, Tuple{PBWAlgElem{T, S}, Oscar.PBWAlgIdeal{D, T, S}}} where {D, T, S}","page":"Ideals in PBW-algebras","title":"ideal_membership","text":"ideal_membership(f::PBWAlgElem{T, S}, I::PBWAlgIdeal{D, T, S}) where {D, T, S}\n\nReturn true if f is contained in I, false otherwise. Alternatively, use f in I.\n\nExamples\n\njulia> D, (x, dx) = weyl_algebra(QQ, [\"x\"]);\n\njulia> I = left_ideal(D, [x*dx^4, x^3*dx^2])\nleft_ideal(x*dx^4, x^3*dx^2)\n\njulia> dx^2 in I\ntrue\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"]);\n\njulia> I = two_sided_ideal(D, [x, dx])\ntwo_sided_ideal(x, dx)\n\njulia> one(D) in I\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#Toric-Divisor-Classes","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#Introduction","page":"Toric Divisor Classes","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"Toric divisor classes are equivalence classes of Weil divisors modulo linear equivalence.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#Constructors","page":"Toric Divisor Classes","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#General-constructors","page":"Toric Divisor Classes","title":"General constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"toric_divisor_class(v::AbstractNormalToricVariety, class::GrpAbFinGenElem)\ntoric_divisor_class(v::AbstractNormalToricVariety, coeffs::Vector{T}) where {T <: IntegerUnion}\ntoric_divisor_class(td::ToricDivisor)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#toric_divisor_class-Tuple{Oscar.AbstractNormalToricVariety, GrpAbFinGenElem}","page":"Toric Divisor Classes","title":"toric_divisor_class","text":"toric_divisor_class(v::AbstractNormalToricVariety, class::GrpAbFinGenElem)\n\nConstruct the toric divisor class associated to a group element of the class group of the normal toric variety v.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, class_group(P2)([1]))\nDivisor class on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#toric_divisor_class-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Divisor Classes","title":"toric_divisor_class","text":"toric_divisor_class(v::AbstractNormalToricVariety, coeffs::Vector{T}) where {T <: IntegerUnion}\n\nConstruct the toric divisor class associated to a list of integers which specify an element of the class group of the normal toric variety v.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, class_group(P2)([ZZRingElem(1)]))\nDivisor class on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#toric_divisor_class-Tuple{ToricDivisor}","page":"Toric Divisor Classes","title":"toric_divisor_class","text":"toric_divisor_class(td::ToricDivisor)\n\nConstruct the toric divisor class associated to the element ... of the class group of the normal toric variety v.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(P2, [1, 2, 3])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> tdc = toric_divisor_class(td)\nDivisor class on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#Addition,-subtraction-and-scalar-multiplication","page":"Toric Divisor Classes","title":"Addition, subtraction and scalar multiplication","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"Toric divisor classes can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#Special-divisor-classes","page":"Toric Divisor Classes","title":"Special divisor classes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"trivial_divisor_class(v::AbstractNormalToricVariety)\nanticanonical_divisor_class(v::AbstractNormalToricVariety)\ncanonical_divisor_class(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#trivial_divisor_class-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Divisor Classes","title":"trivial_divisor_class","text":"trivial_divisor_class(v::AbstractNormalToricVariety)\n\nConstruct the trivial divisor class of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> trivial_divisor_class(v)\nDivisor class on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#anticanonical_divisor_class-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Divisor Classes","title":"anticanonical_divisor_class","text":"anticanonical_divisor_class(v::AbstractNormalToricVariety)\n\nConstruct the anticanonical divisor class of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> anticanonical_divisor_class(v)\nDivisor class on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#canonical_divisor_class-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Divisor Classes","title":"canonical_divisor_class","text":"canonical_divisor_class(v::AbstractNormalToricVariety)\n\nConstruct the canonical divisor class of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> canonical_divisor_class(v)\nDivisor class on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#Properties","page":"Toric Divisor Classes","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"Equality of toric divisor classes can be tested via ==.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"To check if a toric divisor class is trivial, one can invoke is_trivial.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"is_effective(tdc::ToricDivisorClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#is_effective-Tuple{ToricDivisorClass}","page":"Toric Divisor Classes","title":"is_effective","text":"is_effective(tdc::ToricDivisorClass)\n\nDetermines whether the toric divisor class tdc is effective, that is if a toric divisor in this divisor class is linearly equivalent to an effective toric divisor.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety,2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, [1])\nDivisor class on a normal toric variety\n\njulia> is_effective(tdc)\ntrue\n\njulia> tdc2 = toric_divisor_class(P2, [-1])\nDivisor class on a normal toric variety\n\njulia> is_effective(tdc2)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#Attributes","page":"Toric Divisor Classes","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/","page":"Toric Divisor Classes","title":"Toric Divisor Classes","text":"divisor_class(tdc::ToricDivisorClass)\ntoric_variety(tdc::ToricDivisorClass)\ntoric_divisor(tdc::ToricDivisorClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#divisor_class-Tuple{ToricDivisorClass}","page":"Toric Divisor Classes","title":"divisor_class","text":"divisor_class(tdc::ToricDivisorClass)\n\nReturn the element of the class group corresponding to the toric divisor class tdc.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, class_group(P2)([1]))\nDivisor class on a normal toric variety\n\njulia> divisor_class(tdc)\nElement of\nGrpAb: Z\nwith components [1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#toric_variety-Tuple{ToricDivisorClass}","page":"Toric Divisor Classes","title":"toric_variety","text":"toric_variety(tdc::ToricDivisorClass)\n\nReturn the toric variety on which the toric divisor class tdc is defined.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, class_group(P2)([1]))\nDivisor class on a normal toric variety\n\njulia> toric_variety(tdc)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#toric_divisor-Tuple{ToricDivisorClass}","page":"Toric Divisor Classes","title":"toric_divisor","text":"toric_divisor(tdc::ToricDivisorClass)\n\nConstructs a toric divisor corresponding to the toric divisor class tdc.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, class_group(P2)([1]))\nDivisor class on a normal toric variety\n\njulia> toric_divisor(tdc)\nTorus-invariant, prime divisor on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#Affine-and-Projective-Plane-Curves","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"We consider two kinds of plane curves: affine and projective. An affine plane curve is defined by a polynomial in two variables, whereas a projective plane curve is defined by a homogeneous polynomial belonging to a graded polynomial ring in three variables.","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#Affine-Plane-Curves","page":"Affine and Projective Plane Curves","title":"Affine Plane Curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"An affine plane curve is defined as the class of a two-variables polynomial F over a field K, modulo the equivalence relation F sim G iff exists lambda in Kbackslash 0 F = lambda cdot G.","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#Example","page":"Affine and Projective Plane Curves","title":"Example","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"AffinePlaneCurve","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#AffinePlaneCurve","page":"Affine and Projective Plane Curves","title":"AffinePlaneCurve","text":"AffinePlaneCurve{S}(eq::Oscar.MPolyRingElem{S}) where S <: FieldElem\n\nReturn the Affine Plane Curve defined by the polynomial in two variables eq.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> F = y^3*x^6 - y^6*x^2\nx^6*y^3 - x^2*y^6\n\njulia> C = AffinePlaneCurve(F)\nAffine plane curve defined by x^6*y^3 - x^2*y^6\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/plane_curves/#Projective-Plane-Curves","page":"Affine and Projective Plane Curves","title":"Projective Plane Curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"Similarly, a projective plane curve is defined as the class of a three-variables homogeneous polynomial F over a field K, modulo the equivalence relation Fsim G iff exists lambda in Kbackslash 0 F = lambda cdot G. The defining equation is supposed to belong to a graded ring.","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"ProjPlaneCurve","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#ProjPlaneCurve","page":"Affine and Projective Plane Curves","title":"ProjPlaneCurve","text":"ProjPlaneCurve{S}(eq::Oscar.MPolyDecRingElem{S}) where {S <: FieldElem}\n\nReturn the Projective Plane Curve defined by the homogeneous polynomial in three variables eq.\n\nExamples\n\njulia> R, (x,y,z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(R)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> F = T(y^3*x^6 - y^6*x^2*z)\nx^6*y^3 - x^2*y^6*z\n\njulia> ProjPlaneCurve(F)\nProjective plane curve defined by x^6*y^3 - x^2*y^6*z\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"A particular kind of projective curves is the case of elliptic curves, see the corresponding section for more information. The types ProjPlaneCurve and ProjEllipticCurve are subtypes of the abstract type ProjectivePlaneCurve. In addition, the types AffinePlaneCurve and ProjectivePlaneCurve are subtypes of the abstract type PlaneCurve.","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#Points","page":"Affine and Projective Plane Curves","title":"Points","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"When considering curves, it is natural to have a look at points on the curve. We describe in this section how to deal with points, both in the affine and projective settings.","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#Point-in-the-affine-space","page":"Affine and Projective Plane Curves","title":"Point in the affine space","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"A point in the affine space can be defined as follows:","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"Point","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#Point","page":"Affine and Projective Plane Curves","title":"Point","text":"Point(coordinates::Vector{S}) where {S <: FieldElem}\n\nReturn the point with the given coordinates.\n\nExamples\n\njulia> P = Point([QQ(1), QQ(2), QQ(2)])\nPoint with coordinates QQFieldElem[1, 2, 2]\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"We consider also the following function for points.","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"ideal_point(R::MPolyRing{S}, P::Point{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#ideal_point-Union{Tuple{S}, Tuple{MPolyRing{S}, Point{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"ideal_point","text":"ideal_point(R::MPolyRing{S}, P::Point{S}) where S <: FieldElem\n\nReturn the maximal ideal associated to the point P in the ring R.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> P = Point([QQ(2), QQ(1)])\nPoint with coordinates QQFieldElem[2, 1]\n\njulia> Oscar.ideal_point(R, P)\nideal(x - 2, y - 1)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"The following function checks if a given point is on a curve:","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"in(P::Point{S}, C::AffinePlaneCurve{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#in-Union{Tuple{S}, Tuple{Point{S}, AffinePlaneCurve{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"in","text":"in(P::Point{S}, C::AffinePlaneCurve{S}) where S <: FieldElem\n\nReturn true if the point P is on the curve C, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#Point-in-the-projective-space","page":"Affine and Projective Plane Curves","title":"Point in the projective space","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"In order to define a point in the projective plane, one needs first to define the projective plane as follows, where K is the base ring:","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"julia> K = QQ\nRational field\n\njulia> PP = proj_space(K, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"Then, one can define a projective point as follows:","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"julia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(1), QQ(2), QQ(-5)])\n(1 : 2 : -5)\n","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"The following function checks if a given point is on a curve:","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"in(P::Oscar.Geometry.ProjSpcElem{S}, C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#in-Union{Tuple{S}, Tuple{Oscar.Geometry.ProjSpcElem{S}, ProjectivePlaneCurve{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"in","text":"in(P::Oscar.Geometry.ProjSpcElem{S}, C::ProjectivePlaneCurve{S}) where S <: FieldElem\n\nReturn true if the point P is on the curve C, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#General-functions-for-curves","page":"Affine and Projective Plane Curves","title":"General functions for curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"degree(C::Oscar.PlaneCurveModule.PlaneCurve)\nring(C::Oscar.PlaneCurveModule.PlaneCurve)\ncurve_components(C::Oscar.PlaneCurveModule.PlaneCurve{S}) where S <: FieldElem\nreduction(C::AffinePlaneCurve{S}) where S <: FieldElem\nis_irreducible(C::Oscar.PlaneCurveModule.PlaneCurve{S}) where S <: FieldElem\nis_reduced(C::Oscar.PlaneCurveModule.PlaneCurve{S}) where S <: FieldElem\nunion(C::T, D::T) where T <: Oscar.PlaneCurveModule.PlaneCurve\nOscar.PlaneCurveModule.arithmetic_genus(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve)\nOscar.PlaneCurveModule.arithmetic_genus(C::AffinePlaneCurve)\ngeometric_genus(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}) where S <: FieldElem\ngeometric_genus(C::AffinePlaneCurve)","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#degree-Tuple{Oscar.PlaneCurveModule.PlaneCurve}","page":"Affine and Projective Plane Curves","title":"degree","text":"degree(C::PlaneCurve)\n\nReturn the degree of the defining polynomial of C.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#ring-Tuple{Oscar.PlaneCurveModule.PlaneCurve}","page":"Affine and Projective Plane Curves","title":"ring","text":"ring(C::PlaneCurve)\n\nReturn the coordinate ring of the curve C.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^2+x-x^3)\nAffine plane curve defined by -x^3 + x + y^2\n\njulia> Oscar.ring(C)\n(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from\nMultivariate polynomial ring in 2 variables over QQ to Quotient of multivariate polynomial ring by ideal with 1 generator defined by a julia-function with inverse)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#curve_components-Union{Tuple{Oscar.PlaneCurveModule.PlaneCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"curve_components","text":"curve_components(C::PlaneCurve{S}) where S <: FieldElem\n\nReturn a dictionary containing the irreducible components of C and their multiplicity.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^3*x^6 - y^6*x^2)\nAffine plane curve defined by x^6*y^3 - x^2*y^6\n\njulia> Oscar.curve_components(C)\nDict{AffinePlaneCurve{QQFieldElem}, Int64} with 3 entries:\n y => 3\n x => 2\n x^4 - y^3 => 1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#reduction-Union{Tuple{AffinePlaneCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"reduction","text":"reduction(C::AffinePlaneCurve{S}) where S <: FieldElem\nreduction(C::ProjPlaneCurve{S}) where S <: FieldElem\n\nReturn the plane curve defined by the squarefree part of the equation of C.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^3*x^6 - y^6*x^2)\nAffine plane curve defined by x^6*y^3 - x^2*y^6\n\njulia> Oscar.reduction(C)\nAffine plane curve defined by x^5*y - x*y^4\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#is_irreducible-Union{Tuple{Oscar.PlaneCurveModule.PlaneCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"is_irreducible","text":"is_irreducible(C::PlaneCurve{S}) where S <: FieldElem\n\nReturn true if C is irreducible, and false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^2+x-x^3)\nAffine plane curve defined by -x^3 + x + y^2\n\njulia> Oscar.is_irreducible(C)\ntrue\n\njulia> D = AffinePlaneCurve(y^3*x^6 - y^6*x^2)\nAffine plane curve defined by x^6*y^3 - x^2*y^6\n\njulia> Oscar.is_irreducible(D)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#is_reduced-Union{Tuple{Oscar.PlaneCurveModule.PlaneCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"is_reduced","text":"is_reduced(C::PlaneCurve{S}) where S <: FieldElem\n\nReturn true if C is reduced, and false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^2+x-x^3)\nAffine plane curve defined by -x^3 + x + y^2\n\njulia> Oscar.is_reduced(C)\ntrue\n\njulia> D = AffinePlaneCurve(y^3*x^6 - y^6*x^2)\nAffine plane curve defined by x^6*y^3 - x^2*y^6\n\njulia> Oscar.is_reduced(D)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#union-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.PlaneCurveModule.PlaneCurve","page":"Affine and Projective Plane Curves","title":"union","text":"union(C::T, D::T) where T <: PlaneCurve\n\nReturn the union of C and D (with multiplicity).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^2+x-x^3)\nAffine plane curve defined by -x^3 + x + y^2\n\njulia> D = AffinePlaneCurve(y^3*x^6 - y^6*x^2)\nAffine plane curve defined by x^6*y^3 - x^2*y^6\n\njulia> union(C, D)\nAffine plane curve defined by -x^9*y^3 + x^7*y^3 + x^6*y^5 + x^5*y^6 - x^3*y^6 - x^2*y^8\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#arithmetic_genus-Tuple{ProjectivePlaneCurve}","page":"Affine and Projective Plane Curves","title":"arithmetic_genus","text":"arithmetic_genus(C::ProjectivePlaneCurve)\n\nReturn the arithmetic genus of C.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2 * z - x^3 - x * z^2))\nProjective plane curve defined by -x^3 - x*z^2 + y^2*z\n\njulia> Oscar.PlaneCurveModule.arithmetic_genus(C)\n1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#arithmetic_genus-Tuple{AffinePlaneCurve}","page":"Affine and Projective Plane Curves","title":"arithmetic_genus","text":"arithmetic_genus(C::AffinePlaneCurve)\n\nReturn the arithmetic genus of the projective closure of C.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#geometric_genus-Union{Tuple{ProjectivePlaneCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"geometric_genus","text":"geometric_genus(C::ProjectivePlaneCurve{T}) where T <: FieldElem\n\nReturn the geometric genus of C.\n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> C = ProjPlaneCurve(z*x^2-y^3)\nProjective plane curve defined by x^2*z - y^3\n\njulia> geometric_genus(C)\n0\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#geometric_genus-Tuple{AffinePlaneCurve}","page":"Affine and Projective Plane Curves","title":"geometric_genus","text":"geometric_genus(C::AffinePlaneCurve)\n\nReturn the geometric genus of the projective closure of C.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(GF(7), [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over GF(7), fpMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^9 - x^2*(x-1)^9)\nAffine plane curve defined by 6*x^11 + 2*x^10 + 6*x^9 + x^4 + 5*x^3 + x^2 + y^9\n\njulia> geometric_genus(C)\n0\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#Smoothness,-tangents-and-singularity-related-functions","page":"Affine and Projective Plane Curves","title":"Smoothness, tangents and singularity related functions","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"jacobi_ideal(C::Oscar.PlaneCurveModule.PlaneCurve)\nis_smooth(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\nis_smooth(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\ntangent(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\ntangent(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\ncurve_singular_locus(C::AffinePlaneCurve)\ncurve_singular_locus([PP::Oscar.Geometry.ProjSpc{S}], C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}) where S <: FieldElem\nmultiplicity(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\nmultiplicity(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\ntangent_lines(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\ntangent_lines(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\nis_smooth_curve(C::AffinePlaneCurve)\nis_smooth_curve(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve)","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#jacobi_ideal-Tuple{Oscar.PlaneCurveModule.PlaneCurve}","page":"Affine and Projective Plane Curves","title":"jacobi_ideal","text":"jacobi_ideal(C::PlaneCurve)\n\nReturn the Jacobian ideal of the defining polynomial of C.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^3*x^6 - y^6*x^2)\nAffine plane curve defined by x^6*y^3 - x^2*y^6\n\njulia> Oscar.jacobi_ideal(C)\nideal(6*x^5*y^3 - 2*x*y^6, 3*x^6*y^2 - 6*x^2*y^5)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#is_smooth-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, Point{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"is_smooth","text":"is_smooth(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\n\nThrow an error if P is not a point of C, return false if P is a singular point of C, and true if P is a smooth point of C.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))\nAffine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4\n\njulia> P = Point([QQ(0), QQ(0)])\nPoint with coordinates QQFieldElem[0, 0]\n\njulia> is_smooth(C, P)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#is_smooth-Union{Tuple{S}, Tuple{ProjectivePlaneCurve{S}, Oscar.Geometry.ProjSpcElem{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"is_smooth","text":"is_smooth(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\n\nThrow an error if P is not a point of C, return false if P is a singular point of C, and true if P is a smooth point of C.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(x^2*(x+y)*(y^3-x^2*z))\nProjective plane curve defined by -x^5*z - x^4*y*z + x^3*y^3 + x^2*y^4\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])\n(0 : 0 : 1)\n\njulia> is_smooth(C, P)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#tangent-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, Point{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"tangent","text":"tangent(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\n\nReturn the tangent of C at P when P is a smooth point of C, and throw an error otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))\nAffine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4\n\njulia> P2 = Point([QQ(2), QQ(-2)])\nPoint with coordinates QQFieldElem[2, -2]\n\njulia> tangent(C, P2)\nAffine plane curve defined by -48*x - 48*y\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#tangent-Union{Tuple{S}, Tuple{ProjectivePlaneCurve{S}, Oscar.Geometry.ProjSpcElem{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"tangent","text":"tangent(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\n\nReturn the tangent of C at P when P is a smooth point of C, and throw an error otherwise.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\",\"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> C = ProjPlaneCurve(x^2*(x+y)*(y^3-x^2*z))\nProjective plane curve defined by -x^5*z - x^4*y*z + x^3*y^3 + x^2*y^4\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(2), QQ(-2), QQ(1)])\n(2 : -2 : 1)\n\njulia> tangent(C, P)\nProjective plane curve defined by -48*x - 48*y\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#curve_singular_locus-Tuple{AffinePlaneCurve}","page":"Affine and Projective Plane Curves","title":"curve_singular_locus","text":"curve_singular_locus(C::AffinePlaneCurve)\n\nReturn the reduced singular locus of C as a list whose first element is the affine plane curve consisting of the singular components of C (if any), and the second element is the list of the isolated singular points (which may be contained in the singular component). The singular component might not contain any point over the considered field.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))\nAffine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4\n\njulia> curve_singular_locus(C)\n2-element Vector{Vector}:\n AffinePlaneCurve[Affine plane curve defined by x]\n Point[Point with coordinates QQFieldElem[-1, 1], Point with coordinates QQFieldElem[0, 0]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#curve_singular_locus-Union{Tuple{S}, Tuple{Oscar.Geometry.ProjSpc{S}, ProjectivePlaneCurve{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"curve_singular_locus","text":"curve_singular_locus([PP::Oscar.Geometry.ProjSpc{S}], C::ProjectivePlaneCurve{S}) where S <: FieldElem\n\nReturn the reduced singular locus of C as a list whose first element is the projective plane curve consisting of the singular components of C (if any), and the second element is the list of the singular points of the reduction of C (the points are in PP if specified, or in a new projective space otherwise). The singular component might not contain any point over the considered field.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#multiplicity-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, Point{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"multiplicity","text":"multiplicity(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\n\nReturn the multiplicity of C at P.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))\nAffine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4\n\njulia> P = Point([QQ(2), QQ(-2)])\nPoint with coordinates QQFieldElem[2, -2]\n\njulia> multiplicity(C, P)\n1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#multiplicity-Union{Tuple{S}, Tuple{ProjectivePlaneCurve{S}, Oscar.Geometry.ProjSpcElem{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"multiplicity","text":" multiplicity(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\n\nReturn the multiplicity of C at P.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#tangent_lines-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, Point{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"tangent_lines","text":"tangent_lines(C::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\n\nReturn the tangent lines at P to C with their multiplicity.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x^2*(x+y)*(y^3-x^2))\nAffine plane curve defined by -x^5 - x^4*y + x^3*y^3 + x^2*y^4\n\njulia> P = Point([QQ(0), QQ(0)])\nPoint with coordinates QQFieldElem[0, 0]\n\njulia> tangent_lines(C, P)\nDict{AffinePlaneCurve{QQFieldElem}, Int64} with 2 entries:\n x => 4\n x + y => 1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#tangent_lines-Union{Tuple{S}, Tuple{ProjectivePlaneCurve{S}, Oscar.Geometry.ProjSpcElem{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"tangent_lines","text":" tangent_lines(C::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\n\nReturn the tangent lines at P to C with their multiplicity.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#is_smooth_curve-Tuple{AffinePlaneCurve}","page":"Affine and Projective Plane Curves","title":"is_smooth_curve","text":"is_smooth_curve(C::AffinePlaneCurve)\n\nReturn true if C has no singular point, and false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x*(x+y))\nAffine plane curve defined by x^2 + x*y\n\njulia> is_smooth_curve(C)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#is_smooth_curve-Tuple{ProjectivePlaneCurve}","page":"Affine and Projective Plane Curves","title":"is_smooth_curve","text":"is_smooth_curve(C::ProjectivePlaneCurve)\n\nReturn true if C has no singular point, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#Intersection-of-curves","page":"Affine and Projective Plane Curves","title":"Intersection of curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/plane_curves/","page":"Affine and Projective Plane Curves","title":"Affine and Projective Plane Curves","text":"common_components(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}) where S <: FieldElem\ncommon_components(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, D::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}) where S <: FieldElem\ncurve_intersect(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}) where S <: FieldElem\ncurve_intersect([PP::Oscar.Geometry.ProjSpc{S}], C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, D::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}) where S <: FieldElem\nintersection_multiplicity(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\nintersection_multiplicity(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, D::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\naretransverse(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}, P::Point{S}) where S<:FieldElem\naretransverse(C::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, D::Oscar.PlaneCurveModule.ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S<:FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/plane_curves/#common_components-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, AffinePlaneCurve{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"common_components","text":"common_components(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}) where S <: FieldElem\n\nReturn the affine plane curve consisting of the common component of C and D, or an empty vector if they do not have a common component.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x*(x+y)*(x^2 + x + 1))\nAffine plane curve defined by x^4 + x^3*y + x^3 + x^2*y + x^2 + x*y\n\njulia> D = AffinePlaneCurve(x*(x+y)*(x-y))\nAffine plane curve defined by x^3 - x*y^2\n\njulia> common_components(C, D)\n1-element Vector{AffinePlaneCurve{QQFieldElem}}:\n Affine plane curve defined by x^2 + x*y\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#common_components-Union{Tuple{S}, Tuple{ProjectivePlaneCurve{S}, ProjectivePlaneCurve{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"common_components","text":"common_components(C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}) where S <: FieldElem\n\nReturn the projective plane curve consisting of the common component of C and D, or an empty vector if they do not have a common component.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#curve_intersect-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, AffinePlaneCurve{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"curve_intersect","text":"curve_intersect(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}) where S <: FieldElem\n\nReturn a list whose first element is the affine plane curve defined by the gcd of C.eq and D.eq, the second element is the list of the remaining intersection points when the common components are removed from C and D.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x*(x+y))\nAffine plane curve defined by x^2 + x*y\n\njulia> D = AffinePlaneCurve((x-y)*(x-2))\nAffine plane curve defined by x^2 - x*y - 2*x + 2*y\n\njulia> curve_intersect(C, D)\n2-element Vector{Vector}:\n AffinePlaneCurve[]\n Point{QQFieldElem}[Point with coordinates QQFieldElem[0, 0], Point with coordinates QQFieldElem[2, -2]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#curve_intersect-Union{Tuple{S}, Tuple{Oscar.Geometry.ProjSpc{S}, ProjectivePlaneCurve{S}, ProjectivePlaneCurve{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"curve_intersect","text":"curve_intersect([PP::Oscar.Geometry.ProjSpc{S}], C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}) where S <: FieldElem\n\nReturn a list whose first element is the projective plane curve defined by the gcd of C.eq and D.eq, the second element is the list of the remaining intersection points when the common components are removed from C and D (the points are in PP if specified, or in a new projective space otherwise).\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\",\"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> C = ProjPlaneCurve(T(x+y+z))\nProjective plane curve defined by x + y + z\n\njulia> D = ProjPlaneCurve(T(z))\nProjective plane curve defined by z\n\njulia> curve_intersect(PP[1], C, D)\n2-element Vector{Vector{Any}}:\n []\n [(-1 : 1 : 0)]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#intersection_multiplicity-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, AffinePlaneCurve{S}, Point{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"intersection_multiplicity","text":"intersection_multiplicity(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}, P::Point{S}) where S <: FieldElem\n\nReturn the intersection multiplicity of C and D at P.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve((x^2+y^2)*(x^2 + y^2 + 2*y))\nAffine plane curve defined by x^4 + 2*x^2*y^2 + 2*x^2*y + y^4 + 2*y^3\n\njulia> D = AffinePlaneCurve((x^2+y^2)*(y^3*x^6 - y^6*x^2))\nAffine plane curve defined by x^8*y^3 + x^6*y^5 - x^4*y^6 - x^2*y^8\n\njulia> Q = Point([QQ(0), QQ(-2)])\nPoint with coordinates QQFieldElem[0, -2]\n\njulia> intersection_multiplicity(C, D, Q)\n2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#intersection_multiplicity-Union{Tuple{S}, Tuple{ProjectivePlaneCurve{S}, ProjectivePlaneCurve{S}, Oscar.Geometry.ProjSpcElem{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"intersection_multiplicity","text":" intersection_multiplicity(C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\n\nReturn the intersection multiplicity of C and D at P.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#aretransverse-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, AffinePlaneCurve{S}, Point{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"aretransverse","text":"aretransverse(C::AffinePlaneCurve{S}, D::AffinePlaneCurve{S}, P::Point{S}) where S<:FieldElem\n\nReturn true if C and D intersect transversally at P and false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(x*(x+y))\nAffine plane curve defined by x^2 + x*y\n\njulia> D = AffinePlaneCurve((x-y)*(x-2))\nAffine plane curve defined by x^2 - x*y - 2*x + 2*y\n\njulia> P = Point([QQ(0), QQ(0)])\nPoint with coordinates QQFieldElem[0, 0]\n\njulia> Q = Point([QQ(2), QQ(-2)])\nPoint with coordinates QQFieldElem[2, -2]\n\njulia> aretransverse(C, D, P)\nfalse\n\njulia> aretransverse(C, D, Q)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/plane_curves/#aretransverse-Union{Tuple{S}, Tuple{ProjectivePlaneCurve{S}, ProjectivePlaneCurve{S}, Oscar.Geometry.ProjSpcElem{S}}} where S<:FieldElem","page":"Affine and Projective Plane Curves","title":"aretransverse","text":" aretransverse(C::ProjectivePlaneCurve{S}, D::ProjectivePlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S<:FieldElem\n\nReturn true if C and D intersect transversally at P and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/OrthogonalDiscriminants/misc/","page":"Miscellaneous functions","title":"Miscellaneous functions","text":"CurrentModule = Oscar.OrthogonalDiscriminants\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/misc/#Miscellaneous-functions","page":"Miscellaneous functions","title":"Miscellaneous functions","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/misc/#Functions-related-to-Specht-modules","page":"Miscellaneous functions","title":"Functions related to Specht modules","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/misc/","page":"Miscellaneous functions","title":"Miscellaneous functions","text":"dimension_specht_module\ngram_determinant_specht_module","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/misc/#dimension_specht_module","page":"Miscellaneous functions","title":"dimension_specht_module","text":"dimension_specht_module(mu::Partition{T}) where T <: IntegerUnion -> ZZRingElem\n\nReturn the dimension of the Specht module for mu.\n\nExamples\n\njulia> print([dimension_specht_module(p) for p in partitions(4)])\nZZRingElem[1, 3, 2, 3, 1]\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/misc/#gram_determinant_specht_module","page":"Miscellaneous functions","title":"gram_determinant_specht_module","text":"gram_determinant_specht_module(mu::Partition{T}) where T <: IntegerUnion\n\nReturn the determinant of the Gram matrix for the Specht module for mu, in factorized collected form.\n\nExamples\n\njulia> print(gram_determinant_specht_module(partition([4, 3, 2, 1])))\nVector{ZZRingElem}[[3, 1152], [5, 768], [7, 384]]\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/new_developers/#Introduction-for-new-developers","page":"Introduction for new developers","title":"Introduction for new developers","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"This document is meant to get new developers started. It will not go into depth of programming in Julia or working with git, as there are far better resources on these things online.","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"note: Pay attention to your GitHub notifications!\nOnce you open a pull request on GitHub you will receive feedback, comments, and questions on GitHub. So please pay attention to your GitHub notifications.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Important-notes","page":"Introduction for new developers","title":"Important notes","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"If you encounter error messages after rebasing to the current master, chances are that some dependencies need upgrading. Please first try whether executing ]up gets rid of your errors.\nPlease have a look at the Developer Style Guide and the Design Decisions. Adhering to the style guide makes reviewing code easier for us, and hence your new feature can be merged faster.\nLet us know what you are working on early:\nYou can open a draft pull request on GitHub right at the beginning of your work. We are more than happy to look at incomplete prototypes to get an idea of what you are working on. This allows us to assess what kind of problems you might encounter and whether we can mitigate these by making changes to OSCAR.\nFeel free to contact us on Slack.\nHave a look at our community page.\nPlease also read our page on Documenting OSCAR code.\nLook at existing code that does similar things to your project to get an idea of what OSCAR code should look like. Try to look at multiple examples.\nIf you are planning to implement a new feature from scratch, please also read Adding new projects to experimental.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Overview","page":"Introduction for new developers","title":"Overview","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"In general you have to do the following six steps for submitting changes to the OSCAR source:","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Fork the main Oscar.jl repository. For this go to the Oscar.jl GitHub page and click on \"Fork\" at the upper right.\nClone your forked repository to your local machine. If you have set up ssh access you can do this in the following way:\ngit clone git@github.com:your_github_username/Oscar.jl\nCreate a new branch, usually the naming convention is to use your initials (\"yi\") and then describe your change, for example:\ngit checkout -b yi/new_feature\ngit checkout -b yi/issue1234\ngit checkout -b yi/document_feature\nEdit your source and try out your changes locally (see below). To use your local copy of the sources, start Julia and\n]dev /path/to/local/clone/of/your/fork/of/Oscar.jl\nIf this succeeds, you can enter using Oscar in Julia and it will use your local copy.\nOnce you are done editing, push your branch and open a pull request. It is recommended that you open a draft pull request to the main OSCAR repository as soon as you start working. That way OSCAR developers are aware of work being done and can give feedback early in the process.\nOnce you have finished your work, mark your pull request as ready. It will then be reviewed and, probably after feedback and requests for changes, merged.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Alternative:-]dev-Oscar","page":"Introduction for new developers","title":"Alternative: ]dev Oscar","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Alternatively you can call","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"]dev Oscar","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"in Julia. This will create a directory ~/.julia/dev/Oscar. This directory is a git clone of the central OSCAR repository. You can develop your code here, however you will still have to fork OSCAR, as you have no rights to push to the central repository. You can then add your fork as another remote, have a look at the section on rebasing below for hints.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#The-edit-process","page":"Introduction for new developers","title":"The edit process","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/#Editing-the-source","page":"Introduction for new developers","title":"Editing the source","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"The sources can be found in the src folder. Please pay attention to the folder structure and choose sensibly where to place your code (when fixing a bug this is probably a minor question).","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Adding-tests","page":"Introduction for new developers","title":"Adding tests","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"There are two ways to add tests:","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"There are combined tests and examples in the docstrings, namely the jldoctest blocks. For these have a closer look at Documenting OSCAR code.\nLarger tests and tests that aren't useful examples are in the test folder. The main file there is test/runtests.jl which then includes other testfiles. ","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Tests that rely on random values should use Oscar.get_seeded_rng, which will return a seeded random number source, and pass this to any functions that need random values. The code may also directly create and use such a random source. The current seed will be printed at the beginning of the testsuite, it is fixed to 42 in the CI. It can be changed by setting ENV[\"OSCAR_RANDOM_SEED\"] (for the testsuite running in a separate process) or by using Oscar.set_seed! (for the current session, e.g. Oscar.test_module(\"something\", new=false)).","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Oscar.test_module\nOscar.get_seeded_rng","category":"page"},{"location":"DeveloperDocumentation/new_developers/#test_module","page":"Introduction for new developers","title":"test_module","text":"test_module(file::AbstractString; new::Bool = true)\n\nRun the Oscar tests in the file test/.jl where file may be a path.\n\nThe optional parameter new takes the values false and true (default). If true, then the tests are run in a new session, otherwise the currently active session is used.\n\nFor experimental modules, use test_experimental_module instead.\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/new_developers/#get_seeded_rng","page":"Introduction for new developers","title":"get_seeded_rng","text":"get_seeded_rng()\n\nReturn a new random number generator object of type MersenneTwister which is seeded with the global seed value Oscar.rng_seed. This can be used for the testsuite to get more stable output and running times. Using a separate RNG object for each testset (or file) makes sure previous uses don't affect later testcases. It could also be useful for some randomized algorithms. The seed will be initialized with a random value during OSCAR startup but can be set to a fixed value with Oscar.set_seed! as it is done in runtests.jl.\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/new_developers/#Adding-documentation","page":"Introduction for new developers","title":"Adding documentation","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"For more information on docstrings, please read our page on Documenting OSCAR code. There are two places where documentation can be added:","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"In the docstrings above the functions in the src folder;\nIn the documentation files in the docs/src folder. The overall structure is fixed in the file docs/doc.main. If you create a new file in docs/src, you will have to add an entry in docs/doc.main.","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"In general, 1 is preferred to 2, i.e. any explanation of the functions and objects should go there and the files in docs/src should remain relatively sparse. Please also pay attention to the documentation section of the Developer Style Guide.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Further-hints","page":"Introduction for new developers","title":"Further hints","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/#Give-[gh](https://github.com/cli/cli)-a-try","page":"Introduction for new developers","title":"Give gh a try","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Especially if you will be developing a lot, this can speed up your workflow tremendously.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Use-the-[Revise](https://github.com/timholy/Revise.jl)-package","page":"Introduction for new developers","title":"Use the Revise package","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Using Revise you can avoid having to restart Julia and reloading OSCAR when editing the code. As a quick summary, first install Revise with:","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"using Pkg;\nPkg.add(\"Revise\");","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"From then on do","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"using Revise, Oscar","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"whenever you are using OSCAR in Julia.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Ask-OSCAR-Related-Questions-in-the-[OSCAR-Slack](https://oscar-system.org/slack).","page":"Introduction for new developers","title":"Ask OSCAR Related Questions in the OSCAR Slack.","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/#Use-]up","page":"Introduction for new developers","title":"Use ]up","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Working with the development version also entails that the packages Oscar depends on need to be up to date. Julia can update these packages if you type ]up in the Julia prompt. Many error messages after updating the source can be resolved by simply updating.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Style-guide","page":"Introduction for new developers","title":"Style guide","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Please have a look at the Developer Style Guide to get an overview over naming conventions, code formatting, etc.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Building-the-documentation","page":"Introduction for new developers","title":"Building the documentation","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"To build and test the documentation, please have a look at Documenting OSCAR code.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Rebasing","page":"Introduction for new developers","title":"Rebasing","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"One way to stay up to date with the current master is rebasing. In order to do this, add the main Oscar.jl repository as a remote, fetch, and then rebase.","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"git remote add oscar-system git@github.com:oscar-system/Oscar.jl\ngit fetch oscar-system\ngit rebase oscar-system/master","category":"page"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"Adding the remote only has to be executed once.","category":"page"},{"location":"DeveloperDocumentation/new_developers/#Useful-Julia-functions","page":"Introduction for new developers","title":"Useful Julia functions","text":"","category":"section"},{"location":"DeveloperDocumentation/new_developers/","page":"Introduction for new developers","title":"Introduction for new developers","text":"methods,\nmethodswith,\n@which,\n@less,\n@edit.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Multivariate-Polynomial-Ring-Interface","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Multivariate polynomial rings are supported in AbstractAlgebra.jl, and in addition to the standard Ring interface, numerous additional functions are provided.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Unlike other kinds of rings, even complex operations such as GCD depend heavily on the multivariate representation. Therefore AbstractAlgebra.jl cannot provide much in the way of additional functionality to external multivariate implementations.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"This means that external libraries must be able to implement their multivariate formats in whatever way they see fit. The required interface here should be implemented, even if it is not optimal. But it can be extended, either by implementing one of the optional interfaces, or by extending the required interface in some other way.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Naturally, any multivariate polynomial ring implementation provides the full Ring interface, in order to be treated as a ring for the sake of AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Considerations which make it impossible for AbstractAlgebra.jl to provide generic functionality on top of an arbitrary multivariate module include:","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"orderings (lexical, degree, weighted, block, arbitrary)\nsparse or dense representation\ndistributed or recursive representation\npacked or unpacked exponents\nexponent bounds (and whether adaptive or not)\nrandom access or iterators\nwhether monomials and polynomials have the same type\nwhether special cache aware data structures such as Geobuckets are used","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Types-and-parents","page":"Multivariate Polynomial Ring Interface","title":"Types and parents","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"AbstractAlgebra.jl provides two abstract types for multivariate polynomial rings and their elements:","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"MPolyRing{T} is the abstract type for multivariate polynomial ring parent types\nMPolyRingElem{T} is the abstract type for multivariate polynomial types","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"We have that MPolyRing{T} <: Ring and MPolyRingElem{T} <: RingElem.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Note that both abstract types are parameterised. The type T should usually be the type of elements of the coefficient ring of the polynomial ring. For example, in the case of mathbbZx y the type T would be the type of an integer, e.g. BigInt.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Multivariate polynomial rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Multivariate polynomial rings should at least be distinguished based on their base (coefficient) ring and number of variables. But if they have the same base ring, symbols (for their variables/generators) and ordering, they should certainly have the same parent object.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Required-functionality-for-multivariate-polynomials","page":"Multivariate Polynomial Ring Interface","title":"Required functionality for multivariate polynomials","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"In addition to the required functionality for the Ring interface, the Multivariate Polynomial interface has the following required functions.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"We suppose that R is a fictitious base ring (coefficient ring) and that S is a multivariate polynomial ring over R (i.e. S = Rx y ldots) with parent object S of type MyMPolyRing{T}. We also assume the polynomials in the ring have type MyMPoly{T}, where T is the type of elements of the base (coefficient) ring.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Note that the type T must (transitively) belong to the abstract type RingElem or more generally the union type RingElement which includes the Julia integer, rational and floating point types.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Constructors","page":"Multivariate Polynomial Ring Interface","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"To construct a multivariate polynomial ring, there is the following constructor.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"polynomial_ring(R::Ring, s::Vector{<:VarName}; ordering=:lex, cached::Bool=true)","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return a tuple, S, vars consisting of a polynomial ring S and an array of generators (variables) which print according to the strings in the supplied vector s. The ordering can at present be :lex, :deglex or :degrevlex. By default, the polynomial ring is cached, and creating a polynomial ring with the same data will return the same ring object S. If this caching is not desired, it can be switched off by setting cached=false.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Polynomials in a given ring can be constructed using the generators and basic polynomial arithmetic. However, this is inefficient and the following build context is provided for building polynomials term-by-term. It assumes the polynomial data type is random access, and so the constructor functions must be reimplemented for all other types of polynomials.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"MPolyBuildCtx(R::MPolyRing)","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return a build context for creating polynomials in the given polynomial ring.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"push_term!(M::MPolyBuildCtx, c::RingElem, v::Vector{Int})","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Add the term with coefficient c and exponent vector v to the polynomial under construction in the build context M.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"finish(M::MPolyBuildCtx)","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Finish construction of the polynomial, sort the terms, remove duplicate and zero terms and return the created polynomial.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Data-type-and-parent-object-methods","page":"Multivariate Polynomial Ring Interface","title":"Data type and parent object methods","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"symbols(S::MyMPolyRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return an array of Symbols representing the variables (generators) of the polynomial ring. Note that these are Symbols not Strings, though their string values will usually be used when printing polynomials.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"nvars(f::MyMPolyRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the number of variables of the polynomial ring.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"gens(S::MyMPolyRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return an array of all the generators (variables) of the given polynomial ring (as polynomials).","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The first entry in the array will be the variable with most significance with respect to the ordering.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"gen(S::MyMPolyRing{T}, i::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the i-th generator (variable) of the given polynomial ring (as a polynomial).","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"ordering(S::MyMPolyRing{T})","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the ordering of the given polynomial ring as a symbol. Supported values currently include :lex, :deglex and :degrevlex.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Basic-manipulation-of-rings-and-elements","page":"Multivariate Polynomial Ring Interface","title":"Basic manipulation of rings and elements","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"length(f::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the number of nonzero terms of the given polynomial. The length of the zero polynomial is defined to be 0. The return value should be of type Int.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"degrees(f::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return an array of the degrees of the polynomial f in each of the variables.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"total_degree(f::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the total degree of the polynomial f, i.e. the highest sum of exponents occurring in any term of f.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"is_gen(x::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return true if x is a generator of the polynomial ring.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"coefficients(p::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return an iterator for the coefficients of the polynomial p, starting with the coefficient of the most significant term with respect to the ordering. Generic code will provide this function automatically for random access polynomials that implement the coeff function.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"monomials(p::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return an iterator for the monomials of the polynomial p, starting with the monomial of the most significant term with respect to the ordering. Monomials in AbstractAlgebra are defined to have coefficient 1. See the function terms if you also require the coefficients, however note that only monomials can be compared. Generic code will provide this function automatically for random access polynomials that implement the monomial function.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"terms(p::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return an iterator for the terms of the polynomial p, starting with the most significant term with respect to the ordering. Terms in AbstractAlgebra include the coefficient. Generic code will provide this function automatically for random access polynomials that implement the term function.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"exponent_vectors(a::MyMPoly{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return an iterator for the exponent vectors for each of the terms of the polynomial starting with the most significant term with respect to the ordering. Each exponent vector is an array of Ints, one for each variable, in the order given when the polynomial ring was created. Generic code will provide this function automatically for random access polynomials that implement the exponent_vector function.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Exact-division","page":"Multivariate Polynomial Ring Interface","title":"Exact division","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"For any ring that implements exact division, the following can be implemented.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"divexact(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the exact quotient of f by g if it exists, otherwise throw an error.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"divides(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return a tuple (flag, q) where flag is true if g divides f, in which case q will be the exact quotient, or flag is false and q is set to zero.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"remove(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return a tuple (v q) such that the highest power of g that divides f is g^v and the cofactor is q.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"valuation(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return v such that the highest power of g that divides f is g^v.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Ad-hoc-exact-division","page":"Multivariate Polynomial Ring Interface","title":"Ad hoc exact division","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"For any ring that implements exact division, the following can be implemented.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"divexact(f::MyMPoly{T}, c::Integer) where T <: RingElem\ndivexact(f::MyMPoly{T}, c::Rational) where T <: RingElem\ndivexact(f::MyMPoly{T}, c::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Divide the polynomial exactly by the constant c.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Euclidean-division","page":"Multivariate Polynomial Ring Interface","title":"Euclidean division","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Although multivariate polynomial rings are not in general Euclidean, it is possible to define a quotient with remainder function that depends on the polynomial ordering in the case that the quotient ring is a field or a Euclidean domain. In the case that a polynomial g divides a polynomial f, the result no longer depends on the ordering and the remainder is zero, with the quotient agreeing with the exact quotient.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"divrem(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return a tuple (q r) such that f = qg + r, where the coefficients of terms of r whose monomials are divisible by the leading monomial of g are reduced modulo the leading coefficient of g (according to the Euclidean function on the coefficients).","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Note that the result of this function depends on the ordering of the polynomial ring.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"div(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"As per the divrem function, but returning the quotient only. Especially when the quotient happens to be exact, this function can be exceedingly fast.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#GCD","page":"Multivariate Polynomial Ring Interface","title":"GCD","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"In cases where there is a meaningful Euclidean structure on the coefficient ring, it is possible to compute the GCD of multivariate polynomials.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"gcd(f::MyMPoly{T}, g::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return a greatest common divisor of f and g.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Square-root","page":"Multivariate Polynomial Ring Interface","title":"Square root","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Over rings for which an exact square root is available, it is possible to take the square root of a polynomial or test whether it is a square.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"sqrt(f::MyMPoly{T}, check::Bool=true) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the square root of the polynomial f and raise an exception if it is not a square. If check is set to false, the input is assumed to be a perfect square and this assumption is not fully checked. This can be significantly faster.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"is_square(::MyMPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return true if f is a square.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Interface-for-sparse-distributed,-random-access-multivariates","page":"Multivariate Polynomial Ring Interface","title":"Interface for sparse distributed, random access multivariates","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The following additional functions should be implemented by libraries that provide a sparse distributed polynomial format, stored in a representation for which terms can be accessed in constant time (e.g. where arrays are used to store coefficients and exponent vectors).","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Sparse-distributed,-random-access-constructors","page":"Multivariate Polynomial Ring Interface","title":"Sparse distributed, random access constructors","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"In addition to the standard constructors, the following constructor, taking arrays of coefficients and exponent vectors, should be provided.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"(S::MyMPolyRing{T})(A::Vector{T}, m::Vector{Vector{Int}}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Create the polynomial in the given ring with nonzero coefficients specified by the elements of A and corresponding exponent vectors given by the elements of m.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"There is no assumption about coefficients being nonzero or terms being in order or unique. Zero terms are removed by the function, duplicate terms are combined (added) and the terms are sorted so that they are in the correct order.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Each exponent vector uses a separate integer for each exponent field, the first of which should be the exponent for the most significant variable with respect to the ordering. All exponents must be non-negative.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"A library may also optionally provide an interface that makes use of BigInt (or any other big integer type) for exponents instead of Int.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Sparse-distributed,-random-access-basic-manipulation","page":"Multivariate Polynomial Ring Interface","title":"Sparse distributed, random access basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"coeff(f::MyMPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the coefficient of the n-th term of f. The first term should be the most significant term with respect to the ordering.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"coeff(a::MyMPoly{T}, exps::Vector{Int}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the coefficient of the term with the given exponent vector, or zero if there is no such term.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"monomial(f::MyMPoly{T}, n::Int) where T <: RingElem\nmonomial!(m::MyMPoly{T}, f::MyMPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the n-th monomial of f or set m to the n-th monomial of f, respectively. The first monomial should be the most significant term with respect to the ordering. Monomials have coefficient 1 in AbstractAlgebra. See the function term if you also require the coefficient, however, note that only monomials can be compared.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"term(f::MyMPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the n-th term of f. The first term should be the one whose monomial is most significant with respect to the ordering.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"exponent(f::MyMPoly{T}, i::Int, j::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return the exponent of the j-th variable in the i-th term of the polynomial f. The first term is the one with whose monomial is most significant with respect to the ordering.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"exponent_vector(a::MyMPoly{T}, i::Int) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Return a vector of exponents, corresponding to the exponent vector of the i-th term of the polynomial. Term numbering begins at 1 and the exponents are given in the order of the variables for the ring, as supplied when the ring was created.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"setcoeff!(a::MyMPoly, exps::Vector{Int}, c::S) where S <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Set the coefficient of the term with the given exponent vector to the given value c. If no such term exists (and c neq 0), one will be inserted. This function takes O(log n) operations if a term with the given exponent already exists and c neq 0, or if the term is inserted at the end of the polynomial. Otherwise it can take O(n) operations in the worst case. This function must return the modified polynomial.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Unsafe-functions","page":"Multivariate Polynomial Ring Interface","title":"Unsafe functions","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The following functions must be provided, but are considered unsafe, as they may leave the polynomials in an inconsistent state and they mutate their inputs. As usual, such functions should only be applied on polynomials that have no references elsewhere in the system and are mainly intended to be used in carefully written library code, rather than by users.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Users should instead build polynomials using the constructors described above.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"fit!(f::MyMPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Ensure that the polynomial f internally has space for n nonzero terms. This function must mutate the function in-place if it is mutable. It does not return the mutated polynomial. Immutable types can still be supported by defining this function to do nothing.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"setcoeff!(a::MyMPoly{T}, i::Int, c::T) where T <: RingElement\nsetcoeff!(a::MyMPoly{T}, i::Int, c::U) where {T <: RingElement, U <: Integer}","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Set the i-th coefficient of the polynomial a to c. No check is performed on the index i or for c = 0. It may be necessary to call combine_like_terms after calls to this function, to remove zero terms. The function must return the modified polynomial.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"combine_like_terms!(a::MyMPoly{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Remove zero terms and combine any adjacent terms with the same exponent vector (by adding them). It is assumed that all the exponent vectors are already in the correct order with respect to the ordering. The function must return the resulting polynomial.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"set_exponent_vector!(a::MyMPoly{T}, i::Int, exps::Vector{Int}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Set the i-th exponent vector to the given exponent vector. No check is performed on the index i, which is assumed to be valid (or that the polynomial has enough space allocated). No sorting of exponents is performed by this function. To sort the terms after setting any number of exponents with this function, run the sort_terms! function. The function must return the modified polynomial.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"sort_terms!(a::MyMPoly{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Sort the terms of the given polynomial according to the polynomial ring ordering. Zero terms and duplicate exponents are ignored. To deal with those call combine_like_terms. The sorted polynomial must be returned by the function.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Optional-functionality-for-multivariate-polynomials","page":"Multivariate Polynomial Ring Interface","title":"Optional functionality for multivariate polynomials","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The following functions can optionally be implemented for multivariate polynomial types.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Reduction-by-an-ideal","page":"Multivariate Polynomial Ring Interface","title":"Reduction by an ideal","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"divrem(f::MyMPoly{T}, G::Vector{MyMPoly{T}}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"As per the divrem function above, except that each term of r starting with the most significant term, is reduced modulo the leading terms of each of the polynomials in the array G for which the leading monomial is a divisor.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"A tuple (Q r) is returned from the function, where Q is an array of polynomials of the same length as G, and such that f = r + sum QiGi.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The result is again dependent on the ordering in general, but if the polynomials in G are over a field and the reduced generators of a Groebner basis, then the result is unique.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Evaluation","page":"Multivariate Polynomial Ring Interface","title":"Evaluation","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"evaluate(a::MyMPoly{T}, A::Vector{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Evaluate the polynomial at the given values in the coefficient ring of the polynomial. The result should be an element of the coefficient ring.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"evaluate(f::MyMPoly{T}, A::Vector{U}) where {T <: RingElem, U <: Integer}","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Evaluate the polynomial f at the values specified by the entries of the array A.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"(a::MyMPoly{T})(vals::Union{NCRingElem, RingElement}...) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Evaluate the polynomial at the given arguments. This provides functional notation for polynomial evaluation, i.e. f(a b c). It must be defined for each supported polynomial type (Julia does not allow functional notation to be defined for an abstract type).","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The code for this function in MPoly.jl can be used when implementing this as it provides the most general possible evaluation, which is much more general than the case of evaluation at elements of the same ring.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The evaluation should succeed for any set of values for which a multiplication is defined with the product of a coefficient and all the values before it.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"note: Note\nThe values at which a polynomial is evaluated may be in non-commutative rings. Products are performed in the order of the variables in the polynomial ring that the polynomial belongs to, preceded by a multiplication by the coefficient on the left.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#Derivations","page":"Multivariate Polynomial Ring Interface","title":"Derivations","text":"","category":"section"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"The following function allows to compute derivations of multivariate polynomials of type MPoly.","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"derivative(f::MyMPoly{T}, j::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/","page":"Multivariate Polynomial Ring Interface","title":"Multivariate Polynomial Ring Interface","text":"Compute the derivative of f with respect to the j-th variable of the polynomial ring.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/#Polyhedron-and-polymake's-Polytope","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"Many polyhedral computations are done through polymake. polymake (Ewgenij Gawrilow, Michael Joswig (2000), polymake.org) is open source software for research in polyhedral geometry and is attached to Julia via Polymake.jl (Marek Kaluba, Benjamin Lorenz, Sascha Timme (2020), Polymake.jl). This is visible in the structure Polyhedron via a pointer pm_polytope to the corresponding polymake object. Using Polymake.jl one can apply all functionality of polymake to the polymake object hidden behind this pointer.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"Sometimes it can be necessary to directly invoke some polymake functions on an OSCAR Polyhedron object (e.g. because some functionality has not yet been made available via OSCAR's interface). In that case, the following two functions allow extracting the underlying Polymake.jl object from a Polyhedron, respectively wrapping a Polymake.jl object representing a polyhedron into a high-level Polyhedron object.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"Polyhedron{T}(p::Polymake.BigObject, f::Field) where T<:scalar_types\npolyhedron(P::Polymake.BigObject)","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/#Polyhedron-Union{Tuple{T}, Tuple{Polymake.LibPolymake.BigObject, Field}} where T<:Union{Float64, FieldElem}","page":"Polyhedron and polymake's Polytope","title":"Polyhedron","text":"Polyhedron{T}(P::Polymake.BigObject, F::Field) where T<:scalar_types\n\nConstruct a Polyhedron corresponding to a Polymake.BigObject of type Polytope with scalars from Field F.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/polymake/#polyhedron-Tuple{Polymake.LibPolymake.BigObject}","page":"Polyhedron and polymake's Polytope","title":"polyhedron","text":"polyhedron(P::Polymake.BigObject)\n\nConstruct a Polyhedron corresponding to a Polymake.BigObject of type Polytope. Scalar type and parent field will be detected automatically. To improve type stability and performance, please use Polyhedron{T}(p::Polymake.BigObject, f::Field) where T<:scalar_types instead, where possible.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"The following shows all the data currently known for a Polyhedron.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"julia> C = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> C.pm_polytope\ntype: Polytope\ndescription: cube of dimension 3\n\nAFFINE_HULL\n\n\nBOUNDED\n\ttrue\n\nCONE_AMBIENT_DIM\n\t4\n\nCONE_DIM\n\t4\n\nFACETS\n 1 1 0 0\n 1 -1 0 0\n 1 0 1 0\n 1 0 -1 0\n 1 0 0 1\n 1 0 0 -1\n\nVERTICES_IN_FACETS\n\t{0 2 4 6}\n\t{1 3 5 7}\n\t{0 1 4 5}\n\t{2 3 6 7}\n\t{0 1 2 3}\n\t{4 5 6 7}\n","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"polymake allows for an interactive visualization of 3-dimensional polytopes in the browser: Polymake.visual(C.pm_polytope).","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"warning: Warning\nThere are several design differences between polymake and OSCAR. Polyhedra in polymake and Polymake.jl use homogeneous coordinates. The polyhedra in OSCAR use affine coordinates. Indices in polymake are zero-based, whereas in OSCAR they are one-based.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"The next example shows a purely combinatorial construction of a polytope (here: a square). In spite of being given no coordinates, polymake can check for us that this is a simple polytope; i.e., each vertex is contained in dimension many facets.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"julia> Q = Polymake.polytope.Polytope(VERTICES_IN_FACETS=[[0,2],[1,3],[0,1],[2,3]]);\n\njulia> Q.SIMPLE\ntrue\n","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"However, without coordinates, some operations such as computing the volume cannot work:","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"julia> Q.VOLUME\npolymake: WARNING: available properties insufficient to compute 'VOLUME'\n","category":"page"},{"location":"Hecke/function_fields/degree_localization/#Degree-localization-of-a-rational-function-field","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"","category":"section"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/function_fields/degree_localization/#Degree-localization","page":"Degree localization of a rational function field","title":"Degree localization","text":"","category":"section"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"Given k(x) a (univariate) rational function field, there are two rings of interest, both of which are Euclidean:","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"kx\nk_\n\\infty(x) = {a/b | a, b \\in k[x] \\;\\;\\mbox{where}\\;\\; \\deg(a) \\leq \\deg(b)}","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"The second of these rings is the localization of k1x at (1x) inside the rational function field k(x), i.e. the localization of the function field at the point at infinity, i.e. the valuation ring for valuation -degree(x).","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"We refer to this ring as the degree localization of the rational function field k(x).","category":"page"},{"location":"Hecke/function_fields/degree_localization/#Construction-of-the-degree-localization","page":"Degree localization of a rational function field","title":"Construction of the degree localization","text":"","category":"section"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"The degree localization of a rational function field k(x) can be constructed using a localization constructor, passing in the degree function as argument.","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"localization(K::Generic.RationalFunctionField{T}, ::typeof(degree)) where T <: FieldElement","category":"page"},{"location":"Hecke/function_fields/degree_localization/#localization-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.RationalFunctionField{T, U} where U<:Union{MPolyRingElem{T}, PolyRingElem{T}}, typeof(degree)}} where T<:FieldElement","page":"Degree localization of a rational function field","title":"localization","text":"localization(K::RationalFunctionField{T}, ::typeof(degree)) where T <: FieldElement\n\nReturn the localization of k1x at (1x) inside the rational function field k(x), i.e. the localization of the function field at the point at infinity, i.e. the valuation ring for valuation -degree(x). This is the ring k_infty(x) = fg deg(f) leq deg(g).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"","category":"page"},{"location":"Hecke/function_fields/degree_localization/#Example","page":"Degree localization of a rational function field","title":"Example +","text":"","category":"section"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"using Hecke # hide\nK, x = RationalFunctionField(FlintQQ, \"x\");\nR = localization(K, degree)","category":"page"},{"location":"Hecke/function_fields/degree_localization/#Elements-of-the-degree-localization","page":"Degree localization of a rational function field","title":"Elements of the degree localization","text":"","category":"section"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"Elements of the degree localization are created using the parent object R representing the degree localization","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"","category":"page"},{"location":"Hecke/function_fields/degree_localization/#Example-2","page":"Degree localization of a rational function field","title":"Example +","text":"","category":"section"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"using Hecke # hide\nK, x = RationalFunctionField(FlintQQ, \"x\");\nR = localization(K, degree)\n\na = R()\nb = R(1)\nc = R((x + 1)//x)","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"Note that the degree of the denominator of the function field element passed to the constructor must be at least that of the numerator or an exception is raised.","category":"page"},{"location":"Hecke/function_fields/degree_localization/#Element-functionality","page":"Degree localization of a rational function field","title":"Element functionality","text":"","category":"section"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"degree(a::KInftyElem)\nvaluation(a::KInftyElem)","category":"page"},{"location":"Hecke/function_fields/degree_localization/#degree-Tuple{KInftyElem}","page":"Degree localization of a rational function field","title":"degree","text":" degree(a::KInftyElem)\n\nReturn the degree of the given element, i.e. degree(numerator) - degree(denominator).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/function_fields/degree_localization/#valuation-Tuple{KInftyElem}","page":"Degree localization of a rational function field","title":"valuation","text":"valuation(a::KInftyElem)\n\nReturn the degree valuation of the given element, i.e. -degree(a).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"One can test whether a given element of a rational function field is in the degree localization.","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"in(a::Generic.RationalFunctionFieldElem{T}, R::KInftyRing{T}) where T <: FieldElement","category":"page"},{"location":"Hecke/function_fields/degree_localization/#in-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.RationalFunctionFieldElem{T}, KInftyRing{T}}} where T<:FieldElement","page":"Degree localization of a rational function field","title":"in","text":"in(a::Generic.RationalFunctionFieldElem{T}, R::KInftyRing{T}) where T <: FieldElement\n\nReturn true if the given element of the rational function field is an element of k_\\infty(x), i.e. if degree(numerator) <= degree(denominator).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"All basic arithmetic operations are provided for elements of the degree localization.","category":"page"},{"location":"Hecke/function_fields/degree_localization/","page":"Degree localization of a rational function field","title":"Degree localization of a rational function field","text":"As the degree localization is a Euclidean ring, all standard Euclidean functions, including div, divrem, mod, gcd, gcdx, are provided.","category":"page"},{"location":"Hecke/class_fields/intro/#Class-Field-Theory","page":"Class Field Theory","title":"Class Field Theory","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/class_fields/intro/#Introduction","page":"Class Field Theory","title":"Introduction","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"This chapter deals with abelian extensions of number fields and the rational numbers.","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"Class Field Theory, here specifically, class field theory of global number fields, deals with abelian extension, ie. fields where the group of automorphisms is abelian. For extensions of mathbb Q, the famous Kronnecker-Weber theorem classifies all such fields: a field is abelian if and only if it is contained in some cyclotomic field. For general number fields this is more involved and even for extensions of mathbb Q is is not practical.","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"In Hecke, abelian extensions are parametrized by quotients of so called ray class groups. The language of ray class groups while dated is more applicable to algorithms than the modern language of idel class groups and quotients.","category":"page"},{"location":"Hecke/class_fields/intro/#Ray-Class-Groups","page":"Class Field Theory","title":"Ray Class Groups","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"Given an integral ideal m_0 le Z_K and a list of real places m_infty, the ray class group modulo (m_0 m_infty), C(m) is defined as the group of ideals coprime to m_0 modulo the elements ain K^* s.th. v_p(a-1) ge v_p(m_0) and for all vin m_infty, a^(v) 0. This is a finite abelian group. For m_0 = Z_K and m_infty = we get C() is the class group, if m_infty contains all real places, we obtain the narrow class group, or strict class group.","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"ray_class_group(m::Hecke.NfAbsOrdIdl{Nemo.AnticNumberField,Nemo.nf_elem}, inf_plc::Vector{Hecke.InfPlc}; p_part, n_quo)\nclass_group(K::Nemo.AnticNumberField)\nnorm_group(f::Nemo.PolyElem, mR::Hecke.MapRayClassGrp, is_abelian::Bool)\nnorm_group(K::NfRel{nf_elem}, mR::Hecke.MapRayClassGrp, is_abelian::Bool)","category":"page"},{"location":"Hecke/class_fields/intro/#ray_class_group-Tuple{NfOrdIdl, Vector{InfPlc}}","page":"Class Field Theory","title":"ray_class_group","text":"ray_class_group(m::NfOrdIdl, inf_plc::Vector{InfPlc}; n_quo::Int, lp::Dict{NfOrdIdl, Int}) -> GrpAbFinGen, MapRayClassGrp\n\nGiven an ideal m and a set of infinite places of K, this function returns the corresponding ray class group as an abstract group mathcal Cl_m and a map going from the group into the group of ideals of K that are coprime to m. If n_quo is set, it will return the group modulo n_quo. The factorization of m can be given with the keyword argument lp.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#class_group-Tuple{AnticNumberField}","page":"Class Field Theory","title":"class_group","text":"class_group(K::AnticNumberField) -> GrpAbFinGen, Map\n\nShortcut for class_group(maximal_order(K)): returns the class group as an abelian group and a map from this group to the set of ideals of the maximal order.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#norm_group-Tuple{PolyRingElem, MapRayClassGrp, Bool}","page":"Class Field Theory","title":"norm_group","text":"norm_group(f::Nemo.PolyElem, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap\n\nnorm_group(f::Array{PolyElem{nf_elem}}, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap\n\nComputes the subgroup of the Ray Class Group R given by the norm of the extension generated by a/the roots of f. If is_abelian is set to true, then the code assumes the field to be abelian, hence the algorithm stops when the quotient by the norm group has the correct order. Even though the algorithm is probabilistic by nature, in this case the result is guaranteed. If of_closure is given, then the norm group of the splitting field of the polynomial(s) is computed. It is the callers responsibility to ensure that the ray class group passed in is large enough.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#norm_group-Tuple{Hecke.NfRel{nf_elem}, MapRayClassGrp, Bool}","page":"Class Field Theory","title":"norm_group","text":"norm_group(K::NfRel{nf_elem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap\n\nnorm_group(K::NfRelNS{nf_elem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap\n\nComputes the subgroup of the Ray Class Group R given by the norm of the extension.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#Ray-Class-Fields","page":"Class Field Theory","title":"Ray Class Fields","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"In general, the construction of a class field starts with a (ray) class group. Each quotient of a ray class group then defines a ray class field, the defining property is that the (relative) automorphism group is canonically isomorphic to the quotient of the ray class group where the isomorphism is given by the Artin (or Frobenius) map. Since, in Hecke, the (ray) class groups have no link to the field, actually this has to be specified using the maps.","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"It should be noted that this is a lazy construction: nothing is computed at this point.","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"ray_class_field(m::Union{Hecke.MapClassGrp, Hecke.MapRayClassGrp})\nray_class_field(m::Union{Hecke.MapClassGrp, Hecke.MapRayClassGrp}, quomap::Hecke.GrpAbFinGenMap)\nray_class_field(I::Hecke.NfAbsOrdIdl; n_quo, p_part)\nray_class_field(I::Hecke.NfAbsOrdIdl, ::Vector{InfPlc}; n_quo, p_part)\nhilbert_class_field(k::AnticNumberField)\nring_class_field(::NfAbsOrd)","category":"page"},{"location":"Hecke/class_fields/intro/#ray_class_field-Tuple{Union{Hecke.MapClassGrp, MapRayClassGrp}}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(m::MapClassGrp) -> ClassField\nray_class_field(m::MapRayClassGrp) -> ClassField\n\nCreates the (formal) abelian extension defined by the map m A to I where I is the set of ideals coprime to the modulus defining m and A is a quotient of the ray class group (or class group). The map m must be the map returned from a call to {classgroup} or {rayclass_group}.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#ray_class_field-Tuple{Union{Hecke.MapClassGrp, MapRayClassGrp}, GrpAbFinGenMap}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(m::Union{MapClassGrp, MapRayClassGrp}, quomap::GrpAbFinGenMap) -> ClassField\n\nFor m a map computed by either {rayclassgroup} or {class_group} and q a canonical projection (quotient map) as returned by {quo} for q quotient of the domain of m and a subgroup of m, create the (formal) abelian extension where the (relative) automorphism group is canonically isomorphic to the codomain of q.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#ray_class_field-Tuple{NfAbsOrdIdl}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(I::NfAbsOrdIdl; n_quo = 0) -> ClassField\n\nThe ray class field modulo I. If n_quo is given, then the largest subfield of exponent n is computed.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#ray_class_field-Tuple{NfAbsOrdIdl, Vector{InfPlc}}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(I::NfAbsOrdIdl, inf::Vector{InfPlc}; n_quo = 0) -> ClassField\n\nThe ray class field modulo I and the infinite places given. If n_quo is given, then the largest subfield of exponent n is computed.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#hilbert_class_field-Tuple{AnticNumberField}","page":"Class Field Theory","title":"hilbert_class_field","text":"hilbert_class_field(k::AnticNumberField) -> ClassField\n\nThe Hilbert class field of k as a formal (ray-) class field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#ring_class_field-Tuple{NfAbsOrd}","page":"Class Field Theory","title":"ring_class_field","text":"ring_class_field(O::NfAbsOrd) -> ClassField\n\nThe ring class field of O, i.e. the maximal abelian extension ramified only at primes dividing the conductor with the automorphism group isomorphic to the Picard group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#Example","page":"Class Field Theory","title":"Example","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"using Hecke # hide\nQx, x = polynomial_ring(FlintQQ, \"x\");\nK, a = number_field(x^2 - 10, \"a\");\nc, mc = class_group(K)\nA = ray_class_field(mc)","category":"page"},{"location":"Hecke/class_fields/intro/#Conversions","page":"Class Field Theory","title":"Conversions","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"Given a ray class field, it is possible to actually compute defining equation(s) for this field. In general, the number field constructed this way will be non-simple by type and is defined by a polynomial for each maximal cyclic quotient of prime power order in the defining group.","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"The algorithm employed is based on Kummer-theory and requires the addition of a suitable root of unity. Progress can be monitored by setting set_verbose_level(:ClassField, n) where 0le nle 3","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"number_field(C::ClassField)","category":"page"},{"location":"Hecke/class_fields/intro/#number_field-Tuple{ClassField}","page":"Class Field Theory","title":"number_field","text":"number_field(CF::ClassField) -> NfRelNS{nf_elem}\n\nGiven a (formal) abelian extension, compute the class field by finding defining polynomials for all prime power cyclic subfields.\n\nNote, the return type is always a non-simple extension.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"using Hecke; # hide\nQx, x = polynomial_ring(FlintQQ, \"x\");\nk, a = number_field(x^2 - 10, \"a\");\nc, mc = class_group(k);\nA = ray_class_field(mc)\nK = number_field(A)\nZK = maximal_order(K)\nisone(discriminant(ZK))","category":"page"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"ray_class_field(K::NfRel{nf_elem})\ngenus_field(A::ClassField, k::AnticNumberField)\nmaximal_abelian_subfield(A::ClassField, k::AnticNumberField)\nmaximal_abelian_subfield(K::NfRel{nf_elem})","category":"page"},{"location":"Hecke/class_fields/intro/#ray_class_field-Tuple{Hecke.NfRel{nf_elem}}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(K::NfRel{nf_elem}) -> ClassField\nray_class_field(K::AnticNumberField) -> ClassField\n\nFor a (relative) abelian extension, compute an abstract representation as a class field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#genus_field-Tuple{ClassField, AnticNumberField}","page":"Class Field Theory","title":"genus_field","text":"genus_field(A::ClassField, k::AnticNumberField) -> ClassField\n\nThe maximal extension contained in A that is the compositum of K with an abelian extension of k.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#maximal_abelian_subfield-Tuple{ClassField, AnticNumberField}","page":"Class Field Theory","title":"maximal_abelian_subfield","text":"maximal_abelian_subfield(A::ClassField, k::AnticNumberField) -> ClassField\n\nThe maximal abelian extension of k contained in A. k must be a subfield of the base field of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#maximal_abelian_subfield-Tuple{Hecke.NfRel{nf_elem}}","page":"Class Field Theory","title":"maximal_abelian_subfield","text":"maximal_abelian_subfield(K::NfRel{nf_elem}; of_closure::Bool = false) -> ClassField\n\nUsing a probabilistic algorithm for the norm group computation, determine the maximal abelian subfield in K over its base field. If of_closure is set to true, then the algorithm is applied to the normal closure of K (without computing it).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#Invariants","page":"Class Field Theory","title":"Invariants","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"degree(C::ClassField)\nbase_ring(A::Hecke.ClassField)\nbase_field(A::Hecke.ClassField)\ndiscriminant(C::Hecke.ClassField)\nconductor(C::Hecke.ClassField)\ndefining_modulus(C::ClassField)\nis_cyclic(C::ClassField)\nis_conductor(C::Hecke.ClassField, m::NfOrdIdl, inf_plc::Vector{InfPlc})\nis_normal(C::ClassField)\nis_central(C::ClassField)","category":"page"},{"location":"Hecke/class_fields/intro/#degree-Tuple{ClassField}","page":"Class Field Theory","title":"degree","text":"degree(A::ClassField)\n\nThe degree of A over its base field, i.e. the size of the defining ideal group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#base_ring-Tuple{ClassField}","page":"Class Field Theory","title":"base_ring","text":"base_ring(A::ClassField)\n\nThe maximal order of the field that A is defined over.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#base_field-Tuple{ClassField}","page":"Class Field Theory","title":"base_field","text":"base_field(A::ClassField)\n\nThe number field that A is defined over.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#discriminant-Tuple{ClassField}","page":"Class Field Theory","title":"discriminant","text":"discriminant(C::ClassField) -> NfOrdIdl\n\nUsing the conductor-discriminant formula, compute the (relative) discriminant of C. This does not use the defining equations.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#conductor-Tuple{ClassField}","page":"Class Field Theory","title":"conductor","text":"conductor(C::ClassField) -> NfOrdIdl, Vector{InfPlc}\n\nReturn the conductor of the abelian extension corresponding to C.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#defining_modulus-Tuple{ClassField}","page":"Class Field Theory","title":"defining_modulus","text":"defining_modulus(CF::ClassField)\n\nThe modulus, i.e. an ideal of the set of real places, used to create the class field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#is_cyclic-Tuple{ClassField}","page":"Class Field Theory","title":"is_cyclic","text":"is_cyclic(C::ClassField)\n\nTests if the (relative) automorphism group of C is cyclic (by checking the defining ideal group).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#is_conductor-Tuple{ClassField, NfOrdIdl, Vector{InfPlc}}","page":"Class Field Theory","title":"is_conductor","text":"is_conductor(C::Hecke.ClassField, m::NfOrdIdl, inf_plc::Vector{InfPlc}=InfPlc[]; check) -> NfOrdIdl, Vector{InfPlc}\n\nChecks if (m, inf_plc) is the conductor of the abelian extension corresponding to C. If check is false, it assumes that the given modulus is a multiple of the conductor. This is usually faster than computing the conductor.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#is_normal-Tuple{ClassField}","page":"Class Field Theory","title":"is_normal","text":"is_normal(C::ClassField) -> Bool\n\nFor a class field C defined over a normal base field k, decide if C is normal over Q.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#is_central-Tuple{ClassField}","page":"Class Field Theory","title":"is_central","text":"is_central(C::ClassField) -> Bool\n\nFor a class field C defined over a normal base field k, decide if C is central over Q.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#Operations","page":"Class Field Theory","title":"Operations","text":"","category":"section"},{"location":"Hecke/class_fields/intro/","page":"Class Field Theory","title":"Class Field Theory","text":"*(a::Hecke.ClassField, b::Hecke.ClassField)\ncompositum(a::Hecke.ClassField, b::Hecke.ClassField)\n==(a::Hecke.ClassField, b::Hecke.ClassField)\nintersect(a::Hecke.ClassField, b::Hecke.ClassField)\nprime_decomposition_type(C::Hecke.ClassField, p::Hecke.NfAbsOrdIdl)\nHecke.is_subfield(a::ClassField, b::ClassField)\nHecke.is_local_norm(r::Hecke.ClassField, a::Hecke.NfAbsOrdElem)\nHecke.is_local_norm(r::Hecke.ClassField, a::Hecke.NfAbsOrdElem, p::Hecke.NfAbsOrdIdl)\nHecke.normal_closure(r::Hecke.ClassField)\nsubfields(r::ClassField)","category":"page"},{"location":"Hecke/class_fields/intro/#*-Tuple{ClassField, ClassField}","page":"Class Field Theory","title":"*","text":"*(A::ClassField, B::ClassField) -> ClassField\n\nThe compositum of a and b as a (formal) class field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#compositum-Tuple{ClassField, ClassField}","page":"Class Field Theory","title":"compositum","text":"compositum(a::ClassField, b::ClassField) -> ClassField\n\nThe compositum of a and b as a (formal) class field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#==-Tuple{ClassField, ClassField}","page":"Class Field Theory","title":"==","text":"==(a::ClassField, b::ClassField)\n\nTests if a and b are equal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#intersect-Tuple{ClassField, ClassField}","page":"Class Field Theory","title":"intersect","text":"intersect(a::ClassField, b::ClassField) -> ClassField\n\nThe intersection of a and b as a class field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#prime_decomposition_type-Tuple{ClassField, NfAbsOrdIdl}","page":"Class Field Theory","title":"prime_decomposition_type","text":"prime_decomposition_type(C::ClassField, p::NfAbsOrdIdl) -> (Int, Int, Int)\n\nFor a prime p in the base ring of r, determine the splitting type of p in r. ie. the tuple (e f g) giving the ramification degree, the inertia and the number of primes above p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#is_subfield-Tuple{ClassField, ClassField}","page":"Class Field Theory","title":"is_subfield","text":"is_subfield(a::ClassField, b::ClassField) -> Bool\n\nDetermines if a is a subfield of b.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#is_local_norm-Tuple{ClassField, NfAbsOrdElem}","page":"Class Field Theory","title":"is_local_norm","text":"is_local_norm(r::ClassField, a::NfAbsOrdElem) -> Bool\n\nTests if a is a local norm at all finite places in the extension implicitly given by r.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#is_local_norm-Tuple{ClassField, NfAbsOrdElem, NfAbsOrdIdl}","page":"Class Field Theory","title":"is_local_norm","text":"is_local_norm(r::ClassField, a::NfAbsOrdElem, p::NfAbsOrdIdl) -> Bool\n\nTests if a is a local norm at p in the extension implicitly given by r. Currently the conductor cannot have infinite places.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#normal_closure-Tuple{ClassField}","page":"Class Field Theory","title":"normal_closure","text":"normal_closure(C::ClassField) -> ClassField\n\nFor a ray class field C extending a normal base field k, compute the normal closure over Q.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/class_fields/intro/#subfields-Tuple{ClassField}","page":"Class Field Theory","title":"subfields","text":"subfields(C::ClassField; degree::Int) -> Vector{ClassField}\n\nFind all subfields of C over the base field.\n\nIf the optional keyword argument degree is positive, then only those with prescribed degree will be returned.\n\nnote: Note\nThis will not find all subfields over mathbfQ, but only the ones sharing the same base field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#PMatLink","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"This chapter deals with pseudo-matrices. We follow the common terminology and conventions introduced in Henri Cohen (2000), however, we operate on rows, not on columns.","category":"page"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"Let R be a Dedekind domain, typically, the maximal order of some number field K, further fix some finite dimensional K-vectorspace V (with some basis), frequently K^n or the K-structure of some extension of K. Since in general R is not a PID, the R-modules in V are usually not free, but still projective.","category":"page"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"Any finitely generated R-module Msubset V can be represented as a pseudo-matrix PMat as follows: The structure theory of R-modules gives the existence of (fractional) R-ideals mathfrak A_i and elements omega_iin V such that M = sum mathfrak A_i omega_i and the sum is direct.","category":"page"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"Following Cohen we call modules of the form mathfrak Aomega for some ideal mathfrak A and omega in V a pseudo element. A system (mathfrak A_i omega_i) is called a pseudo-generating system for M if langle mathfrak A_iomega_iilangle = M. A pseudo-generating system is called a pseudo-basis if the omega_i are K-linear independent.","category":"page"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"A pseudo-matrix X is a tuple containing a vector of ideals mathfrak A_i (1le ile r) and a matrix Uin K^rtimes n. The i-th row together with the i-th ideal defines a pseudo-element, thus an R-module, all of them together generate a module M.","category":"page"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"A pseudo-matrix X=((mathfrak A_i)_i U) is said to be in pseudo-hnf if U is essentially upper triangular. Similar to the classical hnf, there is an algorithm that transforms any pseudo-matrix into one in pseudo-hnf while maintaining the module.","category":"page"},{"location":"Hecke/pmat/introduction/#Creation","page":"Introduction","title":"Creation","text":"","category":"section"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"In general to create a PMat one has to specify a matrix and a vector of ideals:","category":"page"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"pseudo_matrix(m::AbstractAlgebra.MatElem{nf_elem}, c::Vector{NfOrdIdl})\npseudo_matrix(m::Generic.Mat{NfOrdElem}, c::Vector{NfOrdIdl})\npseudo_matrix(m::Generic.Mat{nf_elem})","category":"page"},{"location":"Hecke/pmat/introduction/#pseudo_matrix-Tuple{MatElem{nf_elem}, Vector{NfOrdIdl}}","page":"Introduction","title":"pseudo_matrix","text":"pseudo_matrix(m::Generic.Mat{nf_elem}, c::Vector{NfOrdIdl}) -> PMat{nf_elem, NfOrdFracIdl}\n\nReturns the (row) pseudo matrix representing the Z_k-module sum c_i m_i where c_i are the ideals in c and m_i the rows of M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#pseudo_matrix-Tuple{AbstractAlgebra.Generic.Mat{NfOrdElem}, Vector{NfOrdIdl}}","page":"Introduction","title":"pseudo_matrix","text":"pseudo_matrix(m::Generic.Mat{NfOrdElem}, c::Vector{NfOrdIdl}) -> PMat{nf_elem, NfOrdFracIdl}\n\nReturns the (row) pseudo matrix representing the Z_k-module sum c_i m_i where c_i are the ideals in c and m_i the rows of M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#pseudo_matrix-Tuple{AbstractAlgebra.Generic.Mat{nf_elem}}","page":"Introduction","title":"pseudo_matrix","text":"pseudo_matrix(m::Generic.Mat{NfOrdElem}) -> PMat{nf_elem, NfOrdFracIdl}\n\nReturns the free (row) pseudo matrix representing the Z_k-module sum Z_k m_i where m_i are the rows of M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"(Those functions are also available as pseudo_matrix)","category":"page"},{"location":"Hecke/pmat/introduction/#Operations","page":"Introduction","title":"Operations","text":"","category":"section"},{"location":"Hecke/pmat/introduction/","page":"Introduction","title":"Introduction","text":"coefficient_ideals(M::PMat)\nmatrix(M::PMat)\nbase_ring(M::PMat)\npseudo_hnf(P::PMat{nf_elem, NfOrdFracIdl})\npseudo_hnf_with_transform(P::PMat{nf_elem, NfOrdFracIdl})","category":"page"},{"location":"Hecke/pmat/introduction/#coefficient_ideals-Tuple{Hecke.PMat}","page":"Introduction","title":"coefficient_ideals","text":"coefficient_ideals(M::PMat)\n\nReturns the vector of coefficient ideals.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#matrix-Tuple{Hecke.PMat}","page":"Introduction","title":"matrix","text":"matrix(M::PMat)\n\nReturns the matrix part of the PMat.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#base_ring-Tuple{Hecke.PMat}","page":"Introduction","title":"base_ring","text":"base_ring(I::MPolyIdeal)\n\nReturn the ambient ring of I.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> base_ring(I)\nMultivariate polynomial ring in 2 variables x, y\n over rational field\n\n\n\n\n\nbase_ring(X::AbsSpec)\n\nOn an affine scheme X𝕜 over 𝕜 this returns the ring 𝕜.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> base_ring(X)\nRational field\n\n\n\n\n\nbase_ring(M::PMat)\n\nThe PMat M defines an R-module for some maximal order R. This function returns the R that was used to defined M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#pseudo_hnf-Tuple{Hecke.PMat{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}}","page":"Introduction","title":"pseudo_hnf","text":"pseudo_hnf(P::PMat)\n\nTransforms P into pseudo-Hermite form as defined by Cohen. Essentially the matrix part of P will be upper triangular with some technical normalisation for the off-diagonal elements. This operation preserves the module.\n\nA optional second argument can be specified as a symbols, indicating the desired shape of the echelon form. Possible are :upperright (the default) and :lowerleft\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#pseudo_hnf_with_transform-Tuple{Hecke.PMat{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}}","page":"Introduction","title":"pseudo_hnf_with_transform","text":"pseudo_hnf_with_transform(P::PMat)\n\nTransforms P into pseudo-Hermite form as defined by Cohen. Essentially the matrix part of P will be upper triangular with some technical normalisation for the off-diagonal elements. This operation preserves the module. The used transformation is returned as a second return value.\n\nA optional second argument can be specified as a symbol, indicating the desired shape of the echelon form. Possible are :upperright (the default) and :lowerleft\n\n\n\n\n\n","category":"method"},{"location":"Hecke/pmat/introduction/#Examples","page":"Introduction","title":"Examples","text":"","category":"section"},{"location":"Nemo/constructors/#Constructing-mathematical-objects-in-Nemo","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"","category":"section"},{"location":"Nemo/constructors/#Constructing-objects-in-Julia","page":"Constructing mathematical objects in Nemo","title":"Constructing objects in Julia","text":"","category":"section"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"In Julia, one constructs objects of a given type by calling a type constructor. This is simply a function with the same name as the type itself. For example, to construct a BigInt object in Julia, we simply call the BigInt constructor:","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"n = BigInt(\"1234567898765434567898765434567876543456787654567890\")","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"Julia also uses constructors to convert between types. For example, to convert an Int to a BigInt:","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"m = BigInt(123)","category":"page"},{"location":"Nemo/constructors/#How-we-construct-objects-in-Nemo","page":"Constructing mathematical objects in Nemo","title":"How we construct objects in Nemo","text":"","category":"section"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"Julia types don't contain enough information to properly model groups, rings and fields, especially if they are parameterised by values. For example, the ring of integers modulo n for a multiprecision modulus n cannot be modeled using types alone.","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"Instead of using types to construct objects in Nemo, we use special objects that we refer to as parent objects. They behave a lot like Julia types.","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"Consider the following simple example, to create a Flint multiprecision integer:","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"n = ZZ(\"12345678765456787654567890987654567898765678909876567890\")","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"Here ZZ is not a Julia type, but a callable object. However, for most purposes one can think of such a parent object ZZ as though it were a type.","category":"page"},{"location":"Nemo/constructors/#Constructing-parent-objects","page":"Constructing mathematical objects in Nemo","title":"Constructing parent objects","text":"","category":"section"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"For more complicated groups, rings, fields, etc., one first needs to construct the parent object before one can use it to construct element objects.","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"Nemo provides a set of functions for constructing such parent objects. For example, to create a parent object for polynomials over the integers, we use the polynomial_ring parent object constructor.","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"R, x = polynomial_ring(ZZ, \"x\")\nf = x^3 + 3x + 1\ng = R(12)","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"In this example, R is the parent object and we use it to convert the Int value 12 to an element of the polynomial ring mathbbZx.","category":"page"},{"location":"Nemo/constructors/#List-of-parent-object-constructors","page":"Constructing mathematical objects in Nemo","title":"List of parent object constructors","text":"","category":"section"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"For convenience, we provide a list of all the parent object constructors in Nemo and explain what domains they represent.","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"Mathematics Nemo constructor\nR = mathbbZ R = ZZ\nR = mathbbQ R = QQ\nR = mathbbF_p^n R, a = FiniteField(p, n, \"a\")\nR = mathbbZnmathbbZ R = residue_ring(ZZ, n)\nS = Rx S, x = polynomial_ring(R, \"x\")\nS = Rx y S, (x, y) = polynomial_ring(R, [\"x\", \"y\"])\nS = Rx (to precision n) S, x = power_series_ring(R, n, \"x\")\nS = R((x)) (to precision n) S, x = laurent_series_ring(R, n, \"x\")\nS = mathrmFrac_R S = fraction_field(R)\nS = R(f) S = residue_ring(R, f)\nS = mathrmMat_mtimes n(R) S = matrix_space(R, m, n)\nS = mathbbQx(f) S, a = number_field(f, \"a\")\nS = mathbbQ_p (to precision N) S = PadicField(p, n)\nS = mathbbR (to precision n) S = RealField(n)\nS = mathbbC (to precision n) S = ComplexField(n)","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Ideals-and-Lie-subalgebras","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"Ideals and Lie subalgebras are represented by the types LieAlgebraIdeal and LieSubalgebra respectively. They are used similarly in most cases.","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Functions","page":"Ideals and Lie subalgebras","title":"Functions","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Ideals","page":"Ideals and Lie subalgebras","title":"Ideals","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"dim(::LieAlgebraIdeal)\nbasis(::LieAlgebraIdeal)\nbasis(::LieAlgebraIdeal, ::Int)\nBase.in(::LieAlgebraElem, ::LieAlgebraIdeal)\nbracket(::LieAlgebraIdeal{C,LieT}, ::LieAlgebraIdeal{C,LieT}) where {C<:RingElement,LieT<:LieAlgebraElem{C}}\nnormalizer(::LieAlgebra, ::LieAlgebraIdeal)\ncentralizer(::LieAlgebra, ::LieAlgebraIdeal)","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#dim-Tuple{LieAlgebraIdeal}","page":"Ideals and Lie subalgebras","title":"dim","text":"dim(I::LieAlgebraIdeal) -> Int\n\nReturn the dimension of the ideal I.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#basis-Tuple{LieAlgebraIdeal}","page":"Ideals and Lie subalgebras","title":"basis","text":"basis(I::LieAlgebraIdeal) -> Vector{LieAlgebraElem}\n\nReturn the basis of the ideal I.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#basis-Tuple{LieAlgebraIdeal, Int64}","page":"Ideals and Lie subalgebras","title":"basis","text":"basis(I::LieAlgebraIdeal, i::Int) -> LieAlgebraElem\n\nReturn the i-th basis element of the ideal I.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#in-Tuple{LieAlgebraElem, LieAlgebraIdeal}","page":"Ideals and Lie subalgebras","title":"in","text":"in(x::LieAlgebraElem, I::LieAlgebraIdeal) -> Bool\n\nReturn true if x is in the ideal I, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#bracket-Union{Tuple{LieT}, Tuple{C}, Tuple{LieAlgebraIdeal{C, LieT}, LieAlgebraIdeal{C, LieT}}} where {C<:RingElement, LieT<:LieAlgebraElem{C}}","page":"Ideals and Lie subalgebras","title":"bracket","text":"bracket(I1::LieAlgebraIdeal, I2::LieAlgebraIdeal) -> LieAlgebraIdeal\n\nReturn I_1I_2.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#normalizer-Tuple{LieAlgebra, LieAlgebraIdeal}","page":"Ideals and Lie subalgebras","title":"normalizer","text":"normalizer(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra\n\nReturn the normalizer of I in L, i.e. x in L mid x I subseteq I = L. As I is an ideal in L, this is just L.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#centralizer-Tuple{LieAlgebra, LieAlgebraIdeal}","page":"Ideals and Lie subalgebras","title":"centralizer","text":"centralizer(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra\n\nReturn the centralizer of I in L, i.e. x in L mid x I = 0.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Lie-subalgebras","page":"Ideals and Lie subalgebras","title":"Lie subalgebras","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"dim(::LieSubalgebra)\nbasis(::LieSubalgebra)\nbasis(::LieSubalgebra, ::Int)\nBase.in(::LieAlgebraElem, ::LieSubalgebra)\nbracket(::LieSubalgebra{C,LieT}, ::LieSubalgebra{C,LieT}) where {C<:RingElement,LieT<:LieAlgebraElem{C}}\nnormalizer(::LieAlgebra, ::LieSubalgebra)\ncentralizer(::LieAlgebra, ::LieSubalgebra)\nis_self_normalizing(S::LieSubalgebra)","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#dim-Tuple{LieSubalgebra}","page":"Ideals and Lie subalgebras","title":"dim","text":"dim(S::LieSubalgebra) -> Int\n\nReturn the dimension of the Lie subalgebra S.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#basis-Tuple{LieSubalgebra}","page":"Ideals and Lie subalgebras","title":"basis","text":"basis(S::LieSubalgebra{C}) -> Vector{LieAlgebraElem{C}}\n\nReturn a basis of the Lie subalgebra S.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#basis-Tuple{LieSubalgebra, Int64}","page":"Ideals and Lie subalgebras","title":"basis","text":"basis(S::LieSubalgebra{C}, i::Int) -> LieAlgebraElem{C}\n\nReturn the i-th basis element of the Lie subalgebra S.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#in-Tuple{LieAlgebraElem, LieSubalgebra}","page":"Ideals and Lie subalgebras","title":"in","text":"in(x::LieAlgebraElem, S::LieSubalgebra) -> Bool\n\nReturn true if x is in the Lie subalgebra S, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#bracket-Union{Tuple{LieT}, Tuple{C}, Tuple{LieSubalgebra{C, LieT}, LieSubalgebra{C, LieT}}} where {C<:RingElement, LieT<:LieAlgebraElem{C}}","page":"Ideals and Lie subalgebras","title":"bracket","text":"bracket(S1::LieSubalgebra, S2::LieSubalgebra) -> LieAlgebraIdeal\n\nReturn S_1 S_2.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#normalizer-Tuple{LieAlgebra, LieSubalgebra}","page":"Ideals and Lie subalgebras","title":"normalizer","text":"normalizer(L::LieAlgebra, S::LieSubalgebra) -> LieSubalgebra\n\nReturn the normalizer of S in L, i.e. x in L mid x S subseteq S.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#centralizer-Tuple{LieAlgebra, LieSubalgebra}","page":"Ideals and Lie subalgebras","title":"centralizer","text":"centralizer(L::LieAlgebra, S::LieSubalgebra) -> LieSubalgebra\n\nReturn the centralizer of S in L, i.e. x in L mid x S = 0.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#is_self_normalizing-Tuple{LieSubalgebra}","page":"Ideals and Lie subalgebras","title":"is_self_normalizing","text":"is_self_normalizing(S::LieSubalgebra) -> Bool\n\nReturn true if S is self-normalizing, i.e. if its normalizer is S.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Constructors","page":"Ideals and Lie subalgebras","title":"Constructors","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Ideals-2","page":"Ideals and Lie subalgebras","title":"Ideals","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"ideal(::LieAlgebra, ::Vector; is_basis::Bool=false)\nideal(::LieAlgebra{C}, ::LieAlgebraElem{C}) where {C<:RingElement}\nideal(::LieAlgebra)","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#ideal-Tuple{LieAlgebra, Vector}","page":"Ideals and Lie subalgebras","title":"ideal","text":"ideal(L::LieAlgebra, gens::Vector{LieAlgebraElem}; is_basis::Bool=false) -> LieAlgebraIdeal\n\nReturn the smallest ideal of L containing gens. If is_basis is true, then gens is assumed to be a basis of the ideal.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#ideal-Union{Tuple{C}, Tuple{LieAlgebra{C}, LieAlgebraElem{C}}} where C<:RingElement","page":"Ideals and Lie subalgebras","title":"ideal","text":"ideal(L::LieAlgebra, gen::LieAlgebraElem) -> LieAlgebraIdeal\n\nReturn the smallest ideal of L containing gen.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#ideal-Tuple{LieAlgebra}","page":"Ideals and Lie subalgebras","title":"ideal","text":"ideal(L::LieAlgebra) -> LieAlgebraIdeal\n\nReturn L as an ideal of itself.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Lie-subalgebras-2","page":"Ideals and Lie subalgebras","title":"Lie subalgebras","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"sub(::LieAlgebra, ::Vector; is_basis::Bool=false)\nsub(::LieAlgebra{C}, ::LieAlgebraElem{C}) where {C<:RingElement}\nsub(::LieAlgebra)","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#sub-Tuple{LieAlgebra, Vector}","page":"Ideals and Lie subalgebras","title":"sub","text":"sub(L::LieAlgebra, gens::Vector{LieAlgebraElem}; is_basis::Bool=false) -> LieSubalgebra\n\nReturn the smallest Lie subalgebra of L containing gens. If is_basis is true, then gens is assumed to be a basis of the subalgebra.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#sub-Union{Tuple{C}, Tuple{LieAlgebra{C}, LieAlgebraElem{C}}} where C<:RingElement","page":"Ideals and Lie subalgebras","title":"sub","text":"sub(L::LieAlgebra, gen::LieAlgebraElem) -> LieSubalgebra\n\nReturn the smallest Lie subalgebra of L containing gen.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#sub-Tuple{LieAlgebra}","page":"Ideals and Lie subalgebras","title":"sub","text":"sub(L::LieAlgebra) -> LieSubalgebra\n\nReturn L as a Lie subalgebra of itself.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#Conversions","page":"Ideals and Lie subalgebras","title":"Conversions","text":"","category":"section"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"lie_algebra(::LieSubalgebra)\nlie_algebra(::LieAlgebraIdeal)\nsub(::LieAlgebra{C}, ::LieAlgebraIdeal{C}) where {C<:RingElement}","category":"page"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#lie_algebra-Tuple{LieSubalgebra}","page":"Ideals and Lie subalgebras","title":"lie_algebra","text":"lie_algebra(S::LieSubalgebra) -> LieAlgebra\n\nReturn S as a Lie algebra.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#lie_algebra-Tuple{LieAlgebraIdeal}","page":"Ideals and Lie subalgebras","title":"lie_algebra","text":"lie_algebra(I::LieAlgebraIdeal) -> LieAlgebra\n\nReturn I as a Lie algebra.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#sub-Union{Tuple{C}, Tuple{LieAlgebra{C}, LieAlgebraIdeal{C, LieT} where LieT<:LieAlgebraElem{C}}} where C<:RingElement","page":"Ideals and Lie subalgebras","title":"sub","text":"sub(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra\n\nReturn I as a subalgebra of L.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/intro/#Content","page":"Introduction","title":"Content","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/intro/","page":"Introduction","title":"Introduction","text":"The schemes part of OSCAR comprises algorithms addressing affine schemes. More functionality (e.g. for general covered schemes and toric schemes) exists in experimental state.","category":"page"},{"location":"AlgebraicGeometry/Schemes/intro/#Status","page":"Introduction","title":"Status","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/intro/","page":"Introduction","title":"Introduction","text":"This project is work-in-progress.","category":"page"},{"location":"AlgebraicGeometry/Schemes/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/Schemes/intro/","page":"Introduction","title":"Introduction","text":"Simon Brandhorst.\nAnne Frühbis-Krüger,\nMatthias Zach,","category":"page"},{"location":"AlgebraicGeometry/Schemes/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/Schemes/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"CurrentModule = Oscar","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/#Polyhedral-Complexes","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"","category":"section"},{"location":"PolyhedralGeometry/polyhedral_complexes/#Introduction","page":"Polyhedral Complexes","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/polyhedral_complexes/","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"Let mathbbF be an ordered field; the default is that mathbbF=mathbbQ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"A nonempty finite collection mathcalP of polyhedra in mathbbF^n, for n fixed, is a polyhedral complex if","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"the set mathcalF is closed with respect to taking faces and\nif CDinmathcalF then Ccap D is a face of both C and D.","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/#Construction","page":"Polyhedral Complexes","title":"Construction","text":"","category":"section"},{"location":"PolyhedralGeometry/polyhedral_complexes/","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"To construct a polyhedral complex, you must pass points of each polyhedron in the polyhedral complex, such that the polyhedron is the convex hull thereof, along with an IncidenceMatrix encoding which points generate which polyhedron.","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"polyhedral_complex","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/#polyhedral_complex","page":"Polyhedral Complexes","title":"polyhedral_complex","text":"polyhedral_complex(::T, polyhedra, vr, far_vertices, L) where T<:scalar_types\n\nArguments\n\nT: Type or parent Field of scalar to use, defaults to QQFieldElem.\npolyhedra::IncidenceMatrix: An incidence matrix; there is a 1 at position (i,j) if the ith polytope contains point j and 0 otherwise.\nvr::AbstractCollection[PointVector]: The points whose convex hulls make up the polyhedral complex. This matrix also contains the far vertices.\nfar_vertices::Vector{Int}: Vector containing the indices of the rows corresponding to the far vertices in vr.\nL::AbstractCollection[RayVector]: Generators of the lineality space of the polyhedral complex.\n\nA polyhedral complex formed from points, rays, and lineality combined into polyhedra indicated by an incidence matrix, where the columns represent the points and the rows represent the polyhedra.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])\n2×4 IncidenceMatrix\n[1, 2, 3]\n[1, 3, 4]\n\n\njulia> vr = [0 0; 1 0; 1 1; 0 1]\n4×2 Matrix{Int64}:\n 0 0\n 1 0\n 1 1\n 0 1\n\njulia> PC = polyhedral_complex(IM, vr)\nPolyhedral complex in ambient dimension 2\n\nPolyhedral complex with rays and lineality:\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> L = [0 0 1];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices, L)\nPolyhedral complex in ambient dimension 3\n\njulia> lineality_dim(PC)\n1\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/polyhedral_complexes/#Auxiliary-functions","page":"Polyhedral Complexes","title":"Auxiliary functions","text":"","category":"section"},{"location":"PolyhedralGeometry/polyhedral_complexes/","page":"Polyhedral Complexes","title":"Polyhedral Complexes","text":"ambient_dim(PC::PolyhedralComplex)\ncodim(PC::PolyhedralComplex)\ndim(PC::PolyhedralComplex)\nf_vector(PC::PolyhedralComplex)\nis_embedded(PC::PolyhedralComplex)\nmaximal_polyhedra(PC::PolyhedralComplex{T}) where T<:scalar_types\nminimal_faces(PC::PolyhedralComplex{T}) where T<:scalar_types\nn_maximal_polyhedra(PC::PolyhedralComplex)\nnpolyhedra(PC::PolyhedralComplex)\nnrays(PC::PolyhedralComplex)\nnvertices(PC::PolyhedralComplex)\npolyhedra_of_dim\nrays(PC::PolyhedralComplex{T}) where T<:scalar_types\nrays_modulo_lineality(PC::PolyhedralComplex{T}) where T<:scalar_types\nvertices(PC::PolyhedralComplex)","category":"page"},{"location":"PolyhedralGeometry/polyhedral_complexes/#ambient_dim-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"ambient_dim","text":"ambient_dim(PC::PolyhedralComplex)\n\nReturn the ambient dimension of PC.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])\n2×4 IncidenceMatrix\n[1, 2, 3]\n[1, 3, 4]\n\n\njulia> V = [0 0; 1 0; 1 1; 0 1]\n4×2 Matrix{Int64}:\n 0 0\n 1 0\n 1 1\n 0 1\n\njulia> PC = polyhedral_complex(IM, V)\nPolyhedral complex in ambient dimension 2\n\njulia> ambient_dim(PC)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#codim-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"codim","text":"codim(PC::PolyhedralComplex)\n\nCompute the codimension of a polyhedral complex.\n\nExamples\n\njulia> VR = [0 0; 1 0; -1 0; 0 1];\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices)\nA polyhedral complex in ambient dimension 2\n\njulia> codim(PC)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#dim-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"dim","text":"dim(PC::PolyhedralComplex)\n\nCompute the dimension of the polyhedral complex.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);\n\njulia> VR = [0 0; 1 0; 1 1; 0 1];\n\njulia> PC = polyhedral_complex(IM, VR)\nPolyhedral complex in ambient dimension 2\n\njulia> dim(PC)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#f_vector-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"f_vector","text":"f_vector(PC::PolyhedralComplex)\n\nCompute the vector (f₀f₁f₂f_dim(PC))` where f_i is the number of faces of PC of dimension i.\n\nExamples\n\njulia> VR = [0 0; 1 0; -1 0; 0 1];\n\njulia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices);\n\njulia> f_vector(PC)\n3-element Vector{Int64}:\n 1\n 3\n 2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#is_embedded-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"is_embedded","text":"is_embedded(PC::PolyhedralComplex)\n\nReturn true if PC is embedded, i.e. if its vertices can be computed as a subset of some mathbbR^n.\n\nExamples\n\njulia> VR = [0 0; 1 0; -1 0; 0 1];\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]]);\n\njulia> PC = polyhedral_complex(IM, VR)\nPolyhedral complex in ambient dimension 2\n\njulia> is_embedded(PC)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#maximal_polyhedra-Union{Tuple{PolyhedralComplex{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Complexes","title":"maximal_polyhedra","text":"maximal_polyhedra(PC::PolyhedralComplex)\n\nReturn the maximal polyhedra of PC\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])\n2×4 IncidenceMatrix\n[1, 2, 3]\n[1, 3, 4]\n\n\njulia> VR = [0 0; 1 0; 1 1; 0 1]\n4×2 Matrix{Int64}:\n 0 0\n 1 0\n 1 1\n 0 1\n\njulia> PC = polyhedral_complex(IM, VR, [2])\nPolyhedral complex in ambient dimension 2\n\njulia> maximal_polyhedra(PC)\n2-element SubObjectIterator{Polyhedron{QQFieldElem}}:\n Polyhedron in ambient dimension 2\n Polyhedron in ambient dimension 2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#minimal_faces-Union{Tuple{PolyhedralComplex{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Complexes","title":"minimal_faces","text":"minimal_faces(as, PC::PolyhedralComplex)\n\nReturn the minimal faces of a polyhedral complex as a NamedTuple with two iterators. For a polyhedral complex without lineality, the base_points are the vertices. If PC has lineality L, then every minimal face is an affine translation p+L, where p is only unique modulo L. The return type is a dict, the key :base_points gives an iterator over such p, and the key :lineality_basis lets one access a basis for the lineality space L of PC.\n\nExamples\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> L = [0 0 1];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices, L)\nPolyhedral complex in ambient dimension 3\n\njulia> MFPC = minimal_faces(PC)\n(base_points = PointVector{QQFieldElem}[[0, 0, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 0, 1]])\n\njulia> MFPC.base_points\n1-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0, 0]\n\njulia> MFPC.lineality_basis\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [0, 0, 1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#n_maximal_polyhedra-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"n_maximal_polyhedra","text":"n_maximal_polyhedra(PC::PolyhedralComplex)\n\nReturn the number of maximal polyhedra of PC\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]])\n2×4 IncidenceMatrix\n[1, 2, 3]\n[1, 3, 4]\n\n\njulia> VR = [0 0; 1 0; 1 1; 0 1]\n4×2 Matrix{Int64}:\n 0 0\n 1 0\n 1 1\n 0 1\n\njulia> PC = polyhedral_complex(IM, VR, [2])\nPolyhedral complex in ambient dimension 2\n\njulia> n_maximal_polyhedra(PC)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#npolyhedra-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"npolyhedra","text":"npolyhedra(PC::PolyhedralComplex)\n\nReturn the total number of polyhedra in the polyhedral complex PC.\n\nExamples\n\njulia> VR = [0 0; 1 0; -1 0; 0 1];\n\njulia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices);\n\njulia> npolyhedra(PC)\n6\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#nrays-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"nrays","text":"nrays(PC::PolyhedralComplex)\n\nReturn the number of rays of PC.\n\nExamples\n\njulia> VR = [0 0; 1 0; -1 0; 0 1];\n\njulia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices);\n\njulia> nrays(PC)\n3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#nvertices-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"nvertices","text":"nvertices(PC::PolyhedralComplex)\n\nReturn the number of vertices of PC.\n\nExamples\n\njulia> VR = [0 0; 1 0; -1 0; 0 1];\n\njulia> IM = IncidenceMatrix([[1,2,4],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices);\n\njulia> nvertices(PC)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#polyhedra_of_dim","page":"Polyhedral Complexes","title":"polyhedra_of_dim","text":"polyhedra_of_dim(PC::PolyhedralComplex, polyhedron_dim::Int)\n\nReturn the polyhedra of a given dimension in the polyhedral complex PC.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);\n\njulia> VR = [0 0; 1 0; 1 1; 0 1];\n\njulia> PC = polyhedral_complex(IM, VR);\n\njulia> P1s = polyhedra_of_dim(PC,1)\n5-element SubObjectIterator{Polyhedron{QQFieldElem}}:\n Polyhedron in ambient dimension 2\n Polyhedron in ambient dimension 2\n Polyhedron in ambient dimension 2\n Polyhedron in ambient dimension 2\n Polyhedron in ambient dimension 2\n\njulia> for p in P1s\n println(dim(p))\n end\n1\n1\n1\n1\n1\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/polyhedral_complexes/#rays-Union{Tuple{PolyhedralComplex{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Complexes","title":"rays","text":"rays(PC::PolyhedralComplex)\n\nReturn the rays of PC\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);\n\njulia> VR = [0 0; 1 0; 1 1; 0 1];\n\njulia> PC = polyhedral_complex(IM, VR, [2])\nPolyhedral complex in ambient dimension 2\n\njulia> rays(PC)\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n\njulia> matrix(QQ, rays(PC))\n[1 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#rays_modulo_lineality-Union{Tuple{PolyhedralComplex{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Complexes","title":"rays_modulo_lineality","text":"rays_modulo_lineality(as, PC::PolyhedralComplex)\n\nReturn the rays of the recession cone of PC up to lineality as a NamedTuple with two iterators. If PC has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of PC/L. The iterator lineality_basis gives a basis of the lineality space L.\n\nExamples\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\n\njulia> IM = IncidenceMatrix([[1,2,3],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> L = [0 0 1];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices, L)\nPolyhedral complex in ambient dimension 3\n\njulia> RML = rays_modulo_lineality(PC)\n(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0, 0], [0, 1, 0], [-1, 0, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 0, 1]])\n\njulia> RML.rays_modulo_lineality\n3-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0, 0]\n [0, 1, 0]\n [-1, 0, 0]\n\njulia> RML.lineality_basis\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [0, 0, 1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#vertices-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"vertices","text":"vertices(T::TropicalVariety{M, EMB})\nvertices(T::TropicalCurve{M, EMB})\nvertices(T::TropicalHypersurface{M, EMB})\nvertices(T::TropicalLinearSpace{M, EMB})\n\nReturn the vertices of T, which are points in euclidean space if T is embedded or elements in an ordered set otherwise.\n\nExamples\n\nThe vertices of a plane tropical line, plane tropical honeycomb quadric, and plane tropical honeycomb cubic\n\njulia> RR = TropicalSemiring(min);\n\njulia> S,(x,y) = RR[\"x\",\"y\"];\n\njulia> f1 = x+y+1;\n\njulia> tropicalLine = TropicalHypersurface(f1);\n\njulia> vertices(tropicalLine)\n1-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 1]\n\njulia> f2 = 1*x^2+x*y+1*y^2+x+y+1;\n\njulia> tropicalQuadric = TropicalHypersurface(f1);\n\njulia> vertices(tropicalQuadric)\n1-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 1]\n\njulia> f3 = x^3+x*y^2+x^2*y+y^3+x^2+x*y+y^2+x+y+1;\n\njulia> tropicalCubic = TropicalHypersurface(f3);\n\njulia> vertices(tropicalCubic)\n2-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [1, 1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Affine-Algebras-and-Their-Ideals","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"With regard to notation, we use affine algebra as a synonym for quotient of a multivariate polynomial ring by an ideal. More specifically, if R is a multivariate polynomial ring with coefficient ring C, and A=RI is the quotient of R by an ideal I of R, we refer to A as an affine algebra over C, or an affine C-algebra. In this section, we discuss functionality for handling such algebras in OSCAR.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"note: Note\nTo emphasize this point: In this section, we view RI together with its ring structure. Realizing RI as an R-module means to implement it as the quotient of a free R-module of rank 1. See the section on modules.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"note: Note\nMost functions discussed here rely on Gröbner basis techniques. In particular, they typically make use of a Gröbner basis for the modulus of the quotient. Nevertheless, the construction of quotients is lazy in the sense that the computation of such a Gröbner basis is delayed until the user performs an operation that indeed requires it (the Gröbner basis is then computed with respect to the default_ordering on the underlying polynomial ring; see the section on Gröbner/Standard Bases for default orderings in OSCAR). Once computed, the Gröbner basis is cached for later reuse.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"note: Note\nRecall that Gröbner basis methods are implemented for multivariate polynomial rings over fields (exact fields supported by OSCAR) and, where not indicated otherwise, for multivariate polynomial rings over the integers.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"note: Note\nIn OSCAR, elements of a quotient A = RI are not necessarily represented by polynomials which are reduced with regard to I. That is, if fin R is the internal polynomial representative of an element of A, then f may not be the normal form mod I with respect to the default ordering on R (see the section on Gröbner/Standard Bases for normal forms). Operations involving Gröbner basis computations may lead to (partial) reductions. The function simplify discussed in this section computes fully reduced representatives. ","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"note: Note\nEach grading on a multivariate polynomial ring R in OSCAR descends to a grading on the affine algebra A = R/I (recall that OSCAR ideals of graded polynomial rings are required to be homogeneous). Functionality for dealing with such gradings and our notation for describing this functionality descend accordingly. This applies, in particular, to the functions is_graded, is_standard_graded, is_z_graded, is_zm_graded, and is_positively_graded which will not be discussed again here. ","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Types","page":"Affine Algebras and Their Ideals","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"The OSCAR type for quotients of multivariate polynomial rings is of parametrized form MPolyQuoRing{T}, with elements of type MPolyQuoRingElem{T}. Here, T is the element type of the polynomial ring.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Constructors","page":"Affine Algebras and Their Ideals","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"quo(R::MPolyRing, I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#quo-Tuple{MPolyRing, MPolyIdeal}","page":"Affine Algebras and Their Ideals","title":"quo","text":"quo(R::MPolyRing, I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(R)) -> MPolyQuoRing, Map\n\nCreate the quotient ring R/I and return the new ring as well as the projection map R to R/I. Computations inside R/I are done w.r.t. ordering.\n\nquo(R::MPolyRing, V::Vector{MPolyRingElem}) -> MPolyQuoRing, Map\n\nAs above, where I is the ideal of R generated by the polynomials in V.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, p = quo(R, ideal(R, [x^2-y^3, x-y]));\n\njulia> A\nQuotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x^2 - y^3, x - y)\n\njulia> typeof(A)\nMPolyQuoRing{QQMPolyRingElem}\n\njulia> typeof(x)\nQQMPolyRingElem\n\njulia> p\nMap from\nMultivariate polynomial ring in 2 variables over QQ to A defined by a julia-function with inverse\n\njulia> p(x)\nx\n\njulia> typeof(p(x))\nMPolyQuoRingElem{QQMPolyRingElem}\n\njulia> S, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> B, _ = quo(S, ideal(S, [x^2*z-y^3, x-y]))\n(Quotient of multivariate polynomial ring by ideal with 2 generators, Map from\nS to B defined by a julia-function with inverse)\n\njulia> typeof(B)\nMPolyQuoRing{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Data-Associated-to-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Data Associated to Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Basic-Data","page":"Affine Algebras and Their Ideals","title":"Basic Data","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"If A=R/I is the quotient of a multivariate polynomial ring R modulo an ideal I of R, then","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"base_ring(A) refers to R,\nmodulus(A) to I,\ngens(A) to the generators of A,\nngens(A) to the number of these generators, and\ngen(A, i) as well as A[i] to the i-th such generator.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Examples","page":"Affine Algebras and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));\n\njulia> base_ring(A)\nMultivariate polynomial ring in 3 variables x, y, z\n over rational field\n\njulia> modulus(A)\nideal(-x^2 + y, -x^3 + z)\n\njulia> gens(A)\n3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x\n y\n z\n\njulia> ngens(A)\n3\n\njulia> gen(A, 2)\ny\n","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"grading_group(q::MPolyQuoRing{<:MPolyDecRingElem})","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#grading_group-Tuple{MPolyQuoRing{<:MPolyDecRingElem}}","page":"Affine Algebras and Their Ideals","title":"grading_group","text":"grading_group(A::MPolyQuoRing{<:MPolyDecRingElem})\n\nIf A is, say, G-graded, return G.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^2*z-y^3, x-y]));\n\njulia> grading_group(A)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"monomial_basis(A::MPolyQuoRing, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#monomial_basis-Tuple{MPolyQuoRing, GrpAbFinGenElem}","page":"Affine Algebras and Their Ideals","title":"monomial_basis","text":"monomial_basis(A::MPolyQuoRing, g::GrpAbFinGenElem)\n\nGiven an affine algebra A over a field which is graded by a free group of type GrpAbFinGen, and given an element g of that group, return a vector of monomials of R such that the residue classes of these monomials form a K-basis of the graded part of A of degree g.\n\nmonomial_basis(A::MPolyQuoRing, W::Vector{<:IntegerUnion})\n\nGiven a mathbb Z^m-graded affine algebra A over a field and a vector W of m integers, convert W into an element g of the grading group of A and proceed as above.\n\nmonomial_basis(A::MPolyQuoRing, d::IntegerUnion)\n\nGiven a mathbb Z-graded affine algebra A over a field and an integer d, convert d into an element g of the grading group of A and proceed as above.\n\nnote: Note\nIf the component of the given degree is not finite dimensional, an error message will be thrown.\n\nExamples\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [x^2])\nideal(x^2)\n\njulia> A, _ = quo(R, I)\n(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from\nR to A defined by a julia-function with inverse)\n\njulia> L = monomial_basis(A, 3)\n2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n y^3\n x*y^2\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"homogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#homogeneous_component-Tuple{MPolyQuoRing{<:MPolyDecRingElem}, GrpAbFinGenElem}","page":"Affine Algebras and Their Ideals","title":"homogeneous_component","text":"homogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::GrpAbFinGenElem)\n\nGiven a graded quotient A of a multivariate polynomial ring over a field, where the grading group is free of type GrpAbFinGen, and given an element g of that group, return the homogeneous component of A of degree g. Additionally, return the embedding of the component into A.\n\nhomogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::Vector{<:IntegerUnion})\n\nGiven a mathbb Z^m-graded quotient A of a multivariate polynomial ring over a field, and given a vector g of m integers, convert g into an element of the grading group of A, and return the homogeneous component of A whose degree is that element. Additionally, return the embedding of the component into A.\n\nhomogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::IntegerUnion)\n\nGiven a mathbb Z-graded quotient A of a multivariate polynomial ring over a field, and given an integer g, convert g into an element of the grading group of A, and return the homogeneous component of A whose degree is that element. Additionally, return the embedding of the component into A.\n\nnote: Note\nIf the component is not finite dimensional, an error message will be thrown.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[w, x, y, z])\n\njulia> L = homogeneous_component(R, 2);\n\njulia> HC = gens(L[1]);\n\njulia> EMB = L[2]\nMap from\nR_[2] of dim 10 to R defined by a julia-function with inverse\n\njulia> for i in 1:length(HC) println(EMB(HC[i])) end\nz^2\ny*z\ny^2\nx*z\nx*y\nx^2\nw*z\nw*y\nw*x\nw^2\n\njulia> PTC = ideal(R, [-x*z + y^2, -w*z + x*y, -w*y + x^2]);\n\njulia> A, _ = quo(R, PTC);\n\njulia> L = homogeneous_component(A, 2);\n\njulia> HC = gens(L[1]);\n\njulia> EMB = L[2]\nMap from\nQuotient space over:\nRational field with 7 generators and no relations to A defined by a julia-function with inverse\n\njulia> for i in 1:length(HC) println(EMB(HC[i])) end\nz^2\ny*z\nx*z\nw*z\nw*y\nw*x\nw^2\n\njulia> R, x, y = polynomial_ring(QQ, \"x\" => 1:2, \"y\" => 1:3);\n\njulia> G = abelian_group([0, 0])\nGrpAb: Z^2\n\njulia> g = gens(G)\n2-element Vector{GrpAbFinGenElem}:\n Element of G with components [1 0]\n Element of G with components [0 1]\n\njulia> W = [g[1], g[1], g[2], g[2], g[2]];\n\njulia> S, _ = grade(R, W);\n\njulia> L = homogeneous_component(S, [2,1]);\n\njulia> HC = gens(L[1]);\n\njulia> EMB = L[2]\nMap from\nhomogeneous component of Graded multivariate polynomial ring in 5 variables over QQ of degree Element of G with components [2 1]\n to S defined by a julia-function with inverse\n\njulia> for i in 1:length(HC) println(EMB(HC[i])) end\nx[2]^2*y[3]\nx[2]^2*y[2]\nx[2]^2*y[1]\nx[1]*x[2]*y[3]\nx[1]*x[2]*y[2]\nx[1]*x[2]*y[1]\nx[1]^2*y[3]\nx[1]^2*y[2]\nx[1]^2*y[1]\n\njulia> I = ideal(S, [x[1]*y[1]-x[2]*y[2]]);\n\njulia> A, = quo(S, I);\n\njulia> L = homogeneous_component(A, [2,1]);\n\njulia> HC = gens(L[1]);\n\njulia> EMB = L[2]\nMap from\nQuotient space over:\nRational field with 7 generators and no relations to A defined by a julia-function with inverse\n\njulia> for i in 1:length(HC) println(EMB(HC[i])) end\nx[2]^2*y[3]\nx[2]^2*y[2]\nx[2]^2*y[1]\nx[1]*x[2]*y[3]\nx[1]*x[2]*y[2]\nx[1]^2*y[3]\nx[1]^2*y[2]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Dimension","page":"Affine Algebras and Their Ideals","title":"Dimension","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"dim(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#dim-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"dim","text":"dim(A::MPolyQuoRing)\n\nReturn the Krull dimension of A.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));\n\njulia> dim(A)\n1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"vector_space_dimension(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#vector_space_dimension-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"vector_space_dimension","text":"vector_space_dimension(A::MPolyQuoRing)\n\nIf, say, A = R/I, where R is a multivariate polynomial ring over a field K, and I is a zero-dimensional ideal of R, return the dimension of A as a K-vector space.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^3+y^3+z^3-1, x^2+y^2+z^2-1, x+y+z-1]));\n\njulia> vector_space_dimension(A)\n6\n\njulia> I = modulus(A)\nideal(x^3 + y^3 + z^3 - 1, x^2 + y^2 + z^2 - 1, x + y + z - 1)\n\njulia> groebner_basis(I, ordering = lex(base_ring(I)))\nGröbner basis with elements\n1 -> z^3 - z^2\n2 -> y^2 + y*z - y + z^2 - z\n3 -> x + y + z - 1\nwith respect to the ordering\nlex([x, y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"monomial_basis(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#monomial_basis-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"monomial_basis","text":"monomial_basis(A::MPolyQuoRing)\n\nIf, say, A = R/I, where R is a multivariate polynomial ring over a field K, and I is a zero-dimensional ideal of R, return a vector of monomials of R such that the residue classes of these monomials form a basis of A as a K-vector space.\n\nExamples\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [x^2, y^3])\nideal(x^2, y^3)\n\njulia> A, _ = quo(R, I)\n(Quotient of multivariate polynomial ring by ideal with 2 generators, Map from\nR to A defined by a julia-function with inverse)\n\njulia> L = monomial_basis(A)\n6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x*y^2\n y^2\n x*y\n y\n x\n 1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Elements-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Elements of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Types-2","page":"Affine Algebras and Their Ideals","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"The OSCAR type for elements of quotients of multivariate polynomial rings is of parametrized form MPolyQuoRing{T}, where T is the element type of the polynomial ring.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Creating-Elements-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Creating Elements of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"Elements of an affine algebra A=R/I are created as images of elements of R under the projection map or by directly coercing elements of R into A.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Examples-2","page":"Affine Algebras and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, p = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));\n\njulia> f = p(x^3*y^2-y^3*x^2+x*y)\nx^3*y^2 - x^2*y^3 + x*y\n\njulia> typeof(f)\nMPolyQuoRingElem{QQMPolyRingElem}\n\njulia> g = A(x^3*y^2-y^3*x^2+x*y)\nx^3*y^2 - x^2*y^3 + x*y\n\njulia> f == g\ntrue\n","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Reducing-Polynomial-Representatives","page":"Affine Algebras and Their Ideals","title":"Reducing Polynomial Representatives","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"simplify(f::MPolyQuoRingElem{T}) where {S<:Union{FieldElem, ZZRingElem}, T<:MPolyRingElem{S}}","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#simplify-Union{Tuple{MPolyQuoRingElem{T}}, Tuple{T}, Tuple{S}} where {S<:Union{FieldElem, ZZRingElem}, T<:MPolyRingElem{S}}","page":"Affine Algebras and Their Ideals","title":"simplify","text":"simplify(f::MPolyQuoRingElem{T}) where {S<:Union{FieldElem, ZZRingElem}, T<:MPolyRingElem{S}}\n\nIf f is an element of the quotient of a multivariate polynomial ring R by an ideal I of R, say, replace the internal polynomial representative of f by its normal form mod I with respect to the default_ordering on R.\n\nnote: Note\n\n\nSince this method only has a computational backend for quotients of polynomial rings over a field, it is not implemented generically.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> A, p = quo(R, ideal(R, [x^4]));\n\njulia> f = p(2*x^6 + x^3 + x)\n2*x^6 + x^3 + x\n\njulia> simplify(f)\nx^3 + x\n\njulia> f\nx^3 + x\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Tests-on-Elements-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Tests on Elements of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"==(f::MPolyQuoRingElem{T}, g::MPolyQuoRingElem{T}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#==-Union{Tuple{T}, Tuple{MPolyQuoRingElem{T}, MPolyQuoRingElem{T}}} where T","page":"Affine Algebras and Their Ideals","title":"==","text":"==(f::MPolyQuoRingElem{T}, g::MPolyQuoRingElem{T}) where T\n\nReturn true if f is equal to g, false otherwise.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> A, p = quo(R, ideal(R, [x^4]));\n\njulia> f = p(x-x^6)\n-x^6 + x\n\njulia> g = p(x)\nx\n\njulia> f == g\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_homogeneous(f::MPolyQuoRingElem{<:MPolyDecRingElem})","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_homogeneous-Tuple{MPolyQuoRingElem{<:MPolyDecRingElem}}","page":"Affine Algebras and Their Ideals","title":"is_homogeneous","text":"is_homogeneous(f::MPolyQuoRingElem{<:MPolyDecRingElem})\n\nGiven an element f of a graded affine algebra, return true if f is homogeneous, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));\n\njulia> f = p(y^2-x^2+z^4)\n-x^2 + y^2 + z^4\n\njulia> is_homogeneous(f)\ntrue\n\njulia> f\nz^4\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Data-associated-to-Elements-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Data associated to Elements of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"Given an element f of an affine algebra A, ","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"parent(f) refers to A.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"In the graded case, we also have:","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":" homogeneous_components(f::MPolyQuoRingElem{<:MPolyDecRingElem})","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#homogeneous_components-Tuple{MPolyQuoRingElem{<:MPolyDecRingElem}}","page":"Affine Algebras and Their Ideals","title":"homogeneous_components","text":"homogeneous_components(f::MPolyQuoRingElem{<:MPolyDecRingElem})\n\nGiven an element f of a graded affine algebra, return the homogeneous components of f.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));\n\njulia> f = p(y^2-x^2+x*y*z+z^4)\n-x^2 + x*y*z + y^2 + z^4\n\njulia> homogeneous_components(f)\nDict{GrpAbFinGenElem, MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}} with 2 entries:\n [4] => z^4\n [3] => y^2*z\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"homogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#homogeneous_component-Tuple{MPolyQuoRingElem{<:MPolyDecRingElem}, GrpAbFinGenElem}","page":"Affine Algebras and Their Ideals","title":"homogeneous_component","text":"homogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::GrpAbFinGenElem)\n\nGiven an element f of a graded affine algebra, and given an element g of the grading group of that algebra, return the homogeneous component of f of degree g.\n\nhomogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::Vector{<:IntegerUnion})\n\nGiven an element f of a mathbb Z^m-graded affine algebra A, say, and given a vector g of m integers, convert g into an element of the grading group of A, and return the homogeneous component of f whose degree is that element.\n\nhomogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::IntegerUnion)\n\nGiven an element f of a mathbb Z-graded affine algebra A, say, and given an integer g, convert g into an element of the grading group of A, and return the homogeneous component of f whose degree is that element.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));\n\njulia> f = p(y^2-x^2+x*y*z+z^4)\n-x^2 + x*y*z + y^2 + z^4\n\njulia> homogeneous_component(f, 4)\nz^4\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"degree(f::MPolyQuoRingElem{<:MPolyDecRingElem})","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#degree-Tuple{MPolyQuoRingElem{<:MPolyDecRingElem}}","page":"Affine Algebras and Their Ideals","title":"degree","text":"degree(f::MPolyQuoRingElem{<:MPolyDecRingElem})\n\nGiven a homogeneous element f of a graded affine algebra, return the degree of f.\n\ndegree(::Type{Vector{Int}}, f::MPolyQuoRingElem{<:MPolyDecRingElem})\n\nGiven a homogeneous element f of a mathbb Z^m-graded affine algebra, return the degree of f, converted to a vector of integer numbers.\n\ndegree(::Type{Int}, f::MPolyQuoRingElem{<:MPolyDecRingElem})\n\nGiven a homogeneous element f of a mathbb Z-graded affine algebra, return the degree of f, converted to an integer number.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"] );\n\njulia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]))\n(Quotient of multivariate polynomial ring by ideal with 2 generators, Map from\nR to A defined by a julia-function with inverse)\n\njulia> f = p(y^2-x^2+z^4)\n-x^2 + y^2 + z^4\n\njulia> degree(f)\n[4]\n\njulia> typeof(degree(f))\nGrpAbFinGenElem\n\njulia> degree(Int, f)\n4\n\njulia> typeof(degree(Int, f))\nInt64\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Ideals-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Ideals in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Constructors-2","page":"Affine Algebras and Their Ideals","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"ideal(Q::MPolyQuoRing{T}, V::Vector{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#ideal-Union{Tuple{T}, Tuple{MPolyQuoRing{T}, Vector{T}}} where T<:MPolyRingElem","page":"Affine Algebras and Their Ideals","title":"ideal","text":"ideal(A::MPolyQuoRing{T}, V::Vector{T}) where T <: MPolyRingElem\n\nGiven a (graded) quotient ring A=R/I and a vector V of (homogeneous) polynomials in R, create the ideal of A which is generated by the images of the entries of V.\n\nideal(A::MPolyQuoRing{T}, V::Vector{MPolyQuoRingElem{T}}) where T <: MPolyRingElem\n\nGiven a (graded) quotient ring A and a vector V of (homogeneous) elements of A, create the ideal of A which is generated by the entries of V.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));\n\njulia> I = ideal(A, [x^2-y])\nideal(x^2 - y)\n\njulia> S, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> B, _ = quo(S, ideal(S, [x^2*z-y^3, x-y]));\n\njulia> J = ideal(B, [x^2-y^2])\nideal(x^2 - y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Reducing-Polynomial-Representatives-of-Generators","page":"Affine Algebras and Their Ideals","title":"Reducing Polynomial Representatives of Generators","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"simplify(a::MPolyQuoIdeal)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#simplify-Tuple{MPolyQuoIdeal}","page":"Affine Algebras and Their Ideals","title":"simplify","text":"simplify(a::MPolyQuoIdeal)\n\nIf a is an ideal of the quotient of a multivariate polynomial ring R by an ideal I of R, say, replace the internal polynomial representative of each generator of a by its normal form mod I with respect to the default_ordering on R.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));\n\njulia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])\nideal(x^3*y^4 - x + y, x*y^2 + x*y)\n\njulia> gens(a)\n2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x^3*y^4 - x + y\n x*y^2 + x*y\n\njulia> simplify(a)\nideal(x^2*y^3 - x + y, x*y^2 + x*y)\n\njulia> gens(a)\n2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x^2*y^3 - x + y\n x*y^2 + x*y\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Data-Associated-to-Ideals-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Data Associated to Ideals in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Basic-Data-2","page":"Affine Algebras and Their Ideals","title":"Basic Data","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"If a is an ideal of the affine algebra A, then","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"base_ring(a) refers to A,\ngens(a) to the generators of a,\nngens(a) to the number of these generators, and\ngen(a, i) as well as a[i] to the i-th such generator.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Examples-3","page":"Affine Algebras and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));\n\njulia> a = ideal(A, [x-y, z^4])\nideal(x - y, z^4)\n\njulia> base_ring(a)\nQuotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(-x^2 + y, -x^3 + z)\n\njulia> gens(a)\n2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x - y\n z^4\n\njulia> ngens(a)\n2\n\njulia> gen(a, 2)\nz^4\n","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Dimension-of-Ideals-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Dimension of Ideals in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"dim(a::MPolyQuoIdeal)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#dim-Tuple{MPolyQuoIdeal}","page":"Affine Algebras and Their Ideals","title":"dim","text":"dim(a::MPolyQuoIdeal)\n\nReturn the Krull dimension of a.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));\n\njulia> a = ideal(A, [x-y])\nideal(x - y)\n\njulia> dim(a)\n0\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Minimal-Sets-of-Generators","page":"Affine Algebras and Their Ideals","title":"Minimal Sets of Generators","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"In the graded case, we have:","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"minimal_generating_set(I::MPolyQuoIdeal{<:MPolyDecRingElem})","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#minimal_generating_set-Tuple{MPolyQuoIdeal{<:MPolyDecRingElem}}","page":"Affine Algebras and Their Ideals","title":"minimal_generating_set","text":"minimal_generating_set(I::MPolyQuoIdeal{<:MPolyDecRingElem})\n\nGiven a homogeneous ideal I of a graded affine algebra over a field, return an array containing a minimal set of generators of I. If I is the zero ideal an empty list is returned.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, p = quo(R, ideal(R, [x-y]));\n\njulia> V = [x, z^2, x^3+y^3, y^4, y*z^5];\n\njulia> a = ideal(A, V);\n\njulia> minimal_generating_set(a)\n2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y\n z^2\n\njulia> a = ideal(A, [x-y])\nideal(x - y)\n\njulia> minimal_generating_set(a)\nMPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}[]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Operations-on-Ideals-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Operations on Ideals in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Simple-Ideal-Operations-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Simple Ideal Operations in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Powers-of-Ideal","page":"Affine Algebras and Their Ideals","title":"Powers of Ideal","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":":^(a::MPolyQuoIdeal, m::Int)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#^-Tuple{MPolyQuoIdeal, Int64}","page":"Affine Algebras and Their Ideals","title":"^","text":":^(a::MPolyQuoIdeal, m::Int)\n\nReturn the m-th power of a.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, [x^2-y, y^2-x+y]);\n\njulia> a = ideal(A, [x+y])\nideal(x + y)\n\njulia> a^2\nideal(x^2 + 2*x*y + y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Sum-of-Ideals","page":"Affine Algebras and Their Ideals","title":"Sum of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":":+(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#+-Union{Tuple{T}, Tuple{MPolyQuoIdeal{T}, MPolyQuoIdeal{T}}} where T","page":"Affine Algebras and Their Ideals","title":"+","text":":+(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T\n\nReturn the sum of a and b.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, [x^2-y, y^2-x+y]);\n\njulia> a = ideal(A, [x+y])\nideal(x + y)\n\njulia> b = ideal(A, [x^2+y^2, x+y])\nideal(x^2 + y^2, x + y)\n\njulia> a+b\nideal(x + y, x^2 + y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Product-of-Ideals","page":"Affine Algebras and Their Ideals","title":"Product of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":":*(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#*-Union{Tuple{T}, Tuple{MPolyQuoIdeal{T}, MPolyQuoIdeal{T}}} where T","page":"Affine Algebras and Their Ideals","title":"*","text":":*(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T\n\nReturn the product of a and b.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, [x^2-y, y^2-x+y]);\n\njulia> a = ideal(A, [x+y])\nideal(x + y)\n\njulia> b = ideal(A, [x^2+y^2, x+y])\nideal(x^2 + y^2, x + y)\n\njulia> a*b\nideal(x^3 + x^2*y + x*y^2 + y^3, x^2 + 2*x*y + y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Intersection-of-Ideals","page":"Affine Algebras and Their Ideals","title":"Intersection of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"intersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T\nintersect(V::Vector{MPolyQuoIdeal{T}}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#intersect-Union{Tuple{T}, Tuple{MPolyQuoIdeal{T}, Vararg{MPolyQuoIdeal{T}}}} where T","page":"Affine Algebras and Their Ideals","title":"intersect","text":"intersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T\nintersect(V::Vector{MPolyQuoIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));\n\njulia> a = ideal(A, [y^2])\nideal(y^2)\n\njulia> b = ideal(A, [x])\nideal(x)\n\njulia> intersect(a,b)\nideal(x*y)\n\njulia> intersect([a,b])\nideal(x*y)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#intersect-Union{Tuple{Array{MPolyQuoIdeal{T}, 1}}, Tuple{T}} where T","page":"Affine Algebras and Their Ideals","title":"intersect","text":"intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T\nintersect(V::Vector{MPolyIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2;\n\njulia> J = ideal(R, [y^2-x^3+x]);\n\njulia> intersect(I, J)\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> intersect([I, J])\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\n\n\n\n\nintersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T\nintersect(V::Vector{MPolyQuoIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));\n\njulia> a = ideal(A, [y^2])\nideal(y^2)\n\njulia> b = ideal(A, [x])\nideal(x)\n\njulia> intersect(a,b)\nideal(x*y)\n\njulia> intersect([a,b])\nideal(x*y)\n\n\n\n\n\nintersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}\nintersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"]);\n\njulia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))\nleft_ideal(-x^3 + dy^2 + x)\n\n\n\n\n\nintersect(M::SubquoModule{T}, N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.\n\nAdditionally, return the inclusion maps M cap N to M and M cap N to N.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[y;]\n[y]\n\njulia> BN = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Subquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n, Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n)\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> AM = Rg[x;];\n\njulia> BM = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, AM, BM)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = Rg[y;];\n\njulia> BN = Rg[x^2; y^3; z^4];\n\njulia> N = SubquoModule(F, AN, BN)\nGraded subquotient of submodule of F generated by\n1 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> M\n-x*y*e[1] -> -x*y*e[1]\nx*z^4*e[1] -> x*z^4*e[1]\nHomogeneous module homomorphism, Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> N\n-x*y*e[1] -> x*y*e[1]\nx*z^4*e[1] -> 0\nHomogeneous module homomorphism)\n\n\n\n\n\n\nintersect(T1, T2)\n\nIntersect two tropical varieties.\n\nExamples\n\njulia> RR = TropicalSemiring(min)\nTropical semiring (min)\n\njulia> S,(x,y) = RR[\"x\",\"y\"]\n(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])\n\njulia> f1 = x+y+1\nx + y + (1)\n\njulia> f2 = x^2+y^2+RR(-6)\nx^2 + y^2 + (-6)\n\njulia> hyp1 = TropicalHypersurface(f1)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> hyp2 = TropicalHypersurface(f2)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> tv12 = intersect(hyp1, hyp2)\nmin tropical variety of dimension 1 embedded in 2-dimensional Euclidean space\n\n\n\n\n\nintersect(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl\n\nReturns a cap b.\n\n\n\n\n\nintersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl\n\nReturns a cap b.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Ideal-Quotients","page":"Affine Algebras and Their Ideals","title":"Ideal Quotients","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"quotient(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#quotient-Union{Tuple{T}, Tuple{MPolyQuoIdeal{T}, MPolyQuoIdeal{T}}} where T","page":"Affine Algebras and Their Ideals","title":"quotient","text":"quotient(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T\n\nReturn the ideal quotient of a by b. Alternatively, use a:b.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));\n\njulia> a = ideal(A, [y^2])\nideal(y^2)\n\njulia> b = ideal(A, [x])\nideal(x)\n\njulia> a:b\nideal(y)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Tests-on-Ideals-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Tests on Ideals in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Basic-Tests","page":"Affine Algebras and Their Ideals","title":"Basic Tests","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_zero(a::MPolyQuoIdeal)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_zero-Tuple{MPolyQuoIdeal}","page":"Affine Algebras and Their Ideals","title":"is_zero","text":"is_zero(a::MPolyQuoIdeal)\n\nReturn true if a is the zero ideal, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, [x^2-y, y^2-x+y]);\n\njulia> a = ideal(A, [x^2+y^2, x+y])\nideal(x^2 + y^2, x + y)\n\njulia> is_zero(a)\nfalse\n\njulia> b = ideal(A, [x^2-y])\nideal(x^2 - y)\n\njulia> is_zero(b)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Containment-of-Ideals-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Containment of Ideals in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_subset(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_subset-Union{Tuple{T}, Tuple{MPolyQuoIdeal{T}, MPolyQuoIdeal{T}}} where T","page":"Affine Algebras and Their Ideals","title":"is_subset","text":"is_subset(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T\n\nReturn true if a is contained in b, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));\n\njulia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])\nideal(x^3*y^4 - x + y, x*y^2 + x*y)\n\njulia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])\nideal(x^3*y^3 - x + y, x^2*y + x*y^2)\n\njulia> is_subset(a,b)\nfalse\n\njulia> is_subset(b,a)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Equality-of-Ideals-in-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Equality of Ideals in Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"==(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#==-Union{Tuple{T}, Tuple{MPolyQuoIdeal{T}, MPolyQuoIdeal{T}}} where T","page":"Affine Algebras and Their Ideals","title":"==","text":"==(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T\n\nReturn true if a is equal to b, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));\n\njulia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])\nideal(x^3*y^4 - x + y, x*y^2 + x*y)\n\njulia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])\nideal(x^3*y^3 - x + y, x^2*y + x*y^2)\n\njulia> a == b\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Ideal-Membership","page":"Affine Algebras and Their Ideals","title":"Ideal Membership","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"ideal_membership(f::MPolyQuoRingElem{T}, a::MPolyQuoIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#ideal_membership-Union{Tuple{T}, Tuple{MPolyQuoRingElem{T}, MPolyQuoIdeal{T}}} where T","page":"Affine Algebras and Their Ideals","title":"ideal_membership","text":"ideal_membership(f::MPolyQuoRingElem{T}, a::MPolyQuoIdeal{T}) where T\n\nReturn true if f is contained in a, false otherwise. Alternatively, use f in a.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));\n\njulia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])\nideal(x^3*y^4 - x + y, x*y^2 + x*y)\n\njulia> f = A(x^2*y^3-x+y)\nx^2*y^3 - x + y\n\njulia> f in a\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Homomorphisms-From-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Homomorphisms From Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"If A=RI is an affine C-algebra, and S is any ring, then defining a ring homomorphism overlinephi A to S means to define a ring homomorphism phi R to S such that Isubset ker(phi). Thus, overlinephi is determined by specifying its restriction to C, and by assigning an image to each generator of A. In OSCAR, such homomorphisms are created as follows:","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"hom(A::MPolyQuoRing, S::NCRing, coeff_map, images::Vector; check::Bool = true)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#hom-Tuple{MPolyQuoRing, NCRing, Any, Vector}","page":"Affine Algebras and Their Ideals","title":"hom","text":"hom(A::MPolyQuoRing, S::NCRing, coeff_map, images::Vector; check::Bool = true)\n\nhom(A::MPolyQuoRing, S::NCRing, images::Vector; check::Bool = true)\n\nGiven a homomorphism coeff_map from C to S, where C is the coefficient ring of the base ring of A, and given a vector images of ngens(A) elements of S, return the homomorphism A to S whose restriction to C is coeff_map, and which sends the i-th generator of A to the i-th entry of images.\n\nIf no coefficient map is entered, invoke a canonical homomorphism of C to S, if such a homomorphism exists, and throw an error, otherwise.\n\nnote: Note\nThe function returns a well-defined homomorphism A to S iff the given data defines a homomorphism from the base ring of A to S whose kernel contains the modulus of A. This condition is checked by the function in case check = true (default).\n\nnote: Note\nIn case check = true (default), the function also checks the conditions below:If S is graded, the assigned images must be homogeneous with respect to the given grading.\nIf S is noncommutative, the assigned images must pairwise commute. \n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"] );\n\njulia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));\n\njulia> S, (s, t) = polynomial_ring(QQ, [\"s\", \"t\"]);\n\njulia> F = hom(A, S, [s, s^2, s^3])\nMap with following data\nDomain:\n=======\nA\nCodomain:\n=========\nMultivariate polynomial ring in 2 variables over QQ\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"Given a ring homomorphism F : R to S as above, domain(F) and codomain(F) refer to R and S, respectively. Given ring homomorphisms F : R to S and G : S to T as above, compose(F, G) refers to their composition.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Homomorphisms-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Homomorphisms of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"The OSCAR homomorphism type AffAlgHom models ring homomorphisms R to S such that the type of both R and S is a subtype of Union{MPolyRing{T}, MPolyQuoRing{U}}, where T <: FieldElem and U <: MPolyRingElem{T}. Functionality for these homomorphism is discussed in what follows.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Data-Associated-to-Homomorphisms-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Data Associated to Homomorphisms of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"preimage(F::AffAlgHom, I::MPolyIdeal)\nkernel(F::AffAlgHom)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#preimage-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U}}}, MPolyIdeal}","page":"Affine Algebras and Their Ideals","title":"preimage","text":"preimage(F::AffAlgHom, I::U) where U <: Union{MPolyIdeal, MPolyQuoIdeal}\n\nReturn the preimage of the ideal I under F.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#kernel-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U}}}}","page":"Affine Algebras and Their Ideals","title":"kernel","text":"kernel(F::AffAlgHom)\n\nReturn the kernel of F.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Examples-4","page":"Affine Algebras and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> D1, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> C1, (s,t) = graded_polynomial_ring(QQ, [\"s\", \"t\"]);\n\njulia> V1 = [s^3, s^2*t, s*t^2, t^3];\n\njulia> para = hom(D1, C1, V1)\nMap with following data\nDomain:\n=======\nGraded multivariate polynomial ring in 4 variables over QQ\nCodomain:\n=========\nGraded multivariate polynomial ring in 2 variables over QQ\n\njulia> twistedCubic = kernel(para)\nideal(-x*z + y^2, -w*z + x*y, -w*y + x^2)\n\njulia> C2, p2 = quo(D1, twistedCubic);\n\njulia> D2, (a, b, c) = graded_polynomial_ring(QQ, [\"a\", \"b\", \"c\"]);\n\njulia> V2 = [p2(w-y), p2(x), p2(z)];\n\njulia> proj = hom(D2, C2, V2)\nMap with following data\nDomain:\n=======\nGraded multivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nQuotient of multivariate polynomial ring by ideal with 3 generators\n\njulia> nodalCubic = kernel(proj)\nideal(-a^2*c + b^3 - 2*b^2*c + b*c^2)\n","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> D3,y = polynomial_ring(QQ, \"y\" => 1:3);\n\njulia> C3, x = polynomial_ring(QQ, \"x\" => 1:3);\n\njulia> V3 = [x[1]*x[2], x[1]*x[3], x[2]*x[3]];\n\njulia> F3 = hom(D3, C3, V3)\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nMultivariate polynomial ring in 3 variables over QQ\n\njulia> sphere = ideal(C3, [x[1]^3 + x[2]^3 + x[3]^3 - 1])\nideal(x[1]^3 + x[2]^3 + x[3]^3 - 1)\n\njulia> steinerRomanSurface = preimage(F3, sphere)\nideal(y[1]^6*y[2]^6 + 2*y[1]^6*y[2]^3*y[3]^3 + y[1]^6*y[3]^6 + 2*y[1]^3*y[2]^6*y[3]^3 + 2*y[1]^3*y[2]^3*y[3]^6 - y[1]^3*y[2]^3*y[3]^3 + y[2]^6*y[3]^6)\n","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Tests-on-Homomorphisms-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Tests on Homomorphisms of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_injective(F::AffAlgHom)\nis_surjective(F::AffAlgHom)\nis_bijective(F::AffAlgHom)\nis_finite(F::AffAlgHom)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_injective-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U}}}}","page":"Affine Algebras and Their Ideals","title":"is_injective","text":"is_injective(F::AffAlgHom)\n\nReturn true if F is injective, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#is_surjective-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U}}}}","page":"Affine Algebras and Their Ideals","title":"is_surjective","text":"is_surjective(F::AffAlgHom)\n\nReturn true if F is surjective, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#is_bijective-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U}}}}","page":"Affine Algebras and Their Ideals","title":"is_bijective","text":"is_bijective(F::AffAlgHom)\n\nReturn true if F is bijective, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#is_finite-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U}}}}","page":"Affine Algebras and Their Ideals","title":"is_finite","text":"is_finite(F::AffAlgHom)\n\nReturn true if F is finite, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Examples-5","page":"Affine Algebras and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> D, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> S, (a, b, c) = polynomial_ring(QQ, [\"a\", \"b\", \"c\"]);\n\njulia> C, p = quo(S, ideal(S, [c-b^3]));\n\njulia> V = [p(2*a + b^6), p(7*b - a^2), p(c^2)];\n\njulia> F = hom(D, C, V)\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nQuotient of multivariate polynomial ring by ideal with 1 generator\n\njulia> is_surjective(F)\ntrue\n\njulia> D1, _ = quo(D, kernel(F));\n\njulia> F1 = hom(D1, C, V);\n\njulia> is_bijective(F1)\ntrue\n","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [ \"x\", \"y\", \"z\"]);\n\njulia> C, (s, t) = polynomial_ring(QQ, [\"s\", \"t\"]);\n\njulia> V = [s*t, t, s^2];\n\njulia> paraWhitneyUmbrella = hom(R, C, V)\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nMultivariate polynomial ring in 2 variables over QQ\n\njulia> D, _ = quo(R, kernel(paraWhitneyUmbrella));\n\njulia> is_finite(hom(D, C, V))\ntrue","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Inverting-Homomorphisms-of-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Inverting Homomorphisms of Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"inverse(F::AffAlgHom)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#inverse-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U}}}}","page":"Affine Algebras and Their Ideals","title":"inverse","text":"inverse(F::AffAlgHom)\n\nIf F is bijective, return its inverse.\n\nExamples\n\njulia> D1, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> D, _ = quo(D1, [y-x^2, z-x^3]);\n\njulia> C, (t,) = polynomial_ring(QQ, [\"t\"]);\n\njulia> F = hom(D, C, [t, t^2, t^3]);\n\njulia> is_bijective(F)\ntrue\n\njulia> G = inverse(F)\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 1 variable over QQ\nCodomain:\n=========\nD\n\njulia> G(t)\nx\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Subalgebras","page":"Affine Algebras and Their Ideals","title":"Subalgebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Subalgebra-Membership","page":"Affine Algebras and Their Ideals","title":"Subalgebra Membership","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"subalgebra_membership(f::T, V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#subalgebra_membership-Union{Tuple{T}, Tuple{T, Vector{T}}} where T<:Union{MPolyRingElem, MPolyQuoRingElem}","page":"Affine Algebras and Their Ideals","title":"subalgebra_membership","text":"subalgebra_membership(f::T, V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}\n\nGiven an element f of a multivariate polynomial ring over a field, or of a quotient of such a ring, and given a vector V of further elements of that ring, consider the subalgebra generated by the entries of V in the given ring. If f is contained in the subalgebra, return (true, h), where h is giving the polynomial relation. Return, (false, 0), otherwise.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:3);\n\njulia> f = x[1]^6*x[2]^6-x[1]^6*x[3]^6;\n\njulia> V = [x[1]^3*x[2]^3-x[1]^3*x[3]^3, x[1]^3*x[2]^3+x[1]^3*x[3]^3]\n2-element Vector{QQMPolyRingElem}:\n x[1]^3*x[2]^3 - x[1]^3*x[3]^3\n x[1]^3*x[2]^3 + x[1]^3*x[3]^3\n\njulia> subalgebra_membership(f, V)\n(true, t1*t2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Minimal-Subalgebra-Generators","page":"Affine Algebras and Their Ideals","title":"Minimal Subalgebra Generators","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"minimal_subalgebra_generators(V::Vector{T}; check::Bool = true) where {T <: Union{MPolyDecRingElem, MPolyQuoRingElem{<: MPolyDecRingElem}}}","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#minimal_subalgebra_generators-Union{Tuple{Vector{T}}, Tuple{T}} where T<:Union{MPolyDecRingElem, MPolyQuoRingElem{<:MPolyDecRingElem}}","page":"Affine Algebras and Their Ideals","title":"minimal_subalgebra_generators","text":"minimal_subalgebra_generators(V::Vector{T}; check::Bool = true) where T <: Union{MPolyRingElem, MPolyQuoRingElem}\n\nGiven a vector V of homogeneous elements of a positively graded multivariate polynomial ring, or of a quotient of such a ring, return a minimal subset of the elements in V which, in the given ring, generate the same subalgebra as all elements in V.\n\nIf check is true (default), the conditions on V and the given ring are checked.\n\nExamples\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> V = [x, y, x^2+y^2]\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x\n y\n x^2 + y^2\n\njulia> minimal_subalgebra_generators(V)\n2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x\n y\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Noether-Normalization","page":"Affine Algebras and Their Ideals","title":"Noether Normalization","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"noether_normalization(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#noether_normalization-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"noether_normalization","text":"noether_normalization(A::MPolyQuoRing)\n\nGiven an affine algebra A=RI over a field K, return a triple (VFG) such that:\n\nV is a vector of d=dim A elements of A, represented by linear forms l_iin R, and such that KVhookrightarrow A is a Noether normalization for A; \nF A=RI to B = Rphi(I) is an isomorphism, induced by a linear change $ \\phi $ of coordinates of R which maps the l_i to the the last d variables of R; \nG = F^-1\n\nwarning: Warning\nThe algorithm may not terminate over a small finite field. If it terminates, the result is correct.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Examples-6","page":"Affine Algebras and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [x*y, x*z]));\n\njulia> L = noether_normalization(A);\n\njulia> L[1]\n2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n -2*x + y\n -5*y + z\n\njulia> L[2]\nMap with following data\nDomain:\n=======\nQuotient of multivariate polynomial ring by ideal with 2 generators\nCodomain:\n=========\nQuotient of multivariate polynomial ring by ideal with 2 generators\n\njulia> L[3]\nMap with following data\nDomain:\n=======\nQuotient of multivariate polynomial ring by ideal with 2 generators\nCodomain:\n=========\nQuotient of multivariate polynomial ring by ideal with 2 generators\n","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#Normalization","page":"Affine Algebras and Their Ideals","title":"Normalization","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"normalization(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#normalization-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"normalization","text":"normalization(A::MPolyQuoRing; algorithm = :equidimDec)\n\nFind the normalization of a reduced affine algebra over a perfect field K. That is, given the quotient A=RI of a multivariate polynomial ring R over K modulo a radical ideal I, compute the integral closure overlineA of A in its total ring of fractions Q(A), together with the embedding f A to overlineA. \n\nImplemented Algorithms and how to Read the Output\n\nThe function relies on the algorithm of Greuel, Laplagne, and Seelisch which proceeds by finding a suitable decomposition I=I_1capdotscap I_r into radical ideals I_k, together with maps A = RI to A_k=overlineRI_k which give rise to the normalization map of A:\n\nAhookrightarrow A_1times dotstimes A_r=overlineA\n\nFor each k, the function specifies two representations of A_k: It returns an array of triples (A_k f_k mathfrak a_k), where A_k is represented as an affine K-algebra, and f_k as a map of affine K-algebras. The third entry mathfrak a_k is a tuple (d_k J_k), consisting of an element d_kin A and an ideal J_ksubset A, such that frac1d_kJ_k = A_k as A-submodules of the total ring of fractions of A.\n\nBy default (algorithm = :equidimDec), as a first step on its way to find the decomposition I=I_1capdotscap I_r, the algorithm computes an equidimensional decomposition of the radical ideal I. Alternatively, if specified by algorithm = :primeDec, the algorithm computes I=I_1capdotscap I_r as the prime decomposition of the radical ideal I.\n\nSee Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010).\n\nwarning: Warning\nThe function does not check whether A is reduced. Use is_reduced(A) in case you are unsure (this may take some time).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]));\n\njulia> L = normalization(A);\n\njulia> size(L)\n(2,)\n\njulia> LL = normalization(A, algorithm = :primeDec);\n\njulia> size(LL)\n(3,)\n\njulia> LL[1][1]\nQuotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(-T(1)*y + x, -T(1)*x + y^2, T(1)^2 - y, -x^2 + y^3)\n\njulia> LL[1][2]\nMap with following data\nDomain:\n=======\nA\nCodomain:\n=========\nQuotient of multivariate polynomial ring by ideal with 4 generators\n\njulia> LL[1][3]\n(y, ideal(x, y))\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"normalization_with_delta(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#normalization_with_delta-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"normalization_with_delta","text":"normalization_with_delta(A::MPolyQuoRing; algorithm::Symbol = :equidimDec)\n\nCompute the normalization\n\nAhookrightarrow A_1times dotstimes A_r=overlineA\n\nof A as does normalize(A), but return additionally the delta invariant of A, that is, the dimension \n\ndim_K(overlineAA)\n\n. \n\nHow to Read the Output\n\nThe return value is a tuple whose first element is normalize(A), whose second element is an array containing the delta invariants of the A_k, and whose third element is the (total) delta invariant of A. The return value -1 in the third element indicates that the delta invariant is infinite.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]));\n\njulia> L = normalization_with_delta(A);\n\njulia> L[2]\n3-element Vector{Int64}:\n 1\n 1\n 0\n\njulia> L[3]\n13\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [z^3-x*y^4]));\n\njulia> L = normalization_with_delta(A);\n\njulia> L[3]\n-1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Integral-Bases","page":"Affine Algebras and Their Ideals","title":"Integral Bases","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"integral_basis(f::MPolyRingElem, i::Int)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#integral_basis-Tuple{MPolyRingElem, Int64}","page":"Affine Algebras and Their Ideals","title":"integral_basis","text":"integral_basis(f::MPolyRingElem, i::Int; algorithm::Symbol = :normal_local)\n\nGiven a polynomial f in two variables with coefficients in a perfect field K, and given an integer iin12 specifying one of the variables, f must be irreducible and monic in the specified variable: Say, finmathbb Kxy is monic in y. Then the normalization of A = Kxylangle f rangle, that is, the integral closure overlineA of A in its quotient field, is a free module over Kx of finite rank, and any set of free generators for overlineA over Kx is called an integral basis for overlineA over Kx. The function returns a pair (d V), where d is an element of A, and V is a vector of elements in A, such that the fractions vd vin V, form an integral basis for overlineA over Kx.\n\nBy default (algorithm = :normal_local), the function relies on the local-to-global approach to normalization presented in Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Andreas Steenpaß, Stefan Steidel (2013). Alternatively, if specified by algorithm = :normal_global, the global normalization algorithm in Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010) is used. If K = mathbb Q, it is recommended to apply the algorithm in Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister (2019), which makes use of Puiseux expansions and Hensel lifting (algorithm = :hensel).\n\nnote: Note\nThe conditions on f are automatically checked.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> f = (y^2-2)^2 + x^5\nx^5 + y^4 - 4*y^2 + 4\n\njulia> integral_basis(f, 2)\n(x^2, MPolyQuoRingElem{QQMPolyRingElem}[x^2, x^2*y, y^2 - 2, y^3 - 2*y])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Tests-on-Affine-Algebras","page":"Affine Algebras and Their Ideals","title":"Tests on Affine Algebras","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/#Reducedness-Test","page":"Affine Algebras and Their Ideals","title":"Reducedness Test","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_reduced(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_reduced-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"is_reduced","text":"is_reduced(A::MPolyQuoRing)\n\nGiven an affine algebra A, return true if A is reduced, false otherwise.\n\nwarning: Warning\nThe function computes the radical of the modulus of A. This may take some time.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^4]));\n\njulia> is_reduced(A)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Normality-Test","page":"Affine Algebras and Their Ideals","title":"Normality Test","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_normal(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_normal-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"is_normal","text":"is_normal(A::MPolyQuoRing)\n\nGiven an affine algebra A over a perfect field, return true if A is normal, false otherwise.\n\nnote: Note\nThis function performs the first step of the normalization algorithm of Greuel, Laplagne, and Seelisch Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010) and may, thus, be more efficient than computing the full normalization of A.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [z^2-x*y]));\n\njulia> is_normal(A)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Cohen-Macaulayness-Test","page":"Affine Algebras and Their Ideals","title":"Cohen-Macaulayness Test","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_cohen_macaulay(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_cohen_macaulay-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"is_cohen_macaulay","text":" is_cohen_macaulay(A::MPolyQuoRing)\n\nGiven a mathbb Z-graded affine algebra A = R/I over a field, say, K, where the grading is inherited from the standard mathbb Z-grading on the polynomial ring R, return true if A is a Cohen-Macaulay ring, false otherwise.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> I = ideal(R, [x*z-y^2, w*z-x*y, w*y-x^2]);\n\njulia> A, _ = quo(R, I);\n\njulia> is_cohen_macaulay(A)\ntrue\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> I = ideal(R, [x*z, y*z]);\n\njulia> A, _ = quo(R, I);\n\njulia> is_cohen_macaulay(A)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Hilbert-Series-and-Hilbert-Polynomial","page":"Affine Algebras and Their Ideals","title":"Hilbert Series and Hilbert Polynomial","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"Given a multivariate polynomial ring R over a field K together with a (multi)grading on R by a finitely generated abelian group G, let I be an ideal of R which is homogeneous with respect to this grading. Then the affine K-algebra A=RI inherits the grading: A = bigoplus_gin G A_g. Suppose now that R is positively graded by G. That is, G is free and each graded piece R_g has finite dimension. Then also A_g is a finite dimensional K-vector space for each g, and we have the well-defined Hilbert function of A,","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"H(A underlinephantomd) G to N gmapsto dim_K(A_g)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"The Hilbert series of A is the generating function ","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"H_A(mathbb t)=sum_gin G H(A g) mathbb t^g","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"(see Section 8.2 in Ezra Miller, Bernd Sturmfels (2005) for a formal discussion extending the classical case of mathbb Z-gradings with positive weights to the more general case of multigradings). As in the classical case, the infinitely many values of the Hilbert function can be expressed in finite terms by representing the Hilbert series as a rational function (see Theorem 8.20 in Ezra Miller, Bernd Sturmfels (2005) for a precise statement).","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"By a result of Macaulay, if A = RI is an affine algebra, and L_(I) is the leading ideal of I with respect to a global monomial ordering , then the Hilbert function of A equals that of RL_(I) (see Theorem 15.26 in David Eisenbud (1995)). Thus, using Gröbner bases, the computation of Hilbert series can be reduced to the case where the modulus of the affine algebra is a monomial ideal. In the latter case, we face a problem of combinatorial nature, and there are various strategies of how to proceed (see Martin Kreuzer, Lorenzo Robbiano (2005)). The functions hilbert_series, hilbert_series_reduced, hilbert_series_expanded, hilbert_function, hilbert_polynomial, and degree address the case of mathbb Z-gradings with positive weights, relying on corresponding Singular functionality. The functions multi_hilbert_series, multi_hilbert_series_reduced, and multi_hilbert_function offer a variety of different strategies and allow one to handle positive gradings in general.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#\\mathbb-Z-Gradings-With-Positive-Weights","page":"Affine Algebras and Their Ideals","title":"mathbb Z-Gradings With Positive Weights","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"Let R=Kx_1 dots x_n be a polynomial ring in n variables over a field K. Assign positive integer weights w_i to the variables x_i, and grade R=bigoplus_din mathbb Z R_d=bigoplus_dgeq 0 R_d according to the corresponding weighted degree. Let I be an ideal of R which is homogeneous with respect to this grading. Then the affine K-algebra A=RI inherits the grading: A = bigoplus_dgeq 0 A_d, where each graded piece A_d is a finite dimensional K-vector space. In this situation, the Hilbert function of A is of type","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"H(A underlinephantomd) N to N d mapsto dim_K(d)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"and the Hilbert series of A is the formal power series","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"H_A(t)=sum_dgeq 0 H(A d) t^dinmathbb Zt","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"The Hilbert series can be written as a rational function p(t)q(t), with denominator","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"q(t) = (1-t^w_1)cdots (1-t^w_n)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"In the standard mathbb Z-graded case, where the weights on the variables are all 1, the Hilbert function is of polynomial nature: There exists a unique polynomial P_A(t)inmathbbQt, the Hilbert polynomial, which satisfies H(Md)=P_M(d) for all d gg 0. Furthermore, the degree of A is defined as the dimension of A over K if this dimension is finite, and as the integer d such that the leading term of the Hilbert polynomial has the form d t^ee, otherwise.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"hilbert_series(A::MPolyQuoRing)\nhilbert_series_reduced(A::MPolyQuoRing)\nhilbert_series_expanded(A::MPolyQuoRing, d::Int)\nhilbert_function(A::MPolyQuoRing, d::Int)\nhilbert_polynomial(A::MPolyQuoRing)\ndegree(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#hilbert_series-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"hilbert_series","text":"hilbert_series(A::MPolyQuoRing; backend::Symbol=:Singular, algorithm::Symbol=:BayerStillmanA)\n\nGiven a mathbb Z-graded affine algebra A = RI over a field K, where the grading is inherited from a mathbb Z-grading on the polynomial ring R defined by assigning positive integer weights to the variables, return a pair (pq), say, of univariate polynomials p qinmathbb Zt such that pq represents the Hilbert series of A as a rational function with denominator \n\nq = (1-t^w_1)cdots (1-t^w_n)\n\nwhere n is the number of variables of R, and w_1 dots w_n are the assigned weights.\n\nSee also hilbert_series_reduced.\n\nnote: Note\nThe advanced user can select different backends for the computation (:Singular and :Abbott for the moment), as well as different algorithms. The latter might be ignored for certain backends. \n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> hilbert_series(A)\n(2*t^3 - 3*t^2 + 1, (-t + 1)^4)\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3]);\n\njulia> A, _ = quo(R, ideal(R, [x*y*z]));\n\njulia> hilbert_series(A)\n(-t^6 + 1, (-t^2 + 1)^1*(-t + 1)^1*(-t^3 + 1)^1)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#hilbert_series_reduced-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"hilbert_series_reduced","text":"hilbert_series_reduced(A::MPolyQuoRing)\n\nGiven a mathbb Z-graded affine algebra A = RI over a field K, where the grading is inherited from a mathbb Z-grading on the polynomial ring R defined by assigning positive integer weights to the variables, return a pair (pq), say, of univariate polynomials p qinmathbb Zt such that pq represents the Hilbert series of A as a rational function written in lowest terms. \n\nSee also hilbert_series.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> hilbert_series_reduced(A)\n(2*t + 1, t^2 - 2*t + 1)\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3]);\n\njulia> A, _ = quo(R, ideal(R, [x*y*z]));\n\njulia> hilbert_series(A)\n(-t^6 + 1, (-t^2 + 1)^1*(-t + 1)^1*(-t^3 + 1)^1)\n\njulia> hilbert_series_reduced(A)\n(t^2 - t + 1, t^2 - 2*t + 1)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#hilbert_series_expanded-Tuple{MPolyQuoRing, Int64}","page":"Affine Algebras and Their Ideals","title":"hilbert_series_expanded","text":"hilbert_series_expanded(A::MPolyQuoRing, d::Int)\n\nGiven a mathbb Z-graded affine algebra A = RI over a field K, where the grading is inherited from a mathbb Z-grading on the polynomial ring R defined by assigning positive integer weights to the variables, return the Hilbert series of A to precision d. \n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> hilbert_series_expanded(A, 7)\n1 + 4*t + 7*t^2 + 10*t^3 + 13*t^4 + 16*t^5 + 19*t^6 + 22*t^7 + O(t^8)\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3]);\n\njulia> A, _ = quo(R, ideal(R, [x*y*z]));\n\njulia> hilbert_series_expanded(A, 5)\n1 + t + 2*t^2 + 3*t^3 + 4*t^4 + 5*t^5 + O(t^6)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#hilbert_function-Tuple{MPolyQuoRing, Int64}","page":"Affine Algebras and Their Ideals","title":"hilbert_function","text":"hilbert_function(A::MPolyQuoRing, d::Int)\n\nGiven a mathbb Z-graded affine algebra A = RI over a field K, where the grading is inherited from a mathbb Z-grading on the polynomial ring R defined by assigning positive integer weights to the variables, return the value H(A d) where \n\nH(A underlinephantomd) N to N d mapsto dim_K A_d\n\nis the Hilbert function of A.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> hilbert_function(A,7)\n22\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3]);\n\njulia> A, _ = quo(R, ideal(R, [x*y*z]));\n\njulia> hilbert_function(A, 5)\n5\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#hilbert_polynomial-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"hilbert_polynomial","text":" hilbert_polynomial(A::MPolyQuoRing)\n\nGiven a mathbb Z-graded affine algebra A = RI over a field K, where the grading is inherited from the standard mathbb Z-grading on the polynomial ring R, return the Hilbert polynomial of A.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> hilbert_polynomial(A)\n3*t + 1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#degree-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"degree","text":"degree(A::MPolyQuoRing)\n\nGiven a mathbb Z-graded affine algebra A = RI over a field K, where the grading is inherited from the standard mathbb Z-grading on the polynomial ring R, return the degree of A.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> degree(A)\n3\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Positive-Gradings-in-General","page":"Affine Algebras and Their Ideals","title":"Positive Gradings in General","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"multi_hilbert_series(A::MPolyQuoRing; algorithm::Symbol=:BayerStillmanA)\nmulti_hilbert_series_reduced(A::MPolyQuoRing; algorithm::Symbol=:BayerStillmanA)\nmulti_hilbert_function(A::MPolyQuoRing, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#multi_hilbert_series-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"multi_hilbert_series","text":"multi_hilbert_series(A::MPolyQuoRing; algorithm::Symbol=:BayerStillmanA, parent::Union{Nothing,Ring}=nothing)\n\nReturn the Hilbert series of the graded affine algebra A.\n\nnote: Note\nThe advanced user can select an algorithm for the computation; see the code for details.\n\nExamples\n\njulia> W = [1 1 1; 0 0 -1];\n\njulia> R, x = graded_polynomial_ring(QQ, [\"x[1]\", \"x[2]\", \"x[3]\"], W)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])\n\njulia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);\n\njulia> A, _ = quo(R, I);\n\njulia> H = multi_hilbert_series(A);\n\njulia> H[1][1]\n-t[1]^7*t[2]^-2 + t[1]^6*t[2]^-1 + t[1]^6*t[2]^-2 + t[1]^5*t[2]^-4 - t[1]^4 + t[1]^4*t[2]^-2 - t[1]^4*t[2]^-4 - t[1]^3*t[2]^-1 - t[1]^3*t[2]^-2 + 1\n\njulia> H[1][2]\n(-t[1] + 1)^2*(-t[1]*t[2]^-1 + 1)^1\n\njulia> H[2][1]\nGrpAb: Z^2\n\njulia> H[2][2]\nIdentity map with\n\nDomain:\n=======\nGrpAb: Z^2\n\njulia> G = abelian_group(ZZMatrix([1 -1]));\n\njulia> g = gen(G, 1)\nElement of G with components [0 1]\n\njulia> W = [g, g, g, g];\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"], W);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> (num, den), (H, iso) = multi_hilbert_series(A);\n\njulia> num\n2*t^3 - 3*t^2 + 1\n\njulia> den\n(-t + 1)^4\n\njulia> H\nGrpAb: Z\n\njulia> iso\nMap with following data\nDomain:\n=======\nH\nCodomain:\n=========\nG\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#multi_hilbert_series_reduced-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"multi_hilbert_series_reduced","text":"multi_hilbert_series_reduced(A::MPolyQuoRing; algorithm::Symbol=:BayerStillmanA)\n\nReturn the reduced Hilbert series of the positively graded affine algebra A.\n\nnote: Note\nThe advanced user can select a algorithm for the computation; see the code for details.\n\nExamples\n\njulia> W = [1 1 1; 0 0 -1];\n\njulia> R, x = graded_polynomial_ring(QQ, [\"x[1]\", \"x[2]\", \"x[3]\"], W)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])\n\njulia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);\n\njulia> A, _ = quo(R, I);\n\njulia> H = multi_hilbert_series_reduced(A);\n\n\njulia> H[1][1]\n-t[1]^5*t[2]^-1 + t[1]^3 + t[1]^3*t[2]^-3 + t[1]^2 + t[1]^2*t[2]^-1 + t[1]^2*t[2]^-2 + t[1] + t[1]*t[2]^-1 + 1\n\njulia> H[1][2]\n-t[1] + 1\n\njulia> H[2][1]\nGrpAb: Z^2\n\njulia> H[2][2]\nIdentity map with\n\nDomain:\n=======\nGrpAb: Z^2\n\njulia> G = abelian_group(ZZMatrix([1 -1]));\n\njulia> g = gen(G, 1)\nElement of G with components [0 1]\n\njulia> W = [g, g, g, g];\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"], W);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> H = multi_hilbert_series_reduced(A);\n\njulia> H[1][1]\n2*t + 1\n\njulia> H[1][2]\nt^2 - 2*t + 1\n\njulia> H[2][1]\nGrpAb: Z\n\njulia> H[2][2]\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z\nCodomain:\n=========\nG\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#multi_hilbert_function-Tuple{MPolyQuoRing, GrpAbFinGenElem}","page":"Affine Algebras and Their Ideals","title":"multi_hilbert_function","text":"multi_hilbert_function(A::MPolyQuoRing, g::GrpAbFinGenElem)\n\nGiven a positively graded affine algebra A over a field K with grading group G, say, and given an element g of G, return the value H(A g) of the Hilbert function\n\nH(A underlinephantomd) G to N gmapsto dim_K(A_g)\n\nmulti_hilbert_function(A::MPolyQuoRing, g::Vector{<:IntegerUnion})\n\nGiven a positively mathbb Z^m-graded affine algebra A over a field K, and given a vector g of m integers, convert g into an element of the grading group of A, and return the value H(A g) as above.\n\nmulti_hilbert_function(A::MPolyQuoRing, g::IntegerUnion)\n\nGiven a positively mathbb Z-graded affine algebra A over a field K, and given an integer g, convert g into an element of the grading group of A, and return the value H(A g) as above.\n\nExamples\n\njulia> W = [1 1 1; 0 0 -1];\n\njulia> R, x = graded_polynomial_ring(QQ, [\"x[1]\", \"x[2]\", \"x[3]\"], W)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])\n\njulia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);\n\njulia> A, _ = quo(R, I);\n\njulia> multi_hilbert_function(A::MPolyQuoRing, [1, 0])\n2\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"], [-1, -1, -1, -1]);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> multi_hilbert_function(A, -7)\n22\n\njulia> G = abelian_group(ZZMatrix([1 -1]));\n\njulia> g = gen(G, 1);\n\njulia> W = [g, g, g, g];\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"], W);\n\njulia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));\n\njulia> multi_hilbert_function(A, 7*g)\n22\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/field_introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AbstractAlgebra/field_introduction/","page":"Introduction","title":"Introduction","text":"A number of basic fields are provided, such as the rationals, finite fields, the real field, etc.","category":"page"},{"location":"AbstractAlgebra/field_introduction/","page":"Introduction","title":"Introduction","text":"Various generic field constructions can then be made recursively on top of these basic fields. For example, fraction fields, residue fields, function fields, etc.","category":"page"},{"location":"AbstractAlgebra/field_introduction/","page":"Introduction","title":"Introduction","text":"From the point of view of the system, all fields are rings and whether an object is a ring/field or an element thereof can be determined at the type level. There are abstract types for all field and for all field element types.","category":"page"},{"location":"AbstractAlgebra/field_introduction/","page":"Introduction","title":"Introduction","text":"The field hierarchy can be extended by implementing new fields to follow one or more field interfaces, including the interface that all fields must follow. Once an interface is satisfied, all the corresponding generic functionality will work over the new field.","category":"page"},{"location":"AbstractAlgebra/field_introduction/","page":"Introduction","title":"Introduction","text":"Implementations of new fields can either be generic or can be specialised implementations provided by, for example, a C library.","category":"page"},{"location":"Hecke/quad_forms/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"This chapter deals with quadratic and hermitian spaces, and lattices there of. Note that even though quadratic spaces/lattices are theoretically a special case of hermitian spaces/lattices, a particular distinction is made here. As a note for knowledgeable users, only methods regarding hermitian spaces/lattices over degree 1 and degree 2 extensions of number fields are implemented up to now.","category":"page"},{"location":"Hecke/quad_forms/introduction/#Definitions-and-vocabulary","page":"Introduction","title":"Definitions and vocabulary","text":"","category":"section"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"We begin by collecting the necessary definitions and vocabulary. The terminology follows mainly [Kir16]","category":"page"},{"location":"Hecke/quad_forms/introduction/#Quadratic-and-hermitian-spaces","page":"Introduction","title":"Quadratic and hermitian spaces","text":"","category":"section"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"Let K be a number field and let E be a finitely generated etale algebra over K of dimension 1 or 2, i.e. E=K or E is a separable extension of K of degree 2. In both cases, EK is endowed with an K-linear involution overlinephantomx colon E to E for which K is the fixed field (in the case E=K, this is simply the identity of K).","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"A hermitian space V over EK is a finite-dimensional E-vector space, together with a sesquilinear (with respect to the involution of EK) morphism Phi colon V times V to E. In the trivial case E=K, Phi is therefore a K-bilinear morphism and we called (V Phi) a quadratic hermitian space over K.","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"We will always work with an implicit canonical basis e_1 ldots e_n of V. In view of this, hermitian spaces over EK are in bijection with hermitian matrices with entries in E, with respect to the involution overlinephantomx. In particular, there is a bijection between quadratic hermitian spaces over K and symmetric matrices with entries in K. For any basis B = (v_1 ldots v_n) of (V Phi), we call the matrix G_B = (Phi(v_i v_j))_1 leq i j leq n in E^n times n the Gram matrix of (V Phi) associated to B. If B is the implicit fixed canonical basis of (V Phi), we simply talk about the Gram matrix of (V Phi).","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"For a hermitian space V, we refer to the field E as the base ring of V and to overlinephantomx as the involution of V. Meanwhile, the field K is referred to as the fixed field of V.","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"By abuse of language, non-quadratic hermitian spaces are sometimes simply called hermitian spaces and, in contrast, quadratic hermitian spaces are called quadratic spaces. In a general context, an arbitrary space (quadratic or hermitian) is referred to as a space throughout this chapter.","category":"page"},{"location":"Hecke/quad_forms/introduction/#Quadratic-and-hermitian-lattices","page":"Introduction","title":"Quadratic and hermitian lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"Let V be a space over EK. A finitely generated mathcal O_E-submodule L of V is called a hermitian lattice. By extension of vocabulary if V is quadratic (i.e. E=K), L is called a quadratic hermitian lattice. We call V the ambient space of L and Lotimes_mathcal O_E E the rational span of L.","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"For a hermitian lattice L, we refer to E as the base field of L and to the ring mathcal O_E as the base ring of L. We also call overlinephantomx colon E to E the involution of L. Finally, we refer to the field K fixed by this involution as the fixed field of L and to mathcal O_K as the fixed ring of L.","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"Once again by abuse of language, non-quadratic hermitian lattices are sometimes simply called hermitian lattices and quadratic lattices refer to quadratic hermitian lattices. Therefore, in a general context, an arbitrary lattice is referred to as a lattice in this chapter.","category":"page"},{"location":"Hecke/quad_forms/introduction/#References","page":"Introduction","title":"References","text":"","category":"section"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"Many of the implemented algorithms for computing with quadratic and hermitian lattices over number fields are based on the Magma implementation of Markus Kirschmer, which can be found here.","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"Most of the definitions and results are taken from:","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"[Kir16] : Definite quadratic and hermitian forms with small class number. Habilitationsschrift. RWTH Aachen University, 2016. pdf","category":"page"},{"location":"Hecke/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"[Kir19] : Determinant groups of hermitian lattices over local fields, Archiv der Mathematik, 113 (2019), no. 4, 337–347. pdf","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#Rational-Parametrizations-of-Rational-Plane-Curves","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"note: Note\nIn this section, C will denote a complex projective plane curve, defined by an absolutely irreducible, homogeneous polynomial in three variables, with coefficients in mathbb Q. Moreover, we will write n = deg C.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"Recall that the curve C is rational if it is birationally equivalent to the projective line mathbb P^1(mathbb C). In other words, there exists a rational parametrization of C, that is, a birational map mathbb P^1(mathbb C)dashrightarrow C. Note that such a parametrization is given by three homogeneous polynomials of the same degree in the homogeneous coordinates on mathbb P^1(mathbb C).","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"note: Note\nThe curve C is rational iff its geometric genus is zero.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"Based on work of Max Noether on adjoint curves, Hilbert und Hurwitz showed that if C is rational, then there is a birational map C dashrightarrow D defined over mathbb Q such that D = mathbb P^1(mathbb C) if n is odd, and Dsubsetmathbb P^2(mathbb C) is a conic if n is even.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"note: Note\nIf a conic D contains a rational point, then there exists a parametrization of D defined over mathbb Q; otherwise, there exists a parametrization of D defined over a quadratic field extension of mathbb Q.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"The approach of Hilbert und Hurwitz is constructive and allows one, in principle, to find rational parametrizations. The resulting algorithm is not very practical, however, as the approach asks to compute adjoint curves repeatedly, at each of a number of reduction steps.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"The algorithm implemented in OSCAR relies on reduction steps of a different type and requires the computation of adjoint curves only once. Its individual steps are interesting in their own right:","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"Assure that the curve C is rational by checking that its geometric genus is zero;\ncompute a basis of the adjoint curves of C of degree n-2; each such basis defines a birational map C dashrightarrow C_n-2 where C_n-2 is a rational normal curve in mathbb P^n-2(mathbb C);\nthe anticanonical linear system on C_n-2 defines a birational map C_n-2dashrightarrow C_n-4, where C_n-4 is a rational normal curve in in mathbb P^n-4(mathbb C);\niterate the previous step to obtain a birational map C_n-2 dashrightarrow dots dashrightarrow D, where D = mathbb P^1(mathbb C) if n is odd, and Dsubsetmathbb P^2(mathbb C) is a conic if n is even;\ninvert the birational map C dashrightarrow C_n-2 dashrightarrow dots dashrightarrow D; \nif n is even, compute a parametrization of the conic D and compose it with the inverted map above.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"note: Note\nThe defining property of an adjoint curve is that it passes with “sufficiently high” multiplicity through the singularities of C. There are several concepts of making this precise. For each such concept, there is a corresponding adjoint ideal of C, namely the homogeneous ideal formed by the defining polynomials of the adjoint curves. In OSCAR, we follow the concept of Gorenstein which leads to the largest possible adjoint ideal.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"See Janko Böhm (1999) and Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister (2017) for details and further references.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#Creating-Projective-Plane-Curves","page":"Rational Parametrizations of Rational Plane Curves","title":"Creating Projective Plane Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"The data structures for algebraic curves in OSCAR are still under development and subject to change. Here is the current constructor for projective plane curves:","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"ProjPlaneCurve(f::MPolyRingElem{T}) where {T <: FieldElem}","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#ProjPlaneCurve-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:FieldElem","page":"Rational Parametrizations of Rational Plane Curves","title":"ProjPlaneCurve","text":"ProjPlaneCurve(f::MPolyRingElem{T}) where {T <: FieldElem}\n\nGiven a homogeneous polynomial f in three variables with coefficients in a field, create the projective plane curve defined by f.\n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(z*x^2-y^3)\nProjective plane curve defined by x^2*z - y^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#The-Genus-of-a-Plane-Curve","page":"Rational Parametrizations of Rational Plane Curves","title":"The Genus of a Plane Curve","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":" geometric_genus(C::ProjectivePlaneCurve{T}) where T <: FieldElem","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#geometric_genus-Union{Tuple{ProjectivePlaneCurve{T}}, Tuple{T}} where T<:FieldElem","page":"Rational Parametrizations of Rational Plane Curves","title":"geometric_genus","text":"geometric_genus(C::ProjectivePlaneCurve{T}) where T <: FieldElem\n\nReturn the geometric genus of C.\n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> C = ProjPlaneCurve(z*x^2-y^3)\nProjective plane curve defined by x^2*z - y^3\n\njulia> geometric_genus(C)\n0\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#Adjoint-Ideals-of-Plane-Curves","page":"Rational Parametrizations of Rational Plane Curves","title":"Adjoint Ideals of Plane Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"adjoint_ideal(C::ProjPlaneCurve{QQFieldElem})","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#adjoint_ideal-Tuple{ProjPlaneCurve{QQFieldElem}}","page":"Rational Parametrizations of Rational Plane Curves","title":"adjoint_ideal","text":"adjoint_ideal(C::ProjPlaneCurve{QQFieldElem})\n\nReturn the Gorenstein adjoint ideal of C. \n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> C = ProjPlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)\nProjective plane curve defined by -2*x^3*z + 3*x^2*z^2 + y^4 - 2*y^2*z^2\n\njulia> I = adjoint_ideal(C)\nideal(-x*z + y^2, x*y - y*z, x^2 - x*z)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#Rational-Points-on-Conics","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Points on Conics","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"rational_point_conic(D::ProjPlaneCurve{QQFieldElem})","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#rational_point_conic-Tuple{ProjPlaneCurve{QQFieldElem}}","page":"Rational Parametrizations of Rational Plane Curves","title":"rational_point_conic","text":"rational_point_conic(D::ProjPlaneCurve{QQFieldElem})\n\nIf the conic D contains a rational point, return the homogeneous coordinates of such a point. If no such point exists, return a point on D defined over a quadratic field extension of mathbb Q.\n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> D = ProjPlaneCurve(x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z);\n\njulia> P = rational_point_conic(D)\n3-element Vector{AbstractAlgebra.Generic.MPoly{nf_elem}}:\n -1//4*a\n -1//4*a + 1//4\n 0\n\njulia> S = parent(P[1])\nMultivariate polynomial ring in 3 variables x, y, z\n over number field of degree 2 over QQ\n\njulia> NF = base_ring(S)\nNumber field with defining polynomial t^2 - 2\n over rational field\n\njulia> a = gen(NF)\na\n\njulia> minpoly(a)\nt^2 - 2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#Parametrizing-Rational-Plane-Curves","page":"Rational Parametrizations of Rational Plane Curves","title":"Parametrizing Rational Plane Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":" parametrization_plane_curve(C::ProjPlaneCurve{QQFieldElem})","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#parametrization_plane_curve-Tuple{ProjPlaneCurve{QQFieldElem}}","page":"Rational Parametrizations of Rational Plane Curves","title":"parametrization_plane_curve","text":"parametrization_plane_curve(C::ProjPlaneCurve{QQFieldElem})\n\nReturn a rational parametrization of C. \n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> C = ProjPlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)\nProjective plane curve defined by -2*x^3*z + 3*x^2*z^2 + y^4 - 2*y^2*z^2\n\njulia> parametrization_plane_curve(C)\n3-element Vector{QQMPolyRingElem}:\n 12*s^4 - 8*s^2*t^2 + t^4\n -12*s^3*t + 2*s*t^3\n 8*s^4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/#Contact","page":"Rational Parametrizations of Rational Plane Curves","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"Janko Böhm,\nWolfram Decker.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/Curves/para_rational_curves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/residue/#Generic-residue-rings","page":"Generic residue rings","title":"Generic residue rings","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"AbstractAlgebra.jl provides modules, implemented in src/Residue.jl and src/residue_field for residue rings and fields, respectively, over any Euclidean domain (in practice most of the functionality is provided for GCD domains that provide a meaningful GCD function) belonging to the AbstractAlgebra.jl abstract type hierarchy.","category":"page"},{"location":"AbstractAlgebra/residue/#Generic-residue-types","page":"Generic residue rings","title":"Generic residue types","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"AbstractAlgebra.jl implements generic residue rings with type Generic.ResidueRingElem{T} or in the case of residue rings that are known to be fields, Generic.ResidueFieldElem{T}, where T is the type of elements of the base ring. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Parent objects of generic residue ring elements have type Generic.ResidueRing{T} and those of residue fields have type GenericResField{T}.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"The defining modulus of the residue ring is stored in the parent object.","category":"page"},{"location":"AbstractAlgebra/residue/#Abstract-types","page":"Generic residue rings","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"All residue element types belong to the abstract type ResElem{T} or ResFieldElem{T} in the case of residue fields, and the residue ring types belong to the abstract type ResidueRing{T} or ResidueField{T} respectively. This enables one to write generic functions that can accept any AbstractAlgebra residue type.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"note: Note\nNote that both the generic residue ring type Generic.ResidueRing{T} and the abstract type it belongs to, ResidueRing{T} are both called ResidueRing, and similarly for the residue field types. In each case, the former is a (parameterised) concrete type for a residue ring over a given base ring whose elements have type T. The latter is an abstract type representing all residue ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).","category":"page"},{"location":"AbstractAlgebra/residue/#Residue-ring-constructors","page":"Generic residue rings","title":"Residue ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"In order to construct residues in AbstractAlgebra.jl, one must first construct the residue ring itself. This is accomplished with one of the following constructors.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"residue_ring(R::Ring, m::RingElem; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"residue_field(R::Ring, m::RingElem; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Given a base ring R and residue m contained in this ring, return the parent object of the residue ring R(m). By default the parent object S will depend only on R and m and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"The residue_field constructor does the same thing as the residue_ring constructor, but the resulting object has type belonging to Field rather than Ring, so it can be used anywhere a field is expected in AbstractAlgebra.jl. No check is made for maximality of the ideal generated by m.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"There are also the following for constructing residue rings and fields.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"quo(R::Ring, m::RingElem; cached::Bool = true)\nquo(::Type{Field}, R::Ring, m::RingElem; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/residue/#quo-Tuple{Ring, RingElem}","page":"Generic residue rings","title":"quo","text":"quo(R::Ring, a::RingElement; cached::Bool = true)\n\nReturns S, f where S = residue_ring(R, a) and f is the projection map from R to S. This map is supplied as a map with section where the section is the lift of an element of the residue field back to the ring R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/residue/#quo-Tuple{Type{Field}, Ring, RingElem}","page":"Generic residue rings","title":"quo","text":"quo(::Type{Field}, R::Ring, a::RingElement; cached::Bool = true)\n\nReturns S, f where S = residue_field(R, a) and f is the projection map from R to S. This map is supplied as a map with section where the section is the lift of an element of the residue field back to the ring R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Here are some examples of creating residue rings and making use of the resulting parent objects to coerce various elements into the residue ring.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Examples","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = residue_ring(R, x^3 + 3x + 1)\nResidue ring of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> f = S()\n0\n\njulia> g = S(123)\n123\n\njulia> h = S(BigInt(1234))\n1234\n\njulia> k = S(x + 1)\nx + 1\n\njulia> U, f = quo(R, x^3 + 3x + 1)\n(Residue ring of univariate polynomial ring modulo x^3 + 3*x + 1, Map with section with the following data\n\nDomain:\n=======\nUnivariate polynomial ring in x over rationals\n\nCodomain:\n========\nResidue ring of univariate polynomial ring modulo x^3 + 3*x + 1)\n\njulia> U === S\ntrue","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"All of the examples here are generic residue rings, but specialised implementations of residue rings provided by external modules will also usually provide a residue_ring constructor to allow creation of their residue rings.","category":"page"},{"location":"AbstractAlgebra/residue/#Residue-constructors","page":"Generic residue rings","title":"Residue constructors","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"One can use the parent objects of a residue ring to construct residues, as per any ring.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"(R::ResidueRing)() # constructs zero\n(R::ResidueRing)(c::Integer)\n(R::ResidueRing)(c::elem_type(R))\n(R::ResidueRing{T})(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/residue/#Functions-for-types-and-parents-of-residue-rings","page":"Generic residue rings","title":"Functions for types and parents of residue rings","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"base_ring(R::ResidueRing)\nbase_ring(a::ResElem)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Return the base ring over which the ring was constructed.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"parent(a::ResElem)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Return the parent of the given residue.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"characteristic(R::ResidueRing)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Return the characteristic of the given residue ring. If the characteristic is not known, an exception is raised.","category":"page"},{"location":"AbstractAlgebra/residue/#Residue-ring-functions","page":"Generic residue rings","title":"Residue ring functions","text":"","category":"section"},{"location":"AbstractAlgebra/residue/#Basic-functionality","page":"Generic residue rings","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Residue rings implement the Ring interface.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"zero(R::NCRing)\none(R::NCRing)\niszero(a::NCRingElement)\nisone(a::NCRingElement)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"divexact(a::T, b::T) where T <: RingElement\ninv(a::T)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"The Residue Ring interface is also implemented.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"modulus(S::ResidueRing)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"data(f::ResElem)\nlift(f::ResElem)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Return a lift of the residue to the base ring.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"The following functions are also provided for residues.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"modulus(::ResElem)","category":"page"},{"location":"AbstractAlgebra/residue/#modulus-Tuple{ResElem}","page":"Generic residue rings","title":"modulus","text":"modulus(R::ResElem)\n\nReturn the modulus a of the residue ring S = R(a) that the supplied residue r belongs to.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Examples","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = residue_ring(R, x^3 + 3x + 1)\nResidue ring of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> f = S(x + 1)\nx + 1\n\njulia> h = zero(S)\n0\n\njulia> k = one(S)\n1\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> is_unit(f)\ntrue\n\njulia> m = modulus(S)\nx^3 + 3*x + 1\n\njulia> d = data(f)\nx + 1\n\njulia> U = base_ring(S)\nUnivariate polynomial ring in x over rationals\n\njulia> V = base_ring(f)\nUnivariate polynomial ring in x over rationals\n\njulia> T = parent(f)\nResidue ring of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> f == deepcopy(f)\ntrue\n\njulia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)","category":"page"},{"location":"AbstractAlgebra/residue/#Inversion","page":"Generic residue rings","title":"Inversion","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Base.inv(::ResElem)","category":"page"},{"location":"AbstractAlgebra/residue/#inv-Tuple{ResElem}","page":"Generic residue rings","title":"inv","text":"Base.inv(a::ResElem)\n\nReturn the inverse of the element a in the residue ring. If an impossible inverse is encountered, an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Examples","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = residue_ring(R, x^3 + 3x + 1)\nResidue ring of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> f = S(x + 1)\nx + 1\n\njulia> g = inv(f)\n1//3*x^2 - 1//3*x + 4//3\n","category":"page"},{"location":"AbstractAlgebra/residue/#Greatest-common-divisor","page":"Generic residue rings","title":"Greatest common divisor","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"gcd{T <: RingElem}(::ResElem{T}, ::ResElem{T})","category":"page"},{"location":"AbstractAlgebra/residue/#gcd-Union{Tuple{T}, Tuple{ResElem{T}, ResElem{T}}} where T<:RingElem","page":"Generic residue rings","title":"gcd","text":"gcd(a::ResElem{T}, b::ResElem{T}) where {T <: RingElement}\n\nReturn a greatest common divisor of a and b if one exists. This is done by taking the greatest common divisor of the data associated with the supplied residues and taking its greatest common divisor with the modulus.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Examples","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = residue_ring(R, x^3 + 3x + 1)\nResidue ring of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> f = S(x + 1)\nx + 1\n\njulia> g = S(x^2 + 2x + 1)\nx^2 + 2*x + 1\n\njulia> h = gcd(f, g)\n1\n","category":"page"},{"location":"AbstractAlgebra/residue/#Square-Root","page":"Generic residue rings","title":"Square Root","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"is_square{T <: Integer}(::ResFieldElem{T})","category":"page"},{"location":"AbstractAlgebra/residue/#is_square-Union{Tuple{AbstractAlgebra.ResFieldElem{T}}, Tuple{T}} where T<:Integer","page":"Generic residue rings","title":"is_square","text":"is_square(a::ResFieldElem{T}) where T <: Integer\n\nReturn true if a is a square.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Base.sqrt{T <: Integer}(::ResFieldElem{T})","category":"page"},{"location":"AbstractAlgebra/residue/#sqrt-Union{Tuple{AbstractAlgebra.ResFieldElem{T}}, Tuple{T}} where T<:Integer","page":"Generic residue rings","title":"sqrt","text":"sqrt(a::ResFieldElem{T}; check::Bool=true) where T <: Integer\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Examples","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"julia> R = residue_field(ZZ, 733)\nResidue field of Integers modulo 733\n\njulia> a = R(86)\n86\n\njulia> is_square(a)\ntrue\n\njulia> sqrt(a)\n532","category":"page"},{"location":"AbstractAlgebra/residue/#Random-generation","page":"Generic residue rings","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Random residues can be generated using rand. The parameters after the residue ring are used to generate elements of the base ring.","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"rand(R::ResidueRing, v...)","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"Examples","category":"page"},{"location":"AbstractAlgebra/residue/","page":"Generic residue rings","title":"Generic residue rings","text":"julia> R = residue_ring(ZZ, 7)\nResidue ring of integers modulo 7\n\njulia> f = rand(R, 0:6)\n4\n\njulia> S, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> U = residue_field(S, x^3 + 3x + 1)\nResidue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> g = rand(S, 2:2, -10:10)\n-1//4*x^2 - 2//7*x + 1","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#Generic-matrix-algebras","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"AbstractAlgebra.jl allows the creation of an algebra (ring) of mtimes m matrices over a computable, commutative ring.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Functions specific to generic matrix algebras of mtimes m matrices are implemented in src/generic/MatrixAlgebra.jl. The remaining functionality is in the file src/generic/Matrix.jl.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"As well as implementing the entire Matrix interface, including the optional functionality, there are many additional generic algorithms implemented for matrix algebras.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Almost all of the functionality specified for generic matrices is available for matrix algebras. The exceptions are functions such as solve and nullspace which may return non-square matrices, or which don't accept square matrices.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"All of the generic functionality is part of the Generic submodule of AbstractAlgebra.jl. This is exported by default, so it is not necessary to qualify names of functions.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#Types-and-parent-objects","page":"Generic matrix algebras","title":"Types and parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Generic matrices in AbstractAlgebra.jl have type Generic.MatAlgElem{T} for matrices in a matrix algebra, where T is the type of elements of the matrix. Internally, generic matrices are implemented using an object wrapping a Julia two dimensional array, though they are not themselves Julia arrays. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Parents of generic matrices in a matrix algebra have type Generic.MatAlgebra{T}.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Note that matrix algebras are noncommutative rings. Thus their types belong to NCRing and NCRingElem. They cannot be used in constructions which require a commutative ring (Ring and RingElem respectively).","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"The generic matrix algebra matrix types belong to the abstract type MatAlgElem{T} and the parent types belong to MatAlgebra{T} Note that both of these require disambiguation from the concrete types in Generic of the same name.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"The degree and base ring R of a generic matrix are stored in its parent object, however to allow creation of matrices without first creating the matrix space parent, generic matrices in Julia do not contain a reference to their parent. They contain the row and column numbers (or degree, in the case of matrix algebras) and the base ring on a per matrix basis. The parent object can then be reconstructed from this data on demand.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#Matrix-algebra-constructors","page":"Generic matrix algebras","title":"Matrix algebra constructors","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"A matrix algebra in AbstractAlgebra.jl represents a collection of all matrices with given degree and base ring.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"In order to construct matrices in AbstractAlgebra.jl, one must construct the matrix algebra itself. This is accomplished with the following constructor.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"MatrixAlgebra(R::Ring, degree::Int)","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Construct the algebra of matrices with the given degree over the given base ring.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Here are some examples of creating matrix algebras and making use of the resulting parent objects to coerce various elements into the matrix algebra.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = MatrixAlgebra(R, 3)\nMatrix algebra of degree 3\n over univariate polynomial ring in t over rationals\n\njulia> A = S()\n[0 0 0]\n[0 0 0]\n[0 0 0]\n\njulia> B = S(12)\n[12 0 0]\n[ 0 12 0]\n[ 0 0 12]\n\njulia> C = S(R(11))\n[11 0 0]\n[ 0 11 0]\n[ 0 0 11]\n","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#Matrix-algebra-element-constructors","page":"Generic matrix algebras","title":"Matrix algebra element constructors","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"The following additional constructors are provided for constructing various kinds of matrices in a matrix algebra.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"identity_matrix(::Generic.MatAlgElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#identity_matrix-Union{Tuple{AbstractAlgebra.Generic.MatAlgElem{T}}, Tuple{T}} where T<:RingElement","page":"Generic matrix algebras","title":"identity_matrix","text":"identity_matrix(M::MatElem{T}) where T <: NCRingElement\n\nConstruct the identity matrix in the same matrix space as M, i.e. with ones down the diagonal and zeroes elsewhere. M must be square. This is an alias for one(M).\n\n\n\n\n\nidentity_matrix(M::MatAlgElem{T}) where T <: RingElement\n\nReturn the identity matrix over the same base ring as M and with the same dimensions.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"S = MatrixAlgebra(ZZ, 2)\nM = zero(S)\n\nP = identity_matrix(M)","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#Matrix-algebra-functionality-provided-by-AbstractAlgebra.jl","page":"Generic matrix algebras","title":"Matrix algebra functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Most of the generic matrix functionality described in the generic matrix section of the documentation is available for both matrix spaces and matrix algebras. Exceptions include functions that do not return or accept square matrices or which cannot specify a parent. Such functions include solve and nullspace which can't be provided for matrix algebras.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"In addition to the functionality described for matrix spaces, matrix algebras support all noncommutative ring operations, and matrix algebras can be used as a base ring for other generic constructs that accept a noncommutative base ring (NCRing).","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"In this section we describe functionality provided for matrix algebras only.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#Basic-matrix-functionality","page":"Generic matrix algebras","title":"Basic matrix functionality","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"As well as the Ring and Matrix interfaces, the following functions are provided to manipulate matrices.","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"degree(::Generic.MatAlgElem)","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#degree-Tuple{AbstractAlgebra.Generic.MatAlgElem}","page":"Generic matrix algebras","title":"degree","text":"degree(a::MatAlgElem{T}) where T <: RingElement\n\nReturn the degree n of the given matrix algebra.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/","page":"Generic matrix algebras","title":"Generic matrix algebras","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = MatrixAlgebra(R, 3)\nMatrix algebra of degree 3\n over univariate polynomial ring in t over rationals\n\njulia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> n = degree(A)\n3\n","category":"page"},{"location":"Hecke/examples/#Examples-and-sample-code","page":"Examples and sample code","title":"Examples and sample code","text":"","category":"section"},{"location":"Hecke/examples/","page":"Examples and sample code","title":"Examples and sample code","text":"Pages = [\n \"examples/reduction.md\",\n]\nDepth = 2","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/qadic/#Qadics","page":"Qadics","title":"Qadics","text":"","category":"section"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Q-adic fields, that is, unramified extensions of p-adic fields, are provided in Nemo by Flint. This allows construction of q-adic fields for any prime power q.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Q-adic fields are constructed using the FlintQadicField function. However, for convenience we define","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"QadicField = FlintQadicField","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"so that q-adic fields can be constructed using QadicField rather than FlintQadicField. Note that this is the name of the constructor, but not of qadic field type.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"The types of q-adic fields in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Library Field Element type Parent type\nFlint mathbbQ_q qadic QadicField","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"All the q-adic field types belong to the Field abstract type and the q-adic field element types belong to the FieldElem abstract type.","category":"page"},{"location":"Nemo/qadic/#P-adic-functionality","page":"Qadics","title":"P-adic functionality","text":"","category":"section"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Q-adic fields in Nemo provide all the functionality described in AbstractAlgebra for fields:.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Below, we document all the additional function that is provide by Nemo for q-adic fields.","category":"page"},{"location":"Nemo/qadic/#Constructors","page":"Qadics","title":"Constructors","text":"","category":"section"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"In order to construct q-adic field elements in Nemo, one must first construct the q-adic field itself. This is accomplished with one of the following constructors.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"FlintQadicField(::Integer, ::Int, ::Int)","category":"page"},{"location":"Nemo/qadic/#FlintQadicField-Tuple{Integer, Int64, Int64}","page":"Qadics","title":"FlintQadicField","text":"FlintQadicField(p::Integer, d::Int, prec::Int, var::String = \"a\")\n\nReturns the parent object for the q-adic field for given prime p and degree d, where the default absolute precision of elements of the field is given by prec and the generator is printed as var.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"It is also possible to call the inner constructor directly. It has the following form.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"FlintQadicField(p::ZZRingElem, d::Int, prec::Int)","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Returns the parent object for the q-adic field for given prime p and degree d, where the default absolute precision of elements of the field is given by prec. It also return the uniformizer p with the default precision.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Here are some examples of creating q-adic fields and making use of the resulting parent objects to coerce various elements into those fields.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Examples","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"julia> R, p = QadicField(7, 1, 30);\n\njulia> S, _ = QadicField(ZZ(65537), 1, 30);\n\njulia> a = R()\n0\n\njulia> b = S(1)\n65537^0 + O(65537^30)\n\njulia> c = S(ZZ(123))\n123*65537^0 + O(65537^30)\n\njulia> d = R(ZZ(1)//7^2)\n7^-2 + O(7^28)","category":"page"},{"location":"Nemo/qadic/#Big-oh-notation","page":"Qadics","title":"Big-oh notation","text":"","category":"section"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Elements of p-adic fields can be constructed using the big-oh notation. For this purpose we define the following functions.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"O(::FlintQadicField, ::Integer)\nO(::FlintQadicField, ::ZZRingElem)\nO(::FlintQadicField, ::QQFieldElem)","category":"page"},{"location":"Nemo/qadic/#O-Tuple{FlintQadicField, Integer}","page":"Qadics","title":"O","text":"O(R::FlintQadicField, m::Integer)\n\nConstruct the value 0 + O(p^n) given m = p^n. An exception results if m is not found to be a power of p = prime(R).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/#O-Tuple{FlintQadicField, ZZRingElem}","page":"Qadics","title":"O","text":"O(R::FlintQadicField, m::ZZRingElem)\n\nConstruct the value 0 + O(p^n) given m = p^n. An exception results if m is not found to be a power of p = prime(R).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/#O-Tuple{FlintQadicField, QQFieldElem}","page":"Qadics","title":"O","text":"O(R::FlintQadicField, m::QQFieldElem)\n\nConstruct the value 0 + O(p^n) given m = p^n. An exception results if m is not found to be a power of p = prime(R).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"The O(p^n) construction can be used to construct q-adic values of precision n by adding it to integer values representing the q-adic value modulo p^n as in the examples.","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Examples","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"julia> R, _ = QadicField(7, 1, 30);\n\njulia> S, _ = QadicField(ZZ(65537), 1, 30);\n\njulia> c = 1 + 2*7 + 4*7^2 + O(R, 7^3)\n7^0 + 2*7^1 + 4*7^2 + O(7^3)\n\njulia> d = 13 + 357*ZZ(65537) + O(S, ZZ(65537)^12)\n13*65537^0 + 357*65537^1 + O(65537^12)\n\njulia> f = ZZ(1)//7^2 + ZZ(2)//7 + 3 + 4*7 + O(R, 7^2)\n7^-2 + 2*7^-1 + 3*7^0 + 4*7^1 + O(7^2)","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Beware that the expression 1 + 2*p + 3*p^2 + O(R, p^n) is actually computed as a normal Julia expression. Therefore if {Int} values are used instead of Flint integers or Julia bignums, overflow may result in evaluating the value.","category":"page"},{"location":"Nemo/qadic/#Basic-manipulation","page":"Qadics","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"prime(::FlintQadicField)","category":"page"},{"location":"Nemo/qadic/#prime-Tuple{FlintQadicField}","page":"Qadics","title":"prime","text":"prime(R::FlintQadicField)\n\nReturn the prime p for the given q-adic field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"precision(::qadic)","category":"page"},{"location":"Nemo/qadic/#precision-Tuple{qadic}","page":"Qadics","title":"precision","text":"precision(a::qadic)\n\nReturn the precision of the given q-adic field element, i.e. if the element is known to O(p^n) this function will return n.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"valuation(::qadic)","category":"page"},{"location":"Nemo/qadic/#valuation-Tuple{qadic}","page":"Qadics","title":"valuation","text":"valuation(a::qadic)\n\nReturn the valuation of the given q-adic field element, i.e. if the given element is divisible by p^n but not a higher power of q then the function will return n.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"lift(::QQPolyRing, ::qadic)\nlift(::ZZPolyRing, ::qadic)","category":"page"},{"location":"Nemo/qadic/#lift-Tuple{QQPolyRing, qadic}","page":"Qadics","title":"lift","text":"lift(R::QQPolyRing, a::qadic)\n\nReturn a lift of the given q-adic field element to mathbbQx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/#lift-Tuple{ZZPolyRing, qadic}","page":"Qadics","title":"lift","text":"lift(R::ZZPolyRing, a::qadic)\n\nReturn a lift of the given q-adic field element to mathbbZx if possible.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Examples","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"R, _ = QadicField(7, 1, 30);\n\na = 1 + 2*7 + 4*7^2 + O(R, 7^3)\nb = 7^2 + 3*7^3 + O(R, 7^5)\nc = R(2)\n\nk = precision(a)\nm = prime(R)\nn = valuation(b)\nQx, x = FlintQQ[\"x\"]\np = lift(Qx, a)\nZy, y = FlintZZ[\"y\"]\nq = lift(Zy, divexact(a, b))","category":"page"},{"location":"Nemo/qadic/#Square-root","page":"Qadics","title":"Square root","text":"","category":"section"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Base.sqrt(::qadic)","category":"page"},{"location":"Nemo/qadic/#sqrt-Tuple{qadic}","page":"Qadics","title":"sqrt","text":"sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of the given Puiseux series a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nBase.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of f. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.\n\n\n\n\n\nBase.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nsqrt(a::FieldElem)\n\nReturn the square root of the element a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Examples","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"julia> R, _ = QadicField(7, 1, 30);\n\njulia> a = 1 + 7 + 2*7^2 + O(R, 7^3)\n7^0 + 7^1 + 2*7^2 + O(7^3)\n\njulia> b = 2 + 3*7 + O(R, 7^5)\n2*7^0 + 3*7^1 + O(7^5)\n\njulia> c = 7^2 + 2*7^3 + O(R, 7^4)\n7^2 + 2*7^3 + O(7^4)\n\njulia> d = sqrt(a)\n7^0 + 4*7^1 + 3*7^2 + O(7^3)\n\njulia> f = sqrt(b)\n4*7^0 + 7^1 + 5*7^2 + 5*7^3 + 6*7^4 + O(7^5)\n\njulia> f = sqrt(c)\n7^1 + 7^2 + O(7^3)\n\njulia> g = sqrt(R(121))\n4*7^0 + 7^1 + O(7^30)","category":"page"},{"location":"Nemo/qadic/#Special-functions","page":"Qadics","title":"Special functions","text":"","category":"section"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Base.exp(::qadic)","category":"page"},{"location":"Nemo/qadic/#exp-Tuple{qadic}","page":"Qadics","title":"exp","text":"exp(a::Generic.LaurentSeriesElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the exponential of the given Puiseux series a.\n\n\n\n\n\nexp(a::AbsPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::RelPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"log(::qadic)","category":"page"},{"location":"Nemo/qadic/#log-Tuple{qadic}","page":"Qadics","title":"log","text":"log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the logarithm of the given Puiseux series a.\n\n\n\n\n\nlog(a::SeriesElem{T}) where T <: FieldElement\n\nReturn the logarithm of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"teichmuller(::qadic)","category":"page"},{"location":"Nemo/qadic/#teichmuller-Tuple{qadic}","page":"Qadics","title":"teichmuller","text":"teichmuller(a::qadic)\n\nReturn the Teichmuller lift of the q-adic value a. We require the valuation of a to be nonnegative. The precision of the output will be the same as the precision of the input. For convenience, if a is congruent to zero modulo q we return zero. If the input is not valid an exception is thrown.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"frobenius(::qadic, ::Int)","category":"page"},{"location":"Nemo/qadic/#frobenius-Tuple{qadic, Int64}","page":"Qadics","title":"frobenius","text":"frobenius(a::qadic, e::Int = 1)\n\nReturn the image of the e-th power of Frobenius on the q-adic value a. The precision of the output will be the same as the precision of the input.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Examples","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"julia> R, _ = QadicField(7, 1, 30);\n\njulia> a = 1 + 7 + 2*7^2 + O(R, 7^3)\n7^0 + 7^1 + 2*7^2 + O(7^3)\n\njulia> b = 2 + 5*7 + 3*7^2 + O(R, 7^3)\n2*7^0 + 5*7^1 + 3*7^2 + O(7^3)\n\njulia> c = 3*7 + 2*7^2 + O(R, 7^5)\n3*7^1 + 2*7^2 + O(7^5)\n\njulia> c = exp(c)\n7^0 + 3*7^1 + 3*7^2 + 4*7^3 + 4*7^4 + O(7^5)\n\njulia> d = log(a)\n7^1 + 5*7^2 + O(7^3)\n\njulia> c = exp(R(0))\n7^0 + O(7^30)\n\njulia> d = log(R(1))\n0\n\njulia> f = teichmuller(b)\n2*7^0 + 4*7^1 + 6*7^2 + O(7^3)\n\njulia> g = frobenius(a, 2)\n7^0 + 7^1 + 2*7^2 + O(7^3)","category":"page"},{"location":"Nemo/misc/#Miscellaneous","page":"Miscellaneous","title":"Miscellaneous","text":"","category":"section"},{"location":"Nemo/misc/#Global-variables-and-precompilation","page":"Miscellaneous","title":"Global variables and precompilation","text":"","category":"section"},{"location":"Nemo/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Due to limitations of the precompilation of modules in julia, global variables referring to certain Nemo types require special attention when used inside modules. As a simple example, the following code for a module called A will not work as expected:","category":"page"},{"location":"Nemo/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"module A\n\nusing Nemo\nQx, x = QQ[\"x\"]\nf(n) = x^n\nend","category":"page"},{"location":"Nemo/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"When running julia and loading the module via using/import A, calling f will lead to segmentation faults. The preferred workaround is to put the definitions of the global variables into the __init__() function of the module as follows:","category":"page"},{"location":"Nemo/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"module A\n\nusing Nemo\n\nfunction __init__()\n global (Qx, x) = QQ[\"x\"]\nend\n\nf(n) = x^n\nend","category":"page"},{"location":"Nemo/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Alternatively, one can disable precompilation by adding __precompile__(false) inside A. Note that this might have other unwanted side effects.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/real/#Real-field","page":"Real field","title":"Real field","text":"","category":"section"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"AbstractAlgebra.jl provides a module, implemented in src/julia/Float.jl for making Julia BigFloats conform to the AbstractAlgebra.jl Field interface.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"In addition to providing a parent object RealField for Julia BigFloats, we implement any additional functionality required by AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"Because BigFloat cannot be directly included in the AbstractAlgebra.jl abstract type hierarchy, we achieve integration of Julia BigFloats by introducing a type union, called FieldElement, which is a union of FieldElem and a number of Julia types, including BigFloat. Everywhere that FieldElem is notionally used in AbstractAlgebra.jl, we are in fact using FieldElement, with additional care being taken to avoid ambiguities.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"The details of how this is done are technical, and we refer the reader to the implementation for details. For most intents and purposes, one can think of the Julia BigFloat type as belonging to FieldElem.","category":"page"},{"location":"AbstractAlgebra/real/#Types-and-parent-objects","page":"Real field","title":"Types and parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"Reals have type BigFloat, as in Julia itself. We simply supplement the functionality for this type as required for computer algebra.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"The parent objects of such integers has type Floats{BigFloat}.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"For convenience, we also make Float64 a part of the AbstractAlgebra.jl type hierarchy and its parent object (accessible as RDF) has type Floats{Float64}.","category":"page"},{"location":"AbstractAlgebra/real/#Rational-constructors","page":"Real field","title":"Rational constructors","text":"","category":"section"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"In order to construct reals in AbstractAlgebra.jl, one can first construct the real field itself. This is accomplished using the following constructor.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"Floats{BigFloat}()","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"This gives the unique object of type Floats{BigFloat} representing the field of reals in AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"In practice, one simply uses RealField which is assigned to be the return value of the above constructor. There is no need to call the constructor in practice.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"Here are some examples of creating the real field and making use of the resulting parent object to coerce various elements into the field.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"Examples","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"julia> RR = RealField\nFloats\n\njulia> f = RR()\n0.0\n\njulia> g = RR(123)\n123.0\n\njulia> h = RR(BigInt(1234))\n1234.0\n\njulia> k = RR(12//7)\n1.714285714285714285714285714285714285714285714285714285714285714285714285714291\n\njulia> m = RR(2.3)\n2.29999999999999982236431605997495353221893310546875\n","category":"page"},{"location":"AbstractAlgebra/real/#Basic-field-functionality","page":"Real field","title":"Basic field functionality","text":"","category":"section"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"The real field in AbstractAlgebra.jl implements the full Field interface.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"We give some examples of such functionality.","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"Examples","category":"page"},{"location":"AbstractAlgebra/real/","page":"Real field","title":"Real field","text":"julia> RR = RealField\nFloats\n\njulia> f = RR(12//7)\n1.714285714285714285714285714285714285714285714285714285714285714285714285714291\n\njulia> h = zero(RR)\n0.0\n\njulia> k = one(RR)\n1.0\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> U = base_ring(RR)\nUnion{}\n\njulia> T = parent(f)\nFloats\n\njulia> f == deepcopy(f)\ntrue\n\njulia> g = f + 12\n13.71428571428571428571428571428571428571428571428571428571428571428571428571433\n\njulia> m = inv(g)\n0.07291666666666666666666666666666666666666666666666666666666666666666666666666631\n","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/#Extending-the-interface-of-AbstractAlgebra.jl","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"In this section we will discuss on how to extend the interface of AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/#Elements-and-parents","page":"Extending the interface of AbstractAlgebra.jl","title":"Elements and parents","text":"","category":"section"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"Any implementation with elements and parents should implement the following interface:","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"parent\nelem_type\nparent_type","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/#parent","page":"Extending the interface of AbstractAlgebra.jl","title":"parent","text":"parent(a)\n\nReturn parent object of given element a.\n\nExamples\n\njulia> G = SymmetricGroup(5); g = Perm([3,4,5,2,1])\n(1,3,5)(2,4)\n\njulia> parent(g) == G\ntrue\n\njulia> S, x = laurent_series_ring(ZZ, 3, \"x\")\n(Laurent series ring in x over integers, x + O(x^4))\n\njulia> parent(x) == S\ntrue\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/#elem_type","page":"Extending the interface of AbstractAlgebra.jl","title":"elem_type","text":"elem_type(::Type{T}) where T <: GAPGroup\nelem_type(::T) where T <: GAPGroup\n\nelem_type maps (the type of) a group to the type of its elements. For now, a group of type T has elements of type BasicGAPGroupElem{T}. So we provide it mostly for consistency with other parts of OSCAR. In the future, a more elaborate setup for group element types might also be needed.\n\n\n\n\n\nelem_type(parent)\nelem_type(parent_type)\n\nGiven a parent object (or its type), return the type of its elements.\n\nExamples\n\njulia> S, x = power_series_ring(QQ, 2, \"x\")\n(Univariate power series ring over rationals, x + O(x^3))\n\njulia> elem_type(S) == typeof(x)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/#parent_type","page":"Extending the interface of AbstractAlgebra.jl","title":"parent_type","text":"parent_type(element)\nparent_type(element_type)\n\nGiven an element (or its type), return the type of its parent object.\n\nExamples\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = matrix_space(R, 2, 2)\nMatrix space of 2 rows and 2 columns\n over univariate polynomial ring in x over integers\n\njulia> a = rand(S, 0:1, 0:1);\n\njulia> parent_type(a) == typeof(S)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/#Acquiring-associated-elements-and-parents","page":"Extending the interface of AbstractAlgebra.jl","title":"Acquiring associated elements and parents","text":"","category":"section"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"Further, if one has a base ring, like polynomials over the integers mathbbZx, then one should implement","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"base_ring","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/#base_ring","page":"Extending the interface of AbstractAlgebra.jl","title":"base_ring","text":"base_ring(a)\n\nReturn base ring R of given element or parent a.\n\nExamples\n\njulia> S, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> base_ring(S) == QQ\ntrue\n\njulia> R = GF(7)\nFinite field F_7\n\njulia> base_ring(R)\nUnion{}\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/#Special-elements","page":"Extending the interface of AbstractAlgebra.jl","title":"Special elements","text":"","category":"section"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"For rings, one has to extend the following methods:","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"one\nzero","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/#one","page":"Extending the interface of AbstractAlgebra.jl","title":"one","text":"one(a)\n\nReturn the multiplicative identity in the algebraic structure of a, which can be either an element or parent.\n\nExamples\n\njulia> S = matrix_space(ZZ, 2, 2)\nMatrix space of 2 rows and 2 columns\n over integers\n\njulia> one(S)\n[1 0]\n[0 1]\n\njulia> R, x = PuiseuxSeriesField(QQ, 4, \"x\")\n(Puiseux series field in x over rationals, x + O(x^5))\n\njulia> one(x)\n1 + O(x^4)\n\njulia> G = GF(5)\nFinite field F_5\n\njulia> one(G)\n1\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/#zero","page":"Extending the interface of AbstractAlgebra.jl","title":"zero","text":"zero(a)\n\nReturn the additive identity in the algebraic structure of a, which can be either an element or parent.\n\nExamples\n\njulia> S = MatrixAlgebra(QQ, 2)\nMatrix algebra of degree 2\n over rationals\n\njulia> zero(S)\n[0//1 0//1]\n[0//1 0//1]\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> zero(x^3 + 2)\n0\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"Groups should only extend at least one of these. The one that is required depends on if the group is additive (commutative) or multiplicative.","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/#Basic-manipulation","page":"Extending the interface of AbstractAlgebra.jl","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"If one would like to implement a ring, these are the basic manipulation methods that all rings should extend:","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"isone\niszero\nis_unit","category":"page"},{"location":"AbstractAlgebra/extending_abstractalgebra/#isone","page":"Extending the interface of AbstractAlgebra.jl","title":"isone","text":"isone(a)\n\nReturn true if a is the multiplicative identity, else return false.\n\nExamples\n\njulia> S = matrix_space(ZZ, 2, 2); T = matrix_space(ZZ, 2, 3); U = matrix_space(ZZ, 3, 2);\n\njulia> isone(S([1 0; 0 1]))\ntrue\n\njulia> isone(T([1 0 0; 0 1 0]))\nfalse\n\njulia> isone(U([1 0; 0 1; 0 0]))\nfalse\n\njulia> T, x = PuiseuxSeriesField(QQ, 10, \"x\")\n(Puiseux series field in x over rationals, x + O(x^11))\n\njulia> isone(x), isone(T(1))\n(false, true)\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/#iszero","page":"Extending the interface of AbstractAlgebra.jl","title":"iszero","text":"iszero(a)\n\nReturn true if a is the additative identity, else return false.\n\nExamples\n\njulia> T, x = PuiseuxSeriesField(QQ, 10, \"x\")\n(Puiseux series field in x over rationals, x + O(x^11))\n\njulia> a = T(0)\nO(x^10)\n\njulia> iszero(a)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/#is_unit","page":"Extending the interface of AbstractAlgebra.jl","title":"is_unit","text":"is_unit(a::T) where {T <: NCRingElem}\n\nReturn true if a is invertible, else return false.\n\nExamples\n\njulia> S, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> is_unit(x), is_unit(S(1)), is_unit(S(4))\n(false, true, true)\n\njulia> is_unit(ZZ(-1)), is_unit(ZZ(4))\n(true, false)\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/extending_abstractalgebra/","page":"Extending the interface of AbstractAlgebra.jl","title":"Extending the interface of AbstractAlgebra.jl","text":"With the same logic as earlier, groups only need to extend one of the methods isone and iszero.","category":"page"},{"location":"Experimental/PlaneCurve/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/PlaneCurve/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/PlaneCurve/introduction/","page":"Introduction","title":"Introduction","text":"The Plane Curves module of OSCAR provides functionality for handling","category":"page"},{"location":"Experimental/PlaneCurve/introduction/","page":"Introduction","title":"Introduction","text":"Affine Plane Curves,\nProjective Plane Curves, in particular Elliptic Curves.","category":"page"},{"location":"Experimental/PlaneCurve/introduction/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"Experimental/PlaneCurve/introduction/","page":"Introduction","title":"Introduction","text":"William Fulton (1969)\nAndreas Gathmann (2018)\nHenri Cohen (1993)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Chain-and-Cochain-Complexes","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"The general OSCAR type ComplexOfMorphisms{T} allows one to model both chain complexes and cochain complexes (the T refers to the type of the differentials of the complex). In the context of commutative algebra, we handle complexes of modules and module homomorphisms over multivariate polynomial rings. In this section, we first show how to create such complexes. Then we discuss functionality for dealing with the constructed complexes, mainly focusing on chain complexes. Cochain complexes can be handled similarly.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Constructors","page":"Chain and Cochain Complexes","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"chain_complex(V::ModuleFPHom...; seed::Int = 0)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#chain_complex-Tuple{Vararg{ModuleFPHom}}","page":"Chain and Cochain Complexes","title":"chain_complex","text":"chain_complex(V::ModuleFPHom...; seed::Int = 0)\n\nGiven a tuple V of module homorphisms between successive modules over a multivariate polynomial ring, return the chain complex defined by these homomorphisms.\n\nchain_complex(V::Vector{<:ModuleFPHom}; seed::Int = 0)\n\nGiven a vector V of module homorphisms between successive modules over a multivariate polynomial ring, return the chain complex defined by these homomorphisms.\n\nnote: Note\nThe integer seed indicates the lowest homological degree of a module in the complex.\n\nnote: Note\nThe function checks whether successive homomorphisms indeed compose to zero.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"cochain_complex(V::ModuleFPHom...; ssed::Int = 0)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#cochain_complex-Tuple{Vararg{ModuleFPHom}}","page":"Chain and Cochain Complexes","title":"cochain_complex","text":"cochain_complex(V::ModuleFPHom...; seed::Int = 0)\n\nGiven a tuple V of module homorphisms between successive modules over a multivariate polynomial ring, return the cochain complex defined by these homomorphisms.\n\ncochain_complex(V::Vector{<:ModuleFPHom}; seed::Int = 0)\n\nGiven a vector V of module homorphisms between successive modules over a multivariate polynomial ring, return the cochain complex defined by these homomorphisms.\n\nnote: Note\nThe integer seed indicates the lowest cohomological degree of a module of the complex.\n\nnote: Note\nThe function checks whether successive homomorphisms indeed compose to zero.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Data-Associated-to-Complexes","page":"Chain and Cochain Complexes","title":"Data Associated to Complexes","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"Given a complex C,","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"range(C) refers to the range of C,\nobj(C, i) and C[i] to the i-th module of C, and\nmap(C, i) to the i-th differential of C.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Examples","page":"Chain and Cochain Complexes","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"julia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A, _ = quo(F, [x^4*F[1]]);\n\njulia> B, _ = quo(F, [x^3*F[1]]);\n\njulia> a = hom(A, B, [x^2*B[1]]);\n\njulia> b = hom(B, B, [x^2*B[1]]);\n\njulia> C = chain_complex([a, b]; seed = 3)\nC_3 <---- C_4 <---- C_5\n\njulia> range(C)\n5:-1:3\n\njulia> C[5]\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 1 generator\n1 -> x^4*e[1]\n\njulia> delta = map(C, 5)\nMap with following data\nDomain:\n=======\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 1 generator\n1 -> x^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 1 generator\n1 -> x^3*e[1]\n\njulia> matrix(delta)\n[x^2]","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Operations-on-Complexes","page":"Chain and Cochain Complexes","title":"Operations on Complexes","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"shift(C::ComplexOfMorphisms{T}, d::Int) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"Return the complex obtained from C by shifting the homological degrees d steps, with maps multiplied by (-1)^d.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Examples-2","page":"Chain and Cochain Complexes","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"julia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A, _ = quo(F, [x^4*F[1]]);\n\njulia> B, _ = quo(F, [x^3*F[1]]);\n\njulia> a = hom(A, B, [x^2*B[1]]);\n\njulia> b = hom(B, B, [x^2*B[1]]);\n\njulia> C = chain_complex([a, b]; seed = 3);\n\njulia> range(C)\n5:-1:3\n\njulia> D = shift(C, 3);\n\njulia> range(D)\n8:-1:6","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"hom(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#hom-Tuple{ComplexOfMorphisms{ModuleFP}, ModuleFP}","page":"Chain and Cochain Complexes","title":"hom","text":"hom(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)\n\nReturn the complex obtained by applying textHom(- M) to C.\n\nIf C is a chain complex, return a cochain complex. If C is a cochain complex, return a chain complex.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A, _ = quo(F, [x^4*F[1]]);\n\njulia> B, _ = quo(F, [x^3*F[1]]);\n\njulia> a = hom(A, B, [x^2*B[1]]);\n\njulia> b = hom(B, B, [x^2*B[1]]);\n\njulia> C = chain_complex([a, b]; seed = 3);\n\njulia> range(C)\n5:-1:3\n\njulia> D = hom(C, A);\n\njulia> range(D)\n3:5\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"hom_without_reversing_direction(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#hom_without_reversing_direction-Tuple{ComplexOfMorphisms{ModuleFP}, ModuleFP}","page":"Chain and Cochain Complexes","title":"hom_without_reversing_direction","text":"hom_without_reversing_direction(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)\n\nReturn the complex obtained by applying textHom(- M) to C.\n\nIf C is a chain complex, return a chain complex. If C is a cochain complex, return a cochain complex.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A, _ = quo(F, [x^4*F[1]]);\n\njulia> B, _ = quo(F, [x^3*F[1]]);\n\njulia> a = hom(A, B, [x^2*B[1]]);\n\njulia> b = hom(B, B, [x^2*B[1]]);\n\njulia> C = chain_complex([a, b]; seed = 3);\n\njulia> range(C)\n5:-1:3\n\njulia> D = hom_without_reversing_direction(C, A);\n\njulia> range(D)\n-3:-1:-5\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"hom(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#hom-Tuple{ModuleFP, ComplexOfMorphisms{ModuleFP}}","page":"Chain and Cochain Complexes","title":"hom","text":"hom(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})\n\nReturn the complex obtained by applying textHom(M, -) to C.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"tensor_product(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#tensor_product-Tuple{ComplexOfMorphisms{ModuleFP}, ModuleFP}","page":"Chain and Cochain Complexes","title":"tensor_product","text":"tensor_product(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)\n\nReturn the complex obtained by applying bullet otimes M to C.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"tensor_product(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#tensor_product-Tuple{ModuleFP, ComplexOfMorphisms{ModuleFP}}","page":"Chain and Cochain Complexes","title":"tensor_product","text":"tensor_product(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})\n\nReturn the complex obtained by applying M otimes bullet to C.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Tests-on-Complexes","page":"Chain and Cochain Complexes","title":"Tests on Complexes","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"The functions below check properties of complexes:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"is_chain_complex(C::ComplexOfMorphisms{ModuleFP})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"is_cochain_complex(C::ComplexOfMorphisms{ModuleFP})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"is_exact(C::ComplexOfMorphisms{ModuleFP})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Examples-3","page":"Chain and Cochain Complexes","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"julia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A, _ = quo(F, [x^4*F[1]]);\n\njulia> B, _ = quo(F, [x^3*F[1]]);\n\njulia> a = hom(A, B, [x^2*B[1]]);\n\njulia> b = hom(B, B, [x^2*B[1]]);\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> C = chain_complex([a, b]);\n\njulia> is_cochain_complex(C)\nfalse","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Maps-of-Complexes","page":"Chain and Cochain Complexes","title":"Maps of Complexes","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Types","page":"Chain and Cochain Complexes","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/#Constructors-2","page":"Chain and Cochain Complexes","title":"Constructors","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/#Genera-of-Integer-Lattices","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"Two mathbbZ-lattices M and N are said to be in the same genus if their completions M otimes mathbbZ_p and N otimes mathbbZ_p are isometric for all prime numbers p as well as M otimes mathbbR cong Notimes mathbbR.","category":"page"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"The genus of a mathbbZ-lattice is encoded in its Conway-Sloane genus symbol. The genus symbol itself is a collection of its local genus symbols. See J. H. Conway, N. J. A. Sloane (1999) Chapter 15 for the definitions. Note that genera for non-integral lattices are supported.","category":"page"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"The class ZZGenus supports genera of mathbbZ-lattices.","category":"page"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"ZZGenus","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#ZZGenus","page":"Genera of Integer Lattices","title":"ZZGenus","text":"ZZGenus\n\nA collection of local genus symbols (at primes) and a signature pair. Together they represent the genus of a non-degenerate integer_lattice.\n\n\n\n\n\n","category":"type"},{"location":"Hecke/quad_forms/Zgenera/#Creation-of-Genera","page":"Genera of Integer Lattices","title":"Creation of Genera","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/#From-an-integral-Lattice","page":"Genera of Integer Lattices","title":"From an integral Lattice","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"genus(::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#genus-Tuple{ZZLat}","page":"Genera of Integer Lattices","title":"genus","text":"genus(L::ZZLat) -> ZZGenus\n\nReturn the genus of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#From-a-gram-matrix","page":"Genera of Integer Lattices","title":"From a gram matrix","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"genus(A::MatElem)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#genus-Tuple{MatElem}","page":"Genera of Integer Lattices","title":"genus","text":"genus(A::MatElem) -> ZZGenus\n\nReturn the genus of a mathbb Z-lattice with gram matrix A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Enumeration-of-genus-symbols","page":"Genera of Integer Lattices","title":"Enumeration of genus symbols","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"integer_genera(sig_pair::Tuple{Int,Int}, determinant::Union{Int,ZZRingElem})","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#integer_genera-Tuple{Tuple{Int64, Int64}, Union{Int64, ZZRingElem}}","page":"Genera of Integer Lattices","title":"integer_genera","text":"integer_genera(sig_pair::Vector{Int}, determinant::RationalUnion;\n min_scale::RationalUnion = min(one(QQ), QQ(abs(determinant))),\n max_scale::RationalUnion = max(one(QQ), QQ(abs(determinant))),\n even=false) -> Vector{ZZGenus}\n\nReturn a list of all genera with the given conditions. Genera of non-integral mathbb Z-lattices are also supported.\n\nArguments\n\nsig_pair: a pair of non-negative integers giving the signature\ndeterminant: a rational number; the sign is ignored\nmin_scale: a rational number; return only genera whose scale is an integer multiple of min_scale (default: min(one(QQ), QQ(abs(determinant))))\nmax_scale: a rational number; return only genera such that max_scale is an integer multiple of the scale (default: max(one(QQ), QQ(abs(determinant))))\neven: boolean; if set to true, return only the even genera (default: false)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#From-other-genus-symbols","page":"Genera of Integer Lattices","title":"From other genus symbols","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"direct_sum(G1::ZZGenus, G2::ZZGenus)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#direct_sum-Tuple{ZZGenus, ZZGenus}","page":"Genera of Integer Lattices","title":"direct_sum","text":"direct_sum(G1::ZZGenus, G2::ZZGenus) -> ZZGenus\n\nReturn the genus of the direct sum of G1 and G2.\n\nThe direct sum is defined via representatives.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Attributes-of-the-genus","page":"Genera of Integer Lattices","title":"Attributes of the genus","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"dim(G::ZZGenus)\nrank(G::ZZGenus)\nsignature(G::ZZGenus)\ndet(G::ZZGenus)\niseven(G::ZZGenus)\nis_definite(G::ZZGenus)\nlevel(G::ZZGenus)\nscale(G::ZZGenus)\nnorm(G::ZZGenus)\nprimes(G::ZZGenus)\nis_integral(G::ZZGenus)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#dim-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"dim","text":"dim(G::ZZGenus) -> Int\n\nReturn the dimension of this genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#rank-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"rank","text":"rank(G::ZZGenus) -> Int\n\nReturn the rank of a (representative of) the genus G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#signature-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"signature","text":"signature(G::ZZGenus) -> Int\n\nReturn the signature of this genus.\n\nThe signature is p - n where p is the number of positive eigenvalues and n the number of negative eigenvalues.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#det-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"det","text":"det(G::ZZGenus) -> QQFieldElem\n\nReturn the determinant of this genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#iseven-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"iseven","text":"iseven(G::ZZGenus) -> Bool\n\nReturn if this genus is even.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#is_definite-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"is_definite","text":"is_definite(G::ZZGenus) -> Bool\n\nReturn if this genus is definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#level-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"level","text":"level(G::ZZGenus) -> QQFieldElem\n\nReturn the level of this genus.\n\nThis is the denominator of the inverse gram matrix of a representative.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#scale-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"scale","text":"scale(G::ZZGenus) -> QQFieldElem\n\nReturn the scale of this genus.\n\nLet L be a lattice with bilinear form b. The scale of (L,b) is defined as the ideal b(L,L).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#norm-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"norm","text":"norm(G::ZZGenus) -> QQFieldElem\n\nReturn the norm of this genus.\n\nLet L be a lattice with bilinear form b. The norm of (L,b) is defined as the ideal generated by b(xx) x in L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#primes-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"primes","text":"primes(G::ZZGenus) -> Vector{ZZRingElem}\n\nReturn the list of primes of the local symbols of G.\n\nNote that 2 is always in the output since the 2-adic symbol of a ZZGenus is, by convention, always defined.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#is_integral-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"is_integral","text":"is_integral(G::ZZGenus) -> Bool\n\nReturn whether G is a genus of integral mathbb Z-lattices.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Discriminant-group","page":"Genera of Integer Lattices","title":"Discriminant group","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"discriminant_group(::ZZGenus)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#Primary-genera","page":"Genera of Integer Lattices","title":"Primary genera","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"is_primary_with_prime(G::ZZGenus)\nis_primary(G::ZZGenus, p::Union{Integer, ZZRingElem})\nis_elementary_with_prime(G::ZZGenus)\nis_elementary(G::ZZGenus, p::Union{Integer, ZZRingElem})","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#is_primary_with_prime-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"is_primary_with_prime","text":"is_primary_with_prime(G::ZZGenus) -> Bool, ZZRingElem\n\nGiven a genus of mathbb Z-lattices G, return whether it is primary, that is whether the bilinear form is integral and the associated discriminant form (see discriminant_group) is a p-group for some prime number p. In case it is, p is also returned as second output.\n\nNote that for unimodular genera, this function returns (true, 1). If the genus is not primary, the second return value is -1 by default.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#is_primary-Tuple{ZZGenus, Union{Integer, ZZRingElem}}","page":"Genera of Integer Lattices","title":"is_primary","text":"is_primary(G::ZZGenus, p::Union{Integer, ZZRingElem}) -> Bool\n\nGiven a genus of integral mathbb Z-lattices G and a prime number p, return whether G is p-primary, that is whether the associated discriminant form (see discriminant_group) is a p-group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#is_elementary_with_prime-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"is_elementary_with_prime","text":"is_elementary_with_prime(G::ZZGenus) -> Bool, ZZRingElem\n\nGiven a genus of mathbb Z-lattices G, return whether it is elementary, that is whether the bilinear form is inegtral and the associated discriminant form (see discriminant_group) is an elementary p-group for some prime number p. In case it is, p is also returned as second output.\n\nNote that for unimodular genera, this function returns (true, 1). If the genus is not elementary, the second return value is -1 by default.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#is_elementary-Tuple{ZZGenus, Union{Integer, ZZRingElem}}","page":"Genera of Integer Lattices","title":"is_elementary","text":"is_elementary(G::ZZGenus, p::Union{Integer, ZZRingElem}) -> Bool\n\nGiven a genus of integral mathbb Z-lattices G and a prime number p, return whether G is p-elementary, that is whether its associated discriminant form (see discriminant_group) is an elementary p-group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#local-Symbol","page":"Genera of Integer Lattices","title":"local Symbol","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"local_symbol(G::ZZGenus, p)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#local_symbol-Tuple{ZZGenus, Any}","page":"Genera of Integer Lattices","title":"local_symbol","text":"local_symbol(G::ZZGenus, p) -> ZZLocalGenus\n\nReturn the local symbol at p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Representative(s)","page":"Genera of Integer Lattices","title":"Representative(s)","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"quadratic_space(G::ZZGenus)\nrational_representative(G::ZZGenus)\nrepresentative(G::ZZGenus)\nrepresentatives(G::ZZGenus)\nmass(G::ZZGenus)\nrescale(::ZZGenus, ::RationalUnion)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#quadratic_space-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"quadratic_space","text":"quadratic_space(G::ZZGenus) -> QuadSpace{QQField, QQMatrix}\n\nReturn the quadratic space defined by this genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#rational_representative-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"rational_representative","text":"rational_representative(G::ZZGenus) -> QuadSpace{QQField, QQMatrix}\n\nReturn the quadratic space defined by this genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#representative-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"representative","text":"representative(G::ZZGenus) -> ZZLat\n\nCompute a representative of this genus && cache it.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#representatives-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"representatives","text":"representatives(G::ZZGenus) -> Vector{ZZLat}\n\nReturn a list of representatives of the isometry classes in this genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#mass-Tuple{ZZGenus}","page":"Genera of Integer Lattices","title":"mass","text":"mass(G::ZZGenus) -> QQFieldElem\n\nReturn the mass of this genus.\n\nThe genus must be definite. Let L_1, ... L_n be a complete list of representatives of the isometry classes in this genus. Its mass is defined as sum_i=1^n frac1O(L_i).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#rescale-Tuple{ZZGenus, Union{Integer, QQFieldElem, ZZRingElem, Rational}}","page":"Genera of Integer Lattices","title":"rescale","text":"rescale(G::ZZGenus, a::RationalUnion) -> ZZGenus\n\nGiven a genus symbol G of mathbb Z-lattices, return the genus symbol of any representative of G rescaled by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Embeddings-and-Representations","page":"Genera of Integer Lattices","title":"Embeddings and Representations","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"represents(G1::ZZGenus, G2::ZZGenus)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#represents-Tuple{ZZGenus, ZZGenus}","page":"Genera of Integer Lattices","title":"represents","text":"represents(G1::ZZGenus, G2::ZZGenus) -> Bool\n\nReturn if G1 represents G2. That is if some element in the genus of G1 represents some element in the genus of G2.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Local-genus-Symbols","page":"Genera of Integer Lattices","title":"Local genus Symbols","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"ZZLocalGenus","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#ZZLocalGenus","page":"Genera of Integer Lattices","title":"ZZLocalGenus","text":"ZZLocalGenus\n\nLocal genus symbol over a p-adic ring.\n\nThe genus symbol of a component p^m A for odd prime = p is of the form (m,n,d), where\n\nm = valuation of the component\nn = rank of A\nd = det(A) \\in \\{1,u\\} for a normalized quadratic non-residue u.\n\nThe genus symbol of a component 2^m A is of the form (m, n, s, d, o), where\n\nm = valuation of the component\nn = rank of A\nd = det(A) in {1,3,5,7}\ns = 0 (or 1) if even (or odd)\no = oddity of A (= 0 if s = 0) in Z/8Z = the trace of the diagonalization of A\n\nThe genus symbol is a list of such symbols (ordered by m) for each of the Jordan blocks A_1,...,A_t.\n\nReference: J. H. Conway, N. J. A. Sloane (1999) Chapter 15, Section 7.\n\nArguments\n\nprime: a prime number\nsymbol: the list of invariants for Jordan blocks A_t,...,A_t given as a list of lists of integers\n\n\n\n\n\n","category":"type"},{"location":"Hecke/quad_forms/Zgenera/#Creation","page":"Genera of Integer Lattices","title":"Creation","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"genus(L::ZZLat, p)\ngenus(A::ZZMatrix, p)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#genus-Tuple{ZZLat, Any}","page":"Genera of Integer Lattices","title":"genus","text":"genus(L::ZZLat, p) -> ZZLocalGenus\n\nReturn the local genus symbol of L at the prime p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#genus-Tuple{ZZMatrix, Any}","page":"Genera of Integer Lattices","title":"genus","text":"genus(A::MatElem, p) -> ZZLocalGenus\n\nReturn the local genus symbol of a Z-lattice with gram matrix A at the prime p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Attributes","page":"Genera of Integer Lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"prime(S::ZZLocalGenus)\niseven(S::ZZLocalGenus)\nsymbol(S::ZZLocalGenus, scale::Int)\nhasse_invariant(S::ZZLocalGenus)\ndet(S::ZZLocalGenus)\ndim(S::ZZLocalGenus)\nrank(S::ZZLocalGenus)\nexcess(S::ZZLocalGenus)\nsignature(S::ZZLocalGenus)\noddity(S::ZZLocalGenus)\nscale(S::ZZLocalGenus)\nnorm(S::ZZLocalGenus)\nlevel(S::ZZLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#prime-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"prime","text":"prime(S::ZZLocalGenus) -> ZZRingElem\n\nReturn the prime p of this p-adic genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#iseven-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"iseven","text":"iseven(S::ZZLocalGenus) -> Bool\n\nReturn if the underlying p-adic lattice is even.\n\nIf p is odd, every lattice is even.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#symbol-Tuple{ZZLocalGenus, Int64}","page":"Genera of Integer Lattices","title":"symbol","text":"symbol(S::ZZLocalGenus, scale::Int) -> Vector{Int}\n\nReturn a copy of the underlying lists of integers for the Jordan block of the given scale\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#hasse_invariant-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"hasse_invariant","text":"hasse_invariant(S::ZZLocalGenus) -> Int\n\nReturn the Hasse invariant of a representative. If the representative is diagonal (a1, ... , an) Then the Hasse invariant is\n\nprod_i j(a_i a_j)_p\n\n.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#det-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"det","text":"det(S::ZZLocalGenus) -> QQFieldElem\n\nReturn an rational representing the determinant of this genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#dim-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"dim","text":"dim(S::ZZLocalGenus) -> Int\n\nReturn the dimension of this genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#rank-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"rank","text":"rank(S::ZZLocalGenus) -> Int\n\nReturn the rank of (a representative of) S.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#excess-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"excess","text":"excess(S::ZZLocalGenus) -> zzModRingElem\n\nReturn the p-excess of the quadratic form whose Hessian matrix is the symmetric matrix A.\n\nWhen p = 2 the p-excess is called the oddity. The p-excess is always even && is divisible by 4 if p is congruent 1 mod 4.\n\nReference\n\nJ. H. Conway, N. J. A. Sloane (1999) pp 370-371.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#signature-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"signature","text":"signature(S::ZZLocalGenus) -> zzModRingElem\n\nReturn the p-signature of this p-adic form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#oddity-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"oddity","text":"oddity(S::ZZLocalGenus) -> zzModRingElem\n\nReturn the oddity of this even form. The oddity is also called the 2-signature\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#scale-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"scale","text":"scale(S::ZZLocalGenus) -> QQFieldElem\n\nReturn the scale of this local genus.\n\nLet L be a lattice with bilinear form b. The scale of (L,b) is defined as the ideal b(L,L).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#norm-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"norm","text":"norm(S::ZZLocalGenus) -> QQFieldElem\n\nReturn the norm of this local genus.\n\nLet L be a lattice with bilinear form b. The norm of (L,b) is defined as the ideal generated by b(xx) x in L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#level-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"level","text":"level(S::ZZLocalGenus) -> QQFieldElem\n\nReturn the maximal scale of a jordan component.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Representative","page":"Genera of Integer Lattices","title":"Representative","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"representative(S::ZZLocalGenus)\ngram_matrix(S::ZZLocalGenus)\nrescale(S::ZZLocalGenus, a::RationalUnion)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#representative-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"representative","text":"representative(S::ZZLocalGenus) -> ZZLat\n\nReturn an integer lattice which represents this local genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#gram_matrix-Tuple{ZZLocalGenus}","page":"Genera of Integer Lattices","title":"gram_matrix","text":"gram_matrix(S::ZZLocalGenus) -> MatElem\n\nReturn a gram matrix of some representative of this local genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#rescale-Tuple{ZZLocalGenus, Union{Integer, QQFieldElem, ZZRingElem, Rational}}","page":"Genera of Integer Lattices","title":"rescale","text":"rescale(G::ZZLocalGenus, a::RationalUnion) -> ZZLocalGenus\n\nGiven a local genus symbol G of mathbb Z-lattices, return the local genus symbol of any representative of G rescaled by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Direct-sums","page":"Genera of Integer Lattices","title":"Direct sums","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"direct_sum(S1::ZZLocalGenus, S2::ZZLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#direct_sum-Tuple{ZZLocalGenus, ZZLocalGenus}","page":"Genera of Integer Lattices","title":"direct_sum","text":"direct_sum(S1::ZZLocalGenus, S2::ZZLocalGenus) -> ZZLocalGenus\n\nReturn the local genus of the direct sum of two representatives.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/Zgenera/#Embeddings/Representations","page":"Genera of Integer Lattices","title":"Embeddings/Representations","text":"","category":"section"},{"location":"Hecke/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"represents(G1::ZZLocalGenus, G2::ZZLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/Zgenera/#represents-Tuple{ZZLocalGenus, ZZLocalGenus}","page":"Genera of Integer Lattices","title":"represents","text":"represents(g1::ZZLocalGenus, g2::ZZLocalGenus) -> Bool\n\nReturn whether g1 represents g2.\n\nBased on O'Meara Integral Representations of Quadratic Forms Over Local Fields Note that for p == 2 there is a typo in O'Meara Theorem 3 (V). The correct statement is (V) 2^i(1+4omega) to mathfrakL_i+1mathfrakl_i.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"InvariantTheory/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"The invariant theory part of OSCAR provides functionality for computing polynomial invariants of group actions, focusing on finite and linearly reductive groups, respectively.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"The basic setting in this context consists of a group G, a field K, a vector space V over K of finite dimension n and a representation rho G to textGL(V) of G on V. The induced action on the dual vector space V^ast,","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"V^ast times G to V^ast (f pi)mapsto f pi = fcirc rho(pi)","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"extends to an action of G on the graded symmetric algebra","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"KV=S(V^*)=bigoplus_dgeq 0 S^d V^*","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"which preserves the grading.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"The invariants of G are the fixed points of this action, its invariant ring is the graded subalgebra","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"KV^G=fin KV mid f pi =f text for any piin G subset KV","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"Explicitly, the choice of a basis of V and its dual basis, say, x_1 dots x_n of V^* gives rise to isomorphisms textGL(V) cong textGL_n(K) and KVcong Kx_1 dots x_n. After identifying textGL(V) with textGL_n(K) and KV with Kx_1 dots x_n by means of these isomorphisms, the action of G on KV is given as follows:","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"(f pi) (x_1 dots x_n) = f((x_1 dots x_n) cdot rho(pi))","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"Accordingly, KV^G may be regarded as a graded subalgebra of Kx_1 dots x_n:","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"KV^G cong Kx_1 dots x_n^G =fin Kx_1 dots x_n mid f pi =f text for any piin G","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"The main objective of invariant theory in OSCAR is the computation of K-algebra generators for invariant rings.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nIf KV^G is finitely generated as a K-algebra, then any minimal system of homogeneous generators is called a fundamental system of invariants for KV^G. By Nakayama's lemma, the number of elements in such a system is uniquely determined as the embedding dimension of KV^G. Similarly, the degrees of these elements are uniquely determined.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nIf KV^G is finitely generated as a K-algebra, then KV^G admits a graded Noether normalization, that is, a Noether normalization Kp_1 dots p_m subset KV^G with p_1 dots p_m homogeneous. Given any such Noether normalization, p_1 dots p_m is called a homogeneous system of parameters or a system of primary invariants for KV^G, and any minimal system s_0=1 s_1dots s_l of homogeneous generators of KV^G as a Kp_1 dots p_m-module is called a system of secondary invariants for KV^G with respect to p_1 dots p_m. A secondary invariant s_ineq 1 is called irreducible if it cannot be written as a polynomial expression in the primary invariants and the other secondary invariants. The irreducible secondary invariants form a minimal system of homogeneous generators for KV^G as a Kp_1 dots p_m-algebra. Somewhat abusing notation, we call every minimal system of homogeneous generators for KV^G as a Kp_1 dots p_m-algebra a system of irreducible secondary invariants.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nFor the invariant rings handled by OSCAR, the assumption that KV^G is finitely generated as a K-algebra will be guaranteed by theoretical results. In addition, where not mentioned otherwise, the following will hold:There exists a Reynolds operator mathcal R KV to KV. That is, mathcal R is a K-linear graded map which projects KV onto KV^G, and which is a KV^G-module homomorphism.\nThe ring KV^G is Cohen-Macaulay. Equivalently, KV^G is a free module (of finite rank) over any of its graded Noether normalizations.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"The textbook","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"Harm Derksen, Gregor Kemper (2015)","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"and the survey article","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"Wolfram Decker, Theo de Jong (1998)","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"provide details on theory and algorithms as well as references.","category":"page"},{"location":"InvariantTheory/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"Wolfram Decker,\nMax Horn,\nJohannes Schmitt.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/puiseux/#Puiseux-series","page":"Puiseux series","title":"Puiseux series","text":"","category":"section"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Nemo allows the creation of Puiseux series over any computable ring R. Puiseux series are series of the form a_jx^jm + a_j+1x^(j+1)m + cdots + a_k-1x^(k-1)m + O(x^km) where m is a positive integer, a_i in R and the relative precision k - j is at most equal to some specified precision n.","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of Puiseux series over numerous specific rings, usually provided by C/C++ libraries.","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"The following table shows each of the Puiseux series types available in Nemo, the base ring R, and the Julia/Nemo types for that kind of series (the type information is mainly of concern to developers).","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl `Generic.PuiseuxSeriesRingElem{T} Generic.PuiseuxSeriesRing{T}\nGeneric field K AbstractAlgebra.jl `Generic.PuiseuxSeriesFieldElem{T} Generic.PuiseuxSeriesField{T}\nmathbbZ Flint FlintPuiseuxSeriesRingElem{ZZLaurentSeriesRingElem} FlintPuiseuxSeriesRing{ZZLaurentSeriesRingElem}","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"For convenience, FlintPuiseuxSeriesRingElem and FlintPuiseuxSeriesFieldElem both belong to a union type called FlintPuiseuxSeriesElem.","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"The maximum relative precision, the string representation of the variable and the base ring R of a generic power series are stored in the parent object. ","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Note that unlike most other Nemo types, Puiseux series are parameterised by the type of the underlying Laurent series type (which must exist before Nemo can make use of it), instead of the type of the coefficients.","category":"page"},{"location":"Nemo/puiseux/#Puiseux-power-series","page":"Puiseux series","title":"Puiseux power series","text":"","category":"section"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Puiseux series have their maximum relative precision capped at some value prec_max. This refers to the maximum precision of the underlying Laurent series. See the description of the generic Puiseux series in AbstractAlgebra.jl for details.","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"There are numerous important things to be aware of when working with Puiseux series, or series in general. Please refer to the documentation of generic Puiseux series and series in general in AbstractAlgebra.jl for details.","category":"page"},{"location":"Nemo/puiseux/#Puiseux-series-functionality","page":"Puiseux series","title":"Puiseux series functionality","text":"","category":"section"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Puiseux series rings in Nemo implement all the same functionality that is available for AbstractAlgebra series rings, with the exception of the pol_length and polcoeff functions:","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/series","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"In addition, generic Puiseux series are provided by AbstractAlgebra.jl","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"We list below only the functionality that differs from that described in AbstractAlgebra, for specific rings provided by Nemo.","category":"page"},{"location":"Nemo/puiseux/#Special-functions","page":"Puiseux series","title":"Special functions","text":"","category":"section"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Base.sqrt(a::FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem})","category":"page"},{"location":"Nemo/puiseux/#sqrt-Tuple{FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem}}","page":"Puiseux series","title":"sqrt","text":"sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of the given Puiseux series a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nBase.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of f. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.\n\n\n\n\n\nBase.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Base.exp(a::FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem})","category":"page"},{"location":"Nemo/puiseux/#exp-Tuple{FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem}}","page":"Puiseux series","title":"exp","text":"exp(a::Generic.LaurentSeriesElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the exponential of the given Puiseux series a.\n\n\n\n\n\nexp(a::AbsPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::RelPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"eta_qexp(x::FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem})","category":"page"},{"location":"Nemo/puiseux/#eta_qexp-Tuple{FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem}}","page":"Puiseux series","title":"eta_qexp","text":"eta_qexp(x::FlintPuiseuxSeriesElem{ZZLaurentSeriesRingElem})\n\nReturn the q-series for eta evaluated at x, which must currently be a rational power of the generator of the Puiseux series ring.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"Examples","category":"page"},{"location":"Nemo/puiseux/","page":"Puiseux series","title":"Puiseux series","text":"julia> S, z = PuiseuxSeriesRing(ZZ, 30, \"z\")\n(Puiseux series ring in z over ZZ, z + O(z^31))\n\njulia> a = 1 + z + 3z^2 + O(z^5)\n1 + z + 3*z^2 + O(z^5)\n\njulia> h = sqrt(a^2)\n1 + z + 3*z^2 + O(z^5)\n\njulia> k = eta_qexp(z)\nz^(1//24) - z^(25//24) + O(z^(31//24))","category":"page"},{"location":"Hecke/orders/ideals/#NfOrdIdlLink","page":"Ideals","title":"Ideals","text":"","category":"section"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"(Integral) ideals in orders are always free Z-module of the same rank as the order, hence have a representation via a Z-basis. This can be made unique by normalising the corresponding matrix to be in reduced row echelon form (HNF).","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"For ideals in maximal orders Z_K, we also have a second presentation coming from the Z_K module structure and the fact that Z_K is a Dedekind ring: ideals can be generated by 2 elements, one of which can be any non-zero element in the ideal.","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"For efficiency, we will choose the 1st generator to be an integer.","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"Ideals here are of type NfAbsOrdIdl, which is, similar to the elements above, also indexed by the type of the field and their elements: NfAbsOrdIdl{AnticNumberField,nf_elem} for ideals in simple absolute fields.","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"Different to elements, the parentof an ideal is the set of all ideals in the ring, of type NfAbsOrdIdlSet.","category":"page"},{"location":"Hecke/orders/ideals/#Creation","page":"Ideals","title":"Creation","text":"","category":"section"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"ideal(::NfOrd, ::ZZRingElem)\nideal(::NfOrd, ::ZZMatrix)\nideal(::NfOrd, ::NfOrdElem)\nideal(::NfOrd, ::ZZRingElem, ::NfOrdElem)\nideal(::NfAbsOrd, ::ZZRingElem, ::NfAbsOrdElem)\nideal(::NfAbsOrd, ::ZZRingElem)\nideal(::NfAbsOrd, ::NfAbsOrdElem)\n\n*(::NfOrd, ::NfOrdElem)\nfactor(::NfOrdIdl)\nfactor(::NfOrdIdlSet, ::nf_elem)\ncoprime_base(::Vector{NfOrdIdl})","category":"page"},{"location":"Hecke/orders/ideals/#ideal-Tuple{NfOrd, ZZRingElem}","page":"Ideals","title":"ideal","text":"ideal(O::NfOrd, a::ZZRingElem) -> NfAbsOrdIdl\nideal(O::NfOrd, a::Integer) -> NfAbsOrdIdl\n\nReturns the ideal of mathcal O which is generated by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ideal-Tuple{NfOrd, ZZMatrix}","page":"Ideals","title":"ideal","text":"ideal(O::NfOrd, M::ZZMatrix; check::Bool = false, M_in_hnf::Bool = false) -> NfAbsOrdIdl\n\nCreates the ideal of mathcal O with basis matrix M. If check is set, then it is checked whether M defines an ideal (expensive). If M_in_hnf is set, then it is assumed that M is already in lower left HNF.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ideal-Tuple{NfOrd, NfOrdElem}","page":"Ideals","title":"ideal","text":"ideal(O::NfOrd, x::NfOrdElem) -> NfAbsOrdIdl\n\nCreates the principal ideal (x) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ideal-Tuple{NfOrd, ZZRingElem, NfOrdElem}","page":"Ideals","title":"ideal","text":"ideal(O::NfOrd, x::ZZRingElem, y::NfOrdElem) -> NfAbsOrdIdl\nideal(O::NfOrd, x::Integer, y::NfOrdElem) -> NfAbsOrdIdl\n\nCreates the ideal (x y) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ideal-Tuple{NfAbsOrd, ZZRingElem, NfAbsOrdElem}","page":"Ideals","title":"ideal","text":"ideal(O::NfOrd, x::ZZRingElem, y::NfOrdElem) -> NfAbsOrdIdl\nideal(O::NfOrd, x::Integer, y::NfOrdElem) -> NfAbsOrdIdl\n\nCreates the ideal (x y) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ideal-Tuple{NfAbsOrd, ZZRingElem}","page":"Ideals","title":"ideal","text":"ideal(O::NfOrd, a::ZZRingElem) -> NfAbsOrdIdl\nideal(O::NfOrd, a::Integer) -> NfAbsOrdIdl\n\nReturns the ideal of mathcal O which is generated by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ideal-Tuple{NfAbsOrd, NfAbsOrdElem}","page":"Ideals","title":"ideal","text":"ideal(O::NfOrd, x::NfOrdElem) -> NfAbsOrdIdl\n\nCreates the principal ideal (x) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#*-Tuple{NfOrd, NfOrdElem}","page":"Ideals","title":"*","text":"*(O::NfOrd, x::NfOrdElem) -> NfAbsOrdIdl\n*(x::NfAbsOrdElem, O::NfAbsOrd) -> NfAbsOrdIdl\n\nReturns the principal ideal (x) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#factor-Tuple{NfOrdIdl}","page":"Ideals","title":"factor","text":"factor(A::NfOrdIdl) -> Dict{NfOrdIdl, Int}\n\nComputes the prime ideal factorization A as a dictionary, the keys being the prime ideal divisors: If lp = factor_dict(A), then keys(lp) are the prime ideal divisors of A and lp[P] is the P-adic valuation of A for all P in keys(lp).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#factor-Tuple{Hecke.NfAbsOrdIdlSet{AnticNumberField, nf_elem}, nf_elem}","page":"Ideals","title":"factor","text":"factor(I::NfOrdIdlSet, a::nf_elem) -> Dict{NfOrdIdl, ZZRingElem}\n\nFactors the principal ideal generated by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#coprime_base-Tuple{Vector{NfOrdIdl}}","page":"Ideals","title":"coprime_base","text":"coprime_base(A::Vector{NfOrdIdl}) -> Vector{NfOrdIdl}\ncoprime_base(A::Vector{NfOrdElem}) -> Vector{NfOrdIdl}\n\nA coprime base for the (principal) ideals in A, i.e. the returned array generated multiplicatively the same ideals as the input and are pairwise coprime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#Arithmetic","page":"Ideals","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"All the usual operations are supported:","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"==, +, *\ndivexact, divides\nlcm, gcd\nin","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"intersect(::NfOrdIdl, ::NfOrdIdl)\ncolon(::NfOrdIdl, ::NfOrdIdl)\nin(::NfOrdElem, ::NfAbsOrdIdl)\nis_power(::NfAbsOrdIdl, ::Int)\nis_power(::NfAbsOrdIdl)\nis_invertible(::NfOrdIdl)\nisone(::NfOrdIdl)","category":"page"},{"location":"Hecke/orders/ideals/#intersect-Tuple{NfOrdIdl, NfOrdIdl}","page":"Ideals","title":"intersect","text":"intersect(x::NfOrdIdl, y::NfOrdIdl) -> NfOrdIdl\n\nReturns x cap y.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#colon-Tuple{NfOrdIdl, NfOrdIdl}","page":"Ideals","title":"colon","text":"colon(a::NfAbsOrdIdl, b::NfAbsOrdIdl) -> NfOrdFracIdl\n\nThe ideal (ab) = x in K xb subseteq a = hom(b a) where K is the number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#in-Tuple{NfOrdElem, NfAbsOrdIdl}","page":"Ideals","title":"in","text":"in(x::NumFieldOrdElem, y::NumFieldOrdIdl)\nin(x::NumFieldElem, y::NumFieldOrdIdl)\nin(x::ZZRingElem, y::NumFieldOrdIdl)\n\nReturns whether x is contained in y.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#is_power-Tuple{NfAbsOrdIdl, Int64}","page":"Ideals","title":"is_power","text":"is_power(A::NfAbsOrdIdl, n::Int) -> Bool, NfAbsOrdIdl\nis_power(A::NfOrdFracIdl, n::Int) -> Bool, NfOrdFracIdl\n\nComputes, if possible, an ideal B s.th. B^n==A holds. In this case, true and B are returned.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#is_power-Tuple{NfAbsOrdIdl}","page":"Ideals","title":"is_power","text":"is_power(I::NfAbsOrdIdl) -> Int, NfAbsOrdIdl\nis_power(a::NfOrdFracIdl) -> Int, NfOrdFracIdl\n\nWrites a = r^e with e maximal. Note: 1 = 1^0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#is_invertible-Tuple{NfOrdIdl}","page":"Ideals","title":"is_invertible","text":"is_invertible(A::NfAbsOrdIdl) -> Bool, NfOrdFracIdl\n\nReturns true and an inverse of A or false and an ideal B such that A*B subsetneq order(A), if A is not invertible.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#isone-Tuple{NfOrdIdl}","page":"Ideals","title":"isone","text":"isone(A::NfAbsOrdIdl) -> Bool\nis_unit(A::NfAbsOrdIdl) -> Bool\n\nTests if A is the trivial ideal generated by 1.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#Class-Group","page":"Ideals","title":"Class Group","text":"","category":"section"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"The group of invertable ideals in any order forms a group and the principal ideals a subgroup. The finite quotient is called class group for maximal orders and Picard group or ring class group in general.","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"class_group(::NfOrd)\nnarrow_class_group(::NfOrd)\npicard_group(::NfOrd)\nring_class_group(::NfAbsOrd)","category":"page"},{"location":"Hecke/orders/ideals/#class_group-Tuple{NfOrd}","page":"Ideals","title":"class_group","text":"class_group(O::NfOrd; bound = -1, method = 3, redo = false, large = 1000) -> GrpAbFinGen, Map\n\nReturns a group A and a map f from A to the set of ideals of O. The inverse of the map is the projection onto the group of ideals modulo the group of principal ideals. redo allows to trigger a re-computation, thus avoiding the cache. bound, when given, is the bound for the factor base.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#narrow_class_group-Tuple{NfOrd}","page":"Ideals","title":"narrow_class_group","text":"narrow_class_group(O::NfOrd) -> GrpAbFinGen, Map\n\nComputes the narrow (or strict) class group of O, ie. the group of invertable ideals modulo principal ideals generated by elements that are positive at all real places.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#picard_group-Tuple{NfOrd}","page":"Ideals","title":"picard_group","text":"picard_group(O::NfOrd) -> GrpAbFinGen, MapClassGrp\n\nReturns the Picard group of O and a map from the group in the set of (invertible) ideals of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ring_class_group-Tuple{NfAbsOrd}","page":"Ideals","title":"ring_class_group","text":"ring_class_group(O::NfAbsOrd)\n\nThe ring class group (Picard group) of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"using Hecke # hide\nk, a = wildanger_field(3, 13);\nzk = maximal_order(k);\nc, mc = class_group(zk)\nlp = prime_ideals_up_to(zk, 20);\n[ mc \\ I for I = lp]\nmc(c[1])\norder(c[1])\nmc(c[1])^Int(order(c[1]))\nmc \\ ans","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"The class group, or more precisely the information used to compute it also allows for principal ideal testing and related tasks. In general, due to the size of the objects, the fac_elem versions are more efficient.","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"is_principal(::NfOrdIdl)\nis_principal_fac_elem(::NfAbsOrdIdl{AnticNumberField,nf_elem})\npower_class(::NfOrdIdl,::ZZRingElem)\npower_product_class(::Vector{NfOrdIdl}, ::Vector{ZZRingElem})\npower_reduce(::NfAbsOrdIdl{AnticNumberField,nf_elem},::ZZRingElem)\nclass_group_ideal_relation(::NfAbsOrdIdl{AnticNumberField,nf_elem}, ::Hecke.ClassGrpCtx)\nfactor_base_bound_grh(::NfOrd)\nfactor_base_bound_bach(::NfOrd)\nprime_ideals_up_to","category":"page"},{"location":"Hecke/orders/ideals/#is_principal-Tuple{NfOrdIdl}","page":"Ideals","title":"is_principal","text":"is_principal(A::NfOrdIdl) -> Bool, NfOrdElem\nis_principal(A::NfOrdFracIdl) -> Bool, NfOrdElem\n\nTests if A is principal and returns (mathtttrue alpha) if A = langle alpharangle or (mathttfalse 1) otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#is_principal_fac_elem-Tuple{NfOrdIdl}","page":"Ideals","title":"is_principal_fac_elem","text":"is_principal_fac_elem(A::NfOrdIdl) -> Bool, FacElem{nf_elem, number_field}\n\nTests if A is principal and returns (mathtttrue alpha) if A = langle alpharangle or (mathttfalse 1) otherwise. The generator will be in factored form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#power_class-Tuple{NfOrdIdl, ZZRingElem}","page":"Ideals","title":"power_class","text":"power_class(A::NfOrdIdl, e::ZZRingElem) -> NfOrdIdl\n\nComputes a (small) ideal in the same class as A^e.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#power_product_class-Tuple{Vector{NfOrdIdl}, Vector{ZZRingElem}}","page":"Ideals","title":"power_product_class","text":"power_product_class(A::Vector{NfOrdIdl}, e::Vector{ZZRingElem}) -> NfOrdIdl\n\nComputes a (small) ideal in the same class as prod A_i^e_i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#power_reduce-Tuple{NfOrdIdl, ZZRingElem}","page":"Ideals","title":"power_reduce","text":"power_reduce(A::NfOrdIdl, e::ZZRingElem) -> NfOrdIdl, FacElem{nf_elem}\n\nComputes B and alpha in factored form, such that alpha B = A^e B has small norm.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#class_group_ideal_relation-Tuple{NfOrdIdl, Hecke.ClassGrpCtx}","page":"Ideals","title":"class_group_ideal_relation","text":"class_group_ideal_relation(I::NfOrdIdl, c::ClassGrpCtx) -> nf_elem, SRow{ZZRingElem}\n\nFinds a number field element alpha such that alpha I factors over the factor base in c.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#factor_base_bound_grh-Tuple{NfOrd}","page":"Ideals","title":"factor_base_bound_grh","text":"factor_base_bound_grh(O::NfOrd) -> Int\n\nReturns an integer B, such that under GRH the ideal class group of mathcal O is generated by the prime ideals of norm bounded by B.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#factor_base_bound_bach-Tuple{NfOrd}","page":"Ideals","title":"factor_base_bound_bach","text":"factor_base_bound_bach(O::NfOrd) -> Int\n\nUse the theorem of Bach to find B such that under GRH the ideal class group of mathcal O is generated by the prime ideals of norm bounded by B.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#prime_ideals_up_to","page":"Ideals","title":"prime_ideals_up_to","text":"prime_ideals_up_to(O::NfOrd,\n B::Int;\n degree_limit::Int = 0, index_divisors::Bool = true) -> Vector{NfOrdIdl}\n\nComputes the prime ideals mathcal O with norm up to B.\n\nIf degree_limit is a nonzero integer k, then prime ideals mathfrak p with deg(mathfrak p) k will be discarded. If 'index_divisors' is set to false, only primes not dividing the index of the order will be computed.\n\n\n\n\n\nprime_ideals_up_to(O::NfOrd,\n B::Int;\n complete::Bool = false,\n degree_limit::Int = 0,\n F::Function,\n bad::ZZRingElem)\n\nComputes the prime ideals mathcal O with norm up to B.\n\nIf degree_limit is a nonzero integer k, then prime ideals mathfrak p with deg(mathfrak p) k will be discarded.\n\nThe function F must be a function on prime numbers not dividing bad such that F(p) = deg(mathfrak p) for all prime ideals mathfrak p lying above p.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"I = mc(c[1])\nis_principal(I)\nI = I^Int(order(c[1]))\nis_principal(I)\nis_principal_fac_elem(I)","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"The computation of S-units is also tied to the class group:","category":"page"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"torsion_units(::NfOrd)\ntorsion_unit_group(::NfOrd)\ntorsion_units_generator(::NfOrd)\nHecke.torsion_units_gen_order(::NfOrd)\nunit_group(::NfOrd)\nunit_group_fac_elem(::NfOrd)\nsunit_group(::Vector{NfOrdIdl})\nsunit_group_fac_elem(::Vector{NfOrdIdl})\nsunit_mod_units_group_fac_elem(::Vector{NfOrdIdl})","category":"page"},{"location":"Hecke/orders/ideals/#torsion_units-Tuple{NfOrd}","page":"Ideals","title":"torsion_units","text":"torsion_units(O::NfOrd) -> Vector{NfOrdElem}\n\nGiven an order O, compute the torsion units of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#torsion_unit_group-Tuple{NfOrd}","page":"Ideals","title":"torsion_unit_group","text":"torsion_unit_group(O::NfOrd) -> GrpAb, Map\n\nGiven an order mathcal O, returns the torsion units as an abelian group G together with a map G to mathcal O^times.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#torsion_units_generator-Tuple{NfOrd}","page":"Ideals","title":"torsion_units_generator","text":"torsion_units_generator(O::NfOrd) -> NfOrdElem\n\nGiven an order O, compute a generator of the torsion units of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#torsion_units_gen_order-Tuple{NfOrd}","page":"Ideals","title":"torsion_units_gen_order","text":"torsion_units_gen_order(O::NfOrd) -> NfOrdElem\n\nGiven an order O, compute a generator of the torsion units of O as well as its order.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#unit_group-Tuple{NfOrd}","page":"Ideals","title":"unit_group","text":"unit_group(O::NfOrd) -> GrpAbFinGen, Map\n\nReturns a group U and an isomorphism map f colon U to mathcal O^times. A set of fundamental units of mathcal O can be obtained via [ f(U[1+i]) for i in 1:unit_group_rank(O) ]. f(U[1]) will give a generator for the torsion subgroup.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#unit_group_fac_elem-Tuple{NfOrd}","page":"Ideals","title":"unit_group_fac_elem","text":"unit_group_fac_elem(O::NfOrd) -> GrpAbFinGen, Map\n\nReturns a group U and an isomorphism map f colon U to mathcal O^times. A set of fundamental units of mathcal O can be obtained via [ f(U[1+i]) for i in 1:unit_group_rank(O) ]. f(U[1]) will give a generator for the torsion subgroup. All elements will be returned in factored form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#sunit_group-Tuple{Vector{NfOrdIdl}}","page":"Ideals","title":"sunit_group","text":"sunit_group(I::Vector{NfOrdIdl}) -> GrpAb, Map\n\nFor an array I of (coprime prime) ideals, find the S-unit group defined by I, ie. the group of non-zero field elements which are only divisible by ideals in I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#sunit_group_fac_elem-Tuple{Vector{NfOrdIdl}}","page":"Ideals","title":"sunit_group_fac_elem","text":"sunit_group_fac_elem(I::Vector{NfOrdIdl}) -> GrpAb, Map\n\nFor an array I of (coprime prime) ideals, find the S-unit group defined by I, ie. the group of non-zero field elements which are only divisible by ideals in I. The map will return elements in factored form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#sunit_mod_units_group_fac_elem-Tuple{Vector{NfOrdIdl}}","page":"Ideals","title":"sunit_mod_units_group_fac_elem","text":"sunit_mod_units_group_fac_elem(I::Vector{NfOrdIdl}) -> GrpAb, Map\n\nFor an array I of (coprime prime) ideals, find the S-unit group defined by I, ie. the group of non-zero field elements which are only divisible by ideals in I modulo the units of the field. The map will return elements in factored form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"u, mu = unit_group(zk)\nmu(u[2])\nu, mu = unit_group_fac_elem(zk)\nmu(u[2])\nevaluate(ans)\nlp = factor(6*zk)\ns, ms = Hecke.sunit_group(collect(keys(lp)))\nms(s[4])\nnorm(ans)\nfactor(numerator(ans))","category":"page"},{"location":"Hecke/orders/ideals/#Miscaellenous","page":"Ideals","title":"Miscaellenous","text":"","category":"section"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"order(::NfAbsOrdIdl)\norder(::NfAbsOrdFracIdl)\norder(::NfRelOrdIdl)\norder(::NfRelOrdFracIdl)\nnf(::NfAbsOrdIdl)\nbasis(::NfOrdIdl)\nHecke.lll_basis(::NfOrdIdl)\nbasis_matrix(::NfAbsOrdIdl)\nbasis_mat_inv(::NfOrdIdl)\nHecke.assure_has_basis_mat_inv(::NfOrdIdl)\nHecke.has_basis(::NfOrdIdl)\nHecke.has_basis_matrix(::NfOrdIdl)\nHecke.has_2_elem(::NfOrdIdl)\nHecke.has_2_elem_normal(::NfOrdIdl)\nHecke.has_weakly_normal(::NfOrdIdl)\nHecke.has_princ_gen_special(::NfOrdIdl)\nHecke.principal_generator(::NfOrdIdl)\nHecke.principal_generator_fac_elem(::NfOrdIdl)\nminimum(::NfOrdIdl)\nminimum(::NfRelOrdIdl)\nminimum(::NfAbsOrdIdl)\nhas_minimum(::NfOrdIdl)\nnorm(::NfOrdIdl)\nHecke.has_norm(::NfOrdIdl)\nidempotents(::NfOrdIdl, ::NfOrdIdl)\nis_prime(::NfOrdIdl)\nHecke.is_prime_known(::NfOrdIdl)\nis_ramified(::NfOrd, ::Union{Int, ZZRingElem})\nramification_index(::NfOrdIdl)\ndegree(::NfOrdIdl)\nvaluation(::nf_elem, ::NfOrdIdl)\nvaluation(::NfOrdElem, ::NfOrdIdl)\nvaluation(::NfOrdIdl, ::NfOrdIdl)\nvaluation(::Integer, ::NfOrdIdl)\nvaluation(::ZZRingElem, ::NfOrdIdl)\nvaluation(::NfOrdFracIdl, ::NfOrdIdl)\nidempotents(::NfAbsOrdIdl, ::NfAbsOrdIdl)","category":"page"},{"location":"Hecke/orders/ideals/#order-Tuple{NfAbsOrdIdl}","page":"Ideals","title":"order","text":"order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion\n\nReturn the order of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> order(cycle_structure(x)) == order(x), gens(g))\ntrue\n\n\n\n\n\norder(I::NumFieldOrdIdl) -> NfOrd\n\nReturns the order of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#order-Tuple{Hecke.NfAbsOrdFracIdl}","page":"Ideals","title":"order","text":"order(a::NfAbsOrdFracIdl) -> NfAbsOrd\n\nThe order that was used to define the ideal a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#order-Tuple{Hecke.NfRelOrdIdl}","page":"Ideals","title":"order","text":"order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion\n\nReturn the order of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> order(cycle_structure(x)) == order(x), gens(g))\ntrue\n\n\n\n\n\norder(I::NumFieldOrdIdl) -> NfOrd\n\nReturns the order of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#order-Tuple{Hecke.NfRelOrdFracIdl}","page":"Ideals","title":"order","text":"order(a::NfRelOrdFracIdl) -> NfRelOrd\n\nReturns the order of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#nf-Tuple{NfAbsOrdIdl}","page":"Ideals","title":"nf","text":"nf(x::NumFieldOrdIdl) -> AnticNumberField\n\nReturns the number field, of which x is an integral ideal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#basis-Tuple{NfOrdIdl}","page":"Ideals","title":"basis","text":"basis(A::NfAbsOrdIdl) -> Vector{NfOrdElem}\n\nReturns the basis of A.\n\n\n\n\n\nbasis(I::NfAbsOrdFracIdl) -> Vector{nf_elem}\n\nReturns the mathbf Z-basis of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#lll_basis-Tuple{NfOrdIdl}","page":"Ideals","title":"lll_basis","text":"lll_basis(I::NumFieldOrdIdl) -> Vector{NumFieldElem}\n\nA basis for I that is reduced using the LLL algorithm for the Minkowski metric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#basis_matrix-Tuple{NfAbsOrdIdl}","page":"Ideals","title":"basis_matrix","text":"basis_matrix(A::NfAbsOrdIdl) -> ZZMatrix\n\nReturns the basis matrix of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#basis_mat_inv-Tuple{NfOrdIdl}","page":"Ideals","title":"basis_mat_inv","text":"basis_mat_inv(A::NfAbsOrdIdl) -> ZZMatrix\n\nReturns the inverse basis matrix of A.\n\n\n\n\n\nbasis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat\n\nReturn the inverse of the basis matrix of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#assure_has_basis_mat_inv-Tuple{NfOrdIdl}","page":"Ideals","title":"assure_has_basis_mat_inv","text":"basis_mat_inv(A::NfAbsOrdIdl) -> FakeFmpqMat\n\nReturns the inverse of the basis matrix of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_basis-Tuple{NfOrdIdl}","page":"Ideals","title":"has_basis","text":"has_basis(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A has a basis already computed.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_basis_matrix-Tuple{NfOrdIdl}","page":"Ideals","title":"has_basis_matrix","text":"has_basis_matrix(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A knows its basis matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_2_elem-Tuple{NfOrdIdl}","page":"Ideals","title":"has_2_elem","text":"has_2_elem(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A is generated by two elements.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_2_elem_normal-Tuple{NfOrdIdl}","page":"Ideals","title":"has_2_elem_normal","text":"has_2_elem_normal(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A has normal two element generators.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_weakly_normal-Tuple{NfOrdIdl}","page":"Ideals","title":"has_weakly_normal","text":"has_weakly_normal(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A has weakly normal two element generators.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_princ_gen_special-Tuple{NfOrdIdl}","page":"Ideals","title":"has_princ_gen_special","text":"has_princ_gen_special(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A knows if it is generated by a rational integer.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#principal_generator-Tuple{NfOrdIdl}","page":"Ideals","title":"principal_generator","text":"principal_generator(A::NfOrdIdl) -> NfOrdElem\n\nFor a principal ideal A, find a generator.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#principal_generator_fac_elem-Tuple{NfOrdIdl}","page":"Ideals","title":"principal_generator_fac_elem","text":"principal_generator_fac_elem(A::NfOrdIdl) -> FacElem{nf_elem, number_field}\n\nFor a principal ideal A, find a generator in factored form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#minimum-Tuple{NfOrdIdl}","page":"Ideals","title":"minimum","text":"minimum(A::NfAbsOrdIdl) -> ZZRingElem\n\nReturns the smallest nonnegative element in A cap mathbf Z.\n\n\n\n\n\n minimum(A::NfRelOrdIdl) -> NfOrdIdl\n minimum(A::NfRelOrdIdl) -> NfRelOrdIdl\n\nReturns the ideal A cap O where O is the maximal order of the coefficient ideals of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#minimum-Tuple{Hecke.NfRelOrdIdl}","page":"Ideals","title":"minimum","text":" minimum(A::NfRelOrdIdl) -> NfOrdIdl\n minimum(A::NfRelOrdIdl) -> NfRelOrdIdl\n\nReturns the ideal A cap O where O is the maximal order of the coefficient ideals of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#minimum-Tuple{NfAbsOrdIdl}","page":"Ideals","title":"minimum","text":"minimum(A::NfAbsOrdIdl) -> ZZRingElem\n\nReturns the smallest nonnegative element in A cap mathbf Z.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_minimum-Tuple{NfOrdIdl}","page":"Ideals","title":"has_minimum","text":"has_minimum(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A knows its minimum.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#norm-Tuple{NfOrdIdl}","page":"Ideals","title":"norm","text":"norm(A::NfAbsOrdIdl) -> ZZRingElem\n\nReturns the norm of A, that is, the cardinality of mathcal OA, where mathcal O is the order of A.\n\n\n\n\n\nnorm(a::NfRelOrdIdl) -> NfOrdIdl\n\nReturns the norm of a.\n\n\n\n\n\nnorm(a::NfRelOrdFracIdl{T, S}) -> S\n\nReturns the norm of a.\n\n\n\n\n\nnorm(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd; copy::Bool = true) -> QQFieldElem\n\nReturns the norm of a considered as an (possibly fractional) ideal of O.\n\n\n\n\n\nnorm(a::AlgAssRelOrdIdl{S, T, U}, O::AlgAssRelOrd{S, T, U}; copy::Bool = true)\n where { S, T, U } -> T\n\nReturns the norm of a considered as an (possibly fractional) ideal of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#has_norm-Tuple{NfOrdIdl}","page":"Ideals","title":"has_norm","text":"has_norm(A::NfAbsOrdIdl) -> Bool\n\nReturns whether A knows its norm.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#idempotents-Tuple{NfOrdIdl, NfOrdIdl}","page":"Ideals","title":"idempotents","text":"idempotents(x::NfOrdIdl, y::NfOrdIdl) -> NfOrdElem, NfOrdElem\n\nReturns a tuple (e, f) consisting of elements e in x, f in y such that 1 = e + f.\n\nIf the ideals are not coprime, an error is raised.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#is_prime-Tuple{NfOrdIdl}","page":"Ideals","title":"is_prime","text":"is_prime(A::NfOrdIdl) -> Bool\n\nReturns whether A is a prime ideal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#is_prime_known-Tuple{NfOrdIdl}","page":"Ideals","title":"is_prime_known","text":"is_prime_known(A::NfOrdIdl) -> Bool\n\nReturns whether A knows if it is prime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#is_ramified-Tuple{NfOrd, Union{Int64, ZZRingElem}}","page":"Ideals","title":"is_ramified","text":"is_ramified(O::NfOrd, p::Int) -> Bool\n\nReturns whether the integer p is ramified in mathcal O. It is assumed that p is prime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#ramification_index-Tuple{NfOrdIdl}","page":"Ideals","title":"ramification_index","text":"ramification_index(P::NfOrdIdl) -> Int\n\nThe ramification index of the prime-ideal P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#degree-Tuple{NfOrdIdl}","page":"Ideals","title":"degree","text":"degree(P::NfOrdIdl) -> Int\n\nThe inertia degree of the prime-ideal P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#valuation-Tuple{nf_elem, NfOrdIdl}","page":"Ideals","title":"valuation","text":"valuation(a::NumFieldElem, p::NfOrdIdl) -> ZZRingElem\n\nComputes the mathfrak p-adic valuation of a, that is, the largest i such that a is contained in mathfrak p^i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#valuation-Tuple{NfOrdElem, NfOrdIdl}","page":"Ideals","title":"valuation","text":"valuation(a::nf_elem, p::NfOrdIdl) -> ZZRingElem\nvaluation(a::NfOrdElem, p::NfOrdIdl) -> ZZRingElem\nvaluation(a::ZZRingElem, p::NfOrdIdl) -> ZZRingElem\n\nComputes the mathfrak p-adic valuation of a, that is, the largest i such that a is contained in mathfrak p^i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#valuation-Tuple{NfOrdIdl, NfOrdIdl}","page":"Ideals","title":"valuation","text":"valuation(A::NfOrdIdl, p::NfOrdIdl) -> ZZRingElem\n\nComputes the mathfrak p-adic valuation of A, that is, the largest i such that A is contained in mathfrak p^i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#valuation-Tuple{Integer, NfOrdIdl}","page":"Ideals","title":"valuation","text":"valuation(a::Integer, p::NfOrdIdl) -> ZZRingElem\n\nComputes the mathfrak p-adic valuation of a, that is, the largest i such that a is contained in mathfrak p^i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#valuation-Tuple{ZZRingElem, NfOrdIdl}","page":"Ideals","title":"valuation","text":"valuation(a::nf_elem, p::NfOrdIdl) -> ZZRingElem\nvaluation(a::NfOrdElem, p::NfOrdIdl) -> ZZRingElem\nvaluation(a::ZZRingElem, p::NfOrdIdl) -> ZZRingElem\n\nComputes the mathfrak p-adic valuation of a, that is, the largest i such that a is contained in mathfrak p^i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#valuation-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, NfOrdIdl}","page":"Ideals","title":"valuation","text":"valuation(A::NfAbsOrdFracIdl, p::NfAbsOrdIdl)\n\nThe valuation of A at p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#idempotents-Tuple{NfAbsOrdIdl, NfAbsOrdIdl}","page":"Ideals","title":"idempotents","text":"idempotents(x::NfOrdIdl, y::NfOrdIdl) -> NfOrdElem, NfOrdElem\n\nReturns a tuple (e, f) consisting of elements e in x, f in y such that 1 = e + f.\n\nIf the ideals are not coprime, an error is raised.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#Quotient-Rings","page":"Ideals","title":"Quotient Rings","text":"","category":"section"},{"location":"Hecke/orders/ideals/","page":"Ideals","title":"Ideals","text":"quo(::Union{NfAbsOrd, AlgAssAbsOrd}, ::Union{NfAbsOrdIdl, AlgAssAbsOrdIdl})\nresidue_ring(::NfOrd, ::NfOrdIdl)\nresidue_field(::NfOrd, ::NfOrdIdl, ::Bool)\nmod(::NfOrdElem, ::NfAbsOrdIdl)\ncrt(::NfOrdElem, ::NfOrdIdl, ::NfOrdElem, ::NfOrdIdl)\neuler_phi(::NfOrdIdl)\nHecke.multiplicative_group(::NfOrdQuoRing)\nHecke.multiplicative_group_generators(::NfOrdQuoRing)","category":"page"},{"location":"Hecke/orders/ideals/#quo-Tuple{Union{Hecke.AlgAssAbsOrd, NfAbsOrd}, Union{Hecke.AlgAssAbsOrdIdl, NfAbsOrdIdl}}","page":"Ideals","title":"quo","text":"quo(O::NfOrd, I::NfOrdIdl) -> NfOrdQuoRing, Map\nquo(O::AlgAssAbsOrd, I::AlgAssAbsOrdIdl) -> AbsOrdQuoRing, Map\n\nThe quotient ring OI as a ring together with the section M OI to O. The pointwise inverse of M is the canonical projection Oto OI.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#residue_ring-Tuple{NfOrd, NfOrdIdl}","page":"Ideals","title":"residue_ring","text":"residue_ring(O::NfOrd, I::NfOrdIdl) -> NfOrdQuoRing\nresidue_ring(O::AlgAssAbsOrd, I::AlgAssAbsOrdIdl) -> AbsOrdQuoRing\n\nThe quotient ring O modulo I as a new ring.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#residue_field-Tuple{NfOrd, NfOrdIdl, Bool}","page":"Ideals","title":"residue_field","text":"residue_field(O::NfOrd, P::NfOrdIdl, check::Bool = true) -> Field, Map\n\nReturns the residue field of the prime ideal P together with the projection map. If check is true, the ideal is checked for being prime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#mod-Tuple{NfOrdElem, NfAbsOrdIdl}","page":"Ideals","title":"mod","text":"mod(x::NfOrdElem, I::NfAbsOrdIdl)\n\nReturns the unique element y of the ambient order of x with x equiv y bmod I and the following property: If a_1dotsca_d in mathbfZ_geq 1 are the diagonal entries of the unique HNF basis matrix of I and (b_1dotscb_d) is the coefficient vector of y, then 0 leq b_i a_i for 1 leq i leq d.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#crt-Tuple{NfOrdElem, NfOrdIdl, NfOrdElem, NfOrdIdl}","page":"Ideals","title":"crt","text":"crt(r1::NfOrdElem, i1::NfOrdIdl, r2::NfOrdElem, i2::NfOrdIdl) -> NfOrdElem\n\nFind x such that x equiv r_1 bmod i_1 and x equiv r_2 bmod i_2 using idempotents.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#euler_phi-Tuple{NfOrdIdl}","page":"Ideals","title":"euler_phi","text":"euler_phi(A::NfOrdIdl) -> ZZRingElem\n\nThe ideal version of the totient function returns the size of the unit group of the residue ring modulo the ideal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#multiplicative_group-Tuple{NfOrdQuoRing}","page":"Ideals","title":"multiplicative_group","text":"multiplicative_group(Q::NfOrdQuoRing) -> GrpAbFinGen, Map{GrpAbFinGen, NfOrdQuoRing}\nunit_group(Q::NfOrdQuoRing) -> GrpAbFinGen, Map{GrpAbFinGen, NfOrdQuoRing}\n\nReturns the unit group of Q as an abstract group A and an isomorphism map f colon A to Q^times.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/ideals/#multiplicative_group_generators-Tuple{NfOrdQuoRing}","page":"Ideals","title":"multiplicative_group_generators","text":"multiplicative_group_generators(Q::NfOrdQuoRing) -> Vector{NfOrdQuoRingElem}\n\nReturn a set of generators for Q^times.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend\n","category":"page"},{"location":"Hecke/elliptic_curves/basics/#Creation","page":"Basics","title":"Creation","text":"","category":"section"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"elliptic_curve\nelliptic_curve_from_j_invariant","category":"page"},{"location":"Hecke/elliptic_curves/basics/#elliptic_curve","page":"Basics","title":"elliptic_curve","text":"elliptic_curve([K::Field], x::Vector; check::Bool = true) -> EllCrv\n\nConstruct an elliptic curve with Weierstrass equation specified by the coefficients in x, which must have either length 2 or 5.\n\nPer default, it is checked whether the discriminant is non-zero. This can be disabled by setting check = false.\n\nExamples\n\njulia> elliptic_curve(QQ, [1, 2, 3, 4, 5])\nElliptic curve with equation\ny^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5\n\njulia> elliptic_curve(GF(3), [1, 1])\nElliptic curve with equation\ny^2 = x^3 + x + 1\n\n\n\n\n\n","category":"function"},{"location":"Hecke/elliptic_curves/basics/#elliptic_curve_from_j_invariant","page":"Basics","title":"elliptic_curve_from_j_invariant","text":"elliptic_curve_from_j_invariant(j::FieldElem) -> EllCrv\n\nReturn an elliptic curve with the given j-invariant.\n\nExamples\n\njulia> K = GF(3)\nFinite field of characteristic 3\n\njulia> elliptic_curve_from_j_invariant(K(2))\nElliptic curve with equation\ny^2 + x*y = x^3 + 1\n\n\n\n\n\n","category":"function"},{"location":"Hecke/elliptic_curves/basics/#Basic-properties","page":"Basics","title":"Basic properties","text":"","category":"section"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"base_field(::EllCrv)\nbase_change(::Field, ::EllCrv)\nbase_change(::Any, ::EllCrv)\ncoefficients(::EllCrv)\na_invars(::EllCrv)\nb_invars(::EllCrv)\nc_invars(::EllCrv)\ndiscriminant(::EllCrv)\nj_invariant(::EllCrv)\nequation(::EllCrv)\nhyperelliptic_polynomials(::EllCrv)","category":"page"},{"location":"Hecke/elliptic_curves/basics/#base_field-Tuple{EllCrv}","page":"Basics","title":"base_field","text":"base_field(E::EllCrv) -> Field\n\nReturn the base field over which E is defined.\n\n\n\n\n\nbase_field(C::HypellCrv) -> Field\n\nReturn the base field over which C is defined.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#base_change-Tuple{Field, EllCrv}","page":"Basics","title":"base_change","text":"base_change(K::Field, E::EllCrv) -> EllCrv\n\nReturn the base change of the elliptic curve E over K if coercion is possible.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#base_change-Tuple{Any, EllCrv}","page":"Basics","title":"base_change","text":"base_change(f, E::EllCrv) -> EllCrv\n\nReturn the base change of the elliptic curve E using the map f.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#coefficients-Tuple{EllCrv}","page":"Basics","title":"coefficients","text":"coefficients(E::EllCrv{T}) -> Tuple{T, T, T, T, T}\n\nReturn the Weierstrass coefficients of E as a tuple (a1, a2, a3, a4, a6) such that E is given by y^2 + a1xy + a3y = x^3 + a2x^2 + a4x + a6.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#a_invars-Tuple{EllCrv}","page":"Basics","title":"a_invars","text":"a_invars(E::EllCrv{T}) -> Tuple{T, T, T, T, T}\n\nReturn the Weierstrass coefficients of E as a tuple (a_1 a_2 a_3 a_4 a_6) such that E is given by y^2 + a_1xy + a_3y = x^3 + a_2x^2 + a_4x + a_6.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#b_invars-Tuple{EllCrv}","page":"Basics","title":"b_invars","text":"b_invars(E::EllCrv{T}) -> Tuple{T, T, T, T}\n\nReturn the b-invariants of E as a tuple (b_2 b_4 b_6 b_8).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#c_invars-Tuple{EllCrv}","page":"Basics","title":"c_invars","text":"c_invars(E::EllCrv{T}) -> Tuple{T, T}\n\nReturn the c-invariants of E as a tuple (c_4 c_6).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#discriminant-Tuple{EllCrv}","page":"Basics","title":"discriminant","text":"discriminant(E::EllCrv) -> FieldElem\n\nReturn the discriminant of E.\n\n\n\n\n\ndiscriminant(C::HypellCrv{T}) -> T\n\nCompute the discriminant of C.\n\n\n\n\n\ndiscriminant(O::AlgssRelOrd)\n\nReturns the discriminant of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#j_invariant-Tuple{EllCrv}","page":"Basics","title":"j_invariant","text":"j_invariant(E::EllCrv) -> FieldElem\n\nCompute the j-invariant of E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#equation-Tuple{EllCrv}","page":"Basics","title":"equation","text":"equation([R::MPolyRing,] E::EllCrv) -> MPolyElem\n\nReturn the equation defining the elliptic curve E as a bivariate polynomial. If the polynomial ring R is specified, it must by a bivariate polynomial ring.\n\nExamples\n\njulia> E = elliptic_curve(QQ, [1, 2, 3, 4, 5]);\n\njulia> equation(E)\n-x^3 - 2*x^2 + x*y - 4*x + y^2 + 3*y - 5\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#hyperelliptic_polynomials-Tuple{EllCrv}","page":"Basics","title":"hyperelliptic_polynomials","text":"hyperelliptic_polynomials([R::PolyRing,] E::EllCrv) -> PolyElem, PolyElem\n\nReturn univariate polynomials f h such that E is given by y^2 + h*y = f.\n\nExamples\n\njulia> E = elliptic_curve(QQ, [1, 2, 3, 4, 5]);\n\njulia> hyperelliptic_polynomials(E)\n(x^3 + 2*x^2 + 4*x + 5, x + 3)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#Points","page":"Basics","title":"Points","text":"","category":"section"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":" (E::EllCrv)(coords::Vector; check::Bool = true)","category":"page"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"Return the point P of E with coordinates specified by coords, which can be either affine coordinates (length(coords) == 2) or projective coordinates (length(coords) == 3).","category":"page"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"Per default, it is checked whether the point lies on E. This can be disabled by setting check = false.","category":"page"},{"location":"Hecke/elliptic_curves/basics/#Examples","page":"Basics","title":"Examples","text":"","category":"section"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"julia> E = elliptic_curve(QQ, [1, 2]);\n\njulia> E([1, -2])\nPoint (1 : -2 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\njulia> E([2, -4, 2])\nPoint (1 : -2 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2","category":"page"},{"location":"Hecke/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"infinity(::EllCrv)\nparent(::EllCrvPt)\nis_on_curve(::EllCrv, ::Vector)\n+(P::EllCrvPt{T}, Q::EllCrvPt{T}) where {T}\ndivision_points(::EllCrvPt, ::Int)","category":"page"},{"location":"Hecke/elliptic_curves/basics/#infinity-Tuple{EllCrv}","page":"Basics","title":"infinity","text":"infinity(E::EllCrv) -> EllCrvPt\n\nReturn the point at infinity with project coordinates 0 1 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#parent-Tuple{EllCrvPt}","page":"Basics","title":"parent","text":"parent(P::EllCrvPt) -> EllCrv\n\nReturn the elliptic curve on which P lies.\n\nExamples\n\njulia> E = elliptic_curve(QQ, [1, 2]);\n\njulia> P = E([1, -2]);\n\njulia> E == parent(P)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#is_on_curve-Tuple{EllCrv, Vector}","page":"Basics","title":"is_on_curve","text":"is_on_curve(E::EllCrv, coords::Vector) -> Bool\n\nReturn true if coords defines a point on E and false otherwise. The array coords must have length 2.\n\nExamples\n\njulia> E = elliptic_curve(QQ, [1, 2]);\n\njulia> is_on_curve(E, [1, -2])\ntrue\n\njulia> is_on_curve(E, [1, -1])\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#+-Union{Tuple{T}, Tuple{EllCrvPt{T}, EllCrvPt{T}}} where T","page":"Basics","title":"+","text":"+(P::EllCrvPt, Q::EllCrvPt) -> EllCrvPt\n\nAdd two points on an elliptic curve.\n\nExamples\n\njulia> E = elliptic_curve(QQ, [1, 2]);\n\njulia> P = E([1, -2]);\n\njulia> P + P\nPoint (-1 : 0 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/basics/#division_points-Tuple{EllCrvPt, Int64}","page":"Basics","title":"division_points","text":"division_points(P::EllCrvPt, m::Int) -> EllCrvPt\n\nCompute the set of points Q defined over the base field such that mQ = P. Returns the empty list if no such points exist.\n\nExamples\n\njulia> E = elliptic_curve(QQ, [1, 2]);\n\njulia> division_points(infinity(E), 2)\n2-element Vector{EllCrvPt{QQFieldElem}}:\n Point (0 : 1 : 0) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n Point (-1 : 0 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/serialization/#Serialization","page":"Serialization","title":"Serialization","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"warning: Warning\nNever load data from an untrusted source. Loading data is inherently unsafe and at this point allows arbitrary code execution on your machine. Just as you should never run a program from someone you do not trust, you should also not load their data.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"warning: Warning\nSerialization development has just started and the concrete design may still change drastically. In particular the mechanism for upgrading old data to newer versions is not in place yet, so at this point we do not yet guarantee that old data can be read.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"This document summarises the serialization efforts of OSCAR, how it is supposed to work, how it works and the overall goal. Serialization broadly speaking is the process of writing data to and reading data from files. There are many reasons for needing this feature in OSCAR, but the main reason is communication on mathematics by mathematicians.","category":"page"},{"location":"DeveloperDocumentation/serialization/#How-it-works","page":"Serialization","title":"How it works","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The mechanism for saving and loading is very simple. It is implemented via two methods save and load, and works in the following manner:","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"julia> save(\"/tmp/fourtitwo.json\", 42);\n\njulia> load(\"/tmp/fourtitwo.json\")\n42\n","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"As hinted by the filename, OSCAR writes a file in JSON format. The file looks as follow:","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"{\n \"_ns\": {\n \"Oscar\": [\n \"https://github.com/oscar-system/Oscar.jl\",\n {\n \"major\": 0,\n \"minor\": 8,\n \"patch\": 3,\n \"prerelease\": [\n \"DEV\"\n ],\n \"build\": []\n }\n ]\n },\n \"id\": \"-1\",\n \"type\": \"Base.Int\",\n \"data\": \"42\"\n}","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"It contains the version of OSCAR it was written by, its type, and the actual content, in this case as a string.","category":"page"},{"location":"DeveloperDocumentation/serialization/#The-id","page":"Serialization","title":"The id","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"If you look at the file src/Serialization/main.jl, you will see that all save methods hand down a SerializerState, and all load methods have a DeserializerState. These two objects are very simple, they just contain dictionaries connecting objects and their id. We use this to avoid saving or loading larger objects twice (or multiple times). Consider the following example code snippet:","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"c = cube(3);\nLP0 = linear_program(c, [2,2,-3]);\nLP1 = linear_program(c, [2,2,4]);\nv = [LP0, LP1];\nsave(\"vector_of_lp.json\", v)","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"This creates two linear programs on the cube, stores them in a vector and then writes this vector to a file. It would be wasteful to store the cube twice for each linear program, instead it is only stored once and the second linear program just gets the id of the cube in its serialized form. Please take some time to look at the file written in this concrete example.","category":"page"},{"location":"DeveloperDocumentation/serialization/#The-version-number","page":"Serialization","title":"The version number","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"We will use the version number for checking compatibility of the data with the current OSCAR version before attempting to load it. If the data version is lower than the OSCAR version we will provide appropriate upgrade scripts such that the data can be loaded. We will not provide scripts for attempting to downgrade data, but we will throw a warning or even error in this case. We may provide an option for attempting to load anyway in such a scenario.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Implementation","page":"Serialization","title":"Implementation","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"All files for serialization can be found in the folder src/Serialization. The naming conventions of the files there follows the overall structure of OSCAR, i.e. the file src/Serialization/PolyhedralGeometry.jl contains functions for serializing objects of the polyhedral geometry section.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The file main.jl contains the core of the serialization process, namely:","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"reading and writing files;\nthe SerializerState and DeserializerState objects;\nwriting and reading versions; and\ngeneric functions for attempting to serialize objects that do not have their own dedicated serialization methods.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"If you want to write a serialization routine for an object, the way to go is to implement the following two functions, here in the example for ZZRingElem:","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function load_internal(s::DeserializerState, ::Type{ZZRingElem}, str::String)\n return ZZRingElem(str)\nend\n\nfunction save_internal(s::SerializerState, z::ZZRingElem)\n return string(z)\nend","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Then the main serialization methods will dispatch to load_internal and save_internal for ZZRingElem instead of attempting the generic serialization.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Often the generic serialization will fail and it is necessary to provide a save_internal and load_internal function. In that case, please have a look at the existing functions to get an idea of how these work, and maybe use something of this as a blueprint.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Challenges","page":"Serialization","title":"Challenges","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"This section documents the various challenges we (will) encounter while implementing this feature.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"OSCAR is based on several subsystems, some of which already have their own serialization. We want this to be compatible, if possible in both directions.\nMany mathematical objects need context to be understood. A polynomial needs the ring it lives in, a group element needs the surrounding group, a divisor needs the underlying variety, etc. We will need a way to store this context along the objects.\nContext should not be stored twice: A matrix of polynomials should only store the surrounding ring once.\nSupport other data formats: It has been proposed to not only support JSON, but binary formats needed for HPC communication as well. It is unclear whether this needs a separate implementation.\nVersioning and upgrading: Work on OSCAR will change what its objects look like. Nevertheless, we still want to be able load data written by older versions of OSCAR. For this we intend to develop an upgrade mechanism.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Another important point is the wider mathematical context of the data and code. For data associated to a publication, this context is provided by the paper.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Goals","page":"Serialization","title":"Goals","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The general goal is to make mathematical data FAIR, a goal for which we cooperate with the MaRDI project.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The ramifications of making mathematical data FAIR are manifold. ","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"It becomes easier to exchange data and code with fellow mathematicians, enhancing communication and boosting research.\nComputer experiments and new implementations require a lot of work and hence deserve to be recognized in form of a publication. Standardizing data plays an important role for this process.\nFuture generations of mathematicians will be able to reuse both data and code if we establish a FAIR culture.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Univariate-polynomials-over-a-noncommutative-ring","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"AbstractAlgebra.jl provides a module, implemented in src/NCPoly.jl for univariate polynomials over any noncommutative ring in the AbstractAlgebra type hierarchy.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Generic-type-for-univariate-polynomials-over-a-noncommutative-ring","page":"Univariate polynomials over a noncommutative ring","title":"Generic type for univariate polynomials over a noncommutative ring","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"AbstractAlgebra.jl implements a generic univariate polynomial type over noncommutative rings in src/generic/NCPoly.jl.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"These generic polynomials have type Generic.NCPoly{T} where T is the type of elements of the coefficient ring. Internally they consist of a Julia array of coefficients and some additional fields for length and a parent object, etc. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Parent objects of such polynomials have type Generic.NCPolyRing{T}.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"The string representation of the variable of the polynomial ring and the base/coefficient ring R is stored in the parent object.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Abstract-types","page":"Univariate polynomials over a noncommutative ring","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"The polynomial element types belong to the abstract type NCPolyRingElem{T} and the polynomial ring types belong to the abstract type NCPolyRing{T}. This enables one to write generic functions that can accept any AbstractAlgebra polynomial type.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"note: Note\nNote that both the generic polynomial ring type Generic.NCPolyRing{T} and the abstract type it belongs to, NCPolyRing{T} are both called NCPolyRing. The former is a (parameterised) concrete type for a polynomial ring over a given base ring whose elements have type T. The latter is an abstract type representing all polynomial ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Polynomial-ring-constructors","page":"Univariate polynomials over a noncommutative ring","title":"Polynomial ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"In order to construct polynomials in AbstractAlgebra.jl, one must first construct the polynomial ring itself. This is accomplished with the following constructor.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"polynomial_ring(R::NCRing, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#polynomial_ring-Tuple{NCRing, Union{Char, AbstractString, Symbol}}","page":"Univariate polynomials over a noncommutative ring","title":"polynomial_ring","text":"polynomial_ring(R::NCRing, s::VarName; cached::Bool = true)\n\nGiven a base ring R and symbol/string s specifying how the generator (variable) should be printed, return a tuple S, x representing the new polynomial ring S = Rx and the generator x of the ring.\n\nBy default the parent object S depends only on R and x and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.\n\nExamples\n\njulia> R, x = polynomial_ring(ZZ, :x)\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, :y)\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"A shorthand version of this function is provided: given a base ring R, we abbreviate the constructor as follows.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"R[\"x\"]","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Here are some examples of creating polynomial rings and making use of the resulting parent objects to coerce various elements into the polynomial ring.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\njulia> U, z = R[\"z\"]\n(Univariate polynomial ring in z over matrix algebra of degree 2 over integers, z)\n\njulia> f = S()\n0\n\njulia> g = S(123)\n[123 0; 0 123]\n\njulia> h = T(BigInt(1234))\n[1234 0; 0 1234]\n\njulia> k = T(x + 1)\nx + 1\n\njulia> m = U(z + 1)\nz + 1\n","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"All of the examples here are generic polynomial rings, but specialised implementations of polynomial rings provided by external modules will also usually provide a polynomial_ring constructor to allow creation of their polynomial rings.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Basic-ring-functionality","page":"Univariate polynomials over a noncommutative ring","title":"Basic ring functionality","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Once a polynomial ring is constructed, there are various ways to construct polynomials in that ring.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"The easiest way is simply using the generator returned by the polynomial_ring constructor and build up the polynomial using basic arithmetic, as described in the Ring interface. ","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"The Julia language also has special syntax for the construction of polynomials in terms of a generator, e.g. we can write 2x instead of 2*x.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"The polynomial rings in AbstractAlgebra.jl implement the full Ring interface. Of course the entire Univariate Polynomial Ring interface is also implemented.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"We give some examples of such functionality.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\njulia> f = x^3 + 3x + 21\nx^3 + [3 0; 0 3]*x + [21 0; 0 21]\n\njulia> g = (x + 1)*y^2 + 2x + 1\n(x + 1)*y^2 + [2 0; 0 2]*x + 1\n\njulia> h = zero(T)\n0\n\njulia> k = one(S)\n1\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> n = length(g)\n3\n\njulia> U = base_ring(T)\nUnivariate polynomial ring in x over matrix algebra of degree 2 over integers\n\njulia> V = base_ring(y + 1)\nUnivariate polynomial ring in x over matrix algebra of degree 2 over integers\n\njulia> v = var(T)\n:y\n\njulia> U = parent(y + 1)\nUnivariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers\n\njulia> g == deepcopy(g)\ntrue","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Polynomial-functionality-provided-by-AbstractAlgebra.jl","page":"Univariate polynomials over a noncommutative ring","title":"Polynomial functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"The functionality listed below is automatically provided by AbstractAlgebra.jl for any polynomial module that implements the full Univariate Polynomial Ring interface over a noncommutative ring. This includes AbstractAlgebra.jl's own generic polynomial rings.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"But if a C library provides all the functionality documented in the Univariate Polynomial Ring interface over a noncommutative ring, then all the functions described here will also be automatically supplied by AbstractAlgebra.jl for that polynomial type.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Of course, modules are free to provide specific implementations of the functions described here, that override the generic implementation.","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Basic-functionality","page":"Univariate polynomials over a noncommutative ring","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"leading_coefficient(::NCPolyRingElem)\ntrailing_coefficient(::NCPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#leading_coefficient-Tuple{NCPolyRingElem}","page":"Univariate polynomials over a noncommutative ring","title":"leading_coefficient","text":"leading_coefficient(a::PolynomialElem)\n\nReturn the leading coefficient of the given polynomial. This will be the nonzero coefficient of the term with highest degree unless the polynomial in the zero polynomial, in which case a zero coefficient is returned.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/#trailing_coefficient-Tuple{NCPolyRingElem}","page":"Univariate polynomials over a noncommutative ring","title":"trailing_coefficient","text":"trailing_coefficient(a::PolynomialElem)\n\nReturn the trailing coefficient of the given polynomial. This will be the nonzero coefficient of the term with lowest degree unless the polynomial is the zero polynomial, in which case a zero coefficient is returned.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"gen(::NCPolyRing)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#gen-Tuple{AbstractAlgebra.NCPolyRing}","page":"Univariate polynomials over a noncommutative ring","title":"gen","text":"gen(R::NCPolyRing)\n\nReturn the generator of the given polynomial ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"is_gen(::NCPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#is_gen-Tuple{NCPolyRingElem}","page":"Univariate polynomials over a noncommutative ring","title":"is_gen","text":"is_gen(a::PolynomialElem)\n\nReturn true if the given polynomial is the constant generator of its polynomial ring, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"is_monomial(::NCPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#is_monomial-Tuple{NCPolyRingElem}","page":"Univariate polynomials over a noncommutative ring","title":"is_monomial","text":"is_monomial(a::PolynomialElem)\n\nReturn true if the given polynomial is a monomial.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"is_term(::NCPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#is_term-Tuple{NCPolyRingElem}","page":"Univariate polynomials over a noncommutative ring","title":"is_term","text":"is_term(a::PolynomialElem)\n\nReturn true if the given polynomial has one term.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\njulia> a = zero(T)\n0\n\njulia> b = one(T)\n1\n\njulia> c = BigInt(1)*y^2 + BigInt(1)\ny^2 + 1\n\njulia> d = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + [3 0; 0 3]\n\njulia> f = leading_coefficient(d)\nx\n\njulia> y = gen(T)\ny\n\njulia> g = is_gen(y)\ntrue\n\njulia> m = is_unit(b)\ntrue\n\njulia> n = degree(d)\n2\n\njulia> is_term(2y^2)\ntrue\n\njulia> is_monomial(y^2)\ntrue\n","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Truncation","page":"Univariate polynomials over a noncommutative ring","title":"Truncation","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"truncate(::NCPolyRingElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#truncate-Tuple{NCPolyRingElem, Int64}","page":"Univariate polynomials over a noncommutative ring","title":"truncate","text":"truncate(a::PolynomialElem, n::Int)\n\nReturn a truncated to n terms, i.e. the remainder upon division by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"mullow(::NCPolyRingElem{T}, ::NCPolyRingElem{T}, ::Int) where T <: NCRingElem","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#mullow-Union{Tuple{T}, Tuple{NCPolyRingElem{T}, NCPolyRingElem{T}, Int64}} where T<:NCRingElem","page":"Univariate polynomials over a noncommutative ring","title":"mullow","text":"mullow(a::NCPolyRingElem{T}, b::NCPolyRingElem{T}, n::Int) where T <: NCRingElem\n\nReturn atimes b truncated to n terms.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + [3 0; 0 3]\n\njulia> g = (x + 1)*y + (x^3 + 2x + 2)\n(x + 1)*y + x^3 + [2 0; 0 2]*x + [2 0; 0 2]\n\njulia> h = truncate(f, 1)\n[3 0; 0 3]\n\njulia> k = mullow(f, g, 4)\n(x^2 + x)*y^3 + (x^4 + [3 0; 0 3]*x^2 + [4 0; 0 4]*x + 1)*y^2 + (x^4 + x^3 + [2 0; 0 2]*x^2 + [7 0; 0 7]*x + [5 0; 0 5])*y + [3 0; 0 3]*x^3 + [6 0; 0 6]*x + [6 0; 0 6]\n","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Reversal","page":"Univariate polynomials over a noncommutative ring","title":"Reversal","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"reverse(::NCPolyRingElem, ::Int)\nreverse(::NCPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#reverse-Tuple{NCPolyRingElem, Int64}","page":"Univariate polynomials over a noncommutative ring","title":"reverse","text":"reverse(x::PolynomialElem, len::Int)\n\nReturn the reverse of the polynomial x, thought of as a polynomial of the given length (the polynomial will be notionally truncated or padded with zeroes before the leading term if necessary to match the specified length). The resulting polynomial is normalised. If len is negative we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/#reverse-Tuple{NCPolyRingElem}","page":"Univariate polynomials over a noncommutative ring","title":"reverse","text":"reverse(x::PolynomialElem)\n\nReturn the reverse of the polynomial x, i.e. the leading coefficient of x becomes the constant coefficient of the result, etc. The resulting polynomial is normalised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + [3 0; 0 3]\n\njulia> g = reverse(f, 7)\n[3 0; 0 3]*y^6 + (x + 1)*y^5 + x*y^4\n\njulia> h = reverse(f)\n[3 0; 0 3]*y^2 + (x + 1)*y + x\n","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Shifting","page":"Univariate polynomials over a noncommutative ring","title":"Shifting","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"shift_left(::NCPolyRingElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#shift_left-Tuple{NCPolyRingElem, Int64}","page":"Univariate polynomials over a noncommutative ring","title":"shift_left","text":"shift_left(f::PolynomialElem, n::Int)\n\nReturn the polynomial f shifted left by n terms, i.e. multiplied by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"shift_right(::NCPolyRingElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#shift_right-Tuple{NCPolyRingElem, Int64}","page":"Univariate polynomials over a noncommutative ring","title":"shift_right","text":"shift_right(f::PolynomialElem, n::Int)\n\nReturn the polynomial f shifted right by n terms, i.e. divided by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + [3 0; 0 3]\n\njulia> g = shift_left(f, 7)\nx*y^9 + (x + 1)*y^8 + [3 0; 0 3]*y^7\n\njulia> h = shift_right(f, 2)\nx\n","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Evaluation","page":"Univariate polynomials over a noncommutative ring","title":"Evaluation","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"evaluate{T <: NCRingElem}(::NCPolyRingElem{T}, ::T)\nevaluate(::NCPolyRingElem, ::Integer)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#evaluate-Union{Tuple{T}, Tuple{NCPolyRingElem{T}, T}} where T<:NCRingElem","page":"Univariate polynomials over a noncommutative ring","title":"evaluate","text":"evaluate(a::NCPolyRingElem, b::T) where T <: NCRingElem\n\nEvaluate the polynomial a at the value b and return the result.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/#evaluate-Tuple{NCPolyRingElem, Integer}","page":"Univariate polynomials over a noncommutative ring","title":"evaluate","text":"evaluate(a::NCPolyRingElem, b::Union{Integer, Rational, AbstractFloat})\n\nEvaluate the polynomial a at the value b and return the result.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"We also overload the functional notation so that the polynomial f can be evaluated at a by writing f(a). ","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + [3 0; 0 3]\n\njulia> k = evaluate(f, 3)\n[12 0; 0 12]*x + [6 0; 0 6]\n\njulia> m = evaluate(f, x^2 + 2x + 1)\nx^5 + [4 0; 0 4]*x^4 + [7 0; 0 7]*x^3 + [7 0; 0 7]*x^2 + [4 0; 0 4]*x + [4 0; 0 4]\n\njulia> r = f(23)\n[552 0; 0 552]*x + [26 0; 0 26]\n","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#Derivative","page":"Univariate polynomials over a noncommutative ring","title":"Derivative","text":"","category":"section"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"derivative(::NCPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/#derivative-Tuple{NCPolyRingElem}","page":"Univariate polynomials over a noncommutative ring","title":"derivative","text":"derivative(a::PolynomialElem)\n\nReturn the derivative of the polynomial a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ncpolynomial/","page":"Univariate polynomials over a noncommutative ring","title":"Univariate polynomials over a noncommutative ring","text":"julia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over matrix algebra of degree 2 over integers, x)\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix algebra of degree 2 over integers, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + [3 0; 0 3]\n\njulia> h = derivative(f)\n[2 0; 0 2]*x*y + x + 1\n","category":"page"},{"location":"Hecke/abelian/structural/#Structural-Computations","page":"-","title":"Structural Computations","text":"","category":"section"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"Abelian groups support a wide range of structural operations such as","category":"page"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"enumeration of subgroups\n(outer) direct products\ntensor and hom constructions\nfree resolutions and general complexes\n(co)-homology and tensor and hom-functors","category":"page"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"snf(A::GrpAbFinGen)\nHecke.find_isomorphism(G, op, A::Hecke.GrpAb)","category":"page"},{"location":"Hecke/abelian/structural/#snf-Tuple{GrpAbFinGen}","page":"-","title":"snf","text":"snf(A::GrpAbFinGen) -> GrpAbFinGen, GrpAbFinGenMap\n\nReturn a pair (G f), where G is an abelian group in canonical Smith normal form isomorphic to A and an isomorphism f G to A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#find_isomorphism-Tuple{Any, Any, Hecke.GrpAb}","page":"-","title":"find_isomorphism","text":"find_isomorphism(G, op, A::GrpAb) -> Dict, Dict\n\nGiven an abelian group A and a collection G which is an abelian group with the operation op, this functions returns isomorphisms G to A and A to G encoded as dictionaries.\n\nIt is assumed that G and A are isomorphic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#Subgroups-and-Quotients","page":"-","title":"Subgroups and Quotients","text":"","category":"section"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"torsion_subgroup(G::GrpAbFinGen)\nsub(G::GrpAbFinGen, s::Vector{GrpAbFinGenElem})\nsub(s::Vector{GrpAbFinGenElem})\nsub(G::GrpAbFinGen, M::ZZMatrix)\nsub(G::GrpAbFinGen, n::ZZRingElem)\nsub(G::GrpAbFinGen, n::Integer)\npsylow_subgroup(G::GrpAbFinGen, p::Union{ZZRingElem, Integer})\nHecke.has_quotient(G::GrpAbFinGen, invariant::Vector{Int})\nHecke.has_complement(f::GrpAbFinGenMap)\nis_pure(U::GrpAbFinGen, G::GrpAbFinGen)\nis_neat(U::GrpAbFinGen, G::GrpAbFinGen)\nsaturate(U::GrpAbFinGen, G::GrpAbFinGen)","category":"page"},{"location":"Hecke/abelian/structural/#torsion_subgroup-Tuple{GrpAbFinGen}","page":"-","title":"torsion_subgroup","text":"torsion_subgroup(G::GrpAbFinGen) -> GrpAbFinGen, Map\n\nReturn the torsion subgroup of G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#sub-Tuple{GrpAbFinGen, Vector{GrpAbFinGenElem}}","page":"-","title":"sub","text":"sub(G::GrpAbFinGen, s::Vector{GrpAbFinGenElem}) -> GrpAbFinGen, GrpAbFinGenMap\n\nCreate the subgroup H of G generated by the elements in s together with the injection iota H to G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#sub-Tuple{Vector{GrpAbFinGenElem}}","page":"-","title":"sub","text":"sub(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}, task::Symbol = :with_morphism) where T\n\nGiven a vector V of (homogeneous) elements of F, return the (graded) submodule of F generated by these elements.\n\nPut more precisely, return the submodule as an object of type SubquoModule. \n\nAdditionally, if N denotes this object, \n\nreturn the inclusion map N to F if task = :with_morphism (default),\nreturn and cache the inclusion map N to F if task = :cache_morphism,\ndo none of the above if task = :none.\n\nIf task = :only_morphism, return only the inclusion map.\n\n\n\n\n\nsub(F::FreeMod{T}, A::MatElem{T}, task::Symbol = :with_morphism) where {T}\n\nGiven a (homogeneous) matrix A, return the (graded) submodule of F generated by the rows of A.\n\nPut more precisely, return this submodule as an object of type SubquoModule. \n\nAdditionally, if N denotes this submodule, \n\nreturn the inclusion map N to F if task = :with_morphism (default),\nreturn and cache the inclusion map N to F if task = :cache_morphism,\ndo none of the above if task = :none.\n\nIf task = :only_morphism, return only the inclusion map.\n\n\n\n\n\nsub(F::FreeMod{T}, O::Vector{<:SubquoModuleElem{T}}, task::Symbol = :with_morphism) where T\n\nReturn S as a submodule of F, where S is generated by O. The embedding module of the parent of the elements of O must be F. If task is set to :none or to :module return only S. If task is set to :with_morphism (default option) or to :both return also the canonical injection morphism S to F. If task is set to :cache_morphism the morphism is also cached. If task is set to :only_morphism return only the morphism.\n\n\n\n\n\nsub(F::FreeMod{T}, s::SubquoModule{T}, task::Symbol = :with_morphism) where T\n\nReturn s as a submodule of F, that is the embedding free module of s must be F and s has no relations. If task is set to :none or to :module return only s. If task is set to :with_morphism (default option) or to :both return also the canonical injection morphism s to F. If task is set to :cache_morphism the morphism is also cached. If task is set to :only_morphism return only the morphism.\n\n\n\n\n\nsub(M::SubquoModule{T}, V::Vector{<:SubquoModuleElem{T}}, task::Symbol = :with_morphism) where T\n\nGiven a vector V of (homogeneous) elements of M, return the (graded) submodule of M generated by these elements.\n\nPut more precisely, return this submodule as an object of type SubquoModule. \n\nAdditionally, if N denotes this object,\n\nreturn the inclusion map N to M if task = :with_morphism (default),\nreturn and cache the inclusion map N to M if task = :cache_morphism,\ndo none of the above if task = :none.\n\nIf task = :only_morphism, return only the inclusion map.\n\n\n\n\n\nsub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T\n\nGiven a vector V of (homogeneous) elements of M, return the (graded) submodule of M generated by these elements.\n\nPut more precisely, return this submodule as an object of type SubquoModule. \n\nAdditionally, if N denotes this object,\n\nreturn the inclusion map N to M if task = :with_morphism (default),\nreturn and cache the inclusion map N to M if task = :cache_morphism,\ndo none of the above if task = :none.\n\nIf task = :only_morphism, return only the inclusion map.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];\n\njulia> N, incl = sub(F, V);\n\njulia> N\nSubmodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nrepresented as subquotient with no relations.\n\njulia> incl\nMap with following data\nDomain:\n=======\nSubmodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nrepresented as subquotient with no relations.\nCodomain:\n=========\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\n\n\n\n\nsub(A::SMat, r::AbstractUnitRange, c::AbstractUnitRange) -> SMat\n\nReturn the submatrix of A, where the rows correspond to r and the columns correspond to c.\n\n\n\n\n\nsub(s::Vector{GrpAbFinGenElem}) -> GrpAbFinGen, GrpAbFinGenMap\n\nAssuming that the non-empty array s contains elements of an abelian group G, this functions returns the subgroup H of G generated by the elements in s together with the injection iota H to G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#sub-Tuple{GrpAbFinGen, ZZMatrix}","page":"-","title":"sub","text":"sub(G::GrpAbFinGen, M::ZZMatrix) -> GrpAbFinGen, GrpAbFinGenMap\n\nCreate the subgroup H of G generated by the elements corresponding to the rows of M together with the injection iota H to G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#sub-Tuple{GrpAbFinGen, ZZRingElem}","page":"-","title":"sub","text":"sub(G::GrpAbFinGen, n::ZZRingElem) -> GrpAbFinGen, GrpAbFinGenMap\n\nCreate the subgroup n cdot G of G together with the injection iota ncdot G to G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#sub-Tuple{GrpAbFinGen, Integer}","page":"-","title":"sub","text":"sub(G::GrpAbFinGen, n::Integer) -> GrpAbFinGen, Map\n\nCreate the subgroup n cdot G of G together with the injection iota n cdot G to G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#psylow_subgroup-Tuple{GrpAbFinGen, Union{Integer, ZZRingElem}}","page":"-","title":"psylow_subgroup","text":"psylow_subgroup(G::GrpAbFinGen, p::IntegerUnion) -> GrpAbFinGen, GrpAbFinGenMap\n\nReturn the p-Sylow subgroup of G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#has_quotient-Tuple{GrpAbFinGen, Vector{Int64}}","page":"-","title":"has_quotient","text":"has_quotient(G::GrpAbFinGen, invariant::Vector{Int}) -> Bool\n\nGiven an abelian group G, return true if it has a quotient with given elementary divisors and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#has_complement-Tuple{GrpAbFinGenMap}","page":"-","title":"has_complement","text":"has_complement(f::GrpAbFinGenMap) -> Bool, GrpAbFinGenMap\nhas_complement(U::GrpAbFinGen, G::GrpAbFinGen) -> Bool, GrpAbFinGenMap\n\nGiven a map representing a subgroup of a group G, or a subgroup U of a group G, return either true and an injection of a complement in G, or false.\n\nSee also: is_pure\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#is_pure-Tuple{GrpAbFinGen, GrpAbFinGen}","page":"-","title":"is_pure","text":"is_pure(U::GrpAbFinGen, G::GrpAbFinGen) -> Bool\n\nA subgroup U of G is called pure if for all n an element in U that is in the image of the multiplication by n map of G is also a multiple of an element in U.\n\nFor finite abelian groups this is equivalent to U having a complement in G. They are also know as isolated subgroups and serving subgroups.\n\nSee also: is_neat, has_complement\n\nEXAMPLES\n\njulia> G = abelian_group([2, 8]);\n\njulia> U, _ = sub(G, [G[1]+2*G[2]]);\n\njulia> is_pure(U, G)\nfalse\n\njulia> U, _ = sub(G, [G[1]+4*G[2]]);\n\njulia> is_pure(U)\ntrue\n\njulia> has_complement(U, G)[1]\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#is_neat-Tuple{GrpAbFinGen, GrpAbFinGen}","page":"-","title":"is_neat","text":"is_neat(U::GrpAbFinGen, G::GrpAbFinGen) -> Bool\n\nA subgroup U of G is called neat if for all primes p an element in U that is in the image of the multiplication by p map of G is also a multiple of an element in U.\n\nSee also: is_pure\n\nEXAMPLES\n\njulia> G = abelian_group([2, 8]);\n\njulia> U, _ = sub(G, [G[1] + 2*G[2]]);\n\njulia> is_neat(U, G)\ntrue\n\njulia> is_pure(U, G)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#saturate-Tuple{GrpAbFinGen, GrpAbFinGen}","page":"-","title":"saturate","text":"saturate(U::GrpAbFinGen, G::GrpAbFinGen) -> GrpAbFinGen\n\nFor a subgroup U of G find a minimal overgroup that is pure, and thus has a complement.\n\nSee also: is_pure, has_complement\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"A sophisticated algorithm for the enumeration of all (or selected) subgroups of a finite abelian group is available.","category":"page"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"psubgroups(g::GrpAbFinGen, p::Integer)","category":"page"},{"location":"Hecke/abelian/structural/#psubgroups-Tuple{GrpAbFinGen, Integer}","page":"-","title":"psubgroups","text":"psubgroups(g::GrpAbFinGen, p::Integer;\n subtype = :all,\n quotype = :all,\n index = -1,\n order = -1)\n\nReturn an iterator for the subgroups of G of the specific form. Note that subtype (and quotype) is the type of the subgroup as an abelian p-group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"using Hecke # hide\nG = abelian_group([6, 12])\nshapes = MSet{Vector{ZZRingElem}}()\nfor U = psubgroups(G, 2)\n push!(shapes, elementary_divisors(U[1]))\nend\nshapes","category":"page"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"So there are 2 subgroups isomorphic to C_4 (ZZRingElem[4] : 2), 1 isomorphic to C_2times C_4, 1 trivial and 3 C_2 subgroups.","category":"page"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"subgroups(g::GrpAbFinGen)","category":"page"},{"location":"Hecke/abelian/structural/#subgroups-Tuple{GrpAbFinGen}","page":"-","title":"subgroups","text":"subgroups(g::GrpAbFinGen;\n subtype = :all ,\n quotype = :all,\n index = -1,\n order = -1)\n\nReturn an iterator for the subgroups of G of the specific form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"for U = subgroups(G, subtype = [2])\n @show U[1], map(U[2], gens(U[1]))\nend\nfor U = subgroups(G, quotype = [2])\n @show U[1], map(U[2], gens(U[1]))\nend","category":"page"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"quo(G::GrpAbFinGen, s::Vector{GrpAbFinGenElem})\nquo(G::GrpAbFinGen, M::ZZMatrix)\nquo(G::GrpAbFinGen, n::Integer)\nquo(G::GrpAbFinGen, n::ZZRingElem)\nquo(G::GrpAbFinGen, U::GrpAbFinGen)","category":"page"},{"location":"Hecke/abelian/structural/#quo-Tuple{GrpAbFinGen, Vector{GrpAbFinGenElem}}","page":"-","title":"quo","text":"quo(G::GrpAbFinGen, s::Vector{GrpAbFinGenElem}) -> GrpAbFinGen, GrpAbfinGemMap\n\nCreate the quotient H of G by the subgroup generated by the elements in s, together with the projection p G to H.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#quo-Tuple{GrpAbFinGen, ZZMatrix}","page":"-","title":"quo","text":"quo(G::GrpAbFinGen, M::ZZMatrix) -> GrpAbFinGen, GrpAbFinGenMap\n\nCreate the quotient H of G by the subgroup generated by the elements corresponding to the rows of M, together with the projection p G to H.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#quo-Tuple{GrpAbFinGen, Integer}","page":"-","title":"quo","text":"quo(G::GrpAbFinGen, n::Integer}) -> GrpAbFinGen, Map\nquo(G::GrpAbFinGen, n::ZZRingElem}) -> GrpAbFinGen, Map\n\nReturns the quotient H = GnG together with the projection p G to H.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#quo-Tuple{GrpAbFinGen, ZZRingElem}","page":"-","title":"quo","text":"quo(G::GrpAbFinGen, n::Integer}) -> GrpAbFinGen, Map\nquo(G::GrpAbFinGen, n::ZZRingElem}) -> GrpAbFinGen, Map\n\nReturns the quotient H = GnG together with the projection p G to H.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#quo-Tuple{GrpAbFinGen, GrpAbFinGen}","page":"-","title":"quo","text":"quo(G::GrpAbFinGen, U::GrpAbFinGen) -> GrpAbFinGen, Map\n\nCreate the quotient H of G by U, together with the projection p G to H.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"For 2 subgroups U and V of the same group G, U+V returns the smallest subgroup of G containing both. Similarly, Ucap V computes the intersection and U subset V tests for inclusion. The difference between issubset = subset and is_subgroup is that the inclusion map is also returned in the 2nd call.","category":"page"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"intersect(mG::GrpAbFinGenMap, mH::GrpAbFinGenMap)","category":"page"},{"location":"Hecke/abelian/structural/#intersect-Tuple{GrpAbFinGenMap, GrpAbFinGenMap}","page":"-","title":"intersect","text":"intersect(mG::GrpAbFinGenMap, mH::GrpAbFinGenMap) -> GrpAbFinGen, Map\n\nGiven two injective maps of abelian groups with the same codomain G, return the intersection of the images as a subgroup of G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#Direct-Products","page":"-","title":"Direct Products","text":"","category":"section"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"direct_product(G::GrpAbFinGen...)\nHecke.canonical_injection(G::GrpAbFinGen, i::Int)\nHecke.canonical_projection(G::GrpAbFinGen, i::Int)\nflat(G::GrpAbFinGen)","category":"page"},{"location":"Hecke/abelian/structural/#direct_product-Tuple{Vararg{GrpAbFinGen}}","page":"-","title":"direct_product","text":"direct_product(G::GrpAbFinGen...) -> GrpAbFinGen, Vector{GrpAbFinGenMap}\n\nReturn the direct product D of the (finitely many) abelian groups G_i, together with the projections D to G_i.\n\nFor finite abelian groups, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain D as a direct sum together with the injections D to G_i, one should call direct_sum(G...). If one wants to obtain D as a biproduct together with the projections and the injections, one should call biproduct(G...).\n\nOtherwise, one could also call canonical_injections(D) or canonical_projections(D) later on.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#canonical_injection-Tuple{GrpAbFinGen, Int64}","page":"-","title":"canonical_injection","text":"canonical_injection(G::GrpAbFinGen, i::Int) -> GrpAbFinGenMap\n\nGiven a group G that was created as a direct product, return the injection from the ith component.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#canonical_projection-Tuple{GrpAbFinGen, Int64}","page":"-","title":"canonical_projection","text":"canonical_projection(G::GrpAbFinGen, i::Int) -> GrpAbFinGenMap\n\nGiven a group G that was created as a direct product, return the projection onto the ith component.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#flat-Tuple{GrpAbFinGen}","page":"-","title":"flat","text":"flat(G::GrpAbFinGen) -> GrpAbFinGenMap\n\nGiven a group G that is created using (iterated) direct products, or (iterated) tensor products, return a group isomorphism into a flat product: for G = (A oplus B) oplus C, it returns the isomorphism G to A oplus B oplus C (resp. otimes).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#Tensor-Producs","page":"-","title":"Tensor Producs","text":"","category":"section"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"tensor_product(G::GrpAbFinGen...)\nhom(G::GrpAbFinGen, H::GrpAbFinGen, A::Vector{ <: Map{GrpAbFinGen, GrpAbFinGen}})","category":"page"},{"location":"Hecke/abelian/structural/#tensor_product-Tuple{Vararg{GrpAbFinGen}}","page":"-","title":"tensor_product","text":"tensor_product(G::GrpAbFinGen...; task::Symbol = :map) -> GrpAbFinGen, Map\n\nGiven groups G_i, compute the tensor product G_1otimes cdots otimes G_n. If task is set to \":map\", a map phi is returned that maps tuples in G_1 times cdots times G_n to pure tensors g_1 otimes cdots otimes g_n. The map admits a preimage as well.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#hom-Tuple{GrpAbFinGen, GrpAbFinGen, Vector{<:Map{GrpAbFinGen, GrpAbFinGen}}}","page":"-","title":"hom","text":"hom(G::GrpAbFinGen, H::GrpAbFinGen, A::Vector{ <: Map{GrpAbFinGen, GrpAbFinGen}}) -> Map\n\nGiven groups G = G_1 otimes cdots otimes G_n and H = H_1 otimes cdot otimes H_n as well as maps phi_i G_ito H_i, compute the tensor product of the maps.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/structural/#Hom-Group","page":"-","title":"Hom-Group","text":"","category":"section"},{"location":"Hecke/abelian/structural/","page":"-","title":"-","text":"hom(::GrpAbFinGen, ::GrpAbFinGen)","category":"page"},{"location":"Hecke/abelian/structural/#hom-Tuple{GrpAbFinGen, GrpAbFinGen}","page":"-","title":"hom","text":"hom(G::GrpAbFinGen, H::GrpAbFinGen; task::Symbol = :map) -> GrpAbFinGen, Map\n\nComputes the group of all homomorpisms from G to H as an abstract group. If task is \":map\", then a map phi is computed that can be used to obtain actual homomorphisms. This map also allows preimages. Set task to \":none\" to not compute the map.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/","page":"Curves","title":"Curves","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#Curves","page":"Curves","title":"Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#Introduction","page":"Curves","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/","page":"Curves","title":"Curves","text":"An abstract tropical curve is a finite, loopless, multigraph. It is defined by an incidence matrix with vertices as columns and edges as rows.","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/","page":"Curves","title":"Curves","text":"A divisor on an abstract tropical curve is a formal linear combination of the vertices with integer coefficients. The degree of a divisor is the sum of its coefficients. A divisor is effective if all its coefficients are nonnegative.","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/","page":"Curves","title":"Curves","text":"For more definitions on the theory of divisors and linear sisyems on abstract tropical curve, we refer to Matthew Baker, Serguei Norine (2007).","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/","page":"Curves","title":"Curves","text":"The tropical Jacobian of an abstract tropical curve is the group of divisors of degree zero modulo the subgroup of principal divisors. Here a principal divisor is the divisor associated to a piecewise-linear function on the vertices by the Laplacian operator. The tropical Jacobian is a finite abelian group, with order equal to the number of maximal spanning trees in the graph. It is isomorphic to prodmathbbZn_imathbbZ, where the n_i are the nonzero elementary divisors of the Laplacian matrix. For more details, see Matthew Baker, Serguei Norine (2007).","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#Construction","page":"Curves","title":"Construction","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/","page":"Curves","title":"Curves","text":"TropicalCurve(PC::PolyhedralComplex)\nDivisorOnTropicalCurve(tc::TropicalCurve, coeffs::Vector{Int})","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#TropicalCurve-Tuple{PolyhedralComplex}","page":"Curves","title":"TropicalCurve","text":"TropicalCurve(PC::PolyhedralComplex)\n\nConstruct a tropical curve from a polyhedral complex. If the curve is embedded, vertices must are points in mathbb R^n. If the curve is abstract, the polyhedral complex is empty, vertices must be 1, ..., n, and the graph is given as attribute.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]])\n3×4 IncidenceMatrix\n[1, 2]\n[1, 3]\n[1, 4]\n\n\njulia> VR = [0 0; 1 0; -1 0; 0 1]\n4×2 Matrix{Int64}:\n 0 0\n 1 0\n -1 0\n 0 1\n\njulia> PC = polyhedral_complex(QQFieldElem, IM, VR)\nPolyhedral complex in ambient dimension 2\n\njulia> TC = TropicalCurve(PC)\nmin tropical curve in 2-dimensional Euclidean space\n\njulia> abs_TC = TropicalCurve(IM)\nAbstract min tropical curve\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#DivisorOnTropicalCurve-Tuple{TropicalCurve, Vector{Int64}}","page":"Curves","title":"DivisorOnTropicalCurve","text":"DivisorOnTropicalCurve(tc::TropicalCurve, coeffs::Vector{Int})\n\nConstruct a divisor with coefficients coeffs on an abstract tropical curve tc.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> coeffs = [0, 1, 1, 1];\n\njulia> dtc = DivisorOnTropicalCurve(tc,coeffs)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#Auxiliary-functions","page":"Curves","title":"Auxiliary functions","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/","page":"Curves","title":"Curves","text":"graph(tc::TropicalCurve)\nn_nodes(tc::TropicalCurve)\ncoefficients(dtc::DivisorOnTropicalCurve)\ndegree(dtc::DivisorOnTropicalCurve)\nis_effective(dtc::DivisorOnTropicalCurve)\nchip_firing_move(dtc::DivisorOnTropicalCurve, position::Int)\nv_reduced(dtc::DivisorOnTropicalCurve, vertex::Int)\nis_linearly_equivalent(dtc1::DivisorOnTropicalCurve, dtc2::DivisorOnTropicalCurve)\nstructure_tropical_jacobian(tc::TropicalCurve) ","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#graph-Tuple{TropicalCurve}","page":"Curves","title":"graph","text":"graph(tc::TropicalCurve)\n\nReturn the graph of an abstract tropical curve tc.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> graph(tc)\n6×4 IncidenceMatrix\n[1, 2]\n[1, 3]\n[1, 4]\n[2, 3]\n[2, 4]\n[3, 4]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#n_nodes-Tuple{TropicalCurve}","page":"Curves","title":"n_nodes","text":"n_nodes(tc::TropicalCurve)\n\nReturn the number of nodes of an abstract tropical curve tc.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> n_nodes(tc)\n4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#coefficients-Tuple{DivisorOnTropicalCurve}","page":"Curves","title":"coefficients","text":"coefficients(dtc::DivisorOnTropicalCurve)\n\nConstruct a divisor dtc with coefficients coeffs on an abstract tropical curve.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> coeffs = [0, 1, 1, 1];\n\njulia> dtc = DivisorOnTropicalCurve(tc,coeffs)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])\n\njulia> coefficients(dtc)\n4-element Vector{Int64}:\n 0\n 1\n 1\n 1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#degree-Tuple{DivisorOnTropicalCurve}","page":"Curves","title":"degree","text":"degree(dtc::DivisorOnTropicalCurve)\n\nCompute the degree of a divisor dtc on an abstract tropical curve.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> coeffs = [0, 1, 1, 1];\n\njulia> dtc = DivisorOnTropicalCurve(tc,coeffs)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])\n\njulia> degree(dtc)\n3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#is_effective-Tuple{DivisorOnTropicalCurve}","page":"Curves","title":"is_effective","text":"is_effective(dtc::DivisorOnTropicalCurve)\n\nCheck whether a divisor dtc on an abstract tropical curve is effective.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> coeffs = [0, 1, 1, 1];\n\njulia> dtc = DivisorOnTropicalCurve(tc,coeffs)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])\n\njulia> is_effective(dtc)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#chip_firing_move-Tuple{DivisorOnTropicalCurve, Int64}","page":"Curves","title":"chip_firing_move","text":"chipfiringmove(dtc::DivisorOnTropicalCurve, position::Int)\n\nGiven a divisor dtc and vertex labelled position, compute the linearly equivalent divisor obtained by a chip firing move from the given vertex position.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> coeffs = [0, 1, 1, 1];\n\njulia> dtc = DivisorOnTropicalCurve(tc,coeffs)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])\n\njulia> chip_firing_move(dtc,1)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [-3, 2, 2, 2])\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#v_reduced-Tuple{DivisorOnTropicalCurve, Int64}","page":"Curves","title":"v_reduced","text":"v_reduced(dtc::DivisorOnTropicalCurve, vertex::Int)\n\nGiven a divisor dtc and vertex labelled vertex, compute the unique divisor reduced with repspect to vertex as defined in Matthew Baker, Serguei Norine (2007). The divisor dtc must have positive coefficients apart from vertex.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> coeffs = [0, 1, 1, 1];\n\njulia> dtc = DivisorOnTropicalCurve(tc,coeffs)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])\n\njulia> v_reduced(dtc,1)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [3, 0, 0, 0])\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#is_linearly_equivalent-Tuple{DivisorOnTropicalCurve, DivisorOnTropicalCurve}","page":"Curves","title":"is_linearly_equivalent","text":"islinearlyequivalent(dtc1::DivisorOnTropicalCurve, dtc2::DivisorOnTropicalCurve)\n\nGiven two effective divisors dtc1 and dtc2 on the same tropical curve, check whether they are linearly equivalent.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]);\n\njulia> tc = TropicalCurve(IM)\nAbstract min tropical curve\n\njulia> coeffs1 = [0, 1, 1, 1];\n\njulia> dtc1 = DivisorOnTropicalCurve(tc,coeffs1)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [0, 1, 1, 1])\n\njulia> coeffs2 = [3,0,0,0];\n\njulia> dtc2 = DivisorOnTropicalCurve(tc,coeffs2)\nDivisorOnTropicalCurve{min, false}(Abstract min tropical curve, [3, 0, 0, 0])\n\njulia> is_linearly_equivalent(dtc1, dtc2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/curve/#structure_tropical_jacobian-Tuple{TropicalCurve}","page":"Curves","title":"structure_tropical_jacobian","text":"structure_tropical_jacobian(TC::TropicalCurve)\n\nCompute the elementary divisors n_i of the Laplacian matrix of the tropical curve TC. The tropical Jacobian is then isomorphic to prod (Z(n_i)Z).\n\nExamples\n\njulia> cg = complete_graph(5);\n\njulia> IM1=IncidenceMatrix([[src(e), dst(e)] for e in edges(cg)])\n10×5 IncidenceMatrix\n[1, 2]\n[1, 3]\n[2, 3]\n[1, 4]\n[2, 4]\n[3, 4]\n[1, 5]\n[2, 5]\n[3, 5]\n[4, 5]\n\njulia> TC1 = TropicalCurve(IM1)\nAbstract min tropical curve\n\njulia> structure_tropical_jacobian(TC1)\n(General) abelian group with relation matrix\n[1 0 0 0; 0 5 0 0; 0 0 5 0; 0 0 0 5]\n\njulia> cg2 = complete_graph(3);\n\njulia> IM2=IncidenceMatrix([[src(e), dst(e)] for e in edges(cg2)])\n3×3 IncidenceMatrix\n[1, 2]\n[1, 3]\n[2, 3]\n\njulia> TC2 = TropicalCurve(IM2)\nAbstract min tropical curve\n\njulia> structure_tropical_jacobian(TC2)\n(General) abelian group with relation matrix\n[1 0; 0 3]\n\njulia> IM3 = IncidenceMatrix([[1,2],[2,3],[3,4],[4,5],[1,5]])\n5×5 IncidenceMatrix\n[1, 2]\n[2, 3]\n[3, 4]\n[4, 5]\n[1, 5]\n\njulia> TC3=TropicalCurve(IM3)\nAbstract min tropical curve\n\njulia> G = structure_tropical_jacobian(TC3)\n(General) abelian group with relation matrix\n[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 5]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/rings/#Creating-Multivariate-Rings","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"In this section, for the convenience of the reader, we recall from the chapters on rings and fields how to create multivariate polynomial rings and their elements, adding illustrating examples. At the same time, we introduce and illustrate a ring type for modelling multivariate polynomial rings with gradings.","category":"page"},{"location":"CommutativeAlgebra/rings/#Types","page":"Creating Multivariate Rings","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"OSCAR provides types for dense univariate and sparse multivariate polynomials. The univariate ring types belong to the abstract type PolyRing{T}, their elements have abstract type PolyRingElem{T}. The multivariate ring types belong to the abstract type MPolyRing{T}, their elements have abstract type MPolyRingElem{T}. Here, T is the element type of the coefficient ring of the polynomial ring.","category":"page"},{"location":"CommutativeAlgebra/rings/#Constructors","page":"Creating Multivariate Rings","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"The basic constructor below allows one to build multivariate polynomial rings:","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"polynomial_ring(C::Ring, V::Vector{String}; ordering=:lex, cached::Bool = true)","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Its return value is a tuple, say R, vars, consisting of a polynomial ring R with coefficient ring C and a vector vars of generators (variables) which print according to the strings in the vector V . The input ordering=:lex refers to the lexicograpical monomial ordering which specifies the default way of storing and displaying polynomials in OSCAR (terms are sorted in descending order). The other possible choices are :deglex and :degrevlex. Gröbner bases, however, can be computed with respect to any monomial ordering. See the section on Gröbner bases.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"note: Note\nCaching is used to ensure that a given ring constructed from given parameters is unique in the system. For example, there is only one ring of multivariate polynomials over mathbbZ with variables printing as x, y, z, and with ordering=:lex.","category":"page"},{"location":"CommutativeAlgebra/rings/#Examples","page":"Creating Multivariate Rings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R, (x, y, z) = polynomial_ring(ZZ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])\n\njulia> typeof(R)\nZZMPolyRing\n\njulia> typeof(x)\nZZMPolyRingElem\n\njulia> S, (a, b, c) = polynomial_ring(ZZ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])\n\njulia> T, _ = polynomial_ring(ZZ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])\n\njulia> R === S === T\ntrue","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R1, x = polynomial_ring(QQ, [\"x\"])\n(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])\n\njulia> typeof(x)\nVector{QQMPolyRingElem} (alias for Array{QQMPolyRingElem, 1})\n\njulia> R2, (x,) = polynomial_ring(QQ, [\"x\"])\n(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])\n\njulia> typeof(x)\nQQMPolyRingElem\n\njulia> R3, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over QQ, x)\n\njulia> typeof(x)\nQQPolyRingElem\n","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> T, x = polynomial_ring(GF(3), [\"x[1]\", \"x[2]\"]);\n\njulia> x\n2-element Vector{fpMPolyRingElem}:\n x[1]\n x[2]\n","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"The constructor illustrated below allows for the convenient handling of variables with multi-indices:","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R, x, y, z = polynomial_ring(QQ, \"x\" => (1:3, 1:4), \"y\" => 1:2, \"z\" => (1:1, 1:1, 1:1));\n\njulia> x\n3×4 Matrix{QQMPolyRingElem}:\n x[1, 1] x[1, 2] x[1, 3] x[1, 4]\n x[2, 1] x[2, 2] x[2, 3] x[2, 4]\n x[3, 1] x[3, 2] x[3, 3] x[3, 4]\n\njulia> y\n2-element Vector{QQMPolyRingElem}:\n y[1]\n y[2]\n\njulia> z\n1×1×1 Array{QQMPolyRingElem, 3}:\n[:, :, 1] =\n z[1, 1, 1]\n","category":"page"},{"location":"CommutativeAlgebra/rings/#Coefficient-Rings","page":"Creating Multivariate Rings","title":"Coefficient Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Gröbner and standard bases are implemented for multivariate polynomial rings over the fields and rings below:","category":"page"},{"location":"CommutativeAlgebra/rings/#The-field-of-rational-numbers-\\mathbb{Q}","page":"Creating Multivariate Rings","title":"The field of rational numbers mathbbQ","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> QQ\nRational field\n","category":"page"},{"location":"CommutativeAlgebra/rings/#Finite-fields-\\mathbb{F_p},-p-a-prime","page":"Creating Multivariate Rings","title":"Finite fields mathbbF_p, p a prime","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> GF(3)\nFinite field of characteristic 3\n\njulia> GF(ZZ(2)^127 - 1)\nFinite field of characteristic 170141183460469231731687303715884105727\n","category":"page"},{"location":"CommutativeAlgebra/rings/#Finite-fields-\\mathbb{F}_{pn}-with-pn-elements,-p-a-prime","page":"Creating Multivariate Rings","title":"Finite fields mathbbF_p^n with p^n elements, p a prime","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> FiniteField(2, 70, \"a\")\n(Finite field of degree 70 over GF(2), a)\n","category":"page"},{"location":"CommutativeAlgebra/rings/#Simple-algebraic-extensions-of-\\mathbb{Q}-or-\\mathbb{F}_p","page":"Creating Multivariate Rings","title":"Simple algebraic extensions of mathbbQ or mathbbF_p","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> T, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over QQ, t)\n\njulia> K, a = number_field(t^2 + 1, \"a\")\n(Number field of degree 2 over QQ, a)\n\njulia> F = GF(3)\nFinite field of characteristic 3\n\njulia> T, t = polynomial_ring(F, \"t\")\n(Univariate polynomial ring in t over GF(3), t)\n\njulia> K, a = FiniteField(t^2 + 1, \"a\")\n(Finite field of degree 2 over GF(3), a)\n","category":"page"},{"location":"CommutativeAlgebra/rings/#Purely-transcendental-extensions-of-\\mathbb{Q}-or-\\mathbb{F}_p","page":"Creating Multivariate Rings","title":"Purely transcendental extensions of mathbbQ or mathbbF_p","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> T, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over QQ, t)\n\njulia> QT = fraction_field(T)\nFraction field\n of univariate polynomial ring in t over QQ\n\njulia> parent(t)\nUnivariate polynomial ring in t over QQ\n\njulia> parent(1//t)\nFraction field\n of univariate polynomial ring in t over QQ\n\njulia> T, (s, t) = polynomial_ring(GF(3), [\"s\", \"t\"]);\n\njulia> QT = fraction_field(T)\nFraction field\n of multivariate polynomial ring in 2 variables over GF(3)\n","category":"page"},{"location":"CommutativeAlgebra/rings/#The-ring-of-integers-\\mathbb{Z}","page":"Creating Multivariate Rings","title":"The ring of integers mathbbZ","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> ZZ\nInteger Ring\n","category":"page"},{"location":"CommutativeAlgebra/rings/#Gradings","page":"Creating Multivariate Rings","title":"Gradings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Given a polynomial ring R = Cx_1 dots x_n, we may endow R with various gradings. The standard mathbb Z-grading on R is the decomposition R=bigoplus_din mathbb Z R_d=bigoplus_dgeq 0 R_d by the usual degree of polynomials. More general mathbb Z-gradings are obtained by assigning integer weights to the variables and considering the corresponding weighted degrees. Even more generally, we may consider multigradings: Given a finitely generated abelian group G, a multigrading on R by G, or a G-grading, or simply a grading, corresponds to a semigroup homomorphism phi mathbb N^n to G: Given phi, the degree of a monomial x^alpha is the image deg(x^alpha)=phi(alpha)in G; the induced G-grading on R is the decomposition R = bigoplus_gin G R_g satisfying R_gcdot R_hsubset R_g+h, where R_g is the free C-module generated by the monomials of degree g. This grading is determined by assigning the weights deg(x_i) to the x_i. In other words, it is determined by the weight vector W = (deg(x_1) dots deg(x_n))in G^n ","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"We refer to the textbooks Ezra Miller, Bernd Sturmfels (2005) and Martin Kreuzer, Lorenzo Robbiano (2005) for details on multigradings. With respect to notation, we follow the former book.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"note: Note\nGiven a G-grading on R, we refer to G as the grading group of R. Moreover, we then say that R is G-graded, or simply that R is graded. If R is a polynomial ring over a field, we say that a G-grading on R is positive if G is free and each graded part R_g, gin G, has finite dimension. We then also say that R is positively graded (by G). Note that the positivity condition can be equivalently expressed by asking that G is free and that the degree zero part consists of the constants only (see Theorem 8.6 in Ezra Miller, Bernd Sturmfels (2005)).","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"note: Note\nGiven a G-grading on R in OSCAR, we say that R is mathbb Z^m-graded if is_free(G) && ngens(G) == rank(G) == m evaluates to true. In this case, conversion routines allow one to switch back and forth between elements of G and integer vectors of length m. Specifically, if R is mathbb Z-graded, that is, is_free(G) && ngens(G) == rank(G) == 1 evaluates to true, elements of G may be converted to integers and vice versa.","category":"page"},{"location":"CommutativeAlgebra/rings/#Types-2","page":"Creating Multivariate Rings","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Multivariate rings with gradings are modelled by objects of type MPolyDecRing{T, S} :< MPolyRing{T}, with elements of type MPolyRingElem_dec{T, S} :< MPolyRingElem{T}. Here, S is the element type of the multivariate ring, and T is the element type of its coefficient ring as above.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"note: Note\nThe types MPolyDecRing{T, S} and MPolyRingElem_dec{T, S} are also meant to eventually model multivariate rings with filtrations and their elements.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"The following function allows one, in particular, to distinguish between graded and filtered rings.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"is_graded(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/rings/#is_graded-Tuple{MPolyRing}","page":"Creating Multivariate Rings","title":"is_graded","text":"is_graded(R::MPolyRing)\n\nReturn true if R is graded, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/#Constructors-for-Graded-Rings","page":"Creating Multivariate Rings","title":"Constructors for Graded Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"There are two basic ways of creating multivariate rings with gradings: While the grade function allows one to create a graded ring by assigning a grading to a polynomial ring already constructed, the graded_polynomial_ring function is meant to create a graded polynomial ring all at once.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"grade(R::MPolyRing, W::Vector{GrpAbFinGenElem})","category":"page"},{"location":"CommutativeAlgebra/rings/#grade-Tuple{MPolyRing, Vector{GrpAbFinGenElem}}","page":"Creating Multivariate Rings","title":"grade","text":"grade(R::MPolyRing, W::Vector{GrpAbFinGenElem})\n\nGiven a vector W of ngens(R) elements of a finitely presented group G, say, create a G-graded ring by assigning the entries of W as weights to the variables of R. Return the new ring as an object of type MPolyDecRing, together with the vector of variables.\n\nExamples\n\njulia> R, (t, x, y) = polynomial_ring(QQ, [\"t\", \"x\", \"y\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[t, x, y])\n\njulia> typeof(R)\nQQMPolyRing\n\njulia> typeof(x)\nQQMPolyRingElem\n\njulia> G = abelian_group([0])\nGrpAb: Z\n\njulia> g = gen(G, 1)\nElement of G with components [1]\n\njulia> S, (t, x, y) = grade(R, [-g, g, g])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[t, x, y])\n\njulia> typeof(S)\nMPolyDecRing{QQFieldElem, QQMPolyRing}\n\njulia> S isa MPolyRing\ntrue\n\njulia> typeof(x)\nMPolyDecRingElem{QQFieldElem, QQMPolyRingElem}\n\njulia> R, x, y = polynomial_ring(QQ, \"x\" => 1:2, \"y\" => 1:3)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2]], QQMPolyRingElem[y[1], y[2], y[3]])\n\njulia> G = abelian_group([0, 0])\nGrpAb: Z^2\n\njulia> g = gens(G)\n2-element Vector{GrpAbFinGenElem}:\n Element of G with components [1 0]\n Element of G with components [0 1]\n\njulia> W = [g[1], g[1], g[2], g[2], g[2]];\n\njulia> S, _ = grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], y[1], y[2], y[3]])\n\njulia> typeof(x[1])\nQQMPolyRingElem\n\njulia> x = map(S, x)\n2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x[1]\n x[2]\n\njulia> y = map(S, y)\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n y[1]\n y[2]\n y[3]\n\njulia> typeof(x[1])\nMPolyDecRingElem{QQFieldElem, QQMPolyRingElem}\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:5)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])\n\njulia> G = abelian_group([0, 0, 2, 2])\n(General) abelian group with relation matrix\n[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]\n\njulia> g = gens(G)\n4-element Vector{GrpAbFinGenElem}:\n Element of G with components [1 0 0 0]\n Element of G with components [0 1 0 0]\n Element of G with components [0 0 1 0]\n Element of G with components [0 0 0 1]\n\njulia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];\n\njulia> S, x = grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"grade(R::MPolyRing, W::Vector{<:Vector{<:IntegerUnion}})","category":"page"},{"location":"CommutativeAlgebra/rings/#grade-Tuple{MPolyRing, Vector{<:Vector{<:Union{Integer, ZZRingElem}}}}","page":"Creating Multivariate Rings","title":"grade","text":"grade(R::MPolyRing, W::Vector{<:Vector{<:IntegerUnion}})\n\nGiven a vector W of ngens(R) integer vectors of the same size m, say, create a free abelian group of type GrpAbFinGen given by m free generators, and convert the vectors in W to elements of that group. Then create a mathbb Z^m-graded ring by assigning the group elements as weights to the variables of R, and return the new ring, together with the vector of variables.\n\ngrade(R::MPolyRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}})\n\nAs above, converting the columns of W.\n\nExamples\n\njulia> R, x, y = polynomial_ring(QQ, \"x\" => 1:2, \"y\" => 1:3)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2]], QQMPolyRingElem[y[1], y[2], y[3]])\n\njulia> W = [1 1 0 0 0; 0 0 1 1 1]\n2×5 Matrix{Int64}:\n 1 1 0 0 0\n 0 0 1 1 1\n\njulia> grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], y[1], y[2], y[3]])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"grade(R::MPolyRing, W::Vector{<:IntegerUnion})","category":"page"},{"location":"CommutativeAlgebra/rings/#grade-Tuple{MPolyRing, Vector{<:Union{Integer, ZZRingElem}}}","page":"Creating Multivariate Rings","title":"grade","text":"grade(R::MPolyRing, W::Vector{<:IntegerUnion})\n\nGiven a vector W of ngens(R) integers, create a free abelian group of type GrpAbFinGen given by one free generator, and convert the entries of W to elements of that group. Then create a mathbb Z-graded ring by assigning the group elements as weights to the variables of R, and return the new ring, together with the vector of variables.\n\ngrade(R::MPolyRing)\n\nAs above, where the grading is the standard mathbb Z-grading on R.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> W = [1, 2, 3];\n\njulia> S, (x, y, z) = grade(R, W)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> T, (x, y, z) = grade(R)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"graded_polynomial_ring(C::Ring, V::Vector{String}, W; ordering=:lex)","category":"page"},{"location":"CommutativeAlgebra/rings/#graded_polynomial_ring-Tuple{Ring, Vector{String}, Any}","page":"Creating Multivariate Rings","title":"graded_polynomial_ring","text":"graded_polynomial_ring(C::Ring, V, W; ordering=:lex)\ngraded_polynomial_ring(C::Ring, n::Int, s::T, W; ordering=:lex) where T<:VarName\n\nCreate a multivariate polynomial_ring with coefficient ring C and variables which print according to the variable names in V (respectively as \"$(s)1\" up to \"$s$n\"), and grade this ring according to the data provided by W. Return the graded ring as an object of type MPolyDecRing, together with the vector of variables.\n\ngraded_polynomial_ring(C::Ring, V; ordering=:lex)\n\nAs above, where the grading is the standard mathbb Z-grading.\n\nExamples\n\njulia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]\n4-element Vector{Vector{Int64}}:\n [1, 0]\n [0, 1]\n [1, 0]\n [4, 1]\n\njulia> R, x = graded_polynomial_ring(QQ, 4, :x, W)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x1, x2, x3, x4])\n\njulia> S, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z], [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> T, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/#Tests-on-Graded-Rings","page":"Creating Multivariate Rings","title":"Tests on Graded Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"is_standard_graded(R::MPolyDecRing)","category":"page"},{"location":"CommutativeAlgebra/rings/#is_standard_graded-Tuple{MPolyDecRing}","page":"Creating Multivariate Rings","title":"is_standard_graded","text":"is_standard_graded(R::MPolyDecRing)\n\nReturn true if R is standard mathbb Z-graded, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> W = [1, 2, 3];\n\njulia> S, (x, y, z) = grade(R, W)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> is_standard_graded(S)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"is_z_graded(R::MPolyDecRing)","category":"page"},{"location":"CommutativeAlgebra/rings/#is_z_graded-Tuple{MPolyDecRing}","page":"Creating Multivariate Rings","title":"is_z_graded","text":"is_z_graded(R::MPolyDecRing)\n\nReturn true if R is mathbb Z-graded, false otherwise.\n\nnote: Note\nWriting G = grading_group(R), we say that R is mathbb Z-graded if is_free(G) && ngens(G) == rank(G) == 1 evaluates to true.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> W = [1, 2, 3];\n\njulia> S, (x, y, z) = grade(R, W)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> is_z_graded(S)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"is_zm_graded(R::MPolyDecRing)","category":"page"},{"location":"CommutativeAlgebra/rings/#is_zm_graded-Tuple{MPolyDecRing}","page":"Creating Multivariate Rings","title":"is_zm_graded","text":"is_zm_graded(R::MPolyDecRing)\n\nReturn true if R is mathbb Z^m-graded for some m, false otherwise.\n\nnote: Note\nWriting G = grading_group(R), we say that R is mathbb Z^m-graded if is_free(G) && ngens(G) == rank(G) == m evaluates to true.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:5)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])\n\njulia> G = abelian_group([0, 0, 2, 2])\n(General) abelian group with relation matrix\n[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]\n\njulia> g = gens(G);\n\njulia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];\n\njulia> S, x = grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])\n\njulia> is_zm_graded(S)\nfalse\n\njulia> G = abelian_group(ZZMatrix([1 -1]));\n\njulia> g = gen(G, 1)\nElement of G with components [0 1]\n\njulia> W = [g, g, g, g];\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"], W);\n\njulia> is_free(G)\ntrue\n\njulia> is_zm_graded(R)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"is_positively_graded(R::MPolyDecRing)","category":"page"},{"location":"CommutativeAlgebra/rings/#is_positively_graded-Tuple{MPolyDecRing}","page":"Creating Multivariate Rings","title":"is_positively_graded","text":"is_positively_graded(R::MPolyDecRing)\n\nReturn true if R is positively graded, false otherwise.\n\nnote: Note\nWe say that R is positively graded by a finitely generated abelian group G if the coefficient ring of R is a field, G is free, and each graded part R_g, gin G, has finite dimension.\n\nExamples\n\njulia> R, (t, x, y) = polynomial_ring(QQ, [\"t\", \"x\", \"y\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[t, x, y])\n\njulia> G = abelian_group([0])\nGrpAb: Z\n\njulia> S, (t, x, y) = grade(R, [-1, 1, 1])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[t, x, y])\n\njulia> is_positively_graded(S)\nfalse\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> G = abelian_group([0, 2])\n(General) abelian group with relation matrix\n[0 0; 0 2]\n\njulia> W = [gen(G, 1)+gen(G, 2), gen(G, 1)]\n2-element Vector{GrpAbFinGenElem}:\n Element of G with components [1 1]\n Element of G with components [1 0]\n\njulia> S, (x, y) = grade(R, W)\n(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])\n\njulia> is_positively_graded(S)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/#Data-Associated-to-Multivariate-Rings","page":"Creating Multivariate Rings","title":"Data Associated to Multivariate Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Given a multivariate polynomial ring R with coefficient ring C, ","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"coefficient_ring(R) refers to C,\ngens(R) to the generators (variables) of R,\nngens(R) to the number of these generators, and\ngen(R, i) as well as R[i] to the i-th such generator.","category":"page"},{"location":"CommutativeAlgebra/rings/#Examples-2","page":"Creating Multivariate Rings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> coefficient_ring(R)\nRational field\n\njulia> gens(R)\n3-element Vector{QQMPolyRingElem}:\n x\n y\n z\n\njulia> gen(R, 2)\ny\n\njulia> R[3]\nz \n\njulia> ngens(R)\n3\n","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"grading_group(R::MPolyDecRing)","category":"page"},{"location":"CommutativeAlgebra/rings/#grading_group-Tuple{MPolyDecRing}","page":"Creating Multivariate Rings","title":"grading_group","text":"grading_group(R::MPolyDecRing)\n\nIf R is, say, G-graded, then return G.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> grading_group(R)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"monomial_basis(R::MPolyDecRing, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#monomial_basis-Tuple{MPolyDecRing, GrpAbFinGenElem}","page":"Creating Multivariate Rings","title":"monomial_basis","text":"monomial_basis(R::MPolyDecRing, g::GrpAbFinGenElem)\n\nGiven a polynomial ring R over a field which is graded by a free group of type GrpAbFinGen, and given an element g of that group, return the monomials of degree g in R.\n\nmonomial_basis(R::MPolyDecRing, W::Vector{<:IntegerUnion})\n\nGiven a mathbb Z^m-graded polynomial ring R over a field and a vector W of m integers, convert W into an element g of the grading group of R and proceed as above.\n\nmonomial_basis(R::MPolyDecRing, d::IntegerUnion)\n\nGiven a mathbb Z-graded polynomial ring R over a field and an integer d, convert d into an element g of the grading group of R and proceed as above.\n\nnote: Note\nIf the component of the given degree is not finite dimensional, an error message will be thrown.\n\nExamples\n\njulia> T, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> G = grading_group(T)\nGrpAb: Z\n\njulia> L = monomial_basis(T, 2)\n6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n z^2\n y*z\n y^2\n x*z\n x*y\n x^2\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"homogeneous_component(R::MPolyDecRing, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#homogeneous_component-Tuple{MPolyDecRing, GrpAbFinGenElem}","page":"Creating Multivariate Rings","title":"homogeneous_component","text":"homogeneous_component(R::MPolyDecRing, g::GrpAbFinGenElem)\n\nGiven a polynomial ring R over a field which is graded by a free group of type GrpAbFinGen, and given an element g of that group, return the homogeneous component of R of degree g as a standard vector space. Additionally, return the map which sends an element of that vector space to the corresponding monomial in R.\n\nhomogeneous_component(R::MPolyDecRing, W::Vector{<:IntegerUnion})\n\nGiven a mathbb Z^m-graded polynomial ring R over a field, and given a vector W of m integers, convert W into an element g of the grading group of R and proceed as above.\n\nhomogeneous_component(R::MPolyDecRing, d::IntegerUnion)\n\nGiven a mathbb Z-graded polynomial ring R over a field, and given an integer d, convert d into an element g of the grading group of R proceed as above.\n\nnote: Note\nIf the component is not finite dimensional, an error message will be thrown.\n\nExamples\n\njulia> R, x, y = polynomial_ring(QQ, \"x\" => 1:2, \"y\" => 1:3);\n\njulia> W = [1 1 0 0 0; 0 0 1 1 1]\n2×5 Matrix{Int64}:\n 1 1 0 0 0\n 0 0 1 1 1\n\njulia> S, _ = grade(R, W);\n\njulia> G = grading_group(S)\nGrpAb: Z^2\n\njulia> L = homogeneous_component(S, [1, 1]);\n\njulia> L[1]\nhomogeneous component of Graded multivariate polynomial ring in 5 variables over QQ of degree [1 1]\n\njulia> FG = gens(L[1]);\n\njulia> EMB = L[2]\nMap from\nS_[1 1] of dim 6 to S defined by a julia-function with inverse\n\njulia> for i in 1:length(FG) println(EMB(FG[i])) end\nx[2]*y[3]\nx[2]*y[2]\nx[2]*y[1]\nx[1]*y[3]\nx[1]*y[2]\nx[1]*y[1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"forget_grading(R::MPolyDecRing)","category":"page"},{"location":"CommutativeAlgebra/rings/#forget_grading-Tuple{MPolyDecRing}","page":"Creating Multivariate Rings","title":"forget_grading","text":"forget_grading(R::MPolyDecRing)\n\nReturn the ungraded undecorated ring.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/#Elements-of-Multivariate-Rings","page":"Creating Multivariate Rings","title":"Elements of Multivariate Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/#Constructors-2","page":"Creating Multivariate Rings","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"One way to create elements of a multivariate polynomial ring is to build up polynomials from the generators (variables) of the ring using basic arithmetic as shown below:","category":"page"},{"location":"CommutativeAlgebra/rings/#Examples-3","page":"Creating Multivariate Rings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> f = 3*x^2+y*z\n3*x^2 + y*z\n\njulia> typeof(f)\nQQMPolyRingElem\n\njulia> S, (x, y, z) = grade(R)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> g = 3*x^2+y*z\n3*x^2 + y*z\n\njulia> typeof(g)\nMPolyDecRingElem{QQFieldElem, QQMPolyRingElem}\n\njulia> g == S(f)\ntrue\n","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Alternatively, there is the following constructor:","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"(R::MPolyRing{T})(c::Vector{T}, e::Vector{Vector{Int}}) where T <: RingElem","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Its return value is the element of R whose nonzero coefficients are specified by the elements of c, with exponent vectors given by the elements of e.","category":"page"},{"location":"CommutativeAlgebra/rings/#Examples-4","page":"Creating Multivariate Rings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> f = 3*x^2+y*z\n3*x^2 + y*z\n\njulia> g = R(QQ.([3, 1]), [[2, 0, 0], [0, 1, 1]])\n3*x^2 + y*z\n\njulia> f == g\ntrue\n","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"An often more effective way to create polynomials is to use the MPoly build context as indicated below:","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> B = MPolyBuildCtx(R)\nBuilder for an element of Multivariate polynomial ring in 2 variables over QQ\n\njulia> for i = 1:5 push_term!(B, QQ(i), [i, i-1]) end\n\njulia> finish(B)\n5*x^5*y^4 + 4*x^4*y^3 + 3*x^3*y^2 + 2*x^2*y + x\n","category":"page"},{"location":"CommutativeAlgebra/rings/#Special-Elements","page":"Creating Multivariate Rings","title":"Special Elements","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Given a multivariate polynomial ring R, zero(R) and one(R) refer to the additive and multiplicative identity of R, respectively. Relevant test calls on an element f of R are iszero(f) and isone(f).","category":"page"},{"location":"CommutativeAlgebra/rings/#Data-Associated-to-Elements-of-Multivariate-Rings","page":"Creating Multivariate Rings","title":"Data Associated to Elements of Multivariate Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Given an element f of a multivariate polynomial ring R or a graded version of such a ring, ","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"parent(f) refers to R, and\ntotal_degree(f) to the total degree of f.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"note: Note\nGiven a set of variables x = x_1 ldots x_n, the total degree of a monomial x^alpha=x_1^alpha_1cdots x_n^alpha_nintextMon_n(x) is the sum of the alpha_i. The total degree of a polynomial f is the maximum of the total degrees of its monomials. In particular, the notion of total degree ignores the weights given to the variables in the graded case.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"For iterators which allow one to recover the monomials (terms, dots) of f we refer to the subsection Monomials, Terms, and More of the section on Gröbner/Standard Bases.","category":"page"},{"location":"CommutativeAlgebra/rings/#Examples-5","page":"Creating Multivariate Rings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R, (x, y) = polynomial_ring(GF(5), [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over GF(5), fpMPolyRingElem[x, y])\n\njulia> c = map(GF(5), [1, 2, 3])\n3-element Vector{fpFieldElem}:\n 1\n 2\n 3\n\njulia> e = [[3, 2], [1, 0], [0, 1]]\n3-element Vector{Vector{Int64}}:\n [3, 2]\n [1, 0]\n [0, 1]\n\njulia> f = R(c, e)\nx^3*y^2 + 2*x + 3*y\n\njulia> parent(f)\nMultivariate polynomial ring in 2 variables x, y\n over finite field of characteristic 5\n\njulia> total_degree(f)\n5","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Further functionality is available in the graded case:","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"homogeneous_components(f::MPolyDecRingElem{T, S}) where {T, S}","category":"page"},{"location":"CommutativeAlgebra/rings/#homogeneous_components-Union{Tuple{MPolyDecRingElem{T, S}}, Tuple{S}, Tuple{T}} where {T, S}","page":"Creating Multivariate Rings","title":"homogeneous_components","text":"homogeneous_components(f::MPolyDecRingElem{T, S}) where {T, S}\n\nGiven an element f of a graded multivariate ring, return the homogeneous components of f.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> f = x^2+y+z\nx^2 + y + z\n\njulia> homogeneous_components(f)\nDict{GrpAbFinGenElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:\n [2] => x^2 + y\n [3] => z\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:5)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])\n\njulia> G = abelian_group([0, 0, 2, 2])\n(General) abelian group with relation matrix\n[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]\n\njulia> g = gens(G);\n\njulia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];\n\njulia> S, x = grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])\n\njulia> f = x[1]^2+x[3]^2+x[5]^2\nx[1]^2 + x[3]^2 + x[5]^2\n\njulia> homogeneous_components(f)\nDict{GrpAbFinGenElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:\n [2 2 0 0] => x[5]^2\n [2 0 0 0] => x[1]^2 + x[3]^2\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"homogeneous_component(f::MPolyDecRingElem, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#homogeneous_component-Tuple{MPolyDecRingElem, GrpAbFinGenElem}","page":"Creating Multivariate Rings","title":"homogeneous_component","text":"homogeneous_component(f::MPolyDecRingElem, g::GrpAbFinGenElem)\n\nGiven an element f of a graded multivariate ring, and given an element g of the grading group of that ring, return the homogeneous component of f of degree g.\n\nhomogeneous_component(f::MPolyDecRingElem, g::Vector{<:IntegerUnion})\n\nGiven an element f of a mathbb Z^m-graded multivariate ring R, say, and given a vector g of m integers, convert g into an element of the grading group of R, and return the homogeneous component of f whose degree is that element.\n\nhomogeneous_component(f::MPolyDecRingElem, g::IntegerUnion)\n\nGiven an element f of a mathbb Z-graded multivariate ring R, say, and given an integer g, convert g into an element of the grading group of R, and return the homogeneous component of f whose degree is that element.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:5)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])\n\njulia> G = abelian_group([0, 0, 2, 2])\n(General) abelian group with relation matrix\n[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]\n\njulia> g = gens(G);\n\njulia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];\n\njulia> S, x = grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])\n\njulia> f = x[1]^2+x[3]^2+x[5]^2\nx[1]^2 + x[3]^2 + x[5]^2\n\njulia> homogeneous_component(f, 2*g[1])\nx[1]^2 + x[3]^2\n\njulia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]\n4-element Vector{Vector{Int64}}:\n [1, 0]\n [0, 1]\n [1, 0]\n [4, 1]\n\njulia> R, x = graded_polynomial_ring(QQ, [\"x[1]\", \"x[2]\", \"x[3]\", \"x[4]\"], W)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4]])\n\njulia> f = x[1]^2*x[2]+x[4]\nx[1]^2*x[2] + x[4]\n\njulia> homogeneous_component(f, [2, 1])\nx[1]^2*x[2]\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> f = x^2+y+z\nx^2 + y + z\n\njulia> homogeneous_component(f, 1)\n0\n\njulia> homogeneous_component(f, 2)\nx^2 + y\n\njulia> homogeneous_component(f, 3)\nz\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"is_homogeneous(f::MPolyDecRingElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#is_homogeneous-Tuple{MPolyDecRingElem}","page":"Creating Multivariate Rings","title":"is_homogeneous","text":"is_homogeneous(f::MPolyDecRingElem)\n\nGiven an element f of a graded multivariate ring, return true if f is homogeneous, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> f = x^2+y*z\nx^2 + y*z\n\njulia> is_homogeneous(f)\nfalse\n\njulia> W = [1 2 1 0; 3 4 0 1]\n2×4 Matrix{Int64}:\n 1 2 1 0\n 3 4 0 1\n\njulia> S, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"], W)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[w, x, y, z])\n\njulia> F = w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3\nw^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3\n\njulia> is_homogeneous(F)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"degree(f::MPolyDecRingElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#degree-Tuple{MPolyDecRingElem}","page":"Creating Multivariate Rings","title":"degree","text":"degree(f::MPolyDecRingElem)\n\nGiven a homogeneous element f of a graded multivariate ring, return the degree of f.\n\ndegree(::Type{Vector{Int}}, f::MPolyDecRingElem)\n\nGiven a homogeneous element f of a mathbb Z^m-graded multivariate ring, return the degree of f, converted to a vector of integer numbers.\n\ndegree(::Type{Int}, f::MPolyDecRingElem)\n\nGiven a homogeneous element f of a mathbb Z-graded multivariate ring, return the degree of f, converted to an integer number.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:5)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5]])\n\njulia> G = abelian_group([0, 0, 2, 2])\n(General) abelian group with relation matrix\n[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]\n\njulia> g = gens(G);\n\njulia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];\n\njulia> S, x = grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4], x[5]])\n\njulia> f = x[2]^2+2*x[4]^2\nx[2]^2 + 2*x[4]^2\n\njulia> degree(f)\nElement of G with components [0 2 0 0]\n\njulia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]\n4-element Vector{Vector{Int64}}:\n [1, 0]\n [0, 1]\n [1, 0]\n [4, 1]\n\njulia> R, x = graded_polynomial_ring(QQ, [\"x[1]\", \"x[2]\", \"x[3]\", \"x[4]\"], W)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3], x[4]])\n\njulia> f = x[1]^4*x[2]+x[4]\nx[1]^4*x[2] + x[4]\n\njulia> degree(f)\n[4 1]\n\njulia> degree(Vector{Int}, f)\n2-element Vector{Int64}:\n 4\n 1\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> f = x^6+y^3+z^2\nx^6 + y^3 + z^2\n\njulia> degree(f)\n[6]\n\njulia> typeof(degree(f))\nGrpAbFinGenElem\n\njulia> degree(Int, f)\n6\n\njulia> typeof(degree(Int, f))\nInt64\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"forget_grading(f::MPolyDecRingElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#forget_grading-Tuple{MPolyDecRingElem}","page":"Creating Multivariate Rings","title":"forget_grading","text":"forget_grading(f::MPolyDecRingElem)\n\nReturn the element in the underlying ungraded ring.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/#Homomorphisms-From-Multivariate-Rings","page":"Creating Multivariate Rings","title":"Homomorphisms From Multivariate Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"If R is a multivariate polynomial ring, and S is any ring, then a ring homomorphism R to S is determined by specifying its restriction to the coefficient ring of R, and by assigning an image to each variable of R. In OSCAR, such homomorphisms are created by using the following constructor:","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"hom(R::MPolyRing, S::NCRing, coeff_map, images::Vector; check::Bool = true)","category":"page"},{"location":"CommutativeAlgebra/rings/#hom-Tuple{MPolyRing, NCRing, Any, Vector}","page":"Creating Multivariate Rings","title":"hom","text":"hom(R::MPolyRing, S::NCRing, coeff_map, images::Vector; check::Bool = true)\n\nhom(R::MPolyRing, S::NCRing, images::Vector; check::Bool = true)\n\nGiven a homomorphism coeff_map from C to S, where C is the coefficient ring of R, and given a vector images of nvars(R) elements of S, return the homomorphism R to S whose restriction to C is coeff_map, and which sends the i-th variable of R to the i-th entry of images.\n\nIf no coefficient map is entered, invoke a canonical homomorphism of C to S, if such a homomorphism exists, and throw an error, otherwise.\n\nnote: Note\nIn case check = true (default), the function checks the conditions below:If S is graded, the assigned images must be homogeneous with respect to the given grading.\nIf S is noncommutative, the assigned images must pairwise commute. \n\nExamples\n\njulia> K, a = FiniteField(2, 2, \"a\");\n\njulia> R, (x, y) = polynomial_ring(K, [\"x\", \"y\"]);\n\njulia> F = hom(R, R, z -> z^2, [y, x])\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 2 variables over GF(2^2)\nCodomain:\n=========\nMultivariate polynomial ring in 2 variables over GF(2^2)\n\njulia> F(a * y)\n(a + 1)*x\n\njulia> Qi, i = quadratic_field(-1)\n(Imaginary quadratic field defined by x^2 + 1, sqrt(-1))\n\njulia> S, (x, y) = polynomial_ring(Qi, [\"x\", \"y\"]);\n\njulia> G = hom(S, S, hom(Qi, Qi, -i), [x^2, y^2])\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 2 variables over imaginary quadratic field defined by x^2 + 1\nCodomain:\n=========\nMultivariate polynomial ring in 2 variables over imaginary quadratic field defined by x^2 + 1\n\njulia> G(x+i*y)\nx^2 - sqrt(-1)*y^2\n\njulia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"]);\n\njulia> f = 3*x^2+2*x+1;\n\njulia> S, (x, y) = polynomial_ring(GF(2), [\"x\", \"y\"]);\n\njulia> H = hom(R, S, gens(S))\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 2 variables over ZZ\nCodomain:\n=========\nMultivariate polynomial ring in 2 variables over GF(2)\n\njulia> H(f)\nx^2 + 1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Given a ring homomorphism F from R to S as above, domain(F) and codomain(F) refer to R and S, respectively.","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"note: Note\nThe OSCAR homomorphism type AffAlgHom models ring homomorphisms R to S such that the type of both R and S is a subtype of Union{MPolyRing{T}, MPolyQuoRing{U}}, where T <: FieldElem and U <: MPolyRingElem{T}. Functionality for these homomorphism is discussed in the section on affine algebras.","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/access/","page":"Access to precomputed OD data","title":"Access to precomputed OD data","text":"CurrentModule = Oscar.OrthogonalDiscriminants\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/access/#Access-to-precomputed-OD-data","page":"Access to precomputed OD data","title":"Access to precomputed OD data","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/access/","page":"Access to precomputed OD data","title":"Access to precomputed OD data","text":"all_od_infos\northogonal_discriminants\northogonal_discriminant","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/access/#all_od_infos","page":"Access to precomputed OD data","title":"all_od_infos","text":"all_od_infos(L...)\n\nReturn the array of all those entries of the known OD data (see OD_data) that satisfy the conditions in L.\n\nThe following conditions are supported.\n\nis_simple with value true or false, meaning entries only for simple or non-simple groups, respectively,\nis_sporadic_simple with value true or false, meaning entries only for sporadic simple or not sporadic simple groups, respectively,\ncharacteristic, with value 0 or a prime integer, meaning entries only for this characteristic,\ncharacter_field, with value either a map or a vector of maps, meaning entries only for characters whose character fields (finite fields if the characteristic is positive, and subfields of cyclotomic fields in characteristic zero) have the given map(s) as embeddings into the algebraic closure or abelian closure, respectively,\nidentifier, with value a string denoting the name of an Atlas group, or a vector of such strings, meaning entries only for these groups,\ndim, with value a positive integer, or a vector of such integers, meaning entries only for characters of these degrees,\northogonal_discriminant, with value a string (\"O+\", \"O-\", or a string that encodes an algebraic integer), meaning entries only with this orthogonal discriminant,\ncomment_matches, with value a string (one of \"ev\", \"specht\", ...), or a vector of such strings, meaning entries whose comment contains these values.\n\nFor all conditions except the boolean valued ones, also a function can be given as value, meaning that all those entries satisfy this condition for which the function returns true when applied to the stored value. For example, the condition characteristic => is_odd matches all entries for characteristics different from 0 and 2, and the condition character_field => (emb -> degree(domain(emb)) == 1) matches all entries for which the character field is the field of rationals.\n\nExamples\n\njulia> length(all_od_infos(identifier => \"A6\"))\n8\n\njulia> length(all_od_infos(identifier => \"A6\", characteristic => 0))\n3\n\njulia> length(all_od_infos(identifier => \"A6\", characteristic => 2:5))\n5\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/access/#orthogonal_discriminants","page":"Access to precomputed OD data","title":"orthogonal_discriminants","text":"orthogonal_discriminants(tbl::Oscar.GAPGroupCharacterTable)\n\nExamples\n\njulia> t = character_table(\"A6\");\n\njulia> println(orthogonal_discriminants(t))\n[\"\", \"\", \"\", \"1\", \"1\", \"\", \"-1\"]\n\njulia> println(orthogonal_discriminants(t % 3))\n[\"\", \"\", \"\", \"O-\", \"\"]\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/access/#orthogonal_discriminant","page":"Access to precomputed OD data","title":"orthogonal_discriminant","text":"orthogonal_discriminant(chi::Oscar.GAPGroupClassFunction)\n\nExamples\n\njulia> t = character_table(\"A6\");\n\njulia> orthogonal_discriminant(t[4])\n\"1\"\n\njulia> t2 = t % 2;\n\njulia> orthogonal_discriminant(t2[4])\n\"O+\"\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Monomial-Orderings","page":"Monomial Orderings","title":"Monomial Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"Given a coefficient ring C as in the previous section, let Cx=Cx_1 ldots x_n be the polynomial ring over C in the set of variables x=x_1 ldots x_n. Monomials in x=x_1 ldots x_n are written using multi–indices: If alpha=(alpha_1 ldots alpha_n)in N^n, set x^alpha=x_1^alpha_1cdots x_n^alpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"textMon_n(x) = textMon(x_1 ldots x_n) = x^alpha mid alpha in N^n","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"A monomial ordering on textMon_n(x) is a total ordering on textMon_n(x) such that","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Longrightarrow x^gamma x^alpha x^gamma x^beta\n text for all alpha beta gamma in mathbb N^n","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"A monomial ordering on textMon_n(x) is called","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"global if x^alpha 1 for all alpha not = (0 dots 0),\nlocal if x^alpha 1 for all alpha not = (0 dots 0), and\nmixed if it is neither global nor local.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nA monomial ordering on textMon_n(x) is global iff it is a well-ordering.\nTo give a monomial ordering on textMon_n(x) means to give a total ordering on $ \\N^n$ such that alpha beta implies $ \\gamma + \\alpha > \\gamma + \\beta$ for all alpha beta gamma in N^n Rather than speaking of a monomial ordering on textMon_n(x), we may, thus, also speak of a (global, local, mixed) monomial ordering on N^n.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nBy a result of Robbiano, every monomial ordering can be realized as a matrix ordering.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nThe lexicograpical monomial ordering specifies the default way of storing and displaying multivariate polynomials in OSCAR (terms are sorted in descending order). The other orderings which can be attached to a multivariate polynomial ring are the degree lexicographical ordering and the degree reverse lexicographical ordering. Independently of the attached orderings, Gröbner bases can be computed with respect to any monomial ordering. See the section on Gröbner bases.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"In this section, we show how to create monomial orderings in OSCAR. ","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nFor the convenient construction of block orderings on the set of monomials in the variables of a given multivariate polynomial ring, we allow to construct orderings on the monomials in blocks of variables, viewing these orderings as partial orderings on the monomials in all variables.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"Here are some illustrating examples:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Examples","page":"Monomial Orderings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"julia> S, (w, x) = polynomial_ring(QQ, [\"w\", \"x\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[w, x])\n\njulia> o = lex([w, x])\nlex([w, x])\n\njulia> canonical_matrix(o)\n[1 0]\n[0 1]\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = degrevlex([w, x])\ndegrevlex([w, x])\n\njulia> is_global(o1)\ntrue\n\njulia> canonical_matrix(o1)\n[1 1 0 0]\n[0 -1 0 0]\n\njulia> o2 = neglex([y, z])\nneglex([y, z])\n\njulia> is_local(o2)\ntrue\n\njulia> canonical_matrix(o2)\n[0 0 -1 0]\n[0 0 0 -1]\n\njulia> o3 = o1*o2\ndegrevlex([w, x])*neglex([y, z])\n\njulia> canonical_matrix(o3)\n[1 1 0 0]\n[0 -1 0 0]\n[0 0 -1 0]\n[0 0 0 -1]\n\njulia> is_mixed(o3)\ntrue","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Monomial-Comparisons","page":"Monomial Orderings","title":"Monomial Comparisons","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The cmp function should be used for comparing two monomials with regard to a monomial ordering.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"cmp(ord::MonomialOrdering, a::MPolyRingElem, b::MPolyRingElem)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#cmp-Tuple{MonomialOrdering, MPolyRingElem, MPolyRingElem}","page":"Monomial Orderings","title":"cmp","text":"cmp(ord::MonomialOrdering, a::MPolyRingElem, b::MPolyRingElem)\n\ncmp(ord::ModuleOrdering, a::FreeModElem{T}, b::FreeModElem{T}) where T <: MPolyRingElem\n\nCompare monomials a and b with regard to the ordering ord: Return -1 for a < b and 1 for a > b and 0 for a == b. An error is thrown if ord is a partial ordering that does not distinguish a from b.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> cmp(lex([x,y]), x, one(R))\n1\n\njulia> try cmp(lex([x,y]), z, one(R)); catch e; e; end\nErrorException(\"z and 1 are incomparable with respect to lex([x, y])\")\n\njulia> cmp(lex([x,y,z]), z, one(R))\n1\n\njulia> F = free_module(R, 2)\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> cmp(lex(R)*revlex(F), F[1], F[2])\n-1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Matrix-Orderings","page":"Monomial Orderings","title":"Matrix Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"Given a matrix Min textMat(ktimes nmathbb R) of rank n, with rows m_1dotsm_k, the matrix ordering defined by M is obtained by setting","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha_M x^beta Leftrightarrow exists 1leq ileq k m_1alpha=m_1betaldots \nm_i-1alpha =m_i-1beta m_ialpham_ibeta","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"(here, alpha and beta are regarded as column vectors).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nBy a theorem of Robbiano, every monomial ordering arises as a matrix ordering as above with Min textGL(nmathbb R).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nTo create matrix orderings, OSCAR allows for matrices with integer coefficients as input matrices.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nFor orderings such as lex and degrevlex which are predefined in OSCAR, using the predefined version is much faster than using a representation as a matrix ordering.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"matrix_ordering(R::MPolyRing, M::Union{Matrix{T}, MatElem{T}}; check::Bool = true) where T","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#matrix_ordering-Union{Tuple{T}, Tuple{MPolyRing, Union{MatElem{T}, Matrix{T}}}} where T","page":"Monomial Orderings","title":"matrix_ordering","text":"matrix_ordering(R::MPolyRing, M::Union{Matrix{T}, MatElem{T}}; check::Bool = true) where T -> MonomialOrdering\n\nGiven an integer matrix M such that nvars(R) = ncols(M) = rank(M), return the matrix ordering on the set of variables of R which is defined by M.\n\nmatrix_ordering(V::AbstractVector{<:MPolyRingElem}, M::Union{Matrix{T}, MatElem{T}}; check::Bool = true) where T -> MonomialOrdering\n\nGiven a vector V of variables and an integer matrix M such that length(V) = ncols(M) = rank(M), return the matrix ordering on the set of monomials in the given variables which is defined by M.\n\nnote: Note\nThe matrix M need not be square.\n\nnote: Note\nIf check = false is supplied, the rank check is omitted, and the resulting ordering may only be partial.\n\nExamples\n\njulia> R, (w, x, y, z) = QQ[\"w\", \"x\", \"y\", \"z\"];\n\njulia> M =[1 1 1 1; 0 -1 -1 -1; 0 0 -1 -1; 0 0 0 -1]\n4×4 Matrix{Int64}:\n 1 1 1 1\n 0 -1 -1 -1\n 0 0 -1 -1\n 0 0 0 -1\n\njulia> o1 = matrix_ordering(R, M)\nmatrix_ordering([w, x, y, z], [1 1 1 1; 0 -1 -1 -1; 0 0 -1 -1; 0 0 0 -1])\n\njulia> N =[1 1; 0 -1]\n2×2 Matrix{Int64}:\n 1 1\n 0 -1\n\njulia> o2 = matrix_ordering([w, x], N)\nmatrix_ordering([w, x], [1 1; 0 -1])\n\njulia> canonical_matrix(o2)\n[1 1 0 0]\n[0 -1 0 0]\n\njulia> o3 = matrix_ordering(gens(R)[3:4], N)\nmatrix_ordering([y, z], [1 1; 0 -1])\n\njulia> o3 = matrix_ordering(gens(R)[3:4], N)\nmatrix_ordering([y, z], [1 1; 0 -1])\n\njulia> canonical_matrix(o3)\n[0 0 1 1]\n[0 0 0 -1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"As already shown above, OSCAR provides functions to recover defining matrices from given monomial orderings:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"matrix(ord::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#matrix-Tuple{MonomialOrdering}","page":"Monomial Orderings","title":"matrix","text":"matrix(ord::MonomialOrdering)\n\nReturn a matrix defining ord as a matrix ordering.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> o1 = degrevlex(R)\ndegrevlex([x, y, z])\n\njulia> matrix(o1)\n[ 1 1 1]\n[ 0 0 -1]\n[ 0 -1 0]\n[-1 0 0]\n\njulia> o2 = degrevlex([x, y])\ndegrevlex([x, y])\n\njulia> matrix(o2)\n[ 1 1 0]\n[ 0 -1 0]\n[-1 0 0]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"canonical_matrix(ord::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#canonical_matrix-Tuple{MonomialOrdering}","page":"Monomial Orderings","title":"canonical_matrix","text":"canonical_matrix(ord::MonomialOrdering)\n\nReturn the canonical matrix defining ord as a matrix ordering.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> o1 = degrevlex(R)\ndegrevlex([x, y, z])\n\njulia> canonical_matrix(o1)\n[1 1 1]\n[0 0 -1]\n[0 -1 0]\n\njulia> o2 = degrevlex([x, y])\ndegrevlex([x, y])\n\njulia> canonical_matrix(o2)\n[1 1 0]\n[0 -1 0]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Predefined-Global-Orderings","page":"Monomial Orderings","title":"Predefined Global Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The lexicographical ordering lex is defined by setting","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow exists 1 leq i leq n alpha_1 = beta_1 dots alpha_i-1 = beta_i-1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"lex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#lex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"lex","text":"lex(R::MPolyRing) -> MonomialOrdering\n\nReturn the lexicographical ordering on the set of monomials in the variables of R.\n\nlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the lexicographical ordering on the set of monomials in these variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = lex(R)\nlex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[1 0 0 0]\n[0 1 0 0]\n[0 0 1 0]\n[0 0 0 1]\n\njulia> o2 = lex([w, x])\nlex([w, x])\n\njulia> o3 = lex(gens(R)[3:4])\nlex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Degree-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Degree Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The degree lexicographical ordering deglex is defined by setting deg(x^alpha) = alpha_1 + cdots + alpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow deg(x^alpha) deg(x^beta) text or exists 1 leq i leq n alpha_1 = beta_1 dots alpha_i-1 = beta_i-1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"deglex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#deglex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"deglex","text":"deglex(R::MPolyRing) -> MonomialOrdering\n\nReturn the degree lexicographical ordering on the set of monomials in the variables of R.\n\ndeglex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the degree lexicographical ordering on the set of monomials in these variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = deglex(R)\ndeglex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[1 1 1 1]\n[0 -1 -1 -1]\n[0 0 -1 -1]\n[0 0 0 -1]\n\njulia> o2 = deglex([w, x])\ndeglex([w, x])\n\njulia> o3 = deglex(gens(R)[3:4])\ndeglex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Reverse-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Reverse Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The reverse lexicographical ordering revlex is defined by setting","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow exists 1 leq i leq n alpha_n = beta_n dots alpha_i+1 = beta_i+1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"revlex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#revlex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"revlex","text":"revlex(R::MPolyRing) -> MonomialOrdering\n\nReturn the reverse lexicographical ordering on the set of monomials in the variables of R.\n\nrevlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the reverse lexicographical ordering on the set of monomials in these variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = revlex(R)\nrevlex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[0 0 0 1]\n[0 0 1 0]\n[0 1 0 0]\n[1 0 0 0]\n\njulia> o2 = revlex([w, x])\nrevlex([w, x])\n\njulia> o3 = revlex(gens(R)[3:4])\nrevlex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Degree-Reverse-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Degree Reverse Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The degree reverse lexicographical ordering degrevlex is defined by setting deg(x^alpha) = alpha_1 + cdots + alpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow deg(x^alpha) deg(x^beta) text or exists 1 leq i leq n alpha_n = beta_n dots alpha_i+1 = beta_i+1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"degrevlex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#degrevlex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"degrevlex","text":"degrevlex(R::MPolyRing) -> MonomialOrdering\n\nReturn the degree reverse lexicographical ordering on the set of monomials in the variables of R.\n\ndegrevlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the degree reverse lexicographical ordering on the set of monomials in these variables\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = degrevlex(R)\ndegrevlex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[1 1 1 1]\n[0 0 0 -1]\n[0 0 -1 0]\n[0 -1 0 0]\n\njulia> o2 = degrevlex([w, x])\ndegrevlex([w, x])\n\njulia> o3 = degrevlex(gens(R)[3:4])\ndegrevlex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Weighted-Lexicographical-Orderings","page":"Monomial Orderings","title":"Weighted Lexicographical Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"If W is a vector of positive integers w_1 dots w_n, the corresponding weighted lexicographical ordering wdeglex(W) is defined by setting textwdeg(x^alpha) = w_1alpha_1 + cdots + w_nalpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow textwdeg(x^alpha) textwdeg(x^beta) text or \n(textwdeg(x^alpha) = textwdeg(x^beta) text and exists 1 leq i leq n alpha_1 = beta_1 dots alpha_i-1 = beta_i-1 alpha_i beta_i)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"wdeglex(R::MPolyRing, W::Vector{Int})","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#wdeglex-Tuple{MPolyRing, Vector{Int64}}","page":"Monomial Orderings","title":"wdeglex","text":"wdeglex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering\n\nIf W is a vector of positive integers, return the corresponding weighted lexicographical ordering on the set of monomials in the variables of R.\n\nwdeglex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering\n\nGiven a vector V of variables and a vector W of positive integers, return the corresponding weighted lexicographical ordering on the set of monomials in the given variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = wdeglex(R, [1, 2, 3, 4])\nwdeglex([w, x, y, z], [1, 2, 3, 4])\n\njulia> canonical_matrix(o1)\n[1 2 3 4]\n[0 -2 -3 -4]\n[0 0 -3 -4]\n[0 0 0 -1]\n\njulia> o2 = wdeglex([w, x], [1, 2])\nwdeglex([w, x], [1, 2])\n\njulia> o3 = wdeglex(gens(R)[3:4], [3, 4])\nwdeglex([y, z], [3, 4])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Weighted-Reverse-Lexicographical-Orderings","page":"Monomial Orderings","title":"Weighted Reverse Lexicographical Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"If W is a vector of positive integers w_1 dots w_n, the corresponding weighted reverse lexicographical ordering wdegrevlex is defined by setting textwdeg(x^alpha) = w_1alpha_1 + cdots + w_nalpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow textwdeg(x^alpha) textwdeg(x^beta) text or \n(textwdeg(x^alpha) = textwdeg(x^beta) text and exists 1 leq i leq n alpha_n = beta_n dots alpha_i+1 = beta_i+1 alpha_i beta_i)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"wdegrevlex(R::MPolyRing, W::Vector{Int})","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#wdegrevlex-Tuple{MPolyRing, Vector{Int64}}","page":"Monomial Orderings","title":"wdegrevlex","text":"wdegrevlex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering\n\nIf W is a vector of positive integers, return the corresponding weighted reverse lexicographical ordering on the set of monomials in the variables of R.\n\nwdegrevlex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering\n\nGiven a vector V of variables and a vector W of positive integers, return the corresponding weighted reverse lexicographical ordering on the set of monomials in the given variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = wdegrevlex(R, [1, 2, 3, 4])\nwdegrevlex([w, x, y, z], [1, 2, 3, 4])\n\njulia> canonical_matrix(o1)\n[1 2 3 4]\n[0 0 0 -1]\n[0 0 -1 0]\n[0 -1 0 0]\n\njulia> o2 = wdegrevlex([w, x], [1, 2])\nwdegrevlex([w, x], [1, 2])\n\njulia> o3 = wdegrevlex(gens(R)[3:4], [3, 4])\nwdegrevlex([y, z], [3, 4])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Predefined-Local-Orderings","page":"Monomial Orderings","title":"Predefined Local Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Negative-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Negative Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The negative lexicographical ordering neglex is defined by setting","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow exists 1 leq i leq n alpha_1 = beta_1 dots alpha_i-1 = beta_i-1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"neglex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#neglex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"neglex","text":"neglex(R::MPolyRing) -> MonomialOrdering\n\nReturn the negative lexicographical ordering on the set of monomials in the variables of R.\n\nneglex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the negative lexicographical ordering on the set of monomials in these variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = neglex(R)\nneglex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[-1 0 0 0]\n[ 0 -1 0 0]\n[ 0 0 -1 0]\n[ 0 0 0 -1]\n\njulia> o2 = neglex([w, x])\nneglex([w, x])\n\njulia> o3 = neglex(gens(R)[3:4])\nneglex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Negative-Degree-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Negative Degree Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The negative degree lexicographical ordering negdeglex is defined by setting deg(x^alpha) = alpha_1 + cdots + alpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow deg(x^alpha) deg(x^beta) text or exists 1 leq i leq n alpha_1 = beta_1 dots alpha_i-1 = beta_i-1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"negdeglex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#negdeglex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"negdeglex","text":"negdeglex(R::MPolyRing) -> MonomialOrdering\n\nReturn the negative degree lexicographical ordering on the set of monomials in the variables of R.\n\nnegdeglex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the negative degree lexicographical ordering on the set of monomials in these variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = negdeglex(R)\nnegdeglex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[-1 -1 -1 -1]\n[ 0 -1 -1 -1]\n[ 0 0 -1 -1]\n[ 0 0 0 -1]\n\njulia> o2 = negdeglex([w, x])\nnegdeglex([w, x])\n\njulia> o3 = negdeglex(gens(R)[3:4])\nnegdeglex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Negative-Reverse-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Negative Reverse Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The negative reverse lexicographical ordering negrevlex is defined by setting","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow exists 1 leq i leq n alpha_n = beta_n dots alpha_i+1 = beta_i+1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"negrevlex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#negrevlex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"negrevlex","text":"negrevlex(R::MPolyRing) -> MonomialOrdering\n\nReturn the negative reverse lexicographical ordering on the set of monomials in the variables of R.\n\nnegrevlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the negative reverse lexicographical ordering on the set of monomials in these variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = negrevlex(R)\nnegrevlex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[ 0 0 0 -1]\n[ 0 0 -1 0]\n[ 0 -1 0 0]\n[-1 0 0 0]\n\njulia> o2 = negrevlex([w, x])\nnegrevlex([w, x])\n\njulia> o3 = negrevlex(gens(R)[3:4])\nnegrevlex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Negative-Degree-Reverse-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Negative Degree Reverse Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The negative degree reverse lexicographical ordering negdegrevlex is defined by setting deg(x^alpha) = alpha_1 + cdots + alpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow deg(x^alpha) deg(x^beta) text or exists 1 leq i leq n alpha_n = beta_n dots alpha_i+1 = beta_i+1 alpha_i beta_i","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"negdegrevlex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#negdegrevlex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"negdegrevlex","text":"negdegrevlex(R::MPolyRing) -> MonomialOrdering\n\nReturn the negative degree reverse lexicographical ordering on the set of monomials in the variables of R.\n\nnegdegrevlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the negative degree reverse lexicographical ordering on the set of monomials in these variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = negdegrevlex(R)\nnegdegrevlex([w, x, y, z])\n\njulia> canonical_matrix(o1)\n[-1 -1 -1 -1]\n[ 0 0 0 -1]\n[ 0 0 -1 0]\n[ 0 -1 0 0]\n\njulia> o2 = negdegrevlex([w, x])\nnegdegrevlex([w, x])\n\njulia> o3 = negdegrevlex(gens(R)[3:4])\nnegdegrevlex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Negative-Weighted-Lexicographical-Orderings","page":"Monomial Orderings","title":"Negative Weighted Lexicographical Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"If W is a vector of positive integers w_1 dots w_n, the corresponding negative weighted lexicographical ordering negwdeglex(W) is defined by setting textwdeg(x^alpha) = w_1alpha_1 + cdots + w_nalpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow textwdeg(x^alpha) textwdeg(x^beta) text or \n(textwdeg(x^alpha) = textwdeg(x^beta) text and exists 1 leq i leq n alpha_1 = beta_1 dots alpha_i-1 = beta_i-1 alpha_i beta_i)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"negwdeglex(R::MPolyRing, W::Vector{Int})","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#negwdeglex-Tuple{MPolyRing, Vector{Int64}}","page":"Monomial Orderings","title":"negwdeglex","text":"negwdeglex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering\n\nIf W is a vector of positive integers, return the corresponding negative weighted lexicographical ordering on the set of monomials in the variables of R.\n\nnegwdeglex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering\n\nGiven a vector V of variables and a vector W of positive integers, return the corresponding negative weighted lexicographical ordering on the set of monomials in the given variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = negwdeglex(R, [1, 2, 3, 4])\nnegwdeglex([w, x, y, z], [1, 2, 3, 4])\n\njulia> canonical_matrix(o1)\n[-1 -2 -3 -4]\n[ 0 -2 -3 -4]\n[ 0 0 -3 -4]\n[ 0 0 0 -1]\n\njulia> o2 = negwdeglex([w, x], [1, 2])\nnegwdeglex([w, x], [1, 2])\n\njulia> o3 = negwdeglex(gens(R)[3:4], [3, 4])\nnegwdeglex([y, z], [3, 4])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Negative-Weighted-Reverse-Lexicographical-Orderings","page":"Monomial Orderings","title":"Negative Weighted Reverse Lexicographical Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"If W is a vector of positive integers w_1 dots w_n, the corresponding negative weighted reverse lexicographical ordering negwdegrevlex(W) is defined by setting textwdeg(x^alpha) = w_1alpha_1 + cdots + w_nalpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha x^beta Leftrightarrow textwdeg(x^alpha) textwdeg(x^beta) text or \n(textwdeg(x^alpha) = textwdeg(x^beta) text and exists 1 leq i leq n alpha_n = beta_n dots alpha_i+1 = beta_i+1 alpha_i beta_i)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"negwdegrevlex(R::MPolyRing, W::Vector{Int})","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#negwdegrevlex-Tuple{MPolyRing, Vector{Int64}}","page":"Monomial Orderings","title":"negwdegrevlex","text":"negwdegrevlex(R::MPolyRing, W::Vector{Int}) -> MonomialOrdering\n\nIf W is a vector of positive integers, return the corresponding negative weighted reverse lexicographical ordering on the set of monomials in the variables of R.\n\nnegwdegrevlex(V::AbstractVector{<:MPolyRingElem}, W::Vector{Int}) -> MonomialOrdering\n\nGiven a vector V of variables and a vector W of positive integers, return the corresponding negative weighted reverse lexicographical ordering on the set of monomials in the given variables.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o1 = negwdegrevlex(R, [1, 2, 3, 4])\nnegwdegrevlex([w, x, y, z], [1, 2, 3, 4])\n\njulia> canonical_matrix(o1)\n[-1 -2 -3 -4]\n[ 0 0 0 -1]\n[ 0 0 -1 0]\n[ 0 -1 0 0]\n\njulia> o2 = negwdegrevlex([w, x], [1, 2])\nnegwdegrevlex([w, x], [1, 2])\n\njulia> o3 = negwdegrevlex(gens(R)[3:4], [3, 4])\nnegwdegrevlex([y, z], [3, 4])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Weight-Orderings","page":"Monomial Orderings","title":"Weight Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"If W is a vector of integers w_1 dots w_n, and is a monomial ordering on textMon_n(x), then the corresponding weight ordering is defined by setting textwdeg(x^alpha) = w_1alpha_1 + cdots + w_nalpha_n and","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha _W x^beta Leftrightarrow textwdeg(x^alpha) textwdeg(x^beta) text or \n(textwdeg(x^alpha) = textwdeg(x^beta) text and x^alpha x^beta)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"weight_ordering(W::Vector{Int}, ord::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#weight_ordering-Tuple{Vector{Int64}, MonomialOrdering}","page":"Monomial Orderings","title":"weight_ordering","text":"weight_ordering(W::Vector{Int}, ord::MonomialOrdering) -> MonomialOrdering\n\nGiven an integer vector W and a monomial ordering ord on a set of monomials in length(W) variables, return the monomial ordering ord_W on this set of monomials which is obtained by first comparing the W-weighted degrees and then using ord in the case of a tie.\n\nnote: Note\nThe ordering ord_W is global if all entries of W are positive, or if they are all non-negative and ord is global,\nan elimination ordering for the set of variables which correspond to positive entries of W. \n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> W = [1, 0, -1];\n\njulia> o = lex(R)\nlex([x, y, z])\n\njulia> matrix(o)\n[1 0 0]\n[0 1 0]\n[0 0 1]\n\njulia> oW = weight_ordering(W, o)\nmatrix_ordering([x, y, z], [1 0 -1])*lex([x, y, z])\n\njulia> matrix(oW)\n[1 0 -1]\n[1 0 0]\n[0 1 0]\n[0 0 1]\n\njulia> canonical_matrix(oW)\n[1 0 -1]\n[0 0 1]\n[0 1 0]\n\njulia> o2 = weight_ordering([1, -1], lex([x, z]))\nmatrix_ordering([x, z], [1 -1])*lex([x, z])\n\njulia> canonical_matrix(o2)\n[1 0 -1]\n[0 0 1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Block-Orderings","page":"Monomial Orderings","title":"Block Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The concept of block orderings (product orderings) allows one to construct new monomial orderings from already given ones: If _1 and _2 are monomial orderings on textMon_s(x_1 ldots x_s) and textMon_n-s(x_s+1 ldots x_n), respectively, then the block ordering = (_1 _2) on textMon_n(x)=textMon_n(x_1 ldots x_n) is defined by setting","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alphax^beta Leftrightarrow x_1^alpha_1cdots x_s^alpha_s _1 x_1^beta_1cdots x_s^beta_s text or \nbigl(x_1^alpha_1cdots x_s^alpha_s = x_1^beta_1cdots x_s^beta_s text and x_s+1^alpha_s+1cdots x_n^alpha_n _2\nx_s+1^beta_s+1cdots x_n^beta_nbigr)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nThe ordering (_1 _2)is global (local) iff both _1 and _2 are global (local). Mixed orderings arise by choosing one of _1 and _2 global and the other one local,\nis an elimination ordering for the first block of variables iff _1 is global.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nThe definition of a block ordering above subdivides x into a block of initial variables and its complementary block of variables. Block orderings for a subdivision of x into any block of variables and its complementary block are defined similarly and have similar properties.\nInductively, one obtains block orderings composed of more than two individual orderings.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"In OSCAR, block orderings are obtained by the concatenation of individual orderings using the * operator.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Examples-2","page":"Monomial Orderings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"julia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[w, x, y, z])\n\njulia> o = degrevlex([w, x])*degrevlex([y, z])\ndegrevlex([w, x])*degrevlex([y, z])\n","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Elimination-Orderings","page":"Monomial Orderings","title":"Elimination Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"Let Cx=Cx_1 ldots x_n be a multivariate polynomial ring with coefficient ring C. Fix a subset sigmasubset 1dots n and write x_sigma for the set of variables x_i with iinsigma. An elimination ordering for xsmallsetminus x_sigma is a monomial ordering on textMon_n(x) which satisfies the following property: If a is a monomial involving one of the variables in xsmallsetminus x_sigma , and b is a monomial depending only on the variables in x_sigma, then a b Computing a Gröbner basis of I with respect to such an ordering provides one way of finding the intersection Icap Cx_sigma, that is, of eliminating the variables in xsmallsetminus x_sigma from I: The Gröbner basis elements which only depend on the variables in x_sigma form a Gröbner basis for Icap Cx_sigma with respect to the restriction of to the set of monomials in Icap Cx_sigma.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"note: Note\nThe lexicographical ordering is an elimination ordering for each initial set of variables x_1 dots x_k. If only a fixed subset of variables is considered, suitable weight or block orderings as discussed above are more effective. The documentation of the is_elimination_ordering function below offers examples and non-examples.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Tests-on-Monomial-Orderings","page":"Monomial Orderings","title":"Tests on Monomial Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"is_elimination_ordering(ord::MonomialOrdering, V::Vector{<:MPolyRingElem})","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#is_elimination_ordering-Tuple{MonomialOrdering, Vector{<:MPolyRingElem}}","page":"Monomial Orderings","title":"is_elimination_ordering","text":"is_elimination_ordering(ord::MonomialOrdering, V::Vector{<:MPolyRingElem})\n\nGiven a vector V of polynomials which are variables, return true if ord is an elimination ordering for the variables in V. Return false, otherwise.\n\nis_elimination_ordering(ord::MonomialOrdering, V:Vector{Int})\n\nGiven a vector V of indices which specify variables, return true if ord is an elimination ordering for the specified variables. Return false, otherwise.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> o1 = lex(R)\nlex([w, x, y, z])\n\njulia> is_elimination_ordering(o1, [w, x])\ntrue\n\njulia> o2 = weight_ordering([1, 1, 0, 0], degrevlex(R))\nmatrix_ordering([w, x, y, z], [1 1 0 0])*degrevlex([w, x, y, z])\n\njulia> is_elimination_ordering(o2, [w, x])\ntrue\n\njulia> o3 = weight_ordering([1, -1, 0, 0], degrevlex(R))\nmatrix_ordering([w, x, y, z], [1 -1 0 0])*degrevlex([w, x, y, z])\n\njulia> is_elimination_ordering(o3, [w, x])\nfalse\n\njulia> o4 = degrevlex([w, x])*degrevlex([y, z])\ndegrevlex([w, x])*degrevlex([y, z])\n\njulia> is_elimination_ordering(o4, [w, x])\ntrue\n\njulia> o5 = degrevlex([w, x])*negdegrevlex([y, z])\ndegrevlex([w, x])*negdegrevlex([y, z])\n\njulia> is_elimination_ordering(o5, [w, x])\ntrue\n\njulia> o6 = negdegrevlex([w, x])*negdegrevlex([y, z])\nnegdegrevlex([w, x])*negdegrevlex([y, z])\n\njulia> is_elimination_ordering(o6, [w, x])\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"is_global(ord::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#is_global-Tuple{MonomialOrdering}","page":"Monomial Orderings","title":"is_global","text":"is_global(ord::MonomialOrdering)\n\nReturn true if ord is global, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> o = matrix_ordering(R, [1 1; 0 -1])\nmatrix_ordering([x, y], [1 1; 0 -1])\n\njulia> is_global(o)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"is_local(ord::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#is_local-Tuple{MonomialOrdering}","page":"Monomial Orderings","title":"is_local","text":"is_local(ord::MonomialOrdering)\n\nReturn true if ord is local, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> o = matrix_ordering(R, [-1 -1; 0 -1])\nmatrix_ordering([x, y], [-1 -1; 0 -1])\n\njulia> is_local(o)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"is_mixed(ord::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#is_mixed-Tuple{MonomialOrdering}","page":"Monomial Orderings","title":"is_mixed","text":"is_mixed(ord::MonomialOrdering)\n\nReturn true if ord is mixed, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> o = matrix_ordering(R, [1 -1; 0 -1])\nmatrix_ordering([x, y], [1 -1; 0 -1])\n\njulia> is_mixed(o)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Transferring-an-ordering-from-another-ring","page":"Monomial Orderings","title":"Transferring an ordering from another ring","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"induce(vars::AbstractVector{<:MPolyRingElem}, ord::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#induce-Tuple{AbstractVector{<:MPolyRingElem}, MonomialOrdering}","page":"Monomial Orderings","title":"induce","text":"induce(vars::AbstractVector{<:MPolyRingElem}, ord::ModuleOrdering)\n\nReturn the monomial ordering on the variables vars induced by transferring the ordering ord.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> S, (a, b, c) = polynomial_ring(GF(5), [\"a\", \"b\", \"c\"]);\n\njulia> ord = degrevlex([x, y])*neglex([z]);\n\njulia> induce([a, b, c], ord)\ndegrevlex([a, b])*neglex([c])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Module-Orderings","page":"Monomial Orderings","title":"Module Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"Let R = Cx=Cx_1 ldots x_n be a multivariate polynomial ring with coefficient ring C. Referring to the section on free modules for details, we recall that by a free R-module we mean a free module of type R^p , where we think of R^p as a free module with a given basis, namely the basis of standard unit vectors. In what follows, F will denote such free R-module, and e_1 dots e_p will denote the given basis.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"A monomial in F, involving the basis element e_i, is a monomial in R times e_i. A term in F is a monomial in F multiplied by a coefficient cin C. Every nonzero element fin F can be uniquely expressed as the sum of finitely many nonzero terms involving distinct monomials. These terms (monomials) are called the terms (monomials} of f.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"A monomial ordering on F is a total ordering on the set of monomials in F such that if x^alpha e_i and x^beta e_j are monomials in F, and x^gamma is a monomial in R, then ","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha e_i x^beta e_j Longrightarrow x^gamma x^alpha e_i x^gamma x^beta e_j","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"In OSCAR, we require in addition that","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha e_i x^beta e_i text iff x^alpha e_j x^beta e_j text for all ij","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"Then induces a unique monomial ordering on R in the obvious way, and we say that is global, local, or mixed if the induced ordering on R is global, local, or mixed. ","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"One way of getting a monomial ordering on F is to pick a monomial ordering on R, and extend it to F. For instance, setting","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha e_i x^beta e_j iff x^alpha x^beta text or (x^alpha = x^beta text and i j)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"gives priority to the monomials in R, whereas the ordering defined below gives priority to the components of F:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"x^alpha e_i x^beta e_j iff i j text or (i = jtext and x^alpha x^beta)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"Alternatively, we may wish to use i j instead of i j in this definition.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"In other words, these orderings are obtained by concatenating a monomial ordering on the monomials of R with a way of ordering the basis vectors of F or vice versa. In OSCAR, we refer to the i j ordering on the basis vectors as lex, and to the i j ordering as revlex. And, we use the * operator for concatenation. ","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#Examples-3","page":"Monomial Orderings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"julia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 3)\nFree module of rank 3 over Multivariate polynomial ring in 4 variables over QQ\n\njulia> o1 = degrevlex(R)*revlex(gens(F))\ndegrevlex([w, x, y, z])*revlex([gen(1), gen(2), gen(3)])\n\njulia> o2 = revlex(gens(F))*degrevlex(R)\nrevlex([gen(1), gen(2), gen(3)])*degrevlex([w, x, y, z])\n","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The induced ordering on the given polynomial ring is recovered as follows:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"induced_ring_ordering(ord::ModuleOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#induced_ring_ordering-Tuple{ModuleOrdering}","page":"Monomial Orderings","title":"induced_ring_ordering","text":"induced_ring_ordering(ord::ModuleOrdering)\n\nReturn the ring ordering induced by ord. \n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 3)\nFree module of rank 3 over Multivariate polynomial ring in 4 variables over QQ\n\njulia> o = revlex(gens(F))*degrevlex(R)\nrevlex([gen(1), gen(2), gen(3)])*degrevlex([w, x, y, z])\n\njulia> induced_ring_ordering(o)\ndegrevlex([w, x, y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The comparison function cmp as well as the tests is_global, is_local, and is_mixed are also available for module orderings.","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Projective/","page":"Projective","title":"Projective","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Projective/","page":"Projective","title":"Projective","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#Projective","page":"Projective","title":"Projective","text":"","category":"section"},{"location":"AlgebraicGeometry/RationalPoints/Projective/","page":"Projective","title":"Projective","text":"AbsProjectiveRationalPoint\nProjectiveRationalPoint\ncoordinates(P::ProjectiveRationalPoint)\nideal(P::ProjectiveRationalPoint)\nscheme(P::ProjectiveRationalPoint)\nnormalize!(a::AbsProjectiveRationalPoint{<:FieldElem})\nnormalize!(a::AbsProjectiveRationalPoint{ZZRingElem})","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#AbsProjectiveRationalPoint","page":"Projective","title":"AbsProjectiveRationalPoint","text":"AbsProjectiveRationalPoint\n\nA rational point P of a projective scheme X. We refer to X as the parent of P.\n\nLet k be a field. A rational point is an element of mathbbP^n(k) = k^n+1 setminus 0 k^* where two vectors vw in k^n+1 setminus 0 are identified if v = alpha w for a non-zero scalar alpha in k^*.\n\nLet X subseteq mathbbP^n_k be an algebraic set or more generally a closed subscheme defined by the homogeneous ideal I = (f_1 dots f_r). Then a rational point of X is p in mathbbP^n(k) such that f_1(p) = dots = f_n(p) = 0.\n\nThis type includes points in weighted projective space.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#ProjectiveRationalPoint","page":"Projective","title":"ProjectiveRationalPoint","text":"ProjectiveRationalPoint{CoeffType<:RingElem, ParentType<:AbsProjectiveScheme}\n\nType for rational points in projective varieties.\n\nExamples\n\njulia> P2 = projective_space(QQ, 2);\n\njulia> P2([4, 0 , 2//3])\nProjective rational point\n of Projective 2-space over QQ with coordinates [s0, s1, s2]\nwith coordinates (4 : 0 : 2//3)\n\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#coordinates-Tuple{Oscar.ProjectiveRationalPoint}","page":"Projective","title":"coordinates","text":"coordinates(p::AbsProjectiveRationalPoint{S,T}) -> Vector{S}\n\nReturn the homogeneous coordinates of the rational point p.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#ideal-Tuple{Oscar.ProjectiveRationalPoint}","page":"Projective","title":"ideal","text":"ideal(P::AbsProjectiveRationalPoint)\n\nReturn the homogeneous ideal associated to P in the homogeneous coordinate ring of its ambient space.\n\n\n\n\n\nideal(O::NfRelOrd, M::PMat; check::Bool = true, M_in_hnf::Bool = false) -> NfRelOrdIdl\n\nCreates the ideal of mathcal O with basis pseudo-matrix M. If check is set, then it is checked whether M defines an ideal. If M_in_hnf is set, then it is assumed that M is already in lower left pseudo HNF.\n\n\n\n\n\nideal(O::NfRelOrd, M::Generic.Mat; check::Bool = true) -> NfRelOrdIdl\n\nCreates the ideal of mathcal O with basis matrix M. If check is set, then it is checked whether M defines an ideal.\n\n\n\n\n\nideal(O::NfRelOrd{T, S}, x::NfRelElem{T}, y::NfRelElem{T}, a::S, b::S; check::Bool = true) -> NfRelOrdIdl{T, S}\n\nCreates the ideal xcdot a + ycdot b of mathcal O. If check is set, then it is checked whether these elements define an ideal.\n\n\n\n\n\nideal(O::NfRelOrd{T, S}, x::NfRelOrdElem{T}) -> NfRelOrdIdl{T, S}\n*(O::NfRelOrd{T, S}, x::NfRelOrdElem{T}) -> NfRelOrdIdl{T, S}\n*(x::NfRelOrdElem{T}, O::NfRelOrd{T, S}) -> NfRelOrdIdl{T, S}\n\nCreates the ideal xcdot mathcal O of mathcal O.\n\n\n\n\n\nideal(O::NfRelOrd{T, S}, a::S; check::Bool = true) -> NfRelOrdIdl{T, S}\n\nCreates the ideal a cdot mathcal O of mathcal O. If check is set, then it is checked whether a defines an (integral) ideal.\n\n\n\n\n\nideal(O::AlgAssAbsOrd, x::AbsAlgAssElem) -> AlgAssAbsOrdIdl\nideal(O::AlgAssAbsOrd, x::AlgAssAbsOrdElem) -> AlgAssAbsOrdIdl\n\nReturns the twosided principal ideal of O generated by x.\n\n\n\n\n\nideal(O::AlgAssAbsOrd, x::AbsAlgAssElem, side::Symbol) -> AlgAssAbsOrdIdl\nideal(O::AlgAssAbsOrd, x::AlgAssAbsOrdElem, side::Symbol) -> AlgAssAbsOrdIdl\n\nReturns the ideal O cdot x if side == :left, and x cdot O if side == :right.\n\n\n\n\n\nideal(A::AbsAlgAss, M::PMat; M_in_hnf::Bool = false) -> AlgAssRelOrdIdl\n\nReturns the ideal in A with basis pseudo-matrix M. If M_in_hnf == true, it is assumed that M is already in lower left pseudo HNF.\n\n\n\n\n\nideal(A::AbsAlgAss, O::AlgAssRelOrd, M::PMat; side::Symbol = :nothing,\n M_in_hnf::Bool = false)\n -> AlgAssRelOrdIdl\n\nReturns the ideal of O in A with basis pseudo-matrix M (in the basis of A). If the ideal is known to be a right/left/twosided ideal of O, side may be set to :right/:left/:twosided respectively. If M_in_hnf == true, it is assumed that M is already in lower left pseudo HNF.\n\n\n\n\n\nideal(O::AlgAssRelOrd, x::AbsAlgAssElem) -> AlgAssRelOrdIdl\nideal(O::AlgAssRelOrd, x::AlgAssRelOrdElem) -> AlgAssRelOrdIdl\n\nReturns the twosided principal ideal of O generated by x.\n\n\n\n\n\nideal(O::AlgAssRelOrd, x::AbsAlgAssElem, side::Symbol) -> AlgAssRelOrdIdl\nideal(O::AlgAssRelOrd, x::AlgAssRelOrdElem, side::Symbol) -> AlgAssRelOrdIdl\n\nReturns the ideal O cdot x if side == :left, and x cdot O if side == :right.\n\n\n\n\n\nideal(O::AlgAssRelOrd, a::NfOrdFracIdl) -> AlgAssRelOrdIdl\nideal(O::AlgAssRelOrd, a::NfRelOrdFracIdl) -> AlgAssRelOrdIdl\n\nReturns the ideal a cdot O where a is a fractional ideal of base_ring(O).\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#scheme-Tuple{Oscar.ProjectiveRationalPoint}","page":"Projective","title":"scheme","text":"scheme(P::AbsProjectiveRationalPoint) -> AbsProjectiveScheme\n\nReturn the rational point P viewed as a reduced, projective subscheme of its ambient projective space.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#normalize!-Tuple{Oscar.AbsProjectiveRationalPoint{<:FieldElem}}","page":"Projective","title":"normalize!","text":"normalize!(a::AbsProjectiveRationalPoint{<:FieldElem})\n\nNormalize a such that its first non-zero coordinate is one.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Projective/#normalize!-Tuple{Oscar.AbsProjectiveRationalPoint{ZZRingElem}}","page":"Projective","title":"normalize!","text":"normalize!(a::AbsProjectiveRationalPoint{ZZRingElem})\n\nNormalize a such that its first non-zero coordinate is positive.\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/debugging/#Debugging-OSCAR-Code","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"","category":"section"},{"location":"DeveloperDocumentation/debugging/#Pitfalls:-Mutable-objects-in-OSCAR-code","page":"Debugging OSCAR Code","title":"Pitfalls: Mutable objects in OSCAR code","text":"","category":"section"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"Suppose you are having the following difficulties. Your code is exhibiting inexplicable behaviour and values that should not be changing are changing in seemingly random locations. To get to the bottom of these kind of issues it is necessary to be familiar with mutable objects in Julia and some of the relevant conventions in place in OSCAR. This section discusses these informal rules as well as some of the exceptions to these rules.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"In Julia, objects that can change after construction are declared with the mutable struct keywords and satisfy the ismutable predicate. These objects can be linked together into an arbitrary dependency graph, and a change to one object may therefore have unintended consequences on another object in the system.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"The simplest example is the creation of a polynomial ring. If we mutate the array of symbols used for printing, we have effectively changed the ring.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"julia> v = [:x, :y, :z]; R = polynomial_ring(QQ, v)[1]\nMultivariate Polynomial Ring in x, y, z over Rational Field\n\njulia> v[3] = :w; R\nMultivariate Polynomial Ring in x, y, w over Rational Field","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"In this example, the modification of v is unexpected and may in fact corrupt the internal data structures used by the polynomial ring. As such, this modification of v has to be considered illegal. Upon creation of the array called v, we have full rights over the object and can mutate at will. However, after passing it to the function polynomial_ring, we have given up ownership of the array and are no longer free to modify it.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"General OSCAR Principle (GOP):","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"Code should be expected to behave as if all objects are immutable.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"Ramifications:","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"This means that the polynomial ring constructor is allowed to expect that v is never mutated for the remaining duration of its life. In return, the constructor is guaranteed not to modify the array, so that v is still [:x, :y, :z] after polynomial_ring returns.\nIn general this means that all functions should be expected to take ownership of their arguments: the user is safest never modifying an existing object that has been passed to an unknown Julia function. Note that assignments such as a[i] = b or a.foo = b usually mutate the object a. See Ownership of function arguments\nFor reasons of efficiency, it is sometimes desirable to defy this principle and modify an existing object. The fact that a given function may modify a preexisting object is usually communicated via coding conventions on the name - either a ! or a _unsafe in the name of the function. See Unsafe arithmetic with OSCAR objects","category":"page"},{"location":"DeveloperDocumentation/debugging/#Ownership-of-function-arguments","page":"Debugging OSCAR Code","title":"Ownership of function arguments","text":"","category":"section"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"In this example we construct the factored element x = 2^3 and then change the 2 to a 1. The GOP says this modification of a on line 3 is illegal.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"julia> a = ZZRingElem(2)\n2\n\njulia> x = FacElem([a], [ZZRingElem(3)]); evaluate(x)\n8\n\njulia> a = one!(a) # illegal in-place assignment of a to 1\n1\n\njulia> evaluate(x) # x has been changed and possibly corrupted\n1","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"In the previous example, the link between the object x and the object a can be broken by passing a deepcopy of a to the FacElem function.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"julia> a = ZZRingElem(2)\n2\n\njulia> x = FacElem([deepcopy(a)], [ZZRingElem(3)]); evaluate(x)\n8\n\njulia> a = one!(a) # we still own a, so modification is legal\n1\n\njulia> evaluate(x) # x is now unchanged\n8","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"It is of course not true that all Julia functions take ownership of their arguments, but the GOP derives from the fact that this decision is an implementation detail with performance consequences. The behaviour of a function may be inconsistent across different types and versions of OSCAR. In the following two snippets, the GOP says both modifications of a are illegal since they have since been passed to a function. If K = QQ, the two mutations turn out to be legal currently, while they are illegal if K = quadratic_field(-1)[1]. Only with special knowledge of the types can the GOP be safely ignored.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"R = polynomial_ring(K, [:x, :y])[1]\na = one(K)\np = R([a], [[0,0]])\n@show p\na = add!(a, a, a) # legal? (does a += a in-place)\n@show p","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"R = polynomial_ring(K, :x)[1]\na = [one(K), one(K)]\np = R(a)\n@show (p, degree(p))\na[2] = zero(K) # legal?\n@show (p, degree(p))","category":"page"},{"location":"DeveloperDocumentation/debugging/#Ownership-of-function-return-values","page":"Debugging OSCAR Code","title":"Ownership of function return values","text":"","category":"section"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"The nuances of who is allowed to modify an object returned by a function is best left to the next section Unsafe arithmetic with OSCAR objects. The GOP says of course you should not do it, but there are cases where it can be more efficient. However, there is another completely different issue of return values that can arise in certain interfaces.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"First, we create the Gaussian rationals and the two primes above 5.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"julia> K, i = quadratic_field(-1)\n(Imaginary quadratic field defined by x^2 + 1, sqrt(-1))\n\njulia> m = Hecke.modular_init(K, 5)\nmodular environment for p=5, using 2 ideals","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"The function modular_project returns the projection of an element of K into each of the residue fields.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"julia> a = Hecke.modular_proj(1+2*i, m)\n2-element Vector{fqPolyRepFieldElem}:\n 2\n 0","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"While the function has produced the correct answer, if we run it again on a different input, we will find that a has changed.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"julia> b = Hecke.modular_proj(2+3*i, m)\n2-element Vector{fqPolyRepFieldElem}:\n 1\n 3\n\njulia> a\n2-element Vector{fqPolyRepFieldElem}:\n 1\n 3","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"The preceding behaviour of the function modular_proj is an artifact of internal efficiency and may be desirable in certain circumstances. In other circumstances, the following deepcopys may be necessary for your code to function correctly.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"julia> a = deepcopy(Hecke.modular_proj(1+2*i, m));\njulia> b = deepcopy(Hecke.modular_proj(2+3*i, m));\njulia> (a, b)\n(fqPolyRepFieldElem[2, 0], fqPolyRepFieldElem[1, 3])","category":"page"},{"location":"DeveloperDocumentation/debugging/#Unsafe-arithmetic-with-OSCAR-objects","page":"Debugging OSCAR Code","title":"Unsafe arithmetic with OSCAR objects","text":"","category":"section"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"Particularly with integers (BigInt and ZZRingElem) - but also to a lesser extent with polynomials - the cost of basic arithmetic operations can easily be dominated by the cost of allocating space for the answer. For this reason, OSCAR offers an interface for in-place arithmetic operations.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"Instead of writing x = a + b to compute a sum, one writes x = add!(x, a, b) with the idea that the object to which x is pointing is modified instead of having x point to a newly allocated object. In order for this to work, x must point to a fully independent object, that is, an object whose modification through the interface Unsafe operators will not change the values of other existing objects. The actual definition of \"fully independent\" is left to the implementation of the ring element type. For example, there is no distinction for immutables.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"It is generally not safe to mutate the return of a function. However, the basic arithmetic operations +, -, *, and ^ are guaranteed to return a fully independent object regardless of the status of their inputs. As such, the following implementation of ^ is illegal by this guarantee.","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"function ^(a::RingElem, n::Int)\n if n == 1\n return a # must be return deepcopy(a)\n else\n ...\n end\nend","category":"page"},{"location":"DeveloperDocumentation/debugging/","page":"Debugging OSCAR Code","title":"Debugging OSCAR Code","text":"In general, if you are not sure if your object is fully independent, a deepcopy should always do the job.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#Lie-algebras","page":"Lie algebras","title":"Lie algebras","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"Lie algebras in OSCAR are currently always finite dimensional, and represented by two different types, namely LinearLieAlgebra{C} and AbstractLieAlgebra{C}, depending on whether a matrix representation is available or not. Both types are subtypes of LieAlgebra{C}. Similar to other types in OSCAR, each Lie algebra type has a corresponding element type. The type parameter C is the element type of the coefficient ring. ","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"zero(::LieAlgebra)\niszero(::LieAlgebraElem)\ndim(::LieAlgebra)\nbasis(::LieAlgebra)\nbasis(::LieAlgebra, ::Int)\ncoefficients(::LieAlgebraElem)\ncoeff(::LieAlgebraElem, ::Int)\ngetindex(::LieAlgebraElem, ::Int)\nsymbols(::LieAlgebra)","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#zero-Tuple{LieAlgebra}","page":"Lie algebras","title":"zero","text":"zero(L::LieAlgebra{C}) -> LieAlgebraElem{C}\n\nReturn the zero element of the Lie algebra L.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#iszero-Tuple{LieAlgebraElem}","page":"Lie algebras","title":"iszero","text":"iszero(x::LieAlgebraElem{C}) -> Bool\n\nCheck whether the Lie algebra element x is zero.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#dim-Tuple{LieAlgebra}","page":"Lie algebras","title":"dim","text":"dim(L::LieAlgebra) -> Int\n\nReturn the dimension of the Lie algebra L.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#basis-Tuple{LieAlgebra}","page":"Lie algebras","title":"basis","text":"basis(L::LieAlgebra{C}) -> Vector{LieAlgebraElem{C}}\n\nReturn a basis of the Lie algebra L.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#basis-Tuple{LieAlgebra, Int64}","page":"Lie algebras","title":"basis","text":"basis(L::LieAlgebra{C}, i::Int) -> LieAlgebraElem{C}\n\nReturn the i-th basis element of the Lie algebra L.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#coefficients-Tuple{LieAlgebraElem}","page":"Lie algebras","title":"coefficients","text":"coefficients(x::LieAlgebraElem{C}) -> Vector{C}\n\nReturn the coefficients of x with respect to basis(::LieAlgebra).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#coeff-Tuple{LieAlgebraElem, Int64}","page":"Lie algebras","title":"coeff","text":"coeff(x::LieAlgebraElem{C}, i::Int) -> C\n\nReturn the i-th coefficient of x with respect to basis(::LieAlgebra).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#getindex-Tuple{LieAlgebraElem, Int64}","page":"Lie algebras","title":"getindex","text":"getindex(x::LieAlgebraElem{C}, i::Int) -> C\n\nReturn the i-th coefficient of x with respect to basis(::LieAlgebra).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#symbols-Tuple{LieAlgebra}","page":"Lie algebras","title":"symbols","text":"symbols(L::LieAlgebra{C}) -> Vector{Symbol}\n\nReturn the symbols used for printing basis elements of the Lie algebra L.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#Special-functions-for-LinearLieAlgebras","page":"Lie algebras","title":"Special functions for LinearLieAlgebras","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"matrix_repr_basis(::LinearLieAlgebra{C}) where {C<:RingElement}\nmatrix_repr_basis(::LinearLieAlgebra{C}, ::Int) where {C<:RingElement}\nmatrix_repr(::LinearLieAlgebraElem{C}) where {C<:RingElement}","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#matrix_repr_basis-Union{Tuple{LinearLieAlgebra{C}}, Tuple{C}} where C<:RingElement","page":"Lie algebras","title":"matrix_repr_basis","text":"matrix_repr_basis(L::LinearLieAlgebra{C}) -> Vector{MatElem{C}}\n\nReturn the basis basis(L) of the Lie algebra L in the underlying matrix representation.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#matrix_repr_basis-Union{Tuple{C}, Tuple{LinearLieAlgebra{C}, Int64}} where C<:RingElement","page":"Lie algebras","title":"matrix_repr_basis","text":"matrix_repr_basis(L::LinearLieAlgebra{C}, i::Int) -> MatElem{C}\n\nReturn the i-th element of the basis basis(L) of the Lie algebra L in the underlying matrix representation.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#matrix_repr-Union{Tuple{LinearLieAlgebraElem{C}}, Tuple{C}} where C<:RingElement","page":"Lie algebras","title":"matrix_repr","text":"matrix_repr(a::Perm)\n\nReturn the permutation matrix as a sparse matrix representing a via natural embedding of the permutation group into the general linear group over mathbbZ.\n\nExamples\n\njulia> p = Perm([2,3,1])\n(1,2,3)\n\njulia> matrix_repr(p)\n3×3 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n ⋅ 1 ⋅\n ⋅ ⋅ 1\n 1 ⋅ ⋅\n\njulia> Array(ans)\n3×3 Matrix{Int64}:\n 0 1 0\n 0 0 1\n 1 0 0\n\n\n\n\n\nmatrix_repr(Y::YoungTableau)\n\nConstruct sparse integer matrix representing the tableau.\n\nExamples\n\njulia> y = YoungTableau([4,3,1]);\n\n\njulia> matrix_repr(y)\n3×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 8 stored entries:\n 1 2 3 4\n 5 6 7 ⋅\n 8 ⋅ ⋅ ⋅\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#Element-constructors","page":"Lie algebras","title":"Element constructors","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"(L::LieAlgebra{C})() returns the zero element of the Lie algebra L.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"(L::LieAlgebra{C})(x::LieAlgebraElem{C}) returns x if x is an element of L, and fails otherwise.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"(L::LieAlgebra{C})(v) constructs the element of L with coefficient vector v. v can be of type Vector{C}, Vector{Int}, SRow{C}, or MatElem{C} (of size 1 times dim(L)).","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"If L is a LinearLieAlgebra of dim(L) > 1, the call (L::LinearLieAlgebra{C})(m::MatElem{C}) returns the Lie algebra element whose matrix representation corresponds to m. This requires m to be a square matrix of size n > 1 (the dimension of L), and to lie in the Lie algebra L (i.e. to be in the span of basis(L)). The case of m being a 1 times dim(L) matrix still works as explained above.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#Arithmetics","page":"Lie algebras","title":"Arithmetics","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"The usual arithmetics, e.g. +, -, and *, are defined for LieAlgebraElems.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"warning: Warning\nPlease note that * refers to the Lie bracket and is thus not associative.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#Properties","page":"Lie algebras","title":"Properties","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"is_abelian(L::LieAlgebra)\nis_simple(L::LieAlgebra)","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#is_abelian-Tuple{LieAlgebra}","page":"Lie algebras","title":"is_abelian","text":"is_abelian(L::LieAlgebra) -> Bool\n\nReturn true if L is abelian, i.e. L L = 0.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#is_simple-Tuple{LieAlgebra}","page":"Lie algebras","title":"is_simple","text":"is_simple(L::LieAlgebra) -> Bool\n\nReturn true if L is simple, i.e. L is not abelian and has no non-trivial ideals.\n\nwarning: Warning\nThis function is not implemented yet.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#More-functions","page":"Lie algebras","title":"More functions","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"derived_algebra(L::LieAlgebra)\ncenter(L::LieAlgebra)\ncentralizer(L::LieAlgebra, xs::AbstractVector{<:LieAlgebraElem})\ncentralizer(L::LieAlgebra, x::LieAlgebraElem)","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#derived_algebra-Tuple{LieAlgebra}","page":"Lie algebras","title":"derived_algebra","text":"derived_algebra(L::LieAlgebra) -> LieAlgebraIdeal\n\nReturn the derived algebra of L, i.e. L L.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#center-Tuple{LieAlgebra}","page":"Lie algebras","title":"center","text":"center(L::LieAlgebra) -> LieAlgebraIdeal\n\nReturn the center of L, i.e. x in L mid x L = 0\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#centralizer-Tuple{LieAlgebra, AbstractVector{<:LieAlgebraElem}}","page":"Lie algebras","title":"centralizer","text":"centralizer(L::LieAlgebra, xs::AbstractVector{<:LieAlgebraElem}) -> LieSubalgebra\n\nReturn the centralizer of xs in L, i.e. y in L mid x y = 0 forall x in xs.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#centralizer-Tuple{LieAlgebra, LieAlgebraElem}","page":"Lie algebras","title":"centralizer","text":"centralizer(L::LieAlgebra, x::LieAlgebraElem) -> LieSubalgebra\n\nReturn the centralizer of x in L, i.e. y in L mid x y = 0.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#Lie-algebra-constructors","page":"Lie algebras","title":"Lie algebra constructors","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"lie_algebra","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#lie_algebra","page":"Lie algebras","title":"lie_algebra","text":"lie_algebra(gapL::GAP.GapObj, s::Vector{<:VarName}; cached::Bool) -> LieAlgebra{elem_type(R)}\n\nConstruct a Lie algebra isomorphic to the GAP Lie algebra gapL. Its basis element are named by s, or by x_i by default. We require gapL to be a finite-dimensional GAP Lie algebra. The return type is dependent on properties of gapL, in particular, whether GAP knows about a matrix representation.\n\nIf cached is true, the constructed Lie algebra is cached.\n\n\n\n\n\nlie_algebra(R::Ring, struct_consts::Matrix{SRow{elem_type(R)}}, s::Vector{<:VarName}; cached::Bool, check::Bool) -> AbstractLieAlgebra{elem_type(R)}\n\nConstruct the Lie algebra over the ring R with structure constants struct_consts and with basis element names s.\n\nThe Lie bracket on the newly constructed Lie algebra L is determined by the structure constants in struct_consts as follows: let x_i denote the i-th standard basis vector of L. Then the entry struct_consts[i,j][k] is a scalar a_ijk such that x_i x_j = sum_k a_ijk x_k.\n\ns: A vector of basis element names. This is [Symbol(\"x_$i\") for i in 1:size(struct_consts, 1)] by default.\ncached: If true, cache the result. This is true by default.\ncheck: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.\n\n\n\n\n\nlie_algebra(R::Ring, struct_consts::Array{elem_type(R),3}, s::Vector{<:VarName}; cached::Bool, check::Bool) -> AbstractLieAlgebra{elem_type(R)}\n\nConstruct the Lie algebra over the ring R with structure constants struct_consts and with basis element names s.\n\nThe Lie bracket on the newly constructed Lie algebra L is determined by the structure constants in struct_consts as follows: let x_i denote the i-th standard basis vector of L. Then the entry struct_consts[i,j,k] is a scalar a_ijk such that x_i x_j = sum_k a_ijk x_k.\n\ns: A vector of basis element names. This is [Symbol(\"x_$i\") for i in 1:size(struct_consts, 1)] by default.\ncached: If true, cache the result. This is true by default.\ncheck: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.\n\nExamples\n\njulia> struct_consts = zeros(QQ, 3, 3, 3);\n\njulia> struct_consts[1, 2, 3] = QQ(1);\n\njulia> struct_consts[2, 1, 3] = QQ(-1);\n\njulia> struct_consts[3, 1, 1] = QQ(2);\n\njulia> struct_consts[1, 3, 1] = QQ(-2);\n\njulia> struct_consts[3, 2, 2] = QQ(-2);\n\njulia> struct_consts[2, 3, 2] = QQ(2);\n\njulia> sl2 = lie_algebra(QQ, struct_consts, [\"e\", \"f\", \"h\"])\nAbstract Lie algebra\n of dimension 3\nover rational field\n\njulia> e, f, h = basis(sl2)\n3-element Vector{AbstractLieAlgebraElem{QQFieldElem}}:\n e\n f\n h\n\njulia> e * f\nh\n\njulia> h * e\n2*e\n\njulia> h * f\n-2*f\n\n\n\n\n\nlie_algebra(R::Ring, dynkin::Tuple{Char,Int}; cached::Bool) -> AbstractLieAlgebra{elem_type(R)}\n\nConstruct the simple Lie algebra over the ring R with Dynkin type given by dynkin. The actual construction is done in GAP.\n\nIf cached is true, the constructed Lie algebra is cached.\n\n\n\n\n\nlie_algebra(R::Ring, n::Int, basis::Vector{<:MatElem{elem_type(R)}}, s::Vector{<:VarName}; cached::Bool) -> LinearLieAlgebra{elem_type(R)}\n\nConstruct the Lie algebra over the ring R with basis basis and basis element names given by s. The basis elements must be square matrices of size n. We require basis to be linearly independent, and to contain the Lie bracket of any two basis elements in its span.\n\nIf cached is true, the constructed Lie algebra is cached.\n\n\n\n\n\nlie_algebra(S::LieSubalgebra) -> LieAlgebra\n\nReturn S as a Lie algebra.\n\n\n\n\n\nlie_algebra(I::LieAlgebraIdeal) -> LieAlgebra\n\nReturn I as a Lie algebra.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/LieAlgebras/lie_algebras/#Classical-Lie-algebras","page":"Lie algebras","title":"Classical Lie algebras","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"general_linear_lie_algebra(R::Ring, n::Int)\nspecial_linear_lie_algebra(R::Ring, n::Int)\nspecial_orthogonal_lie_algebra(R::Ring, n::Int)","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#general_linear_lie_algebra-Tuple{Ring, Int64}","page":"Lie algebras","title":"general_linear_lie_algebra","text":"general_linear_lie_algebra(R::Ring, n::Int) -> LinearLieAlgebra{elem_type(R)}\n\nReturn the general linear Lie algebra mathfrakgl_n(R).\n\nExamples\n\njulia> L = general_linear_lie_algebra(QQ, 2)\nGeneral linear Lie algebra of degree 2\n of dimension 4\nover rational field\n\njulia> basis(L)\n4-element Vector{LinearLieAlgebraElem{QQFieldElem}}:\n x_1_1\n x_1_2\n x_2_1\n x_2_2\n\njulia> matrix_repr_basis(L)\n4-element Vector{QQMatrix}:\n [1 0; 0 0]\n [0 1; 0 0]\n [0 0; 1 0]\n [0 0; 0 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#special_linear_lie_algebra-Tuple{Ring, Int64}","page":"Lie algebras","title":"special_linear_lie_algebra","text":"special_linear_lie_algebra(R::Ring, n::Int) -> LinearLieAlgebra{elem_type(R)}\n\nReturn the special linear Lie algebra mathfraksl_n(R).\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 2)\nSpecial linear Lie algebra of degree 2\n of dimension 3\nover rational field\n\njulia> basis(L)\n3-element Vector{LinearLieAlgebraElem{QQFieldElem}}:\n e_1_2\n f_1_2\n h_1\n\njulia> matrix_repr_basis(L)\n3-element Vector{QQMatrix}:\n [0 1; 0 0]\n [0 0; 1 0]\n [1 0; 0 -1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#special_orthogonal_lie_algebra-Tuple{Ring, Int64}","page":"Lie algebras","title":"special_orthogonal_lie_algebra","text":"special_orthogonal_lie_algebra(R::Ring, n::Int) -> LinearLieAlgebra{elem_type(R)}\n\nReturn the special orthogonal Lie algebra mathfrakso_n(R).\n\nExamples\n\njulia> L = special_orthogonal_lie_algebra(QQ, 3)\nSpecial orthogonal Lie algebra of degree 3\n of dimension 3\nover rational field\n\njulia> basis(L)\n3-element Vector{LinearLieAlgebraElem{QQFieldElem}}:\n x_1_2\n x_1_3\n x_2_3\n\njulia> matrix_repr_basis(L)\n3-element Vector{QQMatrix}:\n [0 1 0; -1 0 0; 0 0 0]\n [0 0 1; 0 0 0; -1 0 0]\n [0 0 0; 0 0 1; 0 -1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#Relation-to-GAP-Lie-algebras","page":"Lie algebras","title":"Relation to GAP Lie algebras","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"Using Oscar.iso_oscar_gap(L), one can get an isomorphism from the OSCAR Lie algebra L to some isomorphic GAP Lie algebra. For more details, please refer to iso_oscar_gap.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/function_field/#Rational-function-fields","page":"Rational function fields","title":"Rational function fields","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"AbstractAlgebra.jl provides a module, implemented in src/generic/RationalFunctionField.jl for rational function fields k(x) or k[x_1, x_2, \\ldots, x_n] over a field k.","category":"page"},{"location":"AbstractAlgebra/function_field/#Generic-rational-function-field-type","page":"Rational function fields","title":"Generic rational function field type","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Rational functions have type Generic.RationalFunctionFieldElem{T, U} where T is the type of elements of the coefficient field k and U is the type of polynomials (either univariate or multivariate) over that field. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Parent objects corresponding to the rational function field k have type Generic.RationalFunctionField{T, U}.","category":"page"},{"location":"AbstractAlgebra/function_field/#Abstract-types","page":"Rational function fields","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"The rational function types belong to the abstract type Field and the rational function field types belong to the abstract type FieldElem.","category":"page"},{"location":"AbstractAlgebra/function_field/#Rational-function-field-constructors","page":"Rational function fields","title":"Rational function field constructors","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"In order to construct rational functions in AbstractAlgebra.jl, one can first construct the function field itself. This is accomplished with one of the following constructors.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"RationalFunctionField(k::Field, s::VarName; cached::Bool = true)\nRationalFunctionField(k::Field, s::Vector{<:VarName}; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Given a coefficient field k return a tuple (S, x) consisting of the parent object of the rational function field over k and the generator(s) x. By default the parent object S will depend only on R and s and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Here are some examples of creating rational function fields and making use of the resulting parent objects to coerce various elements into the function field.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> S, x = RationalFunctionField(QQ, \"x\")\n(Rational function field over rationals, x)\n\njulia> f = S()\n0\n\njulia> g = S(123)\n123\n\njulia> h = S(BigInt(1234))\n1234\n\njulia> k = S(x + 1)\nx + 1\n\njulia> m = S(numerator(x + 1, false), numerator(x + 2, false))\n(x + 1)//(x + 2)\n\njulia> R, (x, y) = RationalFunctionField(QQ, [\"x\", \"y\"])\n(Rational function field over rationals, AbstractAlgebra.Generic.RationalFunctionFieldElem{Rational{BigInt}, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}[x, y])\n\njulia> (x + y)//y^2\n(x + y)//y^2","category":"page"},{"location":"AbstractAlgebra/function_field/#Basic-rational-function-field-functionality","page":"Rational function fields","title":"Basic rational function field functionality","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Fraction fields in AbstractAlgebra.jl implement the full Field interface and the entire fraction field interface.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"We give some examples of such functionality.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> S, x = RationalFunctionField(QQ, \"x\")\n(Rational function field over rationals, x)\n\njulia> f = S(x + 1)\nx + 1\n\njulia> g = (x^2 + x + 1)//(x^3 + 3x + 1)\n(x^2 + x + 1)//(x^3 + 3*x + 1)\n\njulia> h = zero(S)\n0\n\njulia> k = one(S)\n1\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> m = characteristic(S)\n0\n\njulia> U = base_ring(S)\nRationals\n\njulia> V = base_ring(f)\nRationals\n\njulia> T = parent(f)\nRational function field\n over rationals\n\njulia> r = deepcopy(f)\nx + 1\n\njulia> n = numerator(g)\nx^2 + x + 1\n\njulia> d = denominator(g)\nx^3 + 3*x + 1\n","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Note that numerator and denominator are returned as elements of a polynomial ring whose variable is printed the same way as that of the generator of the rational function field.","category":"page"},{"location":"AbstractAlgebra/function_field/#Rational-function-field-functionality-provided-by-AbstractAlgebra.jl","page":"Rational function fields","title":"Rational function field functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"The following functionality is provided for rational function fields.","category":"page"},{"location":"AbstractAlgebra/function_field/#Greatest-common-divisor","page":"Rational function fields","title":"Greatest common divisor","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"gcd(::Generic.RationalFunctionFieldElem{T, U}, ::Generic.RationalFunctionFieldElem{T, U}) where {T <: FieldElement, U <: Union{PolyRingElem, MPolyRingElem}}","category":"page"},{"location":"AbstractAlgebra/function_field/#gcd-Union{Tuple{U}, Tuple{T}, Tuple{AbstractAlgebra.Generic.RationalFunctionFieldElem{T, U}, AbstractAlgebra.Generic.RationalFunctionFieldElem{T, U}}} where {T<:FieldElement, U<:Union{MPolyRingElem, PolyRingElem}}","page":"Rational function fields","title":"gcd","text":"gcd(a::RationalFunctionFieldElem{T, U}, b::RationalFunctionFieldElem{T, U}) where {T <: FieldElement, U <: Union{PolyRingElem, MPolyRingElem}}\n\nReturn a greatest common divisor of a and b if one exists. N.B: we define the GCD of ab and cd to be gcd(ad bc)bd, reduced to lowest terms.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> R, x = RationalFunctionField(QQ, \"x\")\n(Rational function field over rationals, x)\n\njulia> f = (x + 1)//(x^3 + 3x + 1)\n(x + 1)//(x^3 + 3*x + 1)\n\njulia> g = (x^2 + 2x + 1)//(x^2 + x + 1)\n(x^2 + 2*x + 1)//(x^2 + x + 1)\n\njulia> h = gcd(f, g)\n(x + 1)//(x^5 + x^4 + 4*x^3 + 4*x^2 + 4*x + 1)\n","category":"page"},{"location":"AbstractAlgebra/function_field/#Square-root","page":"Rational function fields","title":"Square root","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"is_square(::Generic.RationalFunctionFieldElem{T, U}) where {T <: FieldElem, U <: Union{PolyRingElem, MPolyRingElem}}","category":"page"},{"location":"AbstractAlgebra/function_field/#is_square-Union{Tuple{AbstractAlgebra.Generic.RationalFunctionFieldElem{T, U}}, Tuple{U}, Tuple{T}} where {T<:FieldElem, U<:Union{MPolyRingElem, PolyRingElem}}","page":"Rational function fields","title":"is_square","text":"is_square(f::PolyRingElem{T}) where T <: RingElement\n\nReturn true if f is a perfect square.\n\n\n\n\n\nis_square(a::FracElem{T}) where T <: RingElem\n\nReturn true if a is a square.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Base.sqrt(::Generic.RationalFunctionFieldElem{T, U}) where {T <: FieldElem, U <: Union{PolyRingElem, MPolyRingElem}}","category":"page"},{"location":"AbstractAlgebra/function_field/#sqrt-Union{Tuple{AbstractAlgebra.Generic.RationalFunctionFieldElem{T, U}}, Tuple{U}, Tuple{T}} where {T<:FieldElem, U<:Union{MPolyRingElem, PolyRingElem}}","page":"Rational function fields","title":"sqrt","text":"sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of the given Puiseux series a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nBase.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of f. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.\n\n\n\n\n\nBase.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> R, x = RationalFunctionField(QQ, \"x\")\n(Rational function field over rationals, x)\n\njulia> a = (21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)\n(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)\n\njulia> sqrt(a^2)\n(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)\n\njulia> is_square(a^2)\ntrue","category":"page"},{"location":"AbstractAlgebra/function_field/#Univariate-function-fields","page":"Rational function fields","title":"Univariate function fields","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Univariate function fields in AbstractAlgebra are algebraic extensions Kk(x) of a rational function field k(x) over a field k.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"These are implemented in a module implemented in src/generic/FunctionField.jl.","category":"page"},{"location":"AbstractAlgebra/function_field/#Generic-function-field-types","page":"Rational function fields","title":"Generic function field types","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Function field objects Kk(x) in AbstractAlgebra have type Generic.FunctionField{T} where T is the type of elements of the field k.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Corresponding function field elements have type Generic.FunctionFieldElement{T}. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/function_field/#Abstract-types-2","page":"Rational function fields","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Function field types belong to the abstract type Field and their elements to the abstract type FieldElem.","category":"page"},{"location":"AbstractAlgebra/function_field/#Function-field-constructors","page":"Rational function fields","title":"Function field constructors","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"In order to construct function fields in AbstractAlgebra.jl, one first constructs the rational function field they are an extension of, then supplies a polynomial over this field to the following constructor:","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"FunctionField(p::Poly{RationalFunctionFieldElem{T, U}}, s::AbstractString; cached::Bool=true) where {T <: FieldElement, U <: PolyRingElem{T}}","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Given an irreducible polynomial p over a rational function field return a tuple (S, z) consisting of the parent object of the function field defined by that polynomial over k(x) and the generator z. By default the parent object S will depend only on p and s and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Here are some examples of creating function fields and making use of the resulting parent objects to coerce various elements into the function field.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> R1, x1 = RationalFunctionField(QQ, \"x1\") # characteristic 0\n(Rational function field over rationals, x1)\n\njulia> U1, z1 = R1[\"z1\"]\n(Univariate polynomial ring in z1 over rational function field, z1)\n\njulia> f = (x1^2 + 1)//(x1 + 1)*z1^3 + 4*z1 + 1//(x1 + 1)\n(x1^2 + 1)//(x1 + 1)*z1^3 + 4*z1 + 1//(x1 + 1)\n\njulia> S1, y1 = FunctionField(f, \"y1\")\n(Function Field over Rationals with defining polynomial (x1^2 + 1)*y1^3 + (4*x1 + 4)*y1 + 1, y1)\n\njulia> a = S1()\n0\n\njulia> b = S1((x1 + 1)//(x1 + 2))\n(x1 + 1)//(x1 + 2)\n\njulia> c = S1(1//3)\n1//3\n\njulia> R2, x2 = RationalFunctionField(GF(23), \"x1\") # characteristic p\n(Rational function field over finite field F_23, x1)\n\njulia> U2, z2 = R2[\"z2\"]\n(Univariate polynomial ring in z2 over rational function field, z2)\n\njulia> g = z2^2 + 3z2 + 1\nz2^2 + 3*z2 + 1\n\njulia> S2, y2 = FunctionField(g, \"y2\")\n(Function Field over Finite field F_23 with defining polynomial y2^2 + 3*y2 + 1, y2)\n\njulia> d = S2(R2(5))\n5\n\njulia> e = S2(y2)\ny2","category":"page"},{"location":"AbstractAlgebra/function_field/#Basic-function-field-functionality","page":"Rational function fields","title":"Basic function field functionality","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Function fields implement the full Ring and Field interfaces. We give some examples of such functionality.","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> R, x = RationalFunctionField(GF(23), \"x\") # characteristic p\n(Rational function field over finite field F_23, x)\n\njulia> U, z = R[\"z\"]\n(Univariate polynomial ring in z over rational function field, z)\n\njulia> g = z^2 + 3z + 1\nz^2 + 3*z + 1\n\njulia> S, y = FunctionField(g, \"y\")\n(Function Field over Finite field F_23 with defining polynomial y^2 + 3*y + 1, y)\n\njulia> f = (x + 1)*y + 1\n(x + 1)*y + 1\n\njulia> base_ring(f)\nRational function field\n over finite field F_23\n\njulia> f^2\n(20*x^2 + 19*x + 22)*y + 22*x^2 + 21*x\n\njulia> f*inv(f)\n1","category":"page"},{"location":"AbstractAlgebra/function_field/#Function-field-functionality-provided-by-AbstractAlgebra.jl","page":"Rational function fields","title":"Function field functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"The following functionality is provided for function fields.","category":"page"},{"location":"AbstractAlgebra/function_field/#Basic-manipulation","page":"Rational function fields","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"base_field(::Generic.FunctionField)","category":"page"},{"location":"AbstractAlgebra/function_field/#base_field-Tuple{AbstractAlgebra.Generic.FunctionField}","page":"Rational function fields","title":"base_field","text":"base_field(R::FunctionField)\n\nReturn the rational function field that the field R is an extension of. Synonymous with base_ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"var(::Generic.FunctionField)","category":"page"},{"location":"AbstractAlgebra/function_field/#var-Tuple{AbstractAlgebra.Generic.FunctionField}","page":"Rational function fields","title":"var","text":"var(R::FunctionField)\n\nReturn the variable name of the generator of the function field R as a symbol.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"characteristic(S::Generic.FunctionField)","category":"page"},{"location":"AbstractAlgebra/function_field/#characteristic-Tuple{AbstractAlgebra.Generic.FunctionField}","page":"Rational function fields","title":"characteristic","text":"characteristic(R::FunctionField)\n\nReturn the characteristic of the underlying rational function field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"defining_polynomial(R::Generic.FunctionField)","category":"page"},{"location":"AbstractAlgebra/function_field/#defining_polynomial-Tuple{AbstractAlgebra.Generic.FunctionField}","page":"Rational function fields","title":"defining_polynomial","text":"defining_polynomial(R::FunctionField)\nmodulus(R::FunctionField)\n\nReturn the original polynomial that was used to define the function field R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Base.numerator(::Generic.FunctionField{T}, ::Bool=true) where T <: FieldElement","category":"page"},{"location":"AbstractAlgebra/function_field/#numerator-Union{Tuple{AbstractAlgebra.Generic.FunctionField{T}}, Tuple{T}, Tuple{AbstractAlgebra.Generic.FunctionField{T}, Bool}} where T<:FieldElement","page":"Rational function fields","title":"numerator","text":"Base.numerator(R::FunctionField{T}, canonicalise::Bool=true) where T <: FieldElement\nBase.denominator(R::FunctionField{T}, canonicalise::Bool=true) where T <: FieldElement\n\nThinking of elements of the rational function field as fractions, put the defining polynomial of the function field over a common denominator and return the numerator/denominator respectively. Note that the resulting polynomials belong to a different ring than the original defining polynomial. The canonicalise is ignored, but exists for compatibility with the Generic interface.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Base.numerator(::Generic.FunctionFieldElem{T}, ::Bool=true) where T <: FieldElement","category":"page"},{"location":"AbstractAlgebra/function_field/#numerator-Union{Tuple{AbstractAlgebra.Generic.FunctionFieldElem{T}}, Tuple{T}, Tuple{AbstractAlgebra.Generic.FunctionFieldElem{T}, Bool}} where T<:FieldElement","page":"Rational function fields","title":"numerator","text":"Base.numerator(a::FunctionFieldElem{T}, canonicalise::Bool=true) where T <: FieldElement\nBase.denominator(a::FunctionFieldElem{T}, canonicalise::Bool=true) where T <: FieldElement\n\nReturn the numerator and denominator of the function field element a. Note that elements are stored in fraction free form so that the denominator is a common denominator for the coefficients of the element a. If canonicalise is set to true the fraction is first canonicalised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"degree(::Generic.FunctionField)","category":"page"},{"location":"AbstractAlgebra/function_field/#degree-Tuple{AbstractAlgebra.Generic.FunctionField}","page":"Rational function fields","title":"degree","text":"degree(S::FunctionField)\n\nReturn the degree of the defining polynomial of the function field, i.e. the degree of the extension that the function field makes of the underlying rational function field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"gen(::Generic.FunctionField{T}) where T <: FieldElement","category":"page"},{"location":"AbstractAlgebra/function_field/#gen-Union{Tuple{AbstractAlgebra.Generic.FunctionField{T}}, Tuple{T}} where T<:FieldElement","page":"Rational function fields","title":"gen","text":"gen(S::FunctionField{T}) where T <: FieldElement\n\nReturn the generator of the function field returned by the function field constructor.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"is_gen(a::Generic.FunctionFieldElem)","category":"page"},{"location":"AbstractAlgebra/function_field/#is_gen-Tuple{AbstractAlgebra.Generic.FunctionFieldElem}","page":"Rational function fields","title":"is_gen","text":"is_gen(a::FunctionFieldElem)\n\nReturn true if a is the generator of the function field returned by the function field constructor.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"coeff(::Generic.FunctionFieldElem, ::Int)\nnum_coeff(::Generic.FunctionFieldElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/function_field/#coeff-Tuple{AbstractAlgebra.Generic.FunctionFieldElem, Int64}","page":"Rational function fields","title":"coeff","text":"coeff(a::FunctionFieldElem, n::Int)\n\nReturn the degree n coefficient of the element a in its polynomial representation in terms of the generator of the function field. The coefficient is returned as an element of the underlying rational function field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/#num_coeff-Tuple{AbstractAlgebra.Generic.FunctionFieldElem, Int64}","page":"Rational function fields","title":"num_coeff","text":"num_coeff(a::FunctionFieldElem, n::Int)\n\nReturn the degree n coefficient of the numerator of the element a (in its polynomial representation in terms of the generator of the function field, rationalised as per numerator/denominator described above). The coefficient will be an polynomial over the base_ring of the underlying rational function field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> R, x = RationalFunctionField(QQ, \"x\")\n(Rational function field over rationals, x)\n\njulia> U, z = R[\"z\"]\n(Univariate polynomial ring in z over rational function field, z)\n\njulia> g = z^2 + 3*(x + 1)//(x + 2)*z + 1\nz^2 + (3*x + 3)//(x + 2)*z + 1\n\njulia> S, y = FunctionField(g, \"y\")\n(Function Field over Rationals with defining polynomial (x + 2)*y^2 + (3*x + 3)*y + x + 2, y)\n\njulia> base_field(S)\nRational function field\n over rationals\n\njulia> var(S)\n:y\n\njulia> characteristic(S)\n0\n\njulia> defining_polynomial(S)\nz^2 + (3*x + 3)//(x + 2)*z + 1\n\njulia> numerator(S)\n(x + 2)*y^2 + (3*x + 3)*y + x + 2\n\njulia> denominator(S)\nx + 2\n\njulia> a = (x + 1)//(x^2 + 1)*y + 3x + 2\n((x + 1)*y + 3*x^3 + 2*x^2 + 3*x + 2)//(x^2 + 1)\n\njulia> numerator(a, false)\n(x + 1)*y + 3*x^3 + 2*x^2 + 3*x + 2\n\njulia> denominator(a, false)\nx^2 + 1\n\njulia> degree(S)\n2\n\njulia> gen(S)\ny\n\njulia> is_gen(y)\ntrue\n\njulia> coeff(a, 1)\n(x + 1)//(x^2 + 1)\n\njulia> num_coeff(a, 1)\nx + 1","category":"page"},{"location":"AbstractAlgebra/function_field/#Trace-and-norm","page":"Rational function fields","title":"Trace and norm","text":"","category":"section"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"norm(::Generic.FunctionFieldElem)","category":"page"},{"location":"AbstractAlgebra/function_field/#norm-Tuple{AbstractAlgebra.Generic.FunctionFieldElem}","page":"Rational function fields","title":"norm","text":"norm(a::FunctionFieldElem)\n\nReturn the absolute norm of a as an element of the underlying rational function field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/function_field/","page":"Rational function fields","title":"Rational function fields","text":"julia> R, x = RationalFunctionField(QQ, \"x\")\n(Rational function field over rationals, x)\n\njulia> U, z = R[\"z\"]\n(Univariate polynomial ring in z over rational function field, z)\n\njulia> g = z^2 + 3*(x + 1)//(x + 2)*z + 1\nz^2 + (3*x + 3)//(x + 2)*z + 1\n\njulia> S, y = FunctionField(g, \"y\")\n(Function Field over Rationals with defining polynomial (x + 2)*y^2 + (3*x + 3)*y + x + 2, y)\n\njulia> f = (-3*x - 5//3)//(x - 2)*y + (x^3 + 1//9*x^2 + 5)//(x - 2)\n((-3*x - 5//3)*y + x^3 + 1//9*x^2 + 5)//(x - 2)\n\njulia> norm(f)\n(x^7 + 20//9*x^6 + 766//81*x^5 + 2027//81*x^4 + 110//3*x^3 + 682//9*x^2 + 1060//9*x + 725//9)//(x^3 - 2*x^2 - 4*x + 8)\n\njulia> tr(f)\n(2*x^4 + 38//9*x^3 + 85//9*x^2 + 24*x + 25)//(x^2 - 4)","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/#Construction-and-basic-functionality","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"","category":"section"},{"location":"Experimental/LinearQuotients/linear_quotients/#Constructor","page":"Construction and basic functionality","title":"Constructor","text":"","category":"section"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"Given a finite group Gleq operatornameGL_n(K), one can construct the corresponding linear quotient K^nG:","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"linear_quotient(G::MatrixGroup)","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/#linear_quotient-Tuple{MatrixGroup}","page":"Construction and basic functionality","title":"linear_quotient","text":"linear_quotient(G::MatrixGroup)\n\nReturn the linear quotient by G, that is, the orbit space of the action of G on the vector space of dimension degree(G).\n\nIf the given group is not finite, an error is raised.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"danger: Implicit choice of representation\nLet V = K^n be the regular representation of the matrix group G. In the current version, the object returned by linear_quotient(G) will work with the dual representation, that is, the linear quotient will be V^astG. This might change in the future (notice that this code is still considered experimental)","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"note: Root of unity\nFor many computations, we require that the base field base_ring(G) contains a primitive root of unity of order exponent(G). If your chosen field is 'too small', you can easily change the base field with map_entries(L, G), where L is the larger field.","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/#Class-group","page":"Construction and basic functionality","title":"Class group","text":"","category":"section"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"The divisor class group of a linear quotient VG is controlled by the reflections contained in the group G, see David J. Benson (1993).","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"class_group(L::LinearQuotient)","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/#class_group-Tuple{Oscar.LinearQuotient}","page":"Construction and basic functionality","title":"class_group","text":"class_group(L::LinearQuotient)\n\nReturn the class group of the linear quotient L and a map from group(L) to this group.\n\nIf G = group(L), then the class group is Ab(G/H), where H is the subgroup of G generated by the reflections.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LinearQuotients/linear_quotients/#Singularities","page":"Construction and basic functionality","title":"Singularities","text":"","category":"section"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"One can study the types of the singularities of a linear quotient as follows.","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"has_canonical_singularities(L::LinearQuotient)","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/#has_canonical_singularities-Tuple{Oscar.LinearQuotient}","page":"Construction and basic functionality","title":"has_canonical_singularities","text":"has_canonical_singularities(L::LinearQuotient)\n\nReturn true if L has canonical singularities, false otherwise.\n\nThis is checked using the Reid–Tai criterion, see Theorem 3.21 in János Kollár (2013).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LinearQuotients/linear_quotients/","page":"Construction and basic functionality","title":"Construction and basic functionality","text":"has_terminal_singularities(L::LinearQuotient)","category":"page"},{"location":"Experimental/LinearQuotients/linear_quotients/#has_terminal_singularities-Tuple{Oscar.LinearQuotient}","page":"Construction and basic functionality","title":"has_terminal_singularities","text":"has_terminal_singularities(L::LinearQuotient)\n\nReturn true if L has terminal singularities, false otherwise.\n\nThis is checked using the Reid–Tai criterion, see Theorem 3.21 in János Kollár (2013).\n\n\n\n\n\n","category":"method"},{"location":"Fields/algebraic_closure_fp/","page":"Algebraic closure of finite prime fields","title":"Algebraic closure of finite prime fields","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Fields/algebraic_closure_fp/#Algebraic-closure-of-finite-prime-fields","page":"Algebraic closure of finite prime fields","title":"Algebraic closure of finite prime fields","text":"","category":"section"},{"location":"Fields/algebraic_closure_fp/","page":"Algebraic closure of finite prime fields","title":"Algebraic closure of finite prime fields","text":"It is sometimes useful to consider various finite fields in a fixed characteristic at the same time, together with natural embeddings between these fields. The fields returned by abelian_closure are intended for that purpose.","category":"page"},{"location":"Fields/algebraic_closure_fp/","page":"Algebraic closure of finite prime fields","title":"Algebraic closure of finite prime fields","text":"algebraic_closure\next_of_degree","category":"page"},{"location":"Fields/algebraic_closure_fp/#algebraic_closure","page":"Algebraic closure of finite prime fields","title":"algebraic_closure","text":"algebraic_closure(F::FinField)\n\nLet F be a prime field of order p. Return a field K that is the union of finite fields of oder p^d, for all positive integers d. The degree d extension of F can be obtained as ext_of_degree(K, d).\n\nK is cached in F, and the fields returned by ext_of_degree are cached in K.\n\nExamples\n\njulia> K = algebraic_closure(GF(3, 1));\n\njulia> F2 = ext_of_degree(K, 2);\n\njulia> F3 = ext_of_degree(K, 3);\n\njulia> x = K(gen(F2)) + K(gen(F3));\n\njulia> degree(x)\n6\n\n\n\n\n\n","category":"function"},{"location":"Fields/algebraic_closure_fp/#ext_of_degree","page":"Algebraic closure of finite prime fields","title":"ext_of_degree","text":"ext_of_degree(A::AlgClosure, d::Int)\n\nReturn a finite field F of order p^d where p is the characteristic of K. This field is compatible with A in the sense that A(x) returns the element of A that corresponds to the element x of F.\n\n\n\n\n\n","category":"function"},{"location":"Groups/autgroup/","page":"Groups of automorphisms","title":"Groups of automorphisms","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/autgroup/#Groups-of-automorphisms","page":"Groups of automorphisms","title":"Groups of automorphisms","text":"","category":"section"},{"location":"Groups/autgroup/","page":"Groups of automorphisms","title":"Groups of automorphisms","text":"automorphism_group(G::GAPGroup)","category":"page"},{"location":"Groups/autgroup/#automorphism_group-Tuple{Oscar.GAPGroup}","page":"Groups of automorphisms","title":"automorphism_group","text":"automorphism_group(G::Group) -> A::AutomorphismGroup{T}\n\nReturn the full automorphism group of G. If f is an object of type GAPGroupHomomorphism and it is bijective from G to itself, then A(f) return the embedding of f in A.\n\nGroups of automorphisms over a group G have parametric type AutomorphismGroup{T}, where T is the type of G. \n\nExamples\n\njulia> S = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> typeof(S)\nPermGroup\n\njulia> A = automorphism_group(S)\nAut( Sym( [ 1 .. 3 ] ) )\n\njulia> typeof(A)\nAutomorphismGroup{PermGroup}\n\nThe evaluation of the automorphism f in the element x is analogous to the homomorphism evaluation: it can be obtained by typing either f(x) or x^f.\n\njulia> S = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> A = automorphism_group(S)\nAut( Sym( [ 1 .. 4 ] ) )\n\njulia> x = perm(S,[2,1,4,3])\n(1,2)(3,4)\n\njulia> f = A[2]\nPcgs([ (3,4), (2,4,3), (1,4)(2,3), (1,3)(2,4) ]) -> [ (2,3), (2,4,3), (1,3)(2,4), (1,2)(3,4) ]\n\njulia> f(x)\n(1,4)(2,3)\n\njulia> x^f\n(1,4)(2,3)\n\nIt is possible to turn an automorphism f into a homomorphism by typing hom(f).\n\njulia> S = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> A = automorphism_group(S)\nAut( Sym( [ 1 .. 4 ] ) )\n\njulia> f = A[2]\nPcgs([ (3,4), (2,4,3), (1,4)(2,3), (1,3)(2,4) ]) -> [ (2,3), (2,4,3), (1,3)(2,4), (1,2)(3,4) ]\n\njulia> typeof(f)\nAutomorphismGroupElem{PermGroup} (alias for Oscar.BasicGAPGroupElem{AutomorphismGroup{PermGroup}})\n\njulia> typeof(hom(f))\nGAPGroupHomomorphism{PermGroup, PermGroup}\n\nThe converse is also possible: if g is a bijective homomorphism from the group G to itself and A is the automorphism group of G, then the instruction A(g) returns g as automorphism of G. This is the standard way to explicitly build an automorphism (another way, available for inner automorphisms, is shown in Section Inner_automorphisms).\n\nExamples\n\njulia> S = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> a = perm(S,[2,1,4,3])\n(1,2)(3,4)\n\njulia> f = hom(S,S,x ->x^a)\nGroup homomorphism from \nSym( [ 1 .. 4 ] )\nto\nSym( [ 1 .. 4 ] )\n\njulia> A = automorphism_group(S)\nAut( Sym( [ 1 .. 4 ] ) )\n\njulia> A(f)\nMappingByFunction( Sym( [ 1 .. 4 ] ), Sym( [ 1 .. 4 ] ), )\n\nElements of A can be multiplied with other elements of A or by elements of type GAPGroupHomomorphism; in this last case, the result has type GAPGroupHomomorphism.\n\nExamples\n\njulia> S = symmetric_group(4);\n\njulia> A = automorphism_group(S);\n\njulia> g = hom(S,S,x->x^S[1]);\n\njulia> g in A\nfalse\n\njulia> au = A(g);\n\njulia> au in A\ntrue\n\njulia> g == hom(au)\ntrue\n\njulia> x = cperm(S,[1,2,3]);\n\njulia> au(x)\n(2,3,4)\n\njulia> g(x) == au(x)\ntrue\n\nIn Oscar it is possible to multiply homomorphisms and automorphisms (whenever it makes sense); in such cases, the output is always a variable of type GAPGroupHomomorphism{S,T}.\n\njulia> S = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> A = automorphism_group(S)\nAut( Sym( [ 1 .. 4 ] ) )\n\njulia> g = hom(S,S,x->x^S[1])\nGroup homomorphism from \nSym( [ 1 .. 4 ] )\nto\nSym( [ 1 .. 4 ] )\n\njulia> f = A(g)\nMappingByFunction( Sym( [ 1 .. 4 ] ), Sym( [ 1 .. 4 ] ), )\n\njulia> typeof(g*f)\nGAPGroupHomomorphism{PermGroup, PermGroup}\n\n\n\n\n\n","category":"method"},{"location":"Groups/autgroup/","page":"Groups of automorphisms","title":"Groups of automorphisms","text":"The following functions are available for automorphisms, some of them similar to the corresponding functions for homomorphisms of groups.","category":"page"},{"location":"Groups/autgroup/","page":"Groups of automorphisms","title":"Groups of automorphisms","text":"is_invariant(f::GAPGroupElem{AutomorphismGroup{T}}, H::T) where T<:GAPGroup\nrestrict_automorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::T, A=automorphism_group(H)) where T <: GAPGroup\ninduced_automorphism(f::GAPGroupHomomorphism, mH::GAPGroupHomomorphism)\nhom(x::GAPGroupElem{AutomorphismGroup{T}}) where T <: GAPGroup","category":"page"},{"location":"Groups/autgroup/#is_invariant-Union{Tuple{T}, Tuple{GAPGroupElem{AutomorphismGroup{T}}, T}} where T<:Oscar.GAPGroup","page":"Groups of automorphisms","title":"is_invariant","text":"is_invariant(f::GAPGroupElem{AutomorphismGroup{T}}, H::T)\n\nReturn whether f(H) == H.\n\n\n\n\n\n","category":"method"},{"location":"Groups/autgroup/#restrict_automorphism-Union{Tuple{T}, Tuple{GAPGroupElem{AutomorphismGroup{T}}, T}, Tuple{GAPGroupElem{AutomorphismGroup{T}}, T, Any}} where T<:Oscar.GAPGroup","page":"Groups of automorphisms","title":"restrict_automorphism","text":"restrict_automorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::T)\n\nReturn the restriction of f to H as an automorphism of H. An exception is thrown if H is not invariant under f.\n\n\n\n\n\n","category":"method"},{"location":"Groups/autgroup/#induced_automorphism-Tuple{GAPGroupHomomorphism, GAPGroupHomomorphism}","page":"Groups of automorphisms","title":"induced_automorphism","text":"induced_automorphism(f::GAPGroupHomomorphism, g::GAPGroupHomomorphism)\ninduced_automorphism(f::GAPGroupHomomorphism, g::GAPGroupElem{AutomorphismGroup{T}})\n\nReturn the automorphism h of the image of f such that h(f) == f(g), where g is an automorphism of a group G and f is a group homomorphism defined over G such that the kernel of f is invariant under g\n\n\n\n\n\n","category":"method"},{"location":"Groups/autgroup/#hom-Union{Tuple{GAPGroupElem{AutomorphismGroup{T}}}, Tuple{T}} where T<:Oscar.GAPGroup","page":"Groups of automorphisms","title":"hom","text":"hom(f::GAPGroupElem{AutomorphismGroup{T}}) where T\n\nReturn the element f of type GAPGroupHomomorphism{T,T}.\n\n\n\n\n\n","category":"method"},{"location":"Groups/autgroup/#inner_automorphisms","page":"Groups of automorphisms","title":"Inner automorphisms","text":"","category":"section"},{"location":"Groups/autgroup/","page":"Groups of automorphisms","title":"Groups of automorphisms","text":"OSCAR provides the following functions to handle inner automorphisms of a group.","category":"page"},{"location":"Groups/autgroup/","page":"Groups of automorphisms","title":"Groups of automorphisms","text":"inner_automorphism(g::GAPGroupElem)\nis_inner_automorphism(f::GAPGroupHomomorphism)\ninner_automorphism_group(A::AutomorphismGroup{T}) where T <: GAPGroup","category":"page"},{"location":"Groups/autgroup/#inner_automorphism-Tuple{GAPGroupElem}","page":"Groups of automorphisms","title":"inner_automorphism","text":"inner_automorphism(g::GAPGroupElem)\n\nReturn the inner automorphism in automorphism_group(parent(g)) defined by x -> x^g.\n\n\n\n\n\n","category":"method"},{"location":"Groups/autgroup/#is_inner_automorphism-Tuple{GAPGroupHomomorphism}","page":"Groups of automorphisms","title":"is_inner_automorphism","text":"is_inner_automorphism(f::GAPGroupHomomorphism)\nis_inner_automorphism(f::GAPGroupElem{AutomorphismGroup{T}})\n\nReturn whether f is an inner automorphism.\n\n\n\n\n\n","category":"method"},{"location":"Groups/autgroup/#inner_automorphism_group-Union{Tuple{AutomorphismGroup{T}}, Tuple{T}} where T<:Oscar.GAPGroup","page":"Groups of automorphisms","title":"inner_automorphism_group","text":"inner_automorphism_group(A::AutomorphismGroup{T})\n\nReturn the subgroup of A of the inner automorphisms.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/puiseux/#Generic-Puiseux-series","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"AbstractAlgebra.jl allows the creation of Puiseux series over any computable commutative ring R.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Puiseux series are power series of the form a_jx^jm + a_j+1x^(j+1)m + cdots + a_k-1x^(k-1)m + O(x^km) for some integer m 0 where i geq 0, a_i in R and the relative precision k - j is at most equal to some specified precision n.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"The generic Puiseux series module is implemented in src/generic/PuiseuxSeries.jl.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"As well as implementing the Series Ring interface, the Puiseux series module in AbstractAlgebra.jl implements the generic algorithms described below.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"All of the generic functionality is part of the Generic submodule of AbstractAlgebra.jl. This is exported by default so that it is not necessary to qualify function names.","category":"page"},{"location":"AbstractAlgebra/puiseux/#Types-and-parent-objects","page":"Generic Puiseux series","title":"Types and parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"The types of generic Puiseux series implemented by AbstractAlgebra.jl are Generic.PuiseuxSeriesRingElem{T} and Generic.PuiseuxSeriesFieldElem{T}.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Both series element types belong to the union type Generic.PuiseuxSeriesElem.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Puiseux series elements belong directly to either RingElem or FieldElem since it is more useful to be able to distinguish whether they belong to a ring or field than it is to distinguish that they are Puiseux series.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"The parent types for Puiseux series, Generic.PuiseuxSeriesRing{T} and Generic.PuiseuxSeriesField{T} respectively, belong to Ring and Field respectively.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"The default precision, string representation of the variable and base ring R of a generic Puiseux series are stored in its parent object.","category":"page"},{"location":"AbstractAlgebra/puiseux/#Puiseux-series-ring-constructors","page":"Generic Puiseux series","title":"Puiseux series ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"In order to construct Puiseux series in AbstractAlgebra.jl, one must first construct the ring itself. This is accomplished with any of the following constructors.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"PuiseuxSeriesRing(R::Ring, prec_max::Int, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"PuiseuxSeriesRing(R::Field, prec_max::Int, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"PuiseuxSeriesField(R::Field, prec_max::Int, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Given a base ring R, a maximum relative precision and a string s specifying how the generator (variable) should be printed, return a tuple S, x representing the Puiseux series ring and its generator.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"By default, S will depend only on S, x and the maximum precision and will be cached. Setting the optional argument cached to false will prevent this.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Here are some examples of constructing various kinds of Puiseux series rings and coercing various elements into those rings.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"julia> R, x = PuiseuxSeriesRing(ZZ, 10, \"x\")\n(Puiseux series ring in x over integers, x + O(x^11))\n\njulia> S, y = PuiseuxSeriesField(QQ, 10, \"y\")\n(Puiseux series field in y over rationals, y + O(y^11))\n\njulia> f = R()\nO(x^10)\n\njulia> g = S(123)\n123 + O(y^10)\n\njulia> h = R(BigInt(1234))\n1234 + O(x^10)\n\njulia> k = S(y + 1)\n1 + y + O(y^10)\n","category":"page"},{"location":"AbstractAlgebra/puiseux/#Big-oh-notation","page":"Generic Puiseux series","title":"Big-oh notation","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Series elements can be given a precision using the big-oh notation. This is provided by a function of the following form, (or something equivalent for Laurent series):","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"O(x::SeriesElem)","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"julia> R, x = PuiseuxSeriesRing(ZZ, 10, \"x\")\n(Puiseux series ring in x over integers, x + O(x^11))\n\njulia> f = 1 + 2x + O(x^5)\n1 + 2*x + O(x^5)\n\njulia> g = 2x^(1//3) + 7x^(2//3) + O(x^(7//3))\n2*x^(1//3) + 7*x^(2//3) + O(x^(7//3))","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"What is happening here in practice is that O(x^n) is creating the series 0 + O(x^n) and the rules for addition of series dictate that if this is added to a series of greater precision, then the lower of the two precisions must be used.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Of course it may be that the precision of the series that O(x^n) is added to is already lower than n, in which case adding O(x^n) has no effect. This is the case if the default precision is too low, since x on its own has the default precision.","category":"page"},{"location":"AbstractAlgebra/puiseux/#Puiseux-series-implementation","page":"Generic Puiseux series","title":"Puiseux series implementation","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Puiseux series have their maximum relative precision capped at some value prec_max. This refers to the internal Laurent series used to store the Puiseux series, i.e. the series without denominators in the exponents.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"The Puiseux series type stores such a Laurent series and a scale or denominator for the exponents. For example, f(x) = 1 + x^13 + 2x^23 + O(x^73) would be stored as a Laurent series 1 + x + 2x^2 + O(x^7) and a scale of 3..","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"The maximum precision is also used as a default (Laurent) precision in the case of coercing coefficients into the ring and for any computation where the result could mathematically be given to infinite precision.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"In all models we say that two Puiseux series are equal if they agree up to the minimum absolute precision of the two power series.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Thus, for example, x^5 + O(x^10) == 0 + O(x^5), since the minimum absolute precision is 5.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Sometimes it is necessary to compare Puiseux series not just for arithmetic equality, as above, but to see if they have precisely the same precision and terms. For this purpose we introduce the isequal function.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"For example, if f = x^2 + O(x^7) and g = x^2 + O(x^8) and h = 0 + O(x^2) then f == g, f == h and g == h, but isequal(f, g), isequal(f, h) and isequal(g, h) would all return false. However, if k = x^2 + O(x^7) then isequal(f, k) would return true.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"There are a number of technicalities that must be observed when working with Puiseux series. As these are the same as for the other series rings in AbstractAlgebra.jl, we refer the reader to the documentation of series rings for information about these issues.","category":"page"},{"location":"AbstractAlgebra/puiseux/#Basic-ring-functionality","page":"Generic Puiseux series","title":"Basic ring functionality","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"All Puiseux series provide the functionality described in the Ring and Series Ring interfaces with the exception of the pol_length and polcoeff functions. Naturally the set_precision!, set_valuation! and coeff functions can take a rational exponent.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"julia> S, x = PuiseuxSeriesRing(ZZ, 10, \"x\")\n(Puiseux series ring in x over integers, x + O(x^11))\n\njulia> f = 1 + 3x + x^3 + O(x^10)\n1 + 3*x + x^3 + O(x^10)\n\njulia> g = 1 + 2x^(1//3) + x^(2//3) + O(x^(7//3))\n1 + 2*x^(1//3) + x^(2//3) + O(x^(7//3))\n\njulia> h = zero(S)\nO(x^10)\n\njulia> k = one(S)\n1 + O(x^10)\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> coeff(g, 1//3)\n2\n\njulia> U = base_ring(S)\nIntegers\n\njulia> v = var(S)\n:x\n\njulia> T = parent(x + 1)\nPuiseux series ring in x over integers\n\njulia> g == deepcopy(g)\ntrue\n\njulia> t = divexact(2g, 2)\n1 + 2*x^(1//3) + x^(2//3) + O(x^(7//3))\n\njulia> p = precision(f)\n10//1\n","category":"page"},{"location":"AbstractAlgebra/puiseux/#Puiseux-series-functionality-provided-by-AbstractAlgebra.jl","page":"Generic Puiseux series","title":"Puiseux series functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"The functionality below is automatically provided by AbstractAlgebra.jl for any Puiseux series.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Of course, modules are encouraged to provide specific implementations of the functions described here, that override the generic implementation.","category":"page"},{"location":"AbstractAlgebra/puiseux/#Basic-functionality","page":"Generic Puiseux series","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"coeff(a::Generic.PuiseuxSeriesElem, n::Int)","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"coeff(a::Generic.PuiseuxSeriesElem, n::Rational{Int})","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Return the coefficient of the term of exponent n of the given power series. If n exceeds the current precision of the power series or does not correspond to a nonzero term of the Puiseux series, the function returns a zero coefficient.","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"modulus{T <: ResElem}(::Generic.PuiseuxSeriesElem{T})","category":"page"},{"location":"AbstractAlgebra/puiseux/#modulus-Union{Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}}}, Tuple{T}} where T<:ResElem","page":"Generic Puiseux series","title":"modulus","text":"modulus(a::Generic.PuiseuxSeriesElem{T}) where {T <: ResElem}\n\nReturn the modulus of the coefficients of the given Puiseux series.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"is_gen(::Generic.PuiseuxSeriesElem)","category":"page"},{"location":"AbstractAlgebra/puiseux/#is_gen-Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}} where T<:RingElement}","page":"Generic Puiseux series","title":"is_gen","text":"is_gen(a::Generic.PuiseuxSeriesElem)\n\nReturn true if the given Puiseux series is arithmetically equal to the generator of its Puiseux series ring to its current precision, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"julia> R, t = PuiseuxSeriesRing(QQ, 10, \"t\")\n(Puiseux series field in t over rationals, t + O(t^11))\n\njulia> S, x = PuiseuxSeriesRing(R, 30, \"x\")\n(Puiseux series field in x over puiseux series field, x + O(x^31))\n\njulia> a = O(x^4)\nO(x^4)\n\njulia> b = (t + 3)*x + (t^2 + 1)*x^2 + O(x^4)\n(3 + t + O(t^10))*x + (1 + t^2 + O(t^10))*x^2 + O(x^4)\n\njulia> k = is_gen(gen(R))\ntrue\n\njulia> m = is_unit(-1 + x^(1//3) + 2x^2)\ntrue\n\njulia> n = valuation(a)\n4//1\n\njulia> p = valuation(b)\n1//1\n\njulia> c = coeff(b, 2)\n1 + t^2 + O(t^10)\n","category":"page"},{"location":"AbstractAlgebra/puiseux/#Division","page":"Generic Puiseux series","title":"Division","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Base.inv(::Generic.PuiseuxSeriesElem)","category":"page"},{"location":"AbstractAlgebra/puiseux/#inv-Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}} where T<:RingElement}","page":"Generic Puiseux series","title":"inv","text":"Base.inv(a::PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the inverse of the power series a, i.e. 1a, if it exists. Otherwise an exception is raised.\n\n\n\n\n\n inv(a::LocElem{T}, checked::Bool = true) where {T <: RingElem}\n\nReturns the inverse element of a if a is a unit. If 'checked = false' the invertibility of a is not checked and the corresponding inverse element of the Fraction Field is returned.\n\n\n\n\n\ninv(f::EllCrvIso) -> EllCrvIso\n\nReturn the inverse of the isomorphism f.\n\n\n\n\n\ninv(M::MatrixElem{T}) where {T <: RingElement}\n\nGiven a non-singular ntimes n matrix over a ring, return an ntimes n matrix X such that MX = I_n, where I_n is the ntimes n identity matrix. If M is not invertible over the base ring an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"julia> R, x = PuiseuxSeriesRing(QQ, 30, \"x\")\n(Puiseux series field in x over rationals, x + O(x^31))\n\njulia> a = 1 + x + 2x^2 + O(x^5)\n1 + x + 2*x^2 + O(x^5)\n\njulia> b = R(-1)\n-1 + O(x^30)\n\njulia> c = inv(a)\n1 - x - x^2 + 3*x^3 - x^4 + O(x^5)\n\njulia> d = inv(b)\n-1 + O(x^30)\n","category":"page"},{"location":"AbstractAlgebra/puiseux/#Derivative-and-integral","page":"Generic Puiseux series","title":"Derivative and integral","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"derivative(a::Generic.PuiseuxSeriesElem)\nintegral(a::Generic.PuiseuxSeriesElem)","category":"page"},{"location":"AbstractAlgebra/puiseux/#derivative-Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}} where T<:RingElement}","page":"Generic Puiseux series","title":"derivative","text":"derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the derivative of the given Puiseux series a.\n\n\n\n\n\nderivative(f::AbsPowerSeriesRingElem{T})\n\nReturn the derivative of the power series f.\n\n\n\n\n\nderivative(f::RelPowerSeriesRingElem{T})\n\nReturn the derivative of the power series f.\n\njulia> R, x = power_series_ring(QQ, 10, \"x\")\n(Univariate power series ring in x over Rationals, x + O(x^11))\n\njulia> f = 2 + x + 3x^3\n2 + x + 3*x^3 + O(x^10)\n\njulia> derivative(f)\n1 + 9*x^2 + O(x^9)\n\n\n\n\n\nderivative(f::AbstractAlgebra.MPolyRingElem{T}, j::Int) where {T <: RingElement}\n\nReturn the partial derivative of f with respect to j-th variable of the polynomial ring.\n\n\n\n\n\nderivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.\n\n\n\n\n\nderivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem\n\nReturn the derivative of x with respect to the variable of index n.\n\n\n\n\n\nderivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem\n\nReturn the derivative of x with respect to the variable v.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/#integral-Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}} where T<:RingElement}","page":"Generic Puiseux series","title":"integral","text":"integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the integral of the given Puiseux series a.\n\n\n\n\n\nintegral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(f::AbsPowerSeriesRingElem{T})\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(f::RelPowerSeriesRingElem{T})\n\nReturn the integral of the power series f.\n\njulia> R, x = power_series_ring(QQ, 10, \"x\")\n(Univariate power series ring in x over Rationals, x + O(x^11))\n\njulia> f = 2 + x + 3x^3\n2 + x + 3*x^3 + O(x^10)\n\njulia> integral(f)\n2*x + 1//2*x^2 + 3//4*x^4 + O(x^11)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"julia> R, x = PuiseuxSeriesRing(QQ, 10, \"x\")\n(Puiseux series field in x over rationals, x + O(x^11))\n\njulia> f = x^(5//3) + x^(7//3) + x^(11//3)\nx^(5//3) + x^(7//3) + x^(11//3) + O(x^5)\n\njulia> derivative(f)\n5//3*x^(2//3) + 7//3*x^(4//3) + 11//3*x^(8//3) + O(x^4)\n\njulia> derivative(integral(f)) == f\ntrue","category":"page"},{"location":"AbstractAlgebra/puiseux/#Special-functions","page":"Generic Puiseux series","title":"Special functions","text":"","category":"section"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Base.log(a::Generic.PuiseuxSeriesElem)\nBase.exp(a::Generic.PuiseuxSeriesElem)","category":"page"},{"location":"AbstractAlgebra/puiseux/#log-Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}} where T<:RingElement}","page":"Generic Puiseux series","title":"log","text":"log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the logarithm of the given Puiseux series a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/#exp-Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}} where T<:RingElement}","page":"Generic Puiseux series","title":"exp","text":"exp(a::Generic.LaurentSeriesElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the exponential of the given Puiseux series a.\n\n\n\n\n\nexp(a::AbsPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::RelPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Base.sqrt(a::Generic.PuiseuxSeriesElem)","category":"page"},{"location":"AbstractAlgebra/puiseux/#sqrt-Tuple{Union{AbstractAlgebra.Generic.PuiseuxSeriesFieldElem{T}, AbstractAlgebra.Generic.PuiseuxSeriesRingElem{T}} where T<:RingElement}","page":"Generic Puiseux series","title":"sqrt","text":"sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of the given Puiseux series a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nBase.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of f. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.\n\n\n\n\n\nBase.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S, x = PuiseuxSeriesRing(R, 30, \"x\")\n(Puiseux series ring in x over univariate polynomial ring, x + O(x^31))\n\njulia> T, z = PuiseuxSeriesRing(QQ, 30, \"z\")\n(Puiseux series field in z over rationals, z + O(z^31))\n\njulia> a = 1 + z + 3z^2 + O(z^5)\n1 + z + 3*z^2 + O(z^5)\n\njulia> b = z + 2z^2 + 5z^3 + O(z^5)\nz + 2*z^2 + 5*z^3 + O(z^5)\n\njulia> c = exp(x + O(x^40))\n1 + x + 1//2*x^2 + 1//6*x^3 + 1//24*x^4 + 1//120*x^5 + 1//720*x^6 + 1//5040*x^7 + 1//40320*x^8 + 1//362880*x^9 + 1//3628800*x^10 + 1//39916800*x^11 + 1//479001600*x^12 + 1//6227020800*x^13 + 1//87178291200*x^14 + 1//1307674368000*x^15 + 1//20922789888000*x^16 + 1//355687428096000*x^17 + 1//6402373705728000*x^18 + 1//121645100408832000*x^19 + 1//2432902008176640000*x^20 + 1//51090942171709440000*x^21 + 1//1124000727777607680000*x^22 + 1//25852016738884976640000*x^23 + 1//620448401733239439360000*x^24 + 1//15511210043330985984000000*x^25 + 1//403291461126605635584000000*x^26 + 1//10888869450418352160768000000*x^27 + 1//304888344611713860501504000000*x^28 + 1//8841761993739701954543616000000*x^29 + 1//265252859812191058636308480000000*x^30 + O(x^31)\n\njulia> d = divexact(x, exp(x + O(x^40)) - 1)\n1 - 1//2*x + 1//12*x^2 - 1//720*x^4 + 1//30240*x^6 - 1//1209600*x^8 + 1//47900160*x^10 - 691//1307674368000*x^12 + 1//74724249600*x^14 - 3617//10670622842880000*x^16 + 43867//5109094217170944000*x^18 - 174611//802857662698291200000*x^20 + 77683//14101100039391805440000*x^22 - 236364091//1693824136731743669452800000*x^24 + 657931//186134520519971831808000000*x^26 - 3392780147//37893265687455865519472640000000*x^28 + O(x^29)\n\njulia> f = exp(b)\n1 + z + 5//2*z^2 + 43//6*z^3 + 193//24*z^4 + O(z^5)\n\njulia> h = sqrt(a)\n1 + 1//2*z + 11//8*z^2 - 11//16*z^3 - 77//128*z^4 + O(z^5)\n","category":"page"},{"location":"DeveloperDocumentation/documentation/#Documenting-OSCAR-code","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"","category":"section"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"The general philosophy of the OSCAR documentation is to put as much of the information as possible into the docstrings and only use the doc pages for collecting this information and provide some additional general context. Exceptions to this philosophy are the developer and general pages.","category":"page"},{"location":"DeveloperDocumentation/documentation/#Docstrings-of-exported-functions","page":"Documenting OSCAR code","title":"Docstrings of exported functions","text":"","category":"section"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"Exported function should have docstrings, which look like","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"@doc raw\"\"\"\n functionname(x::ArgumentType, b::OtherArgument; c::Keyword = default) -> Int, Int\n\nA short description of the function. It is allowed to use $\\LaTeX$.\n\"\"\"\nfunctionname(x...,b...; c = ...)","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"If the signature is too long, use linebreaks to fit 80 characters.","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"Please also do provide an example within the docstring if possible, preferably as a jldoctest, i.e.","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"@doc raw\"\"\"\n functionname(x::ArgumentType, b::OtherArgument; c::Keyword = default) -> Int, Int\n\nA short description of the function. It is allowed to use $\\LaTeX$.\n\n# Examples\nThis shows that `functionname` does the right thing for input `input`\n```jldoctest\njulia> input = ...\n\njulia> functionname(input)\noutput\n```\n\"\"\"\nfunctionname(x...,b...; c = ...)","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"This allows the user to immediately see how the function can be used, gives them some code that they can copy-paste and manipulate, and, as a bonus, provides a testcase as well.","category":"page"},{"location":"DeveloperDocumentation/documentation/#The-folder-docs","page":"Documenting OSCAR code","title":"The folder docs","text":"","category":"section"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"The folder docs/src contains the OSCAR documentation website. Most of the pages are relatively sparse and consist of","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"```@docs\nsome_function\nsome_other_function\n[...]\n```","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"blocks that simply pull in the docstring from the corresponding source file. If you add a new page in docs/src, you will have to modify docs/doc.main to include your new page in the appropriate place.","category":"page"},{"location":"DeveloperDocumentation/documentation/#Building-the-OSCAR-documentation-with-Oscar.build_doc","page":"Documenting OSCAR code","title":"Building the OSCAR documentation with Oscar.build_doc","text":"","category":"section"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"note: Previewing the documentation\nOnce you have created a pull request it is possible to preview the documentation on github using the link https://docs.oscar-system.org/previews/PR/ where you insert the number of your PR for prnumber. Alternatively you can look at the github actions tab of your PR and click the details link next to the documenter/deploy action. There are a few conditions for this to work:No conflicts with the master branch.\nDocumentation action is successful, i.e. no doctest errors.\nThe branch for the PR is in the main oscar-system/Oscar.jl repository.You can still build the documentation locally with the commands described below.","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"build_doc","category":"page"},{"location":"DeveloperDocumentation/documentation/#build_doc","page":"Documenting OSCAR code","title":"build_doc","text":"build_doc(; doctest=false, strict=false, open_browser=true)\n\nBuild the manual of Oscar.jl locally and open the front page in a browser.\n\nThe optional parameter doctest can take three values:\n\nfalse: Do not run the doctests (default).\ntrue: Run the doctests and report errors.\n:fix: Run the doctests and replace the output in the manual with the output produced by Oscar. Please use this option carefully.\n\nIn GitHub Actions the Julia version used for building the manual is 1.9 and doctests are run with >= 1.7. Using a different Julia version may produce errors in some parts of Oscar, so please be careful, especially when setting doctest=:fix.\n\nThe optional parameter strict is passed on to makedocs of Documenter.jl and if set to true then according to the manual of Documenter.jl \"a doctesting error will always make makedocs throw an error in this mode\".\n\nTo prevent the opening of the browser at the end, set the optional parameter open_browser to false.\n\nWhen working on the manual the Revise package can significantly sped up running build_doc. First, install Revise in the following way:\n\nusing Pkg ; Pkg.add(\"Revise\")\n\nSecond, restart Julia and load Revise before Oscar:\n\nusing Revise, Oscar;\n\nThe first run of build_doc will take the usual few minutes, subsequently runs will be significantly faster.\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"Please also read the section below on repairing the jldoctests using build_doc.","category":"page"},{"location":"DeveloperDocumentation/documentation/#Automatically-repairing-jldoctests","page":"Documenting OSCAR code","title":"Automatically repairing jldoctests","text":"","category":"section"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"It is possible to have julia fix the output of all jldoctests when your changes to the code entail changes to the output. Just run the following command:","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"build_doc(doctest = :fix)","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"danger: Danger\nPlease use this command carefully:Make sure to only commit the changes to the doctests originating from your changes to the code.\nThe doctests also serve as actual tests, so make absolutely sure that the output is still mathematically correct.","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"tip: Tip\nIf this command fails with an error message indicating lacking permissions to change AbstractAlgebra.jl related docs, it may help to run the following command:]dev AbstractAlgebra","category":"page"},{"location":"DeveloperDocumentation/documentation/#Updating-the-bibliography","page":"Documenting OSCAR code","title":"Updating the bibliography","text":"","category":"section"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"When editing docs/oscar_references.bib please follow the style of the existing entries. An easy way to do that is to add your new BibTeX entry, then run bibtool by invoking it as follows from the root directory of the Oscar.jl repository:","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"bibtool docs/oscar_references.bib -o docs/oscar_references.bib","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"For every pull request on github, the CI checks if running bibtool leads to changes in the bibliography. If so, this test fails and indicates that the (recently) added bibliography entries are not standardized. For a merge, it is not required that this test is passed. Still, please feel encouraged to fix this failure by running bibtool locally as explained above.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"General/architecture/#Architecture","page":"Architecture","title":"Architecture","text":"","category":"section"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"This page aims to give a short technical overview of the architecture of OSCAR. A more in-depth overview of the various components of OSCAR is given on the OSCAR homepage.","category":"page"},{"location":"General/architecture/#Julia-packages","page":"Architecture","title":"Julia packages","text":"","category":"section"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"OSCAR is developed as a pure julia package Oscar.jl and builds on the features and interfaces provided by the julia packages for the cornerstones:","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"ANTIC: AbstractAlgebra.jl, Hecke.jl, Nemo.jl\nGAP.jl\nPolymake.jl\nSingular.jl","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"The packages are integrated into the julia package manager and will be installed automatically as dependencies of OSCAR. They can be accessed directly by their names once OSCAR is loaded.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"The current versions of these packages can be inspected with the Oscar.versioninfo command:","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"Oscar.versioninfo()","category":"page"},{"location":"General/architecture/#Binary-packages-for-non-julia-libraries","page":"Architecture","title":"Binary packages for non-julia libraries","text":"","category":"section"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"In addition to the pure julia packages, OSCAR builds on many non-julia libraries for the cornerstones (FLINT, GAP, polymake, Singular) and their dependencies.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"Both Polymake.jl and Singular.jl use CxxWrap.jl together with the corresponding libcxxwrap-julia library as an intermediate layer between the julia packages and the C / C++ libraries.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"All dependencies have been integrated into the BinaryBuilder ecosystem which provides precompiled binaries for all supported architectures. The build-recipes are maintained in julia's Yggdrasil repository. These are used to automatically build binary artifacts together with the corresponding jll packages which allow automatic installation of all required binaries as dependencies for OSCAR.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"The binary packages can be found under the JuliaBinaryWrappers organization. Each repository has an autogenerated Readme file which gives some details on the original sources, supported platforms, and dependencies.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"The Oscar.versioninfo function can also include the versions of all binary packages that are maintained by the OSCAR developers:","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"Oscar.versioninfo(jll=true)","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"For a full list of all dependencies of the current project please use using Pkg; Pkg.status(mode=PKGMODE_MANIFEST) or the Pkg REPL command ]st -m.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"versioninfo","category":"page"},{"location":"General/architecture/#versioninfo","page":"Architecture","title":"versioninfo","text":"Oscar.versioninfo(io::IO=stdout; branch=false, jll=false, julia=false, commit=false, full=false)\n\nPrint the versions of all Oscar-related dependencies.\n\nArguments\n\nbranch::Bool=false: include git branch name in the output\ncommit::Bool=false: include git commit hash and date where applicable\njll::Bool=false : include binary packages (jll) in the output\njulia::Bool=false : include julia versioninfo output\nfull::Bool=false : include all of the above\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Univariate-Polynomial-Ring-Interface","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Univariate polynomial rings are supported in AbstractAlgebra, and in addition to the standard Ring interface, numerous additional functions are required to be present for univariate polynomial rings.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Univariate polynomial rings can be built over both commutative and noncommutative rings.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Univariate polynomial rings over a field are also Euclidean and therefore such rings must implement the Euclidean interface.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Since a sparse distributed multivariate format can generally also handle sparse univariate polynomials, the univariate polynomial interface is designed around the assumption that they are dense. This is not a requirement, but it may be easier to use the multivariate interface for sparse univariate types.","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Types-and-parents","page":"Univariate Polynomial Ring Interface","title":"Types and parents","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"AbstractAlgebra provides two abstract types for polynomial rings and their elements over a commutative ring:","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"PolyRing{T} is the abstract type for univariate polynomial ring parent types\nPolyRingElem{T} is the abstract type for univariate polynomial types","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Similarly there are two abstract types for polynomial rings and their elements over a noncommutative ring:","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"NCPolyRing{T} is the abstract type for univariate polynomial ring parent types\nNCPolyRingElem{T} is the abstract type for univariate polynomial types","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"We have that PolyRing{T} <: Ring and PolyRingElem{T} <: RingElem. Similarly we have that NCPolyRing{T} <: NCRing and NCPolyRingElem{T} <: NCRingElem.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Note that the abstract types are parameterised. The type T should usually be the type of elements of the coefficient ring of the polynomial ring. For example, in the case of mathbbZx the type T would be the type of an integer, e.g. BigInt.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"If the parent object for such a ring has type MyZX and polynomials in that ring have type MyZXPoly then one would have:","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"MyZX <: PolyRing{BigInt}\nMyZXPoly <: PolyRingElem{BigInt}","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Polynomial rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Polynomial rings should at least be distinguished based on their base (coefficient) ring. But if they have the same base ring and symbol (for their variable/generator), they should certainly have the same parent object.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Required-functionality-for-univariate-polynomials","page":"Univariate Polynomial Ring Interface","title":"Required functionality for univariate polynomials","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"In addition to the required functionality for the Ring/NCRing interface (and in the case of polynomials over a field, the Euclidean Ring interface), the Polynomial Ring interface has the following required functions.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"We suppose that R is a fictitious base ring (coefficient ring) and that S is a univariate polynomial ring over R (i.e. S = Rx) with parent object S of type MyPolyRing{T}. We also assume the polynomials in the ring have type MyPoly{T}, where T is the type of elements of the base (coefficient) ring.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Note that the type T must (transitively) belong to the abstract type RingElem or NCRingElem.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"We describe the functionality below for polynomials over commutative rings, i.e. with element type belonging to RingElem, however similar constructors should be available for element types belonging to NCRingElem instead, if the coefficient ring is noncommutative.","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Constructors","page":"Univariate Polynomial Ring Interface","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"In addition to the standard constructors, the following constructors, taking an array of coefficients, must be available.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"(S::MyPolyRing{T})(A::Vector{T}) where T <: RingElem\n(S::MyPolyRing{T})(A::Vector{U}) where T <: RingElem, U <: RingElem\n(S::MyPolyRing{T})(A::Vector{U}) where T <: RingElem, U <: Integer","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Create the polynomial in the given ring whose degree i coefficient is given by A[1 + i]. The elements of the array are assumed to be able to be coerced into the base ring R. If the argument is an empty vector, the zero polynomial shall be returned.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"It may be desirable to have a additional version of the function that accepts an array of Julia Int values if this can be done more efficiently.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"It is also possible to create polynomials directly without first creating the corresponding polynomial ring.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"polynomial(R::Ring, arr::Vector{T}, var::VarName=:x; cached::Bool=true)","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Given an array of coefficients construct the polynomial with those coefficients over the given ring and with the given variable.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"note: Note\nIf cached is set to false then the parent ring of the created polynomial is not cached. However, this means that subsequent polynomials created in the same way will not be compatible. Instead, one should use the parent object of the first polynomial to create subsequent polynomials instead of calling this function repeatedly with cached=false.","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Data-type-and-parent-object-methods","page":"Univariate Polynomial Ring Interface","title":"Data type and parent object methods","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"var(S::MyPolyRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Return a Symbol representing the variable (generator) of the polynomial ring. Note that this is a Symbol not a String, though its string value will usually be used when printing polynomials.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"symbols(S::MyPolyRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Return the array [s] where s is a Symbol representing the variable of the given polynomial ring. This is provided for uniformity with the multivariate interface, where there is more than one variable and hence an array of symbols.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"dense_poly_type(::Type{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Return the type of a polynomial whose coefficients have the given type. In our example MyPoly{T}.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"This function is defined for generic polynomials and only needs to be defined for custom polynomial rings, e.g. ones defined by a C implementation.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"polynomial_ring_only(R::Ring, s::Symbol; cached::Bool=true)","category":"page"},{"location":"AbstractAlgebra/poly_interface/#polynomial_ring_only-Tuple{Ring, Symbol}","page":"Univariate Polynomial Ring Interface","title":"polynomial_ring_only","text":"polynomial_ring_only(R::NCRing, s::Symbol; cached::Bool=true)\n\nLike polynomial_ring(R::NCRing, s::Symbol) but return only the polynomial ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"The default implementation figures out the appropriate polynomial ring type via dense_poly_type and calls its constructor with R, s, cached as arguments. In our example, this would be","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"MyPolyRing{T}(R, s, cached)","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Accordingly, polynomial_ring_only only needs to be defined, if such a constructor does not exist or other behaviour is wanted.","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Basic-manipulation-of-rings-and-elements","page":"Univariate Polynomial Ring Interface","title":"Basic manipulation of rings and elements","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"length(f::MyPoly{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Return the length of the given polynomial. The length of the zero polynomial is defined to be 0, otherwise the length is the degree plus 1. The return value should be of type Int.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"set_length!(f::MyPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"This function must zero any coefficients beyond the requested length n and then set the length of the polynomial to n. This function does not need to normalise the polynomial and is not useful to the user, but is used extensively by the AbstractAlgebra generic functionality.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"This function returns the resulting polynomial.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"coeff(f::MyPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Return the coefficient of the polynomial f of degree n. If n is larger than the degree of the polynomial, it should return zero in the coefficient ring. ","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"setcoeff!(f::MyPoly{T}, n::Int, a::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Set the degree n coefficient of f to a. This mutates the polynomial in-place if possible and returns the mutated polynomial (so that immutable types can also be supported). The function must not assume that the polynomial already has space for n + 1 coefficients. The polynomial must be resized if this is not the case.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Note that this function is not required to normalise the polynomial and is not necessarily useful to the user, but is used extensively by the generic functionality in AbstractAlgebra.jl. It is for setting raw coefficients in the representation.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"normalise(f::MyPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Given a polynomial whose length is currently n, including any leading zero coefficients, return the length of the normalised polynomial (either zero or the length of the polynomial with nonzero leading coefficient). Note that the function does not actually perform the normalisation.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"fit!(f::MyPoly{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Ensure that the polynomial f internally has space for n coefficients. This function must mutate the function in-place if it is mutable. It does not return the mutated polynomial. Immutable types can still be supported by defining this function to do nothing.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Some interfaces for C polynomial types automatically manage the internal allocation of polynomials in every function that can be called on them. Explicit adjustment by the generic code in AbstractAlgebra.jl is not required. In such cases, this function can also be defined to do nothing.","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Optional-functionality-for-polynomial-rings","page":"Univariate Polynomial Ring Interface","title":"Optional functionality for polynomial rings","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Sometimes parts of the Euclidean Ring interface can and should be implemented for polynomials over a ring that is not necessarily a field.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"When divisibility testing can be implemented for a polynomial ring over a field, it should be possible to implement the following functions from the Euclidean Ring interface:","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"divides\nremove\nvaluation","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"When the given polynomial ring is a GCD domain, with an effective GCD algorithm, it may be possible to implement the following functions:","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"gcd\nlcm","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Polynomial rings can optionally implement any part of the generic univariate polynomial functionality provided by AbstractAlgebra.jl, using the same interface. ","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Obviously additional functionality can also be added to that provided by AbstractAlgebra.jl on an ad hoc basis.","category":"page"},{"location":"AbstractAlgebra/poly_interface/#Similar","page":"Univariate Polynomial Ring Interface","title":"Similar","text":"","category":"section"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"The similar function is available for all univariate polynomial types, but new polynomial rings can define a specialised version of it if required.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"similar(x::MyPoly{T}, R::Ring=base_ring(x), var::VarName=var(parent(x))) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Construct the zero polynomial with the given variable and coefficients in the given ring, if specified, and with the defaults shown if not.","category":"page"},{"location":"AbstractAlgebra/poly_interface/","page":"Univariate Polynomial Ring Interface","title":"Univariate Polynomial Ring Interface","text":"Custom polynomial rings may choose which polynomial type is best-suited to return for any given arguments. If they don't specialise the function the default polynomial type returned is a Generic.Poly.","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"CurrentModule = Oscar","category":"page"},{"location":"Combinatorics/matroids/#Matroids","page":"Matroids","title":"Matroids","text":"","category":"section"},{"location":"Combinatorics/matroids/#Introduction","page":"Matroids","title":"Introduction","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"Matroids are a fundamental combinatorial object with connections to various fields of mathematics. It is an abstraction of linear independence in vector spaces and forests in graphs. One way to define a matroid is via the following two sets of data:","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"a finite ground set E = 1ldotsn and\na nonempty finite set mathcalB subseteq mathcalP(E) of bases satisfying an exchange property.","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"There are however many equivalent ways to define a matroid. One can also define a matroid via its circuits, hyperplanes, a graph, or a matrix. For a detailed introduction of matroids we refer to the textbook James Oxley (2011).","category":"page"},{"location":"Combinatorics/matroids/#Construction","page":"Matroids","title":"Construction","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"matroid_from_bases(bases::AbstractVector{T}, nelements::IntegerUnion; check::Bool=true) where T<:GroundsetType\nmatroid_from_nonbases(nonbases::AbstractVector{T}, nelements::IntegerUnion; check::Bool=true) where T<:GroundsetType\nmatroid_from_circuits(circuits::AbstractVector{T}, nelements::IntegerUnion) where T<:GroundsetType\nmatroid_from_hyperplanes(hyperplanes::AbstractVector{T}, nelements::IntegerUnion) where T<:GroundsetType\nmatroid_from_matrix_columns(A::MatrixElem; check::Bool=true)\nmatroid_from_matrix_rows(A::MatrixElem, ; check::Bool=true)\ncycle_matroid(g::Graph)\nbond_matroid(g::Graph)\ncocycle_matroid(g::Graph)\nMatroid(pm_matroid::Polymake.BigObjectAllocated, E::GroundsetType=Vector{Integer}(1:pm_matroid.N_ELEMENTS))\nmatroid_from_revlex_basis_encoding(rvlx::String, r::IntegerUnion, n::IntegerUnion)","category":"page"},{"location":"Combinatorics/matroids/#matroid_from_bases-Union{Tuple{T}, Tuple{AbstractVector{T}, Union{Integer, ZZRingElem}}} where T<:Union{AbstractSet, AbstractVector}","page":"Matroids","title":"matroid_from_bases","text":"matroid_from_bases(B, [n, E])\n\nArguments\n\nB::AbstractVector: The set of bases of the matroid.\nn::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.\nE::AbstractVector: An explicit ground set passed as vector.\n\nConstruct a matroid with bases B on the ground set E (which can be the empty set). The set B is a non-empty collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n.\n\nSee Section 1.2 of James Oxley (2011).\n\nExamples\n\nTo construct a rank two matroid with five bases on four elements you can write:\n\njulia> B = [[1,2],[1,3],[1,4],[2,3],[2,4]];\n\njulia> M = matroid_from_bases(B,4)\nMatroid of rank 2 on 4 elements\n\nTo construct the same matroid on the four elements 1,2,i,j you may write:\n\njulia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j'])\nMatroid of rank 2 on 4 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#matroid_from_nonbases-Union{Tuple{T}, Tuple{AbstractVector{T}, Union{Integer, ZZRingElem}}} where T<:Union{AbstractSet, AbstractVector}","page":"Matroids","title":"matroid_from_nonbases","text":"matroid_from_nonbases(N, [n, E])\n\nArguments\n\nN::AbstractVector: The set of nonbases of the matroid.\nn::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.\nE::AbstractVector: An explicit ground set passed as vector.\n\nConstruct a matroid with nonbases N on the ground set E (which can be the empty set). That means that the matroid has as bases all subsets of the size |N[1]| of the ground set that are not in N. The set N can't be empty in this function. The described complement of N needs to be a non-empty collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n.\n\nSee Section 1.2 of James Oxley (2011).\n\nExamples\n\nTo construct the Fano matroid you may write:\n\njulia> H = [[1,2,4],[2,3,5],[1,3,6],[3,4,7],[1,5,7],[2,6,7],[4,5,6]];\n\njulia> M = matroid_from_nonbases(H,7)\nMatroid of rank 3 on 7 elements\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#matroid_from_circuits-Union{Tuple{T}, Tuple{AbstractVector{T}, Union{Integer, ZZRingElem}}} where T<:Union{AbstractSet, AbstractVector}","page":"Matroids","title":"matroid_from_circuits","text":"matroid_from_circuits(C, [n, E])\n\nArguments\n\nC::AbstractVector: The set of circuits of the matroid.\nn::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.\nE::AbstractVector: An explicit ground set passed as vector.\n\nA matroid with circuits C on the ground set E (which can be the empty set). The set C is a collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n. \n\nSee Section 1.1 of James Oxley (2011).\n\nExamples\n\nTo construct a rank two matroid with five bases on four elements by its circuits you may write:\n\njulia> C = [[1,2,3],[1,2,4],[3,4]];\n\njulia> M = matroid_from_circuits(C,4)\nMatroid of rank 2 on 4 elements\n\nTo construct the same matroid on the ground set {1,2,i,j} you may write:\n\njulia> C = [[1,2,'j'],[1,2,'i'],['i','j']];\n\njulia> M = matroid_from_circuits(C,[1,2,'i','j'])\nMatroid of rank 2 on 4 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#matroid_from_hyperplanes-Union{Tuple{T}, Tuple{AbstractVector{T}, Union{Integer, ZZRingElem}}} where T<:Union{AbstractSet, AbstractVector}","page":"Matroids","title":"matroid_from_hyperplanes","text":"matroid_from_hyperplanes(H, [n, E])\n\nArguments\n\nH::AbstractVector: The set of hyperplanes of the matroid.\nn::InterUnion: The size of the ground set. The ground set will be {1,..n} in this case.\nE::AbstractVector: An explicit ground set passed as vector.\n\nA matroid with hyperplanes H on the ground set E (which can be the empty set). A hyperplane is a flat of rank r-1. The set H is a collection of subsets of the ground set E satisfying an exchange property, and the default value for E is the set {1,..n} for a non-negative value n. \n\nSee Section 1.4 of James Oxley (2011).\n\nExamples\n\nTo construct the Fano matroid you may write:\n\njulia> H = [[1,2,4],[2,3,5],[1,3,6],[3,4,7],[1,5,7],[2,6,7],[4,5,6]];\n\njulia> M = matroid_from_hyperplanes(H,7)\nMatroid of rank 3 on 7 elements\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#matroid_from_matrix_columns-Tuple{MatrixElem}","page":"Matroids","title":"matroid_from_matrix_columns","text":"matroid_from_matrix_columns(A::MatrixElem)\n\nA matroid represented by the column vectors of a matrix A.\n\nSee Section 1.1 of James Oxley (2011).\n\nExamples\n\nTo construct the vector matroid (a.k.a linear matroid) of the matrix A over the field with two elements write:\n\njulia> A = matrix(GF(2),[[1,0,1,1],[0,1,1,1]]);\n\njulia> M = matroid_from_matrix_columns(A)\nMatroid of rank 2 on 4 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#matroid_from_matrix_rows-Tuple{MatrixElem}","page":"Matroids","title":"matroid_from_matrix_rows","text":"matroid_from_matrix_columns(A::MatrixElem)\n\nA matroid represented by the row vectors of a matrix.\n\nSee Section 1.1 of James Oxley (2011).\n\nExamples\n\nTo construct the linear matroid of the rows of the matrix A over the field with two elements write:\n\njulia> A = matrix(GF(2),[[1,0],[0,1],[1,1],[1,1]]);\n\njulia> M = matroid_from_matrix_rows(A)\nMatroid of rank 2 on 4 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#cycle_matroid-Tuple{Graph}","page":"Matroids","title":"cycle_matroid","text":"cycle_matroid(g::Graph)\n\nThe cycle matroid of a graph g.\n\nSee Section 1.1 of James Oxley (2011).\n\nExamples\n\nTo construct the cycle matroid of the complete graph of 4 vertices write:\n\njulia> g = complete_graph(4);\n\njulia> M = cycle_matroid(g)\nMatroid of rank 3 on 6 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#bond_matroid-Tuple{Graph}","page":"Matroids","title":"bond_matroid","text":"bond_matroid(g::Graph)\n\nThe \"bond matroid\" or \"cocycle matroid\" of a graph which is the dual of a cycle matroid, i.e., cographic.\n\nSee Section 2.3 of James Oxley (2011).\n\nExamples\n\nTo construct the bond or cocycle matroid of the complete graph of 4 vertices write:\n\njulia> g = complete_graph(4);\n\njulia> M = bond_matroid(g)\nMatroid of rank 3 on 6 elements\n\nor equivalently\n\njulia> g = complete_graph(4);\n\njulia> M = cocycle_matroid(g)\nMatroid of rank 3 on 6 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#cocycle_matroid-Tuple{Graph}","page":"Matroids","title":"cocycle_matroid","text":"See bond_matroid.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#Matroid","page":"Matroids","title":"Matroid","text":"Matroid(pm_matroid::Polymake.BigObjectAllocated, [E::GroundsetType])\n\nConstruct a matroid from a polymake matroid M on the default ground set {1,...,n}.\n\n\n\n\n\n","category":"type"},{"location":"Combinatorics/matroids/#matroid_from_revlex_basis_encoding-Tuple{String, Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Matroids","title":"matroid_from_revlex_basis_encoding","text":"matroid_from_revlex_basis_encoding(rvlx::String, r::IntegerUnion, n::IntegerUnion)\n\nConstruct a matroid from a revlex-basis-encoding-string rvlx of rank r and size n.\n\nExamples\n\njulia> matroid_from_revlex_basis_encoding(\"0******0******0***0******0*0**0****\", 3, 7)\nMatroid of rank 3 on 7 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#Examples","page":"Matroids","title":"Examples","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"uniform_matroid(r::IntegerUnion,n::IntegerUnion)\nfano_matroid()\nnon_fano_matroid()\nnon_pappus_matroid()\npappus_matroid()\nvamos_matroid()\nall_subsets_matroid(r::Int)\nprojective_plane(q::Int)\nprojective_geometry(r::Int, q::Int; check::Bool=false)\naffine_geometry(r::Int, q::Int; check::Bool=false)","category":"page"},{"location":"Combinatorics/matroids/#uniform_matroid-Tuple{Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Matroids","title":"uniform_matroid","text":"uniform_matroid(r,n)\n\nConstruct the uniform matroid of rank r on the n elements {1,...,n}.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#fano_matroid-Tuple{}","page":"Matroids","title":"fano_matroid","text":"fano_matroid()\n\nConstruct the Fano matroid.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#non_fano_matroid-Tuple{}","page":"Matroids","title":"non_fano_matroid","text":"non_fano_matroid()\n\nConstruct the non-Fano matroid.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#non_pappus_matroid-Tuple{}","page":"Matroids","title":"non_pappus_matroid","text":"non_pappus_matroid()\n\nConstruct the non-Pappus matroid.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#pappus_matroid-Tuple{}","page":"Matroids","title":"pappus_matroid","text":"pappus_matroid()\n\nConstruct the Pappus matroid.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#vamos_matroid-Tuple{}","page":"Matroids","title":"vamos_matroid","text":"vamos_matroid()\n\nConstruct the Vamos matroid.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#all_subsets_matroid-Tuple{Int64}","page":"Matroids","title":"all_subsets_matroid","text":"all_subsets_matroid(r)\n\nConstruct the all-subsets-matroid of rank r, a.k.a. the matroid underlying the resonance arrangement or rank r.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#projective_plane-Tuple{Int64}","page":"Matroids","title":"projective_plane","text":"projective_plane(q::Int)\n\nThe projective plane of order q. Note that this only works for prime numbers q for now.\n\nSee Section 6.1 of James Oxley (2011).\n\nExamples\n\njulia> M = projective_plane(3)\nMatroid of rank 3 on 13 elements\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#projective_geometry-Tuple{Int64, Int64}","page":"Matroids","title":"projective_geometry","text":"projective_geometry(r::Int, q::Int)\n\nThe projective geometry of order q and rank r+1. Note that this only works for prime numbers q for now.\n\nSee Section 6.1 of James Oxley (2011). Warning: Following the book of Oxley, the rank of the resulting matroid is r+1.\n\nExamples\n\njulia> M = projective_geometry(2, 3)\nMatroid of rank 3 on 13 elements\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#affine_geometry-Tuple{Int64, Int64}","page":"Matroids","title":"affine_geometry","text":"affine_geometry(r::Int, q::Int)\n\nThe affine geometry of order q and rank r+1. Note that this only works for prime numbers q for now.\n\nSee Section 6.1 of James Oxley (2011). Warning: Following the book of Oxley, the rank of the resulting matroid is r+1.\n\nExamples\n\njulia> M = affine_geometry(2, 3)\nMatroid of rank 3 on 9 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#Modifying-matroids","page":"Matroids","title":"Modifying matroids","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"dual_matroid(M::Matroid)\ndirect_sum(M::Matroid, N::Matroid)\ndeletion(M::Matroid,set::GroundsetType)\nrestriction(M::Matroid, set::GroundsetType)\ncontraction(M::Matroid,set::GroundsetType)\nminor(M::Matroid, set_del::GroundsetType, set_cont::GroundsetType)\nprincipal_extension(M::Matroid, set::GroundsetType, elem::ElementType)\nfree_extension(M::Matroid, elem::ElementType)\nseries_extension(M::Matroid, old::ElementType, new::ElementType)\nparallel_extension(M::Matroid, old::ElementType, new::ElementType)","category":"page"},{"location":"Combinatorics/matroids/#dual_matroid-Tuple{Matroid}","page":"Matroids","title":"dual_matroid","text":"dual_matroid(M::Matroid)\n\nThe dual matroid of a given matroid M.\n\nSee page 65 and Sectrion 2 in James Oxley (2011).\n\nExamples\n\nTo construct the dual of the Fano matroid write:\n\njulia> M = dual_matroid(fano_matroid())\nMatroid of rank 4 on 7 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#direct_sum-Tuple{Matroid, Matroid}","page":"Matroids","title":"direct_sum","text":"direct_sum(M::Matroid, N::Matroid)\n\nThe direct sum of the matroids M and N. Optionally one can also pass a vector of matroids.\n\nSee Section 4.2 of James Oxley (2011).\n\nTo obtain the direct sum of the Fano and a uniform matroid type:\n\nExamples\n\njulia> direct_sum(fano_matroid(), uniform_matroid(2,4))\nMatroid of rank 5 on 11 elements\n\nTo take the sum of three uniform matroids use:\n\nExamples\n\njulia> matroids = Vector([uniform_matroid(2,4), uniform_matroid(1,3), uniform_matroid(3,4)]);\n\njulia> M = direct_sum(matroids)\nMatroid of rank 6 on 11 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#deletion-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"deletion","text":"deletion(M, [S, e])\n\nArguments\n\nM::Matroid: A matroid M.\nS::GroundsetType: A subset S of the ground set of M.\ne::ElementType: An element e of the ground set of M.\n\nThe deletion M\\S of an element e or a subset S of the ground set E of the matroid M.\n\nSee Section 3 of James Oxley (2011).\n\nExamples\n\njulia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);\n\njulia> N = deletion(M,'i')\nMatroid of rank 2 on 3 elements\n\nExamples\n\njulia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);\n\njulia> N = deletion(M,['i','j'])\nMatroid of rank 2 on 2 elements\n\njulia> matroid_groundset(N)\n2-element Vector{Any}:\n 1\n 2\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#restriction-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"restriction","text":"restriction(M, S)\n\nArguments\n\nM::Matroid: A matroid M.\nS::GroundSetType: A subset S of the ground set of M.\n\nThe restriction M|S on a subset S of the ground set E of the matroid M.\n\nSee Section 3 of James Oxley (2011).\n\nExamples\n\njulia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);\n\njulia> N = restriction(M,[1,2])\nMatroid of rank 2 on 2 elements\n\njulia> matroid_groundset(N)\n2-element Vector{Any}:\n 1\n 2\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#contraction-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"contraction","text":"contraction(M, [S, e])\n\nArguments\n\nM::Matroid: A matroid M.\nS::GroundSetType: A subset S of the ground set of M.\ne::ElementType: An element e of the ground set of M.\n\nThe contraction M/S of an element or a subset S of the ground set E of the matroid M.\n\nSee Section 3 of James Oxley (2011).\n\nExamples\n\njulia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);\n\njulia> N = contraction(M,'i')\nMatroid of rank 1 on 3 elements\n\nExamples\n\njulia> M = matroid_from_bases([[1,2],[1,'i'],[1,'j'],[2,'i'],[2,'j']],[1,2,'i','j']);\n\njulia> N = contraction(M,['i','j'])\nMatroid of rank 1 on 2 elements\n\njulia> matroid_groundset(N)\n2-element Vector{Any}:\n 1\n 2\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#minor-Tuple{Matroid, Union{AbstractSet, AbstractVector}, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"minor","text":"minor(M::Matroid, set_del::GroundsetType, set_cont::GroundsetType)\n\nThe minor M\\S/T of disjoint subsets S and T of the ground set E of the matroid M.\n\nSee also contraction and deletion. You can find more in Section 3 of James Oxley (2011).\n\nExamples\n\njulia> M = fano_matroid();\n\njulia> S = [1,2,3];\n\njulia> T = [4];\n\njulia> N = minor(M,S,T) \nMatroid of rank 2 on 3 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#principal_extension-Tuple{Matroid, Union{AbstractSet, AbstractVector}, Union{Char, Integer, String, ZZRingElem}}","page":"Matroids","title":"principal_extension","text":"principal_extension(M::Matroid, F::GroundsetType, e::ElementType)\n\nThe principal extension M +_F e of a matroid M where the element e is freely added to the flat F.\n\nSee Section 7.2 of James Oxley (2011).\n\nExamples\n\nTo add 5 freely to the flat {1,2} of the uniform matroid U_{3,4} do\n\njulia> M = uniform_matroid(3,4);\n\njulia> N = principal_extension(M,[1,2],5)\nMatroid of rank 3 on 5 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#free_extension-Tuple{Matroid, Union{Char, Integer, String, ZZRingElem}}","page":"Matroids","title":"free_extension","text":"free_extension(M::Matroid, e::ElementType)\n\nThe free extension M +_E e of a matroid M where the element e.\n\nSee principal_extension and Section 7.2 of James Oxley (2011).\n\nExamples\n\nTo add 5 freely to the uniform matroid U_{3,4} do\n\njulia> M = uniform_matroid(3,4);\n\njulia> N = free_extension(M,5)\nMatroid of rank 3 on 5 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#series_extension-Tuple{Matroid, Union{Char, Integer, String, ZZRingElem}, Union{Char, Integer, String, ZZRingElem}}","page":"Matroids","title":"series_extension","text":"series_extension(M::Matroid, f::ElementType, e::ElementType)\n\nThe series extension of a matroid M where the element e is added in series to f.\n\nThis is actually a coextension see also Section 7.2 of James Oxley (2011).\n\nExamples\n\nTo add e in series to 1 in the uniform matroid U_{3,4} do\n\njulia> M = uniform_matroid(1,4);\n\njulia> N = series_extension(M,1,'e')\nMatroid of rank 2 on 5 elements\n\njulia> cocircuits(N)[1]\n2-element Vector{Any}:\n 1\n 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#parallel_extension-Tuple{Matroid, Union{Char, Integer, String, ZZRingElem}, Union{Char, Integer, String, ZZRingElem}}","page":"Matroids","title":"parallel_extension","text":"parallel_extension(M::Matroid, f::ElementType, e::ElementType)\n\nThe parallel extension M +_{cl(f)} e of a matroid M where the element e is added parallel to (the closure of) f.\n\nSee Section 7.2 of James Oxley (2011).\n\nExamples\n\nTo add e parallel to 1 in the uniform matroid U_{3,4} do\n\njulia> M = uniform_matroid(3,4);\n\njulia> N = parallel_extension(M,1,'e')\nMatroid of rank 3 on 5 elements\n\njulia> circuits(N)[1]\n2-element Vector{Any}:\n 1\n 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#Properties","page":"Matroids","title":"Properties","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"matroid_groundset(M::Matroid)\nlength(M::Matroid)\nrank(M::Matroid)\nrank(M::Matroid, set::GroundsetType)\nbases(M::Matroid)\nnonbases(M::Matroid)\ncircuits(M::Matroid)\nhyperplanes(M::Matroid)\nflats(M::Matroid, r::Union{Int,Nothing}=nothing)\ncyclic_flats(M::Matroid, r::Union{Int,Nothing}=nothing)\nclosure(M::Matroid, set::GroundsetType)\nnullity(M::Matroid, set::GroundsetType)\nfundamental_circuit(M::Matroid, basis::GroundsetType, elem::ElementType)\nfundamental_cocircuit(M::Matroid, basis::GroundsetType, elem::ElementType)\nindependent_sets(M::Matroid)\nspanning_sets(M::Matroid)\ncobases(M::Matroid)\ncocircuits(M::Matroid)\ncohyperplanes(M::Matroid)\ncorank(M::Matroid, set::GroundsetType)\nis_clutter(sets::AbstractVector{T}) where T <: GroundsetType\nis_regular(M::Matroid)\nis_binary(M::Matroid)\nis_ternary(M::Matroid)\nn_connected_components(M::Matroid)\nconnected_components(M::Matroid)\nis_connected(M::Matroid)\nloops(M::Matroid)\ncoloops(M::Matroid)\nis_loopless(M::Matroid)\nis_coloopless(M::Matroid)\nis_simple(M::Matroid)\ndirect_sum_components(M::Matroid)\nconnectivity_function(M::Matroid, set::GroundsetType)\nis_vertical_k_separation(M::Matroid,k::IntegerUnion, set::GroundsetType) \nis_k_separation(M::Matroid,k::IntegerUnion, set::GroundsetType)\nvertical_connectivity(M::Matroid)\ngirth(M::Matroid, set::GroundsetType=M.groundset)\ntutte_connectivity(M::Matroid)\ntutte_polynomial(M::Matroid)\ncharacteristic_polynomial(M::Matroid)\nreduced_characteristic_polynomial(M::Matroid)\nrevlex_basis_encoding(M::Matroid)\nis_isomorphic(M1::Matroid, M2::Matroid)\nis_minor(M::Matroid, N::Matroid)","category":"page"},{"location":"Combinatorics/matroids/#matroid_groundset-Tuple{Matroid}","page":"Matroids","title":"matroid_groundset","text":"matroid_groundset(M::Matroid)\n\nThe ground set E of a matroid M.\n\nTo obtain the ground set of the Fano matroid write:\n\nExamples\n\njulia> matroid_groundset(fano_matroid())\n7-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#length-Tuple{Matroid}","page":"Matroids","title":"length","text":"length(M::Matroid)\n\nReturn the size of the ground set of the matroid M.\n\nExamples\n\njulia> length(fano_matroid())\n7\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#rank-Tuple{Matroid}","page":"Matroids","title":"rank","text":"rank(M::Matroid)\n\nReturn the rank of the matroid M.\n\nExamples\n\njulia> rank(fano_matroid())\n3\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#rank-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"rank","text":"rank(M::Matroid, set::GroundsetType)\n\nReturn the rank of set in the matroid M.\n\nExamples\n\njulia> M = fano_matroid();\n\njulia> rank(M, [1,2,3])\n2\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#bases-Tuple{Matroid}","page":"Matroids","title":"bases","text":"bases(M::Matroid)\n\nReturn the list of bases of the matroid M.\n\nExamples\n\njulia> bases(uniform_matroid(2, 3))\n3-element Vector{Vector{Int64}}:\n [1, 2]\n [1, 3]\n [2, 3]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#nonbases-Tuple{Matroid}","page":"Matroids","title":"nonbases","text":"nonbases(M::Matroid)\n\nReturn the list of nonbases of the matroid M.\n\nExamples\n\njulia> nonbases(fano_matroid())\n7-element Vector{Vector{Int64}}:\n [1, 2, 3]\n [1, 4, 5]\n [1, 6, 7]\n [2, 4, 6]\n [2, 5, 7]\n [3, 4, 7]\n [3, 5, 6]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#circuits-Tuple{Matroid}","page":"Matroids","title":"circuits","text":"circuits(M::Matroid)\n\nReturn the list of circuits of the matroid M.\n\nExamples\n\njulia> circuits(uniform_matroid(2, 4))\n4-element Vector{Vector{Int64}}:\n [1, 2, 3]\n [1, 2, 4]\n [1, 3, 4]\n [2, 3, 4]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#hyperplanes-Tuple{Matroid}","page":"Matroids","title":"hyperplanes","text":"hyperplanes(M::Matroid)\n\nReturn the list of hyperplanes of the matroid M.\n\nExamples\n\njulia> hyperplanes(fano_matroid())\n7-element Vector{Vector{Int64}}:\n [3, 5, 6]\n [3, 4, 7]\n [2, 5, 7]\n [2, 4, 6]\n [1, 6, 7]\n [1, 4, 5]\n [1, 2, 3]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#flats","page":"Matroids","title":"flats","text":"flats(M::Matroid, [r::Int])\n\nReturn the list of flats of the matroid M. By default all flats are returned. One may specify a rank r as the second parameter in which case only the flats of rank r are returned.\n\nExamples\n\njulia> M = fano_matroid()\nMatroid of rank 3 on 7 elements\n\njulia> flats(M)\n16-element Vector{Vector}:\n Any[]\n [1]\n [2]\n [3]\n [4]\n [5]\n [6]\n [7]\n [1, 2, 3]\n [1, 4, 5]\n [1, 6, 7]\n [2, 4, 6]\n [2, 5, 7]\n [3, 5, 6]\n [3, 4, 7]\n [1, 2, 3, 4, 5, 6, 7]\n\njulia> flats(M, 2)\n7-element Vector{Vector}:\n [1, 2, 3]\n [1, 4, 5]\n [1, 6, 7]\n [2, 4, 6]\n [2, 5, 7]\n [3, 5, 6]\n [3, 4, 7]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/matroids/#cyclic_flats","page":"Matroids","title":"cyclic_flats","text":"cyclic_flats(M::Matroid, [r::Int])\n\nReturn the list of cyclic flats of the matroid M. These are the flats that are the union of cycles. See Section 2.1 in James Oxley (2011).\n\nBy default all cyclic flats are returned. One may specify a rank r as the second parameter. In this case only the cyclic flats of this rank are returned.\n\nExamples\n\njulia> M = fano_matroid()\nMatroid of rank 3 on 7 elements\n\njulia> cyclic_flats(M)\n9-element Vector{Vector}:\n Any[]\n [1, 2, 3]\n [1, 4, 5]\n [1, 6, 7]\n [2, 4, 6]\n [2, 5, 7]\n [3, 5, 6]\n [3, 4, 7]\n [1, 2, 3, 4, 5, 6, 7]\n\njulia> cyclic_flats(M, 2)\n7-element Vector{Vector}:\n [1, 2, 3]\n [1, 4, 5]\n [1, 6, 7]\n [2, 4, 6]\n [2, 5, 7]\n [3, 5, 6]\n [3, 4, 7]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/matroids/#closure-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"closure","text":"closure(M::Matroid, set::GroundsetType)\n\nReturn the closure of set in the matroid M.\n\nExamples\n\njulia> closure(fano_matroid(), [1,2])\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#nullity-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"nullity","text":"nullity(M::Matroid, set::GroundsetType)\n\nReturn the nullity of set in the matroid M. This is defined to be |set| - rk(set).\n\nExamples\n\njulia> M = fano_matroid();\n\njulia> nullity(M, [1,2,3])\n1\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#fundamental_circuit-Tuple{Matroid, Union{AbstractSet, AbstractVector}, Union{Char, Integer, String, ZZRingElem}}","page":"Matroids","title":"fundamental_circuit","text":"fundamental_circuit(M::Matroid, basis::GroundsetType, elem::ElementType)\n\nReturn the unique circuit contained in the union of basis and elem of the matroid M. See Section 1.2 of James Oxley (2011). Note that elem needs to be in the complement of the basis in this case.\n\nExamples\n\njulia> M = fano_matroid();\n\njulia> fundamental_circuit(M, [1,2,4], 7)\n4-element Vector{Int64}:\n 1\n 2\n 4\n 7\n\njulia> fundamental_circuit(M, [1,2,4], 3)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#fundamental_cocircuit-Tuple{Matroid, Union{AbstractSet, AbstractVector}, Union{Char, Integer, String, ZZRingElem}}","page":"Matroids","title":"fundamental_cocircuit","text":"fundamental_cocircuit(M::Matroid, cobasis::GroundsetType, elem::ElementType)\n\nReturn the unique circuit of the dual matroid of M in the union of the complement of basis and elem. See Section 2.1 of James Oxley (2011). Note that elem needs to be an element of the basis in this case.\n\nExamples\n\njulia> fundamental_cocircuit(fano_matroid(), [1,2,4], 4)\n4-element Vector{Int64}:\n 4\n 5\n 6\n 7\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#independent_sets-Tuple{Matroid}","page":"Matroids","title":"independent_sets","text":"independent_sets(M::Matroid)\n\nReturn the list of independent sets of the matroid M. These are all subsets of the bases.\n\nExamples\n\njulia> independent_sets(uniform_matroid(2, 3))\n7-element Vector{Vector{Integer}}:\n []\n [1]\n [2]\n [3]\n [1, 3]\n [2, 3]\n [1, 2]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#spanning_sets-Tuple{Matroid}","page":"Matroids","title":"spanning_sets","text":"spanning_sets(M::Matroid)\n\nReturn the list of spanning sets of the matroid M. These are all sets containing a basis.\n\nExamples\n\njulia> spanning_sets(uniform_matroid(2, 3))\n4-element Vector{Vector{Integer}}:\n [1, 2]\n [1, 3]\n [2, 3]\n [1, 2, 3]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#cobases-Tuple{Matroid}","page":"Matroids","title":"cobases","text":"cobases(M::Matroid)\n\nReturn the bases of the dual matroid of M. See Section 2 in James Oxley (2011).\n\nExamples\n\njulia> cobases(uniform_matroid(2, 3))\n3-element Vector{Vector{Int64}}:\n [3]\n [2]\n [1]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#cocircuits-Tuple{Matroid}","page":"Matroids","title":"cocircuits","text":"cocircuits(M::Matroid)\n\nReturn the circuits of the dual matroid of M. See Section 2 in James Oxley (2011).\n\nExamples\n\njulia> cocircuits(uniform_matroid(2, 5))\n5-element Vector{Vector{Int64}}:\n [1, 2, 3, 4]\n [1, 2, 3, 5]\n [1, 2, 4, 5]\n [1, 3, 4, 5]\n [2, 3, 4, 5]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#cohyperplanes-Tuple{Matroid}","page":"Matroids","title":"cohyperplanes","text":"cohyperplanes(M::Matroid)\n\nReturn the hyperplanes of the dual matroid of M. See Section 2 in James Oxley (2011).\n\nExamples\n\njulia> cohyperplanes(fano_matroid())\n14-element Vector{Vector{Int64}}:\n [4, 5, 6, 7]\n [2, 3, 6, 7]\n [2, 3, 4, 5]\n [1, 3, 5, 7]\n [1, 3, 4, 6]\n [1, 2, 5, 6]\n [1, 2, 4, 7]\n [3, 5, 6]\n [3, 4, 7]\n [2, 5, 7]\n [2, 4, 6]\n [1, 6, 7]\n [1, 4, 5]\n [1, 2, 3]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#corank-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"corank","text":"corank(M::Matroid, set::GroundsetType)\n\nReturn the rank of set in the dual matroid of M.\n\nExamples\n\njulia> corank(fano_matroid(), [1,2,3])\n3\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_clutter-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:Union{AbstractSet, AbstractVector}","page":"Matroids","title":"is_clutter","text":"is_clutter(sets::AbstractVector{T}) where T <: GroundsetType\n\nChecks if the collection of subsets sets is a clutter. A collection of subsets is a clutter if none of the sets is a proper subset of another. See Section 2.1 in James Oxley (2011).\n\nExamples\n\njulia> is_clutter([[1,2], [1,2,3]])\nfalse\n\njulia> is_clutter(circuits(fano_matroid()))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_regular-Tuple{Matroid}","page":"Matroids","title":"is_regular","text":"is_regular(M::Matroid)\n\nChecks if the matroid M is regular, that is representable over every field. See Section 6.6 in James Oxley (2011).\n\nExamples\n\njulia> is_regular(uniform_matroid(2, 3))\ntrue\n\njulia> is_regular(fano_matroid())\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_binary-Tuple{Matroid}","page":"Matroids","title":"is_binary","text":"is_binary(M::Matroid)\n\nChecks if the matroid M is binary, that is representable over the finite field F_2. See Section 6.5 in James Oxley (2011).\n\nExamples\n\njulia> is_binary(uniform_matroid(2, 4))\nfalse\n\njulia> is_binary(fano_matroid())\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_ternary-Tuple{Matroid}","page":"Matroids","title":"is_ternary","text":"is_ternary(M::Matroid)\n\nChecks if the matroid M is ternary, that is representable over the finite field F_3. See Section 4.1 in James Oxley (2011).\n\nExamples\n\njulia> is_ternary(uniform_matroid(2, 4))\ntrue\n\njulia> is_ternary(fano_matroid())\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#n_connected_components-Tuple{Matroid}","page":"Matroids","title":"n_connected_components","text":"n_connected_components(M::Matroid)\n\nReturn the number of connected components of M. See Section 4.1 in James Oxley (2011).\n\nExamples\n\njulia> n_connected_components(fano_matroid())\n1\n\njulia> n_connected_components(uniform_matroid(3, 3))\n3\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#connected_components-Tuple{Matroid}","page":"Matroids","title":"connected_components","text":"connected_components(M::Matroid)\n\nReturn the connected components of M. The function returns a partition of the ground set where each part corresponds to one connected component. See Section 4.1 in James Oxley (2011).\n\nExamples\n\njulia> connected_components(fano_matroid())\n1-element Vector{Vector{Int64}}:\n [1, 2, 3, 4, 5, 6, 7]\n\njulia> connected_components(uniform_matroid(3, 3))\n3-element Vector{Vector{Int64}}:\n [1]\n [2]\n [3]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_connected-Tuple{Matroid}","page":"Matroids","title":"is_connected","text":"is_connected(M::Matroid)\n\nCheck if the matroid M is connected, that is has one connected component See Section 4.1 in James Oxley (2011).\n\nExamples\n\njulia> is_connected(fano_matroid())\ntrue\n\njulia> is_connected(uniform_matroid(3, 3))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#loops-Tuple{Matroid}","page":"Matroids","title":"loops","text":"loops(M::Matroid)\n\nReturn the loops of M. A loop is an element of the ground set that is not contained in any basis.\n\nExamples\n\njulia> loops(matroid_from_bases([[1,2]], 4))\n2-element Vector{Int64}:\n 3\n 4\n\njulia> loops(fano_matroid())\nAny[]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#coloops-Tuple{Matroid}","page":"Matroids","title":"coloops","text":"coloops(M::Matroid)\n\nReturn the coloops of M. A coloop is an element of the ground set that is contained in every basis.\n\nExamples\n\njulia> coloops(matroid_from_bases([[1,2]], 4))\n2-element Vector{Int64}:\n 1\n 2\n\njulia> coloops(fano_matroid())\nAny[]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_loopless-Tuple{Matroid}","page":"Matroids","title":"is_loopless","text":"is_loopless(M::Matroid)\n\nCheck if M has a loop. Return true if M does not have a loop. See also loops.\n\nExamples\n\njulia> is_loopless(matroid_from_bases([[1,2]], 4))\nfalse\n\njulia> is_loopless(fano_matroid())\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_coloopless-Tuple{Matroid}","page":"Matroids","title":"is_coloopless","text":"is_coloopless(M::Matroid)\n\nCheck if M has a coloop. Return true if M does not have a coloop. See also coloops.\n\nExamples\n\njulia> is_coloopless(matroid_from_bases([[1,2]], 4))\nfalse\n\njulia> is_coloopless(fano_matroid())\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_simple-Tuple{Matroid}","page":"Matroids","title":"is_simple","text":"is_simple(M::Matroid)\n\nCheck if M has is simple. A matroid is simple if it doesn't have loops and doesn't have parallel elements. Return true if M is simple. See also loops.\n\nExamples\n\njulia> is_simple(matroid_from_bases([[1,2]], 4))\nfalse\n\njulia> is_simple(fano_matroid())\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#direct_sum_components-Tuple{Matroid}","page":"Matroids","title":"direct_sum_components","text":"direct_sum_components(M::Matroid)\n\nReturn the connected components of M as a list of matroids. See Section 4.1 in James Oxley (2011).\n\nExamples\n\njulia> direct_sum_components(fano_matroid())\n1-element Vector{Matroid}:\n Matroid of rank 3 on 7 elements\n\njulia> direct_sum_components(uniform_matroid(3, 3))\n3-element Vector{Matroid}:\n Matroid of rank 1 on 1 elements\n Matroid of rank 1 on 1 elements\n Matroid of rank 1 on 1 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#connectivity_function-Tuple{Matroid, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"connectivity_function","text":"connectivity_function(M::Matroid, set::GroundsetType)\n\nReturn the value of the connectivity function of set in the matroid M. See Section 8.1 in James Oxley (2011).\n\nExamples\n\njulia> connectivity_function(fano_matroid(), [1,2,4])\n3\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_vertical_k_separation-Tuple{Matroid, Union{Integer, ZZRingElem}, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"is_vertical_k_separation","text":"is_vertical_k_separation(M::Matroid, k::IntegerUnion, set::GroundsetType)\n\nCheck if set together with its complement defines a k separation in M See Section 8.6 in James Oxley (2011).\n\nExamples\n\njulia> is_vertical_k_separation(fano_matroid(), 2, [1,2,4])\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_k_separation-Tuple{Matroid, Union{Integer, ZZRingElem}, Union{AbstractSet, AbstractVector}}","page":"Matroids","title":"is_k_separation","text":"is_k_separation(M::Matroid, k::IntegerUnion, set::GroundsetType)\n\nCheck if set together with its complement defines a k separation in M See Section 8.1 in James Oxley (2011).\n\nExamples\n\njulia> is_k_separation(fano_matroid(), 2, [1,2,4])\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#vertical_connectivity-Tuple{Matroid}","page":"Matroids","title":"vertical_connectivity","text":"vertical_connectivity(M::Matroid)\n\nIf 'M' has two disjoint cocircuits, its vertical connectivity is defined to be least positive integer k such that M has a vertical k separation. Otherwise its vertical connectivity is defined to be the rank of M. See Section 8.6 in James Oxley (2011).\n\nExamples\n\njulia> vertical_connectivity(fano_matroid())\n3\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#girth","page":"Matroids","title":"girth","text":"girth(M::Matroid, set::GroundsetType)\n\nReturn the girth of set in the matroid M. This is the size of the smallest circuit contained in set and infinite otherwise. See Section 8.6 in James Oxley (2011).\n\nExamples\n\njulia> girth(fano_matroid(), [1,2,3,4])\n3\n\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/matroids/#tutte_connectivity-Tuple{Matroid}","page":"Matroids","title":"tutte_connectivity","text":"tutte_connectivity(M::Matroid)\n\nThe Tutte connectivity of M is the least integer k such that M has a k separation. It can be infinite if no k separation exists. See Section 8.6 in James Oxley (2011).\n\nExamples\n\njulia> tutte_connectivity(fano_matroid())\n3\n\njulia> tutte_connectivity(uniform_matroid(2,4))\nPosInf()\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#tutte_polynomial-Tuple{Matroid}","page":"Matroids","title":"tutte_polynomial","text":"tutte_polynomial(M::Matroid)\n\nReturn the Tutte polynomial of M. This is polynomial in the variables x and y with integral coefficients. See Section 15.3 in James Oxley (2011).\n\nExamples\n\njulia> tutte_polynomial(fano_matroid())\nx^3 + 4*x^2 + 7*x*y + 3*x + y^4 + 3*y^3 + 6*y^2 + 3*y\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#characteristic_polynomial-Tuple{Matroid}","page":"Matroids","title":"characteristic_polynomial","text":"characteristic_polynomial(M::Matroid)\n\nReturn the characteristic polynomial of M. This is polynomial in the variable q with integral coefficients. It is computed as an evaluation of the Tutte polynmomial. See Section 15.2 in James Oxley (2011).\n\nExamples\n\njulia> characteristic_polynomial(fano_matroid())\nq^3 - 7*q^2 + 14*q - 8\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#reduced_characteristic_polynomial-Tuple{Matroid}","page":"Matroids","title":"reduced_characteristic_polynomial","text":"reduced_characteristic_polynomial(M::Matroid)\n\nReturn the reduced characteristic polynomial of M. This is the quotient of the characteristic polynomial by (q-1). See Section 15.2 in James Oxley (2011).\n\nExamples\n\njulia> reduced_characteristic_polynomial(fano_matroid())\nq^2 - 6*q + 8\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#revlex_basis_encoding-Tuple{Matroid}","page":"Matroids","title":"revlex_basis_encoding","text":"revlex_basis_encoding(M::Matroid)\n\nComputes the revlex basis encoding and the minimal revlex basis encoding among isomorphic matroids \n\nExamples\n\nTo get the revlex basis encoding of the fano matroid and to preduce a matrod form the encoding write:\n\njulia> string1, string2 = revlex_basis_encoding(fano_matroid())\n(\"0******0******0***0******0*0**0****\", \"0******0******0***0******0*0**0****\")\n\njulia> matroid_from_revlex_basis_encoding(string2, 3, 7)\nMatroid of rank 3 on 7 elements\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_isomorphic-Tuple{Matroid, Matroid}","page":"Matroids","title":"is_isomorphic","text":"is_isomorphic(M1::Matroid, M2::Matroid)\n\nChecks if the matroid M1 is isomorphic to the matroid M2 under the action of the symmetric group that acts on their groundsets.\n\nExamples\n\nTo compare two matrods write:\n\njulia> H = [[1,2,4],[2,3,5],[1,3,6],[3,4,7],[1,5,7],[2,6,7],[4,5,6]];\n\njulia> M = matroid_from_hyperplanes(H,7);\n\njulia> is_isomorphic(M,fano_matroid())\ntrue\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#is_minor-Tuple{Matroid, Matroid}","page":"Matroids","title":"is_minor","text":"is_minor(M::Matroid, N::Matroid)\n\nChecks if the matroid M is isomorphic to a minor of the matroid N.\n\nExamples\n\njulia> is_minor(direct_sum(uniform_matroid(0,1), uniform_matroid(2,2)), fano_matroid())\nfalse\n\njulia> is_minor(direct_sum(uniform_matroid(0,1), uniform_matroid(2,2)), parallel_extension(uniform_matroid(3,4), 1, 5))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#Chow-Rings","page":"Matroids","title":"Chow Rings","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"chow_ring(M::Matroid; ring::Union{MPolyRing,Nothing}=nothing, extended::Bool=false)\naugmented_chow_ring(M::Matroid)","category":"page"},{"location":"Combinatorics/matroids/#chow_ring-Tuple{Matroid}","page":"Matroids","title":"chow_ring","text":"chow_ring(M::Matroid; ring::MPolyRing=nothing, extended::Bool=false)\n\nReturn the Chow ring of a matroid, optionally also with the simplicial generators and the polynomial ring.\n\nSee Karim Adiprasito, June Huh, Eric Katz (2018) and Spencer Backman, Christopher Eur, Connor Simpson (2019). \n\nExamples\n\nThe following computes the Chow ring of the Fano matroid.\n\njulia> M = fano_matroid();\n\njulia> R = chow_ring(M);\n\njulia> R[1]*R[8]\n-x_{3,4,7}^2\n\nThe following computes the Chow ring of the Fano matroid including variables for the simplicial generators.\n\njulia> M = fano_matroid();\n\njulia> R = chow_ring(M, extended=true);\n\njulia> f = R[22] + R[8] - R[29]\nx_{1,2,3} + h_{1,2,3} - h_{1,2,3,4,5,6,7}\n\njulia> f==0\ntrue\n\nThe following computes the Chow ring of the free matroid on three elements in a given graded polynomial ring.\n\njulia> M = uniform_matroid(3,3);\n\njulia> GR, _ = graded_polynomial_ring(QQ,[\"a\",\"b\",\"c\",\"d\",\"e\",\"f\"]);\n\njulia> R = chow_ring(M, ring=GR);\n\njulia> hilbert_series_reduced(R)\n(t^2 + 4*t + 1, 1) \n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#augmented_chow_ring-Tuple{Matroid}","page":"Matroids","title":"augmented_chow_ring","text":"augmented_chow_ring(M::Matroid)\n\nReturn an augmented Chow ring of a matroid. As described in Tom Braden, June Huh, Jacob P. Matherne, Nicholas Proudfoot, Botong Wang (2020). \n\nExamples\n\njulia> M = fano_matroid();\n\njulia> R = augmented_chow_ring(M);\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#Matroid-strata-and-realization-spaces","page":"Matroids","title":"Matroid strata and realization spaces","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"For a matroid M, of rank d on a ground set E of size n realizable over a ring K, its matroid realization space mathsfGr(M) is the locally closed subscheme of the Grassmannian mathsfGr(dK^n) of d-dimensional subspaces of K^n realizing M. Precisely, ","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":" mathsfGr(M) = F in mathsfGr(dK^n) p_I(F) neq 0 text iff I in mathcalB(M)","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"where mathcalB(M) denotes the set of bases of M and p_I(F) denotes the Ith Pl\\\"ucker coordinate of the linear subspace F subset K^n. The coordinate ring of mathsfGr(M) can be computed using matrix coordinates, see Construction 2.2 of D. Corey (2021). The following function computes this ring. ","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"matroid_stratum_matrix_coordinates(M::Matroid, B::GroundsetType, F::AbstractAlgebra.Ring = ZZ)","category":"page"},{"location":"Combinatorics/matroids/#matroid_stratum_matrix_coordinates","page":"Matroids","title":"matroid_stratum_matrix_coordinates","text":"matroid_stratum_matrix_coordinates(M::Matroid, B::GroundsetType, F::AbstractAlgebra.Ring = ZZ)\n\nReturn the data of the coordinate ring of the matroid stratum of M in the Grassmannian with respect to matrix coordinates. Here, B is a basis of Mand the submatrix with columns indexed byB' is the identity. This function returns a pair (A, W) where A is the coordinate matrix, and W is the coordinate ring of the stratum, in general this is a localized quotient ring. \n\nExamples\n\njulia> M = fano_matroid();\n\njulia> (A, W) = matroid_stratum_matrix_coordinates(M, [1,2,4], GF(2));\n\njulia> A # The coordinate matrix with entries in the polynomial ring `R`.\n[1 0 x[1, 1] 0 x[1, 2] 0 x[1, 4]]\n[0 1 x[2, 1] 0 0 x[2, 3] x[2, 4]]\n[0 0 0 1 x[3, 2] x[3, 3] x[3, 4]]\n\njulia> W # The coordinate ring of the stratum; in general a localized quotient ring `(R/I)[S⁻¹]`.\nLocalization\n of quotient of multivariate polynomial ring by ideal with 4 generators\n at products of 28 elements\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"When the matroid M is connected, the diagonal torus of mathsfPGL(n) acts freely on mathsfGr(M) and its quotient is the realization space R(M) of M. There are two main differences between the coordinate rings KmathsfGr(M) and KR(M).","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"To comupte KR(M), we assume that d+1 columns A = a_1ldotsa_d+1 of the reference matrix X are the unit vectors e_1ldotse_n and e_1+ cdots + e_n. Note that every d element subset of A must be a basis of M. Disconnected matroids do not satisfy this property.\nThe columns of the reference matrix X may be treated as projective coordinates.","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"The coordinate ring of R(M) is computed in the following function. ","category":"page"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"matroid_realization_space(M::Matroid, A::GroundsetType, F::AbstractAlgebra.Ring=ZZ)","category":"page"},{"location":"Combinatorics/matroids/#matroid_realization_space","page":"Matroids","title":"matroid_realization_space","text":"matroid_realization_space(M::Matroid, A::GroundsetType, F::AbstractAlgebra.Ring=ZZ)\n\nReturn the data of the coordinate ring of the realization space of the matroid M using matrix coordinates. The matroid M should be a simple and connected matroid, say its rank is d, and ground set n. The vector A is rank(M)+1 consists of d+1 elements (in order) of n such that each d-element subset is a basis of M.\n\nThis function returns a pair (X, W) where X is the reduced dn matrix of variables, and the coordinate ring of the matroid realization space is W.\n\nExamples\n\njulia> M = fano_matroid();\n\njulia> (X, W) = matroid_realization_space(M, [1,2,4,7], GF(2));\n\njulia> X # The coordinate matrix.\n[1 0 x[1, 1] 0 x[1, 2] 0 1]\n[0 1 1 0 0 x[2, 3] 1]\n[0 0 0 1 1 1 1]\n\njulia> W # The coordinate ring of the stratum.\nLocalization\n of quotient of multivariate polynomial ring by ideal with 4 generators\n at products of 9 elements\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":" automorphism_group(m::Matroid)","category":"page"},{"location":"Combinatorics/matroids/#automorphism_group-Tuple{Matroid}","page":"Matroids","title":"automorphism_group","text":"automorphism_group(m::Matroid)\n\nGiven a matroid m return its automorphism group as a PermGroup. The group acts on the elements of m.\n\nExamples\n\njulia> M = uniform_matroid(2, 4)\nMatroid of rank 2 on 4 elements\n\njulia> automorphism_group(M)\nGroup([ (3,4), (1,2), (2,3) ])\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/free_module/#Free-Modules-and-Vector-Spaces","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"","category":"section"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"AbstractAlgebra allows the construction of free modules of any rank over any Euclidean ring and the vector space of any dimension over a field. By default the system considers the free module of a given rank over a given ring or vector space of given dimension over a field to be unique.","category":"page"},{"location":"AbstractAlgebra/free_module/#Generic-free-module-and-vector-space-types","page":"Free Modules and Vector Spaces","title":"Generic free module and vector space types","text":"","category":"section"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"AbstractAlgebra provides generic types for free modules and vector spaces, via the type FreeModule{T} for free modules, where T is the type of the elements of the ring R over which the module is built.","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"Elements of a free module have type FreeModuleElem{T}.","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"Vector spaces are simply free modules over a field.","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"The implementation of generic free modules can be found in src/generic/FreeModule.jl.","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"The free module of a given rank over a given ring is made unique on the system by caching them (unless an optional cache parameter is set to false).","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).","category":"page"},{"location":"AbstractAlgebra/free_module/#Abstract-types","page":"Free Modules and Vector Spaces","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"The type FreeModule{T} belongs to FPModule{T} and FreeModuleElem{T} to FPModuleElem{T}. Here the FP prefix stands for finitely presented.","category":"page"},{"location":"AbstractAlgebra/free_module/#Functionality-for-free-modules","page":"Free Modules and Vector Spaces","title":"Functionality for free modules","text":"","category":"section"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"As well as implementing the entire module interface, free modules provide the following functionality.","category":"page"},{"location":"AbstractAlgebra/free_module/#Constructors","page":"Free Modules and Vector Spaces","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"FreeModule(R::Ring, rank::Int)\nVectorSpace(F::Field, dim::Int)","category":"page"},{"location":"AbstractAlgebra/free_module/#FreeModule-Tuple{Ring, Int64}","page":"Free Modules and Vector Spaces","title":"FreeModule","text":"FreeModule(R::NCRing, rank::Int; cached::Bool = true)\n\nReturn the free module over the ring R with the given rank.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_module/#VectorSpace-Tuple{Field, Int64}","page":"Free Modules and Vector Spaces","title":"VectorSpace","text":"VectorSpace(R::Field, dim::Int; cached::Bool = true)\n\nReturn the vector space over the field R with the given dimension.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"Construct the free module/vector space of given rank/dimension.","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"Examples","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"julia> M = FreeModule(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> V = VectorSpace(QQ, 2)\nVector space of dimension 2 over rationals\n","category":"page"},{"location":"AbstractAlgebra/free_module/#Basic-manipulation","page":"Free Modules and Vector Spaces","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"rank(M::Generic.FreeModule{T}) where T <: RingElem\ndim(V::Generic.FreeModule{T}) where T <: FieldElem\nbasis(V::Generic.FreeModule{T}) where T <: FieldElem","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"Examples","category":"page"},{"location":"AbstractAlgebra/free_module/","page":"Free Modules and Vector Spaces","title":"Free Modules and Vector Spaces","text":"julia> M = FreeModule(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> V = VectorSpace(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> rank(M)\n3\n\njulia> dim(V)\n2\n\njulia> basis(V)\n2-element Vector{AbstractAlgebra.Generic.FreeModuleElem{Rational{BigInt}}}:\n (1//1, 0//1)\n (0//1, 1//1)","category":"page"},{"location":"Hecke/abelian/elements/#Elements","page":"-","title":"Elements","text":"","category":"section"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"Elements in a finitely generated abelian group are of type GrpAbFinGenElem and are always given as a linear combination of the generators. Internally this representation is normliased to have a unique representative.","category":"page"},{"location":"Hecke/abelian/elements/#Creation","page":"-","title":"Creation","text":"","category":"section"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"In addition to the standard function id, zero and one that can be used to create the neutral element, we also support more targeted creation:","category":"page"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"gens(G::GrpAbFinGen)\nGrpAbFinGen(x::Vector{ZZRingElem})\nGrpAbFinGen(x::ZZMatrix)\ngetindex(A::GrpAbFinGen, i::Int)\nrand(G::GrpAbFinGen)\nrand(G::GrpAbFinGen, B::ZZRingElem)\nparent(x::GrpAbFinGenElem)","category":"page"},{"location":"Hecke/abelian/elements/#gens-Tuple{GrpAbFinGen}","page":"-","title":"gens","text":"gens(G::GrpAbFinGen) -> Vector{GrpAbFinGenElem}\n\nThe sequence of generators of G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#GrpAbFinGen-Tuple{Vector{ZZRingElem}}","page":"-","title":"GrpAbFinGen","text":"(A::GrpAbFinGen)(x::Vector{ZZRingElem}) -> GrpAbFinGenElem\n\nGiven an array x of elements of type ZZRingElem of the same length as ngens(A), this function returns the element of A with components x.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#GrpAbFinGen-Tuple{ZZMatrix}","page":"-","title":"GrpAbFinGen","text":"(A::GrpAbFinGen)(x::ZZMatrix) -> GrpAbFinGenElem\n\nGiven a matrix over the integers with either 1 row and ngens(A) columns or ngens(A) rows and 1 column, this function returns the element of A with components x.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#getindex-Tuple{GrpAbFinGen, Int64}","page":"-","title":"getindex","text":"getindex(A::GrpAbFinGen, i::Int) -> GrpAbFinGenElem\n\nReturns the element of A with components (0dotsc010dotsc0), where the 1 is at the i-th position.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#rand-Tuple{GrpAbFinGen}","page":"-","title":"rand","text":"rand(G::GrpAbFinGen) -> GrpAbFinGenElem\n\nReturns an element of G chosen uniformly at random.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#rand-Tuple{GrpAbFinGen, ZZRingElem}","page":"-","title":"rand","text":"rand(G::GrpAbFinGen, B::ZZRingElem) -> GrpAbFinGenElem\n\nFor a (potentially infinite) abelian group G, return an element chosen uniformly at random with coefficients bounded by B.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#parent-Tuple{GrpAbFinGenElem}","page":"-","title":"parent","text":"parent(x::GrpAbFinGenElem) -> GrpAbFinGen\n\nReturns the parent of x.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#Access","page":"-","title":"Access","text":"","category":"section"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"getindex(x::GrpAbFinGenElem, i::Int)","category":"page"},{"location":"Hecke/abelian/elements/#getindex-Tuple{GrpAbFinGenElem, Int64}","page":"-","title":"getindex","text":"getindex(x::GrpAbFinGenElem, i::Int) -> ZZRingElem\n\nReturns the i-th component of the element x.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#Predicates","page":"-","title":"Predicates","text":"","category":"section"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"We have the standard predicates iszero, isone and is_identity to test an element for being trivial.","category":"page"},{"location":"Hecke/abelian/elements/#Invariants","page":"-","title":"Invariants","text":"","category":"section"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"order(A::GrpAbFinGenElem)","category":"page"},{"location":"Hecke/abelian/elements/#order-Tuple{GrpAbFinGenElem}","page":"-","title":"order","text":"order(A::GrpAbFinGenElem) -> ZZRingElem\n\nReturns the order of A. It is assumed that the order is finite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/elements/#Iterator","page":"-","title":"Iterator","text":"","category":"section"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"One can iterate over the elements of a finite abelian group.","category":"page"},{"location":"Hecke/abelian/elements/","page":"-","title":"-","text":"using Hecke # hide\nG = abelian_group(ZZRingElem[1 2; 3 4])\nfor g = G\n println(g)\nend","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Gröbner/Standard-Bases-Over-Fields","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"We fix our notation in the context of standard (Gröbner) bases and present relevant OSCAR functions.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Let Kx = Kx_1 dots x_n be a polynomial ring over a field K, and let be a monomial ordering on textMon_n(x).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Given a polynomial fin Kxsetminus 0, write f as the sum of its nonzero terms as follows:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"f = a_alpha x^alpha + a_beta_1 x^beta_1 + dots + a_beta_s x^beta_squad x^alpha x^beta_1 dots x^beta_s ","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Then, with respect to , we refer to textLT_(f) = a_alpha x^alpha, textLM_(f) = x^alpha, textLE_(f) = alpha, textLC_(f) = a_alpha, and texttail_(f) = f - textLT_(f) as the leading term, the leading monomial, the leading exponent, the leading coefficient, and the tail of f, respectively.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Next note that the set","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"U_= uin Kxsetminus 0 mid textLM_(u)=1 ","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"is a multiplicatively closed subset of Kx. Consider the localization","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Kx_= KxU^-1 = left fracfu bigg f in Kx uin U_right","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Then Kxsubseteq Kx_subseteq Kx_langle x rangle where Kx_langle x rangle is the localization of Kx at the maximal ideal langle x rangle Moreover,","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Kx = Kx_ iff is global, and\nKx_ = Kx_langle x rangle iff is local.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Extending the notation introduced for polynomials, let now fin Kx_setminus 0. Choose uin U_ such that ufin Kx. Then, with respect to , the leading term of f is defined to be textLT_(f) = textLT_(uf) (this definition is independent of the choice of u). The leading monomial textLM_(f), the leading exponent textLE_(f), the leading coefficient textLC_(f), and the tail texttail_(f) of f are defined similarly.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nGiven a monomial ordering on a free Kx-module F = Kx^p with basis e_1 dots e_p, the above notation extends naturally to elements of Kx^p and Kx_^p, respectively. There is one particularity: Given an element f = Kx^psetminus 0 with leading term textLT(f) = x^alpha e_i, we write textLE_(f) = (alpha i).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Default-Orderings","page":"Gröbner/Standard Bases Over Fields","title":"Default Orderings","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nThe OSCAR functions discussed in this section depend on a monomial ordering which is entered as a keyword argument. Given a polynomial ring R, the default_ordering for this is degrevlex except if R is mathbb Z-graded with positive weights. Then the corresponding wdegrevlex ordering is used. Given a free R-module F, the default_ordering is default_ordering(R)*lex(gens(F)).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Here are some illustrating OSCAR examples:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Examples","page":"Gröbner/Standard Bases Over Fields","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> default_ordering(R)\ndegrevlex([x, y, z])\n\njulia> F = free_module(R, 2)\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> default_ordering(F)\ndegrevlex([x, y, z])*lex([gen(1), gen(2)])\n\njulia> S, _ = grade(R, [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> default_ordering(S)\nwdegrevlex([x, y, z], [1, 2, 3])","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Monomials,-Terms,-and-More","page":"Gröbner/Standard Bases Over Fields","title":"Monomials, Terms, and More","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Here are examples which indicate how to recover monomials, terms, and more from a given polynomial.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> f = 3*z^3+2*x*y+1\n2*x*y + 3*z^3 + 1\n\njulia> terms(f)\nterms iterator of 3*z^3 + 2*x*y + 1\n\njulia> collect(ans)\n3-element Vector{QQMPolyRingElem}:\n 3*z^3\n 2*x*y\n 1\n\njulia> monomials(f, ordering = lex(R))\nmonomials iterator of 2*x*y + 3*z^3 + 1\n\njulia> coefficients(f)\ncoefficients iterator of 3*z^3 + 2*x*y + 1\n\njulia> exponents(f, ordering = neglex(R))\nexponents iterator of 1 + 3*z^3 + 2*x*y\n\njulia> coefficients_and_exponents(f)\ncoefficients and exponents iterator of 3*z^3 + 2*x*y + 1\n\njulia> collect(ans)\n3-element Vector{Tuple{QQFieldElem, Vector{Int64}}}:\n (3, [0, 0, 3])\n (2, [1, 1, 0])\n (1, [0, 0, 0])\n\njulia> leading_term(f)\n3*z^3\n\njulia> leading_monomial(f, ordering = lex(R))\nx*y\n\njulia> leading_exponent(f, ordering = neglex(R))\n3-element Vector{Int64}:\n 0\n 0\n 0\n\njulia> leading_coefficient(f)\n3\n\njulia> tail(f)\n2*x*y + 1","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> F = free_module(R, 3)\nFree module of rank 3 over Multivariate polynomial ring in 2 variables over QQ\n\njulia> f = (5*x*y^2-y^10+3)*F[1]+(4*x^3+2*y) *F[2]+16*x*F[3]\n(5*x*y^2 - y^10 + 3)*e[1] + (4*x^3 + 2*y)*e[2] + 16*x*e[3]\n\njulia> default_ordering(F)\ndegrevlex([x, y])*lex([gen(1), gen(2), gen(3)])\n\njulia> collect(terms(f))\n6-element Vector{FreeModElem{QQMPolyRingElem}}:\n -y^10*e[1]\n 4*x^3*e[2]\n 5*x*y^2*e[1]\n 16*x*e[3]\n 2*y*e[2]\n 3*e[1]\n\njulia> collect(terms(f, ordering = lex(F)*lex(R)))\n6-element Vector{FreeModElem{QQMPolyRingElem}}:\n 5*x*y^2*e[1]\n -y^10*e[1]\n 3*e[1]\n 4*x^3*e[2]\n 2*y*e[2]\n 16*x*e[3]\n\njulia> tail(f)\n(5*x*y^2 + 3)*e[1] + (4*x^3 + 2*y)*e[2] + 16*x*e[3]\n\njulia> leading_exponent(f)\n([0, 10], 1)\n\njulia> leading_exponent(f, ordering = lex(F)*lex(R))\n([1, 2], 1)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Division-With-Remainder","page":"Gröbner/Standard Bases Over Fields","title":"Division With Remainder","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"The computation of Gröbner (standard) bases relies on multivariate division with remainder which is interesting in its own right. If a monomial ordering is given, the basic idea is to mimic Euclidean division with remainder, allowing more than one divisor: At each step of the resulting process, this amounts to removing the leading term of the intermediate dividend, using the leading term of some divisor by which it is divisible. In its basic form, the process works well if is global, but may not terminate for local and mixed orderings. In the latter case, Mora's division algorithm, which relies on a more restricted selection strategy for the divisors to be used, comes to our rescue.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"We discuss this in more detail:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"First suppose that is global and let polynomials gin Kx and f_1 dots f_rin Kxsetminus 0 be given. In this situation, multivariate division with remainder allows us to compute expressions","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"g = q_1f_1+dots q_rf_r + h hin Kx text all q_i in Kx","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"such that:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"textLM_(g) ge textLM_(q_if_i) whenever both sides are nonzero.\nIf h is nonzero, then textLM_(h) is not divisible by any textLM_(f_i).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Each such expression is called a standard representation for g with quotients q_i and remainder h (on division by the f_i, with respect to ). If, at each step of the division process, we allow to remove some term of the current dividend instead of just focusing on its leading term, then the algorithm will return a standard expression in which the remainder is fully reduced. That is, h satisfies the stronger condition below:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"If h is nonzero, then no term of h is divisible by any textLM_(f_i).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Without restrictions on , let elements gin Kx_ and f_1 dots f_rin Kxsetminus 0 be given. In this situation, Mora division with remainder allows us to compute expressions","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"ug = q_1f_1+dots q_rf_r + h hin Kx_ text all q_i in Kx_","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"such that:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"u is a unit of Kx_, that is, textLM_(u)=1.\ntextLM_(g) ge textLM_(q_if_i) whenever both sides are nonzero.\nIf h is nonzero, then textLM_(h) is not divisible by any textLM_(f_i).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Each such expression is called a weak standard representation for g with quotients q_i and remainder h (on division by the f_i, with respect to ). If gin Kx, we speak of a polynomial weak standard representation if u and the q_i are elements of Kx Using power series expansions, it makes still sense to speak of fully reduced remainders. However, even if we start from polynomial data, such remainders may not be computable (in finitely many steps).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nGiven a monomial ordering on a free Kx-module F = Kx^p with basis e_1 dots e_p, the above notation and the division algorithms extend naturally to Kx^p and Kx_^p, respectively.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"The OSCAR functions discussed below compute standard representations and polynomial weak standard representations, respectively. In the global case, they always return fully reduced remainders.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"reduce(g::T, F::Vector{T}; \n\tordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#reduce-Union{Tuple{T}, Tuple{T, Vector{T}}} where T<:MPolyRingElem","page":"Gröbner/Standard Bases Over Fields","title":"reduce","text":"reduce(g::T, F::Vector{T}; \n ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem\n\nIf ordering is global, return the remainder in a standard representation for g on division by the polynomials in F with respect to ordering. Otherwise, return the remainder in a weak standard representation for g on division by the polynomials in F with respect to ordering.\n\nreduce(G::Vector{T}, F::Vector{T};\n ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem\n\nReturn a Vector which contains, for each element g of G, a remainder as above.\n\nnote: Note\nIn the global case, the returned remainders are fully reduced.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> reduce(y^3, [x^2, x*y-y^3])\nx*y\n\njulia> reduce(y^3, [x^2, x*y-y^3], ordering = lex(R))\ny^3\n\njulia> R, (z, y, x) = polynomial_ring(QQ, [\"z\", \"y\", \"x\"]);\n\njulia> f1 = y-x^2; f2 = z-x^3;\n\njulia> g = x^3*y-3*y^2*z^2+x*y*z;\n\njulia> reduce(g, [f1, f2], ordering = lex(R))\n-3*x^10 + x^6 + x^5\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"reduce_with_quotients(g::T, F::Vector{T}; \n\tordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#reduce_with_quotients-Union{Tuple{T}, Tuple{T, Vector{T}}} where T<:MPolyRingElem","page":"Gröbner/Standard Bases Over Fields","title":"reduce_with_quotients","text":"reduce_with_quotients(g::T, F::Vector{T}; \n ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem\n\nIf ordering is global, return the quotients and the remainder in a standard representation for g on division by the polynomials in F with respect to ordering. Otherwise, return the quotients and the remainder in a weak standard representation for g on division by the polynomials in F with respect to ordering.\n\nreduce_with_quotients(G::Vector{T}, F::Vector{T}; \n ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem\n\nReturn a Vector which contains, for each element g of G, quotients and a remainder as above.\n\nnote: Note\nIn the global case, the returned remainders are fully reduced.\n\nExamples\n\njulia> R, (z, y, x) = polynomial_ring(QQ, [\"z\", \"y\", \"x\"]);\n\njulia> f1 = y-x^2; f2 = z-x^3;\n\njulia> g = x^3*y-3*y^2*z^2+x*y*z;\n\njulia> Q, h = reduce_with_quotients(g, [f1, f2], ordering = lex(R));\n\njulia> Q\n[-3*y*x^6 - 3*x^8 + x^4 + x^3 -3*z*y^2 - 3*y^2*x^3 + y*x]\n\njulia> h\n-3*x^10 + x^6 + x^5\n\njulia> g == Q[1]*f1+Q[2]*f2+h\ntrue\n\njulia> G = [g, x*y^3-3*x^2*y^2*z^2];\n\njulia> Q, H = reduce_with_quotients(G, [f1, f2], ordering = lex(R));\n\njulia> Q\n[ -3*y*x^6 - 3*x^8 + x^4 + x^3 -3*z*y^2 - 3*y^2*x^3 + y*x]\n[y^2*x - 3*y*x^8 + y*x^3 - 3*x^10 + x^5 -3*z*y^2*x^2 - 3*y^2*x^5]\n\njulia> H\n2-element Vector{QQMPolyRingElem}:\n -3*x^10 + x^6 + x^5\n -3*x^12 + x^7\n\njulia> G == Q*[f1, f2]+H\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"reduce_with_quotients_and_unit(g::T, F::Vector{T}; \n\tordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#reduce_with_quotients_and_unit-Union{Tuple{T}, Tuple{T, Vector{T}}} where T<:MPolyRingElem","page":"Gröbner/Standard Bases Over Fields","title":"reduce_with_quotients_and_unit","text":"reduce_with_quotients_and_unit(g::T, F::Vector{T};\n ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem\n\nReturn the unit, the quotients and the remainder in a weak standard representation for g on division by the polynomials in F with respect to ordering.\n\nreduce_with_quotients_and_unit(G::Vector{T}, F::Vector{T};\n ordering::MonomialOrdering = default_ordering(parent(F[1]))) where T <: MPolyRingElem\n\nReturn a Vector which contains, for each element g of G, a unit, quotients, and a remainder as above.\n\nnote: Note\nIn the global case, a standard representation with a fully reduced remainder is computed.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> f1 = x^2+x^2*y; f2 = y^3+x*y*z; f3 = x^3*y^2+z^4;\n\njulia> g = x^3*y+x^5+x^2*y^2*z^2+z^6;\n\njulia> u, Q, h = reduce_with_quotients_and_unit(g, [f1,f2, f3], ordering = negdegrevlex(R))\n([y+1], [x^3-x*y^2*z^2+x*y+y^2*z^2 0 y*z^2+z^2], 0)\n\njulia> u*g == Q[1]*f1+Q[2]*f2+Q[3]*f3+h\ntrue\n\njulia> G = [g, x*y^3-3*x^2*y^2*z^2];\n\njulia> U, Q, H = reduce_with_quotients_and_unit(G, [f1, f2, f3], ordering = lex(R));\n\njulia> U\n[1 0]\n[0 1]\n\njulia> H\n2-element Vector{QQMPolyRingElem}:\n -z^9 + z^7 + z^6 + z^4\n -3*z^7 + z^6\n\njulia> U*G == Q*[f1, f2, f3]+H\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Computing-Gröbner/Standard-Bases","page":"Gröbner/Standard Bases Over Fields","title":"Computing Gröbner/Standard Bases","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Still keeping the notation introduced at the beginning of this section, let G be a subset of Kx_. Then the leading ideal of G is the ideal of Kx defined by","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"textL_(G)=langle textLT_(g) mid gin Gsetminus0ranglesubset Kx","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"A finite subset G of an ideal Isubset Kx_ is called a standard basis of I (with respect to ) if textL_(G) = textL_(I). A finite subset of Kx_ is a standard basis if it is a standard basis of the ideal it generates. A standard basis with respect to a global monomial ordering is also called a Gröbner basis.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nEvery standard basis of I generates I.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nGröbner bases (standard bases) can be computed using Buchberger's algorithm (Buchberger's algorithm as enhanced by Mora).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"We call a standard basis G = g_1dots g_rsubset Kx_setminus 0 minimal if textLM_(g_i)neq textLM_(g_j) for ineq j.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nThe definition of minimal above deviates from the definition in most textbooks as we do not ask that the leading coefficients of the standard basis elements are 1.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nThe standard bases returned by OSCAR are always minimal in the sense above.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"We call a standard basis G = g_1dots g_r with respect to a global monomial ordering reduced if it is minimal and no term of g_i is divisible by textLM_(g_j), for ineq j. Using power series expansions, we may extend this notion to local and mixed orderings. However, while reduced standard bases can be computed in the global case, they may not be computable (in finitely many steps) in the other cases.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nGiven a monomial ordering on a free Kx-module F = Kx^p with basis e_1 dots e_p, the above notation and results extend naturally to submodules of Kx_^p.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Here are the relevant OSCAR functions for computing Gröbner and standard bases. The elements of a computed basis can be retrieved by using the elements function or its alias gens.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"groebner_basis(I::MPolyIdeal;\n\tord::MonomialOrdering = default_ordering(base_ring(I)),\n\tcomplete_reduction::Bool = false, algorithm::Symbol = :buchberger)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#groebner_basis-Tuple{MPolyIdeal}","page":"Gröbner/Standard Bases Over Fields","title":"groebner_basis","text":"groebner_basis(I::MPolyIdeal;\n ordering::MonomialOrdering = default_ordering(base_ring(I)),\n complete_reduction::Bool = false, algorithm::Symbol = :buchberger)\n\nIf ordering is global, return a Gröbner basis of I with respect to ordering.\n\nThe keyword algorithm can be set to\n\n:buchberger (implementation of Buchberger's algorithm in Singular),\n:hilbert (implementation of a Hilbert driven Gröbner basis computation in Singular),\n:fglm (implementation of the FGLM algorithm in Singular), and\n:f4 (implementation of Faugère's F4 algorithm in the msolve package).\n\nnote: Note\nSee the description of the functions groebner_basis_hilbert_driven, fglm, and f4 in the OSCAR documentation for some more details and for restrictions on the input data when using these versions of the standard basis algorithm.\n\nnote: Note\nThe returned Gröbner basis is reduced if complete_reduction = true.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> I = ideal(R, [y-x^2, z-x^3]);\n\njulia> G = groebner_basis(I)\nGröbner basis with elements\n1 -> y^2 - x*z\n2 -> x*y - z\n3 -> x^2 - y\nwith respect to the ordering\ndegrevlex([x, y, z])\n\njulia> elements(G)\n3-element Vector{QQMPolyRingElem}:\n -x*z + y^2\n x*y - z\n x^2 - y\n\njulia> elements(G) == gens(G)\ntrue\n\njulia> groebner_basis(I, ordering = lex(R))\nGröbner basis with elements\n1 -> y^3 - z^2\n2 -> x*z - y^2\n3 -> x*y - z\n4 -> x^2 - y\nwith respect to the ordering\nlex([x, y, z])\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [\"x\", \"y\"], [1, 3]);\n\njulia> I = ideal(R, [x*y-3*x^4,y^3-2*x^6*y]);\n\njulia> groebner_basis(I)\nGröbner basis with elements\n1 -> 3*x^4 - x*y\n2 -> 2*x^3*y^2 - 3*y^3\n3 -> x*y^3\n4 -> y^4\nwith respect to the ordering\nwdegrevlex([x, y], [1, 3])\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> V = [3*x^3*y+x^3+x*y^3+y^2*z^2, 2*x^3*z-x*y-x*z^3-y^4-z^2,\n 2*x^2*y*z-2*x*y^2+x*z^2-y^4];\n\njulia> I = ideal(R, V);\n\njulia> G = groebner_basis(I, ordering = lex(R), algorithm = :fglm);\n\njulia> length(G)\n8\n\njulia> total_degree(G[8])\n34\n\njulia> leading_coefficient(G[8])\n-91230304237130414552564280286681870842473427917231798336639893796481988733936505735341479640589040146625319419037353645834346047404145021391726185993823650399589880820226804328750\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"standard_basis(I::MPolyIdeal;\n\tord::MonomialOrdering = default_ordering(base_ring(I)),\n\tcomplete_reduction::Bool = false, algorithm::Symbol = :buchberger)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#standard_basis-Tuple{MPolyIdeal}","page":"Gröbner/Standard Bases Over Fields","title":"standard_basis","text":"standard_basis(I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(base_ring(I)),\n complete_reduction::Bool = false, algorithm::Symbol = :buchberger)\n\nReturn a standard basis of I with respect to ordering.\n\nThe keyword algorithm can be set to\n\n:buchberger (implementation of Buchberger's algorithm in Singular),\n:hilbert (implementation of a Hilbert driven Gröbner basis computation in Singular),\n:fglm (implementation of the FGLM algorithm in Singular), and\n:f4 (implementation of Faugère's F4 algorithm in the msolve package).\n\nnote: Note\nSee the description of the functions groebner_basis_hilbert_driven, fglm, and f4 in the OSCAR documentation for some more details and for restrictions on the input data when using these versions of the standard basis algorithm.\n\nnote: Note\nThe returned standard basis is reduced if ordering is global and complete_reduction = true.\n\nExamples\n\njulia> R,(x,y) = polynomial_ring(QQ, [\"x\",\"y\"]);\n\njulia> I = ideal([x*(x+1), x^2-y^2+(x-2)*y]);\n\njulia> standard_basis(I, ordering = negdegrevlex(R))\nStandard basis with elements\n1 -> x\n2 -> y\nwith respect to the ordering\nnegdegrevlex([x, y])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Gröbner-Bases-with-transformation-matrix","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner Bases with transformation matrix","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"groebner_basis_with_transformation_matrix(I::MPolyIdeal;\n\tordering::MonomialOrdering = default_ordering(base_ring(I)),\n\tcomplete_reduction::Bool=false)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#groebner_basis_with_transformation_matrix-Tuple{MPolyIdeal}","page":"Gröbner/Standard Bases Over Fields","title":"groebner_basis_with_transformation_matrix","text":"groebner_basis_with_transformation_matrix(I::MPolyIdeal;\n ordering::MonomialOrdering = default_ordering(base_ring(I)),\n complete_reduction::Bool=false)\n\nReturn a pair G, T, say, where G is a Gröbner basis of I with respect to ordering, and T is a transformation matrix from gens(I) to G. That is, gens(I)*T == G.\n\nnote: Note\nThe returned Gröbner basis is reduced if complete_reduction = true.\n\nExamples\n\njulia> R,(x,y) = polynomial_ring(QQ,[\"x\",\"y\"]);\n\njulia> I = ideal([x*y^2-1,x^3+y^2+x*y]);\n\njulia> G, T = groebner_basis_with_transformation_matrix(I)\n(Gröbner basis with elements\n1 -> x*y^2 - 1\n2 -> x^3 + x*y + y^2\n3 -> y^4 + x^2 + y\nwith respect to the ordering\ndegrevlex([x, y]), [1 0 -x^2-y; 0 1 y^2])\n\njulia> gens(I)*T == gens(G)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"standard_basis_with_transformation_matrix(I::MPolyIdeal;\n\tordering::MonomialOrdering = default_ordering(base_ring(I)),\n\tcomplete_reduction::Bool=false)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#standard_basis_with_transformation_matrix-Tuple{MPolyIdeal}","page":"Gröbner/Standard Bases Over Fields","title":"standard_basis_with_transformation_matrix","text":"standard_basis_with_transformation_matrix(I::MPolyIdeal;\n ordering::MonomialOrdering = default_ordering(base_ring(I)),\n complete_reduction::Bool=false)\n\nReturn a pair G, T, say, where G is a standard basis of I with respect to ordering, and T is a transformation matrix from gens(I) to G. That is, gens(I)*T == G.\n\nnote: Note\nThe returned Gröbner basis is reduced if ordering is a global monomial odering and complete_reduction = true.\n\nExamples\n\njulia> R,(x,y) = polynomial_ring(QQ,[\"x\",\"y\"]);\n\njulia> I = ideal([x*y^2-1,x^3+y^2+x*y]);\n\njulia> G, T = standard_basis_with_transformation_matrix(I, ordering=neglex(R))\n(Standard basis with elements\n1 -> 1 - x*y^2\nwith respect to the ordering\nneglex([x, y]), [-1; 0])\n\njulia> gens(I)*T == gens(G)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Gröbner-Basis-Conversion-Algorithms","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner Basis Conversion Algorithms","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"The performance of Buchberger's Gröbner basis algorithm is sensitive to the choice of monomial ordering. A Gröbner basis computation with respect to a less favorable ordering such as lex may easily run out of time or memory even in cases where a Gröbner basis computation with respect to a more efficient ordering such as degrevlex is very well feasible. Gröbner basis conversion algorithms and the Hilbert driven Buchberger algorithm discussed subsequently take their cue from this observation.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Gröbner basis conversion algorithms proceed along the following lines:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Given an ideal I of a multivariate polynomial ring over a field and a slow destination_ordering, compute a Gröbner basis for I with respect to an appropriately chosen fast start_ordering.\nConvert the result to a Gröbner basis with respect to the given slow destination_ordering.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"The algorithms differ in how they perform the conversion.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#The-FGLM-Algorithm","page":"Gröbner/Standard Bases Over Fields","title":"The FGLM Algorithm","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"fglm(I::MPolyIdeal; start_ordering::MonomialOrdering = default_ordering(base_ring(I)),\n destination_ordering::MonomialOrdering)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#fglm-Tuple{MPolyIdeal}","page":"Gröbner/Standard Bases Over Fields","title":"fglm","text":"fglm(I::MPolyIdeal; start_ordering::MonomialOrdering = default_ordering(base_ring(I)),\n destination_ordering::MonomialOrdering)\n\nGiven a zero-dimensional ideal I, return the reduced Gröbner basis of I with respect to destination_ordering.\n\nnote: Note\nBoth start_ordering and destination_ordering must be global and the base ring of I must be a polynomial ring over a field.\n\nnote: Note\nThe function implements the Gröbner basis conversion algorithm by Faugère, Gianni, Lazard, and Mora. See J.C. Faugère, P. Gianni, D. Lazard, T. Mora (1993) for more information.\n\nExamples\n\njulia> R, (a, b, c, d, e) = polynomial_ring(QQ, [\"a\", \"b\", \"c\", \"d\", \"e\"]);\n\njulia> f1 = a+b+c+d+e;\n\njulia> f2 = a*b+b*c+c*d+a*e+d*e;\n\njulia> f3 = a*b*c+b*c*d+a*b*e+a*d*e+c*d*e;\n\njulia> f4 = b*c*d+a*b*c*e+a*b*d*e+a*c*d*e+b*c*d*e;\n\njulia> f5 = a*b*c*d*e-1;\n\njulia> I = ideal(R, [f1, f2, f3, f4, f5]);\n\njulia> G = fglm(I, destination_ordering = lex(R));\n\njulia> length(G)\n8\n\njulia> total_degree(G[8])\n60\n\njulia> leading_coefficient(G[8])\n83369589588385815165248207597941242098312973356252482872580035860533111990678631297423089011608753348453253671406641805924218003925165995322989635503951507226650115539638517111445927746874479234\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Gröbner-Walk-Algorithms","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner Walk Algorithms","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#The-Hilbert-driven-Buchberger-Algorithm","page":"Gröbner/Standard Bases Over Fields","title":"The Hilbert driven Buchberger Algorithm","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Calling the functions standard_basis and groebner_basis with algorithm = :hilbert in OSCAR triggers a version of the Hilbert driven Gröbner basis algorithm which proceeds along the following lines.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Given an ideal I of a multivariate polynomial ring R over a field K and a slow destination_ordering, check whether I is homogeneous with respect to the standard mathbb Z-grading on R. If so, set start_ordering to degrevlex and go to step 3.\nCheck whether there exists a mathbb Z-grading on R with positive weights such that I is homogeneous with respect to this grading. If so, let start_ordering be the corresponding weight ordering. If not, go to step 5.\nCompute a Gröbner basis of I with respect to start_ordering and use this Gröbner basis to compute the Hilbert function of RI.\nCompute a Gröbner basis with respect to destination_ordering, proceeding by increasing (weighted) degree, and skipping all further Buchberger tests in a given (weighted) degree as soon as the leading terms found so far account for the Hilbert function in that (weighted) degree. Return the computed Gröbner basis.\nExtend R to a polynomial ring S by appending an extra variable, equip S with the standard mathbb Z-grading, and let I^hsubset S be the homogenization of I with respect to the extra variable. Compute a Gröbner basis of I with respect to degrevlex on R, and homogenize its elements to obtain a Gröbner basis of I^h with respect to degrevlex on S. Use the latter basis to compute the Hilbert function of SI^h. Extend destination_ordering to a block ordering on S. Following the recipe in step 4, compute a Gröbner basis of SI^h with respect to the extended ordering. Return the dehomogenization of this basis with respect to the extra variable.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"If the characteristic of K is zero, by semi-continuity of the Hilbert function, it is sufficient to perform step 3 for the reduction of I modulo a conveniently chosen prime number rather than for I itself.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"note: Note\nIf appropriate weights and/or the Hilbert function with respect to appropriate weights are already known to the user, this information can be entered when calling the Hilbert driven Gröbner basis algorithm as follows:","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"groebner_basis_hilbert_driven(I::MPolyIdeal{P};\n destination_ordering::MonomialOrdering,\n complete_reduction::Bool = false,\n weights::Vector{Int} = ones(Int, ngens(base_ring(I))),\n hilbert_numerator::Union{Nothing, ZZPolyRingElem} = nothing) where {P <: MPolyRingElem}","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#groebner_basis_hilbert_driven-Union{Tuple{MPolyIdeal{P}}, Tuple{P}} where P<:MPolyRingElem","page":"Gröbner/Standard Bases Over Fields","title":"groebner_basis_hilbert_driven","text":"groebner_basis_hilbert_driven(I::MPolyIdeal{P}; destination_ordering::MonomialOrdering,\n complete_reduction::Bool = false,\n weights::Vector{Int} = ones(Int, ngens(base_ring(I))),\n hilbert_numerator::Union{Nothing, ZZPolyRingElem} = nothing) \n where {P <: MPolyRingElem}\n\nReturn a Gröbner basis of I with respect to destination_ordering.\n\nnote: Note\nThe function implements a version of the Hilbert driven Gröbner basis algorithm. See the corresponding section of the OSCAR documentation for some details.\n\nnote: Note\nAll weights must be positive. If no weight vector is entered by the user, all weights are set to 1. An error is thrown if the generators of I are not homogeneous with respect to the corresponding (weighted) degree. \n\nnote: Note\nIf R denotes the parent ring of I, and p qinmathbb Zt are polynomials such that pq represents the Hilbert series of RI as a rational function with denominator q = (1-t^w_1)cdots (1-t^w_n) where n is the number of variables of R, and w_1 dots w_n are the assigned weights, then hilbert_numerator is meant to be p. If this numerator is not entered by the user, it will be computed internally.\n\nExamples\n\njulia> R, (a, b, c, d, e, f, g) = polynomial_ring(QQ, [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]);\n\njulia> V = [-3*a^2+2*f*b+3*f*d, (3*g*b+3*g*e)*a-3*f*c*b,\n -3*g^2*a^2-c*b^2*a-g^2*f*e-g^4, e*a-f*b-d*c];\n\njulia> I = ideal(R, V);\n\njulia> o = degrevlex([a, b, c])*degrevlex([d, e, f, g]);\n\njulia> G = groebner_basis_hilbert_driven(I, destination_ordering = o);\n\njulia> length(G)\n296\n\njulia> total_degree(G[49])\n30\n\njulia> R, (x, y, z) = polynomial_ring(GF(32003), [\"x\", \"y\", \"z\"]);\n\njulia> f1 = x^2*y+169*y^21+151*x*y*z^10;\n\njulia> f2 = 6*x^2*y^4+x*z^14+3*z^24;\n\njulia> f3 = 11*x^3+5*x*y^10*z^10+2*y^20*z^10+y^10*z^20;\n\njulia> I = ideal(R, [f1, f2,f3]);\n\njulia> W = [10, 1, 1];\n\njulia> GB = groebner_basis_hilbert_driven(I, destination_ordering = lex(R), weights = W);\n\njulia> length(GB)\n40\n\njulia> R, (x, y, z) = polynomial_ring(GF(32003), [\"x\", \"y\", \"z\"]);\n\njulia> f1 = x^2*y+169*y^21+151*x*y*z^10;\n\njulia> f2 = 6*x^2*y^4+x*z^14+3*z^24;\n\njulia> f3 = 11*x^3+5*x*y^10*z^10+2*y^20*z^10+y^10*z^20;\n\njulia> I = ideal(R, [f1, f2,f3]);\n\njulia> W = [10, 1, 1];\n\njulia> S, t = polynomial_ring(ZZ, \"t\")\n(Univariate polynomial ring in t over ZZ, t)\n\njulia> hn = -t^75 + t^54 + t^51 + t^45 - t^30 - t^24 - t^21 + 1\n-t^75 + t^54 + t^51 + t^45 - t^30 - t^24 - t^21 + 1\n\njulia> GB = groebner_basis_hilbert_driven(I, destination_ordering = lex(R), weights = W, hilbert_numerator = hn);\n\njulia> length(GB)\n40\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Faugère's-F4-Algorithm","page":"Gröbner/Standard Bases Over Fields","title":"Faugère's F4 Algorithm","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"warning: Expert function for computing Gröbner bases\nWith many adjustable keyword arguments, the following function provides low-level implementations of various versions of the Gröbner basis algorithm. Use these functions only if you know what you are doing.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"groebner_basis_f4( I::MPolyIdeal; initial_hts::Int=17, nr_thrds::Int=1, max_nr_pairs::Int=0, la_option::Int=2, reduce_gb::Int=1, info_level::Int=0)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#groebner_basis_f4-Tuple{MPolyIdeal}","page":"Gröbner/Standard Bases Over Fields","title":"groebner_basis_f4","text":"groebner_basis_f4(I::MPolyIdeal, )\n\nCompute a Gröbner basis of I with respect to degrevlex using Faugère's F4 algorithm. See Jean-Charles Faugère (1999) for more information.\n\nnote: Note\nAt current state only prime fields of characteristic 0 < p < 2^{31} are supported.\n\nPossible keyword arguments\n\ninitial_hts::Int=17: initial hash table size log_2.\nnr_thrds::Int=1: number of threads for parallel linear algebra.\nmax_nr_pairs::Int=0: maximal number of pairs per matrix, only bounded by minimal degree if 0.\nla_option::Int=2: linear algebra option: exact sparse-dense (1), exact sparse (2, default), probabilistic sparse-dense (42), probabilistic sparse(44).\neliminate::Int=0: size of first block of variables to be eliminated.\ncomplete_reduction::Bool=true: compute a reduced Gröbner basis for I\ninfo_level::Int=0: info level printout: off (0, default), summary (1), detailed (2).\n\nExamples\n\njulia> R,(x,y,z) = polynomial_ring(GF(101), [\"x\",\"y\",\"z\"], ordering=:degrevlex)\n(Multivariate polynomial ring in 3 variables over GF(101), fpMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x+2*y+2*z-1, x^2+2*y^2+2*z^2-x, 2*x*y+2*y*z-y])\nideal(x + 2*y + 2*z + 100, x^2 + 2*y^2 + 2*z^2 + 100*x, 2*x*y + 2*y*z + 100*y)\n\njulia> groebner_basis_f4(I)\nGröbner basis with elements\n1 -> x + 2*y + 2*z + 100\n2 -> y*z + 82*z^2 + 10*y + 40*z\n3 -> y^2 + 60*z^2 + 20*y + 81*z\n4 -> z^3 + 28*z^2 + 64*y + 13*z\nwith respect to the ordering\ndegrevlex([x, y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Leading-Ideals","page":"Gröbner/Standard Bases Over Fields","title":"Leading Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"leading_ideal(G::Vector{T}; ordering::MonomialOrdering = default_ordering(parent(G[1]))) where T <: MPolyRingElem\nleading_ideal(I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(base_ring(I)))","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#leading_ideal-Union{Tuple{Vector{T}}, Tuple{T}} where T<:MPolyRingElem","page":"Gröbner/Standard Bases Over Fields","title":"leading_ideal","text":"leading_ideal(G::Vector{T}; ordering::MonomialOrdering = default_ordering(parent(G[1]))) \n where T <: MPolyRingElem\n\nReturn the leading ideal of G with respect to ordering.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> L = leading_ideal([x*y^2-3*x, x^3-14*y^5], ordering=degrevlex(R))\nideal(x*y^2, y^5)\n\njulia> L = leading_ideal([x*y^2-3*x, x^3-14*y^5], ordering=lex(R))\nideal(x*y^2, x^3)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#leading_ideal-Tuple{MPolyIdeal}","page":"Gröbner/Standard Bases Over Fields","title":"leading_ideal","text":"leading_ideal(I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(base_ring(I)))\n\nReturn the leading ideal of I with respect to ordering.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R,[x*y^2-3*x, x^3-14*y^5])\nideal(x*y^2 - 3*x, x^3 - 14*y^5)\n\njulia> L = leading_ideal(I, ordering=degrevlex(R))\nideal(x*y^2, x^4, y^5)\n\njulia> L = leading_ideal(I, ordering=lex(R))\nideal(y^7, x*y^2, x^3)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Normal-Forms","page":"Gröbner/Standard Bases Over Fields","title":"Normal Forms","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Given a polynomial gin Kx, an ideal Isubset Kx, and a global monomial ordering on the monomials in x, the fully reduced remainder h in a standard expression on division by the elements of a Gröbner basis of I with respect to is uniquely determined by g, I, and (and does not depend on the choice of Gröbner basis). We refer to such a remainder as the normal form of g mod I, with respect to .","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"normal_form(g::T, I::MPolyIdeal; ordering::MonomialOrdering = default_ordering(base_ring(I))) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#normal_form-Union{Tuple{T}, Tuple{T, MPolyIdeal}} where T<:MPolyRingElem","page":"Gröbner/Standard Bases Over Fields","title":"normal_form","text":"normal_form(g::T, I::MPolyIdeal; \n ordering::MonomialOrdering = default_ordering(base_ring(I))) where T <: MPolyRingElem\n\nCompute the normal form of g mod I with respect to ordering.\n\nnormal_form(G::Vector{T}, I::MPolyIdeal; \n ordering::MonomialOrdering = default_ordering(base_ring(I))) where T <: MPolyRingElem\n\nReturn a Vector which contains for each element g of G a normal form as above.\n\nExamples\n\njulia> R,(a,b,c) = polynomial_ring(QQ,[\"a\",\"b\",\"c\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[a, b, c])\n\njulia> J = ideal(R,[-1+c+b,-1+b+c*a+2*a*b])\nideal(b + c - 1, 2*a*b + a*c + b - 1)\n\njulia> gens(groebner_basis(J))\n2-element Vector{QQMPolyRingElem}:\n b + c - 1\n a*c - 2*a + c\n\njulia> normal_form(-1+c+b+a^3, J)\na^3\n\njulia> R,(a,b,c) = polynomial_ring(QQ,[\"a\",\"b\",\"c\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[a, b, c])\n\njulia> A = [-1+c+b+a^3,-1+b+c*a+2*a^3,5+c*b+c^2*a]\n3-element Vector{QQMPolyRingElem}:\n a^3 + b + c - 1\n 2*a^3 + a*c + b - 1\n a*c^2 + b*c + 5\n\njulia> J = ideal(R,[-1+c+b,-1+b+c*a+2*a*b])\nideal(b + c - 1, 2*a*b + a*c + b - 1)\n\njulia> gens(groebner_basis(J))\n2-element Vector{QQMPolyRingElem}:\n b + c - 1\n a*c - 2*a + c\n\njulia> normal_form(A, J)\n3-element Vector{QQMPolyRingElem}:\n a^3\n 2*a^3 + 2*a - 2*c\n 4*a - 2*c^2 - c + 5\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#Syzygies","page":"Gröbner/Standard Bases Over Fields","title":"Syzygies","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"We refer to the section on modules for more on syzygies.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"syzygy_generators(G::Vector{<:MPolyRingElem})","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#syzygy_generators-Tuple{Vector{<:MPolyRingElem}}","page":"Gröbner/Standard Bases Over Fields","title":"syzygy_generators","text":"syzygy_generators(G::Vector{<:MPolyRingElem})\n\nReturn generators for the syzygies on the polynomials given as elements of G.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> S = syzygy_generators([x^3+y+2,x*y^2-13*x^2,y-14])\n3-element Vector{FreeModElem{QQMPolyRingElem}}:\n (-y + 14)*e[2] + (-13*x^2 + x*y^2)*e[3]\n (-169*y + 2366)*e[1] + (-13*x*y + 182*x - 196*y + 2744)*e[2] + (13*x^2*y^2 - 2548*x^2 + 196*x*y^2 + 169*y + 338)*e[3]\n (-13*x^2 + 196*x)*e[1] + (-x^3 - 16)*e[2] + (x^4*y + 14*x^4 + 13*x^2 + 16*x*y + 28*x)*e[3]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#Hypersurface-models","page":"Hypersurface models","title":"Hypersurface models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/#Introduction","page":"Hypersurface models","title":"Introduction","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"A hypersurface model describes a particular form of an elliptic fibration. For now, we consider such models in toric settings only, that is we restrict to a toric base space B and assume that the generic fiber is a hypersurface in a 2-dimensional toric fiber ambient space F.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"In addition, we shall assume that the first two homogeneous coordinates of F transform in the divisor classes D_1 and D_2 over the base B of the elliptic fibration. The remaining coordinates of F are assumed to transform in the trivial bundle over B. See Denis Klevers, Damian Kaloni Mayorga Pena, Paul-Konstantin Oehlmann, Hernan Piragua, Jonas Reuter (2015) for more details.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Given this set of information, it is possible to compute a toric ambient space A for the elliptic fibration. The elliptic fibration is then a hypersurface in this toric space A. Furthermore, since we assume that this fibration is Calabi-Yau, it is clear that the hypersurface equation is a (potentially very special) section of the overlineK_A. This hypersurface equation completes the information required about a hypersurface model.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#Constructors","page":"Hypersurface models","title":"Constructors","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"We aim to provide support for hypersurface models over the following bases:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"a toric variety,\na toric scheme,\na (covered) scheme.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"[Often, one also wishes to obtain information about a hypersurface model without explicitly specifying the base space. Also for this application, we provide support.]","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Finally, we provide support for some standard constructions.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Before we detail these constructors, we must comment on the constructors over toric base spaces. Namely, in order to construct a hypersurface model, we first have to construct the ambient space in question. For a toric base, one way to achieve this is by means of triangulations. However, this is a rather time consuming and computationally challenging task, which leads to a huge number of ambient spaces. Even more, typically one wishes to only pick one of thees many ambient spaces. For instance, a common and often appropriate choice is a toric ambient space which contains the toric base space in a manifest way.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"To circumvent this very demanding computation, our constructors operate in the opposite direction. That is, they begin by extracting the rays and maximal cones of the chosen toric base space. Subsequently, those rays and cones are extended to form one of the many toric ambient spaces. This proves hugely superior in performance than going through the triangulation task of enumerating all possible toric ambient spaces. One downside of this strategy is that the so-constructed ambient space need not be smooth.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#A-toric-variety-as-base-space","page":"Hypersurface models","title":"A toric variety as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"We require that the provided toric base space is complete. This is a technical limitation as of now. The functionality of OSCAR only allows us to compute a section basis (or a finite subset thereof) for complete toric varieties. In the future, this could be extended.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Completeness is an expensive check. Therefore, we provide an optional argument which one can use to disable this check if desired. To this end, one passes the optional argument completeness_check = false as last argument to the constructor. The following examples demonstrate this:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"hypersurface_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)\nhypersurface_model(base::AbstractNormalToricVariety, fiber_ambient_space::AbstractNormalToricVariety, D1::ToricDivisorClass, D2::ToricDivisorClass; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model-Tuple{Oscar.AbstractNormalToricVariety}","page":"Hypersurface models","title":"hypersurface_model","text":"hypersurface_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)\n\nConstruct a hypersurface model. This constructor takes mathbbP^231 as fiber ambient space with coordinates xyz and ensures that x transforms as 2 overlineK_B_3 and y as 3 overlineK_B_3.\n\nExamples\n\njulia> base = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> hypersurface_model(base; completeness_check = false)\nHypersurface model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model-Tuple{Oscar.AbstractNormalToricVariety, Oscar.AbstractNormalToricVariety, ToricDivisorClass, ToricDivisorClass}","page":"Hypersurface models","title":"hypersurface_model","text":"hypersurface_model(base::AbstractNormalToricVariety, fiber_ambient_space::AbstractNormalToricVariety, D1::ToricDivisorClass, D2::ToricDivisorClass; completeness_check::Bool = true)\n\nConstruct a hypersurface model, for which the user can specify a fiber ambient space as well as divisor classes of the toric base space, in which the first two homogeneous coordinates of the fiber ambient space transform.\n\nExamples\n\njulia> base = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])\nNormal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor\n\njulia> set_coordinate_names(fiber_ambient_space, [\"x\", \"y\", \"z\"])\n\njulia> D1 = 2 * anticanonical_divisor_class(base)\nDivisor class on a normal toric variety\n\njulia> D2 = 3 * anticanonical_divisor_class(base)\nDivisor class on a normal toric variety\n\njulia> hypersurface_model(base, fiber_ambient_space, D1, D2; completeness_check = false)\nHypersurface model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#A-toric-scheme-as-base-space","page":"Hypersurface models","title":"A toric scheme as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"For the same reasons as above, the toric base must be complete. Similar to toric varieties as bases, we can use the optional argument completeness_check = false to switch off the expensive completeness check. The following examples demonstrate this:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"hypersurface_model(base::ToricCoveredScheme; completeness_check::Bool = true)\nhypersurface_model(base::ToricCoveredScheme, fiber_ambient_space::ToricCoveredScheme, D1::ToricDivisorClass, D2::ToricDivisorClass; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model-Tuple{ToricCoveredScheme}","page":"Hypersurface models","title":"hypersurface_model","text":"hypersurface_model(base::ToricCoveredScheme; completeness_check::Bool = true)\n\nConstruct a hypersurface model. This constructor takes mathbbP^231 as fiber ambient space with coordinates xyz and ensures that x transforms as 2 overlineK_B_3 and y as 3 overlineK_B_3.\n\nExamples\n\njulia> base = projective_space(ToricCoveredScheme, 2)\nScheme of a toric variety\n\njulia> hypersurface_model(base; completeness_check = false)\nHypersurface model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model-Tuple{ToricCoveredScheme, ToricCoveredScheme, ToricDivisorClass, ToricDivisorClass}","page":"Hypersurface models","title":"hypersurface_model","text":"hypersurface_model(base::ToricCoveredScheme, fiber_ambient_space::ToricCoveredScheme, D1::ToricDivisorClass, D2::ToricDivisorClass; completeness_check::Bool = true)\n\nConstruct a hypersurface model, for which the user can specify a fiber ambient space as well as divisor classes of the toric base space, in which the first two homogeneous coordinates of the fiber ambient space transform.\n\nExamples\n\njulia> base = projective_space(ToricCoveredScheme, 2)\nScheme of a toric variety\n\njulia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])\nNormal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor\n\njulia> set_coordinate_names(fiber_ambient_space, [\"x\", \"y\", \"z\"])\n\njulia> fiber_ambient_space = ToricCoveredScheme(fiber_ambient_space)\nScheme of a toric variety\n\njulia> D1 = 2 * anticanonical_divisor_class(underlying_toric_variety(base))\nDivisor class on a normal toric variety\n\njulia> D2 = 3 * anticanonical_divisor_class(underlying_toric_variety(base))\nDivisor class on a normal toric variety\n\njulia> h = hypersurface_model(base, fiber_ambient_space, D1, D2; completeness_check = false)\nHypersurface model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#A-(covered)-scheme-as-base-space","page":"Hypersurface models","title":"A (covered) scheme as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"This functionality does not yet exist.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#Base-space-not-specified","page":"Hypersurface models","title":"Base space not specified","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"This method constructs a hypersurface model over a base space, where this base space is not (fully) specified. We currently provide the following constructors:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"hypersurface_model(auxiliary_base_vars::Vector{String}, auxiliary_base_grading::Matrix{Int64}, d::Int, fiber_ambient_space::NormalToricVariety, D1::Vector{Int64}, D2::Vector{Int64}, p::MPolyRingElem)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model-Tuple{Vector{String}, Matrix{Int64}, Int64, NormalToricVariety, Vector{Int64}, Vector{Int64}, MPolyRingElem}","page":"Hypersurface models","title":"hypersurface_model","text":"hypersurface_model(auxiliary_base_vars::Vector{String}, auxiliary_base_grading::Matrix{Int64}, d::Int, fiber_ambient_space::NormalToricVariety, D1::Vector{Int64}, D2::Vector{Int64}, p::MPolyRingElem)\n\nThis method constructs a hypersurface model over a base space that is not fully specified. In the background, we construct an auxiliary toric base space. This method requires the following information:\n\nThe names of the homogeneous coordinates of the auxiliary toric base space.\nThe grading of the Cox ring of the auxiliary toric base space.\nThe weights corresponding to the divisor class D_1 of the auxiliary toric base space under which the first fiber coordinate transforms.\nThe weights corresponding to the divisor class D_2 of the auxiliary toric base space under which the first fiber coordinate transforms.\nThe dimension of the auxiliary toric base space.\nThe fiber ambient space.\nThe hypersurface equation.\n\nNote that many studies in the literature use the class of the anticanonical bundle in their analysis. We anticipate this by adding this class as a variable of the auxiliary base space, unless the user already provides this grading. Our convention is that the first grading refers to Kbar and that the homogeneous variable corresponding to this class carries the name \"Kbar\".\n\nThe following example exemplifies this constructor.\n\nExamples\n\njulia> auxiliary_base_vars = [\"a1\", \"a21\", \"a32\", \"a43\", \"a65\", \"w\"]\n6-element Vector{String}:\n \"a1\"\n \"a21\"\n \"a32\"\n \"a43\"\n \"a65\"\n \"w\"\n\njulia> auxiliary_base_grading = [1 2 3 4 6 0; 0 -1 -2 -3 -5 1]\n2×6 Matrix{Int64}:\n 1 2 3 4 6 0\n 0 -1 -2 -3 -5 1\n\njulia> D1 = [4,0]\n2-element Vector{Int64}:\n 4\n 0\n\njulia> D2 = [6,0]\n2-element Vector{Int64}:\n 6\n 0\n\njulia> d = 3\n3\n\njulia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])\nNormal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor\n\njulia> set_coordinate_names(fiber_ambient_space, [\"x\", \"y\", \"z\"])\n\njulia> auxiliary_ambient_ring, (a1, a21, a32, a43, a65, w, x, y, z) = QQ[\"a1\", \"a21\", \"a32\", \"a43\", \"a65\", \"w\", \"x\", \"y\", \"z\"]\n(Multivariate polynomial ring in 9 variables over QQ, QQMPolyRingElem[a1, a21, a32, a43, a65, w, x, y, z])\n\njulia> p = x^3 - y^2 - x * y * z * a1 + x^2 * z^2 * a21 * w - y * z^3 * a32 * w^2 + x * z^4 * a43 * w^3 + z^6 * a65 * w^5\n-a1*x*y*z + a21*w*x^2*z^2 - a32*w^2*y*z^3 + a43*w^3*x*z^4 + a65*w^5*z^6 + x^3 - y^2\n\njulia> h = hypersurface_model(auxiliary_base_vars, auxiliary_base_grading, d, fiber_ambient_space, D1, D2, p)\nAssuming that the first row of the given grading is the grading under Kbar\n\nHypersurface model over a not fully specified base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#Standard-constructions","page":"Hypersurface models","title":"Standard constructions","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"We provide convenient constructions of hypersurface models over famous base spaces. Currently, we support the following:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"hypersurface_model_over_projective_space(d::Int)\nhypersurface_model_over_hirzebruch_surface(r::Int)\nhypersurface_model_over_del_pezzo_surface(b::Int)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model_over_projective_space-Tuple{Int64}","page":"Hypersurface models","title":"hypersurface_model_over_projective_space","text":"hypersurface_model_over_projective_space(d::Int)\n\nThis method constructs a hypersurface model over the projective space.\n\nExamples\n\njulia> hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model_over_hirzebruch_surface-Tuple{Int64}","page":"Hypersurface models","title":"hypersurface_model_over_hirzebruch_surface","text":"hypersurface_model_over_hirzebruch_surface(r::Int)\n\nThis method constructs a hypersurface model over a Hirzebruch surface.\n\nExamples\n\njulia> hypersurface_model_over_hirzebruch_surface(1)\nHypersurface model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model_over_del_pezzo_surface-Tuple{Int64}","page":"Hypersurface models","title":"hypersurface_model_over_del_pezzo_surface","text":"hypersurface_model_over_del_pezzo_surface(b::Int)\n\nThis method constructs a hypersurface model over a del-Pezzo surface.\n\nExamples\n\njulia> hypersurface_model_over_del_pezzo_surface(3)\nHypersurface model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#Attributes","page":"Hypersurface models","title":"Attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/#Basic-attributes","page":"Hypersurface models","title":"Basic attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"For all hypersurface models – irrespective over whether the base is toric or not – we support the following attributes:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"hypersurface_equation(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_equation-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"hypersurface_equation","text":"hypersurface_equation(h::HypersurfaceModel)\n\nReturn the hypersurface equation.\n\njulia> h = hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\njulia> hypersurface_equation(h);\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"One can also decide to specify a custom hypersurface equation:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"set_hypersurface_equation(h::HypersurfaceModel, p::MPolyRingElem)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#set_hypersurface_equation-Tuple{HypersurfaceModel, MPolyRingElem}","page":"Hypersurface models","title":"set_hypersurface_equation","text":"set_hypersurface_equation(h::HypersurfaceModel, p::MPolyRingElem)\n\nSet the hypersurface equation to a custom value.\n\njulia> h = hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\njulia> R = parent(hypersurface_equation(h));\n\njulia> new_poly = gens(R)[4]^3\nx^3\n\njulia> set_hypersurface_equation(h, new_poly);\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"The fiber ambient space can be accessed via","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"fiber_ambient_space(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#fiber_ambient_space-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"fiber_ambient_space","text":"fiber_ambient_space(HypersurfaceModel)\n\nReturn the fiber ambient space of the hypersurface model.\n\njulia> h = hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\njulia> fiber_ambient_space(h)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"In case the hypersurface model is constructed over a not fully specified base, recall that we construct an auxiliary (toric) base space as well as an auxiliary (toric) ambient space. The (auxiliary) base and ambient space can be accessed with the following functions:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"base_space(h::HypersurfaceModel)\nambient_space(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#base_space-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"base_space","text":"base_space(h::HypersurfaceModel)\n\nReturn the base space of the hypersurface model.\n\njulia> h = hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\njulia> base_space(h)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#ambient_space-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"ambient_space","text":"ambient_space(h::HypersurfaceModel)\n\nReturn the ambient space of the hypersurface model.\n\njulia> h = hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\njulia> ambient_space(h)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"The following method allows to tell if the base/ambient space is auxiliary or not:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"base_fully_specified(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#base_fully_specified-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"base_fully_specified","text":"base_fully_specified(h::HypersurfaceModel)\n\nReturn true is the hypersurface model has a concrete base space and false otherwise.\n\njulia> h = hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\njulia> base_fully_specified(h)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"The user can decide to get an information whenever an auxiliary base space, auxiliary ambient space or auxiliary hypersurface have been computed. To this end, one invokes set_verbosity_level(:HypersurfaceModel, 1). More background information is available here.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#Attributes-in-toric-settings","page":"Hypersurface models","title":"Attributes in toric settings","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"If the base space of the hypersurface model is a toric space, then we also provide a special type for the Calabi-Yau hypersurface:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"calabi_yau_hypersurface(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#calabi_yau_hypersurface-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"calabi_yau_hypersurface","text":"calabi_yau_hypersurface(h::HypersurfaceModel)\n\nReturn the Calabi-Yau hypersurface in the toric ambient space which defines the hypersurface model.\n\njulia> h = hypersurface_model_over_projective_space(2)\nHypersurface model over a concrete base\n\njulia> calabi_yau_hypersurface(h)\nClosed subvariety of a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#Attributes-based-on-the-corresponding-global-Tate-and-Weierstrass-models","page":"Hypersurface models","title":"Attributes based on the corresponding global Tate and Weierstrass models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Currently, we do not provide functionality to convert a hypersurface model into a Weierstrass or global Tate model. Still, for some constructions this might be known or detailed in the literature. If the user wishes, one can then associate a corresponding Weierstrass or global Tate model as follows:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"set_weierstrass_model(h::HypersurfaceModel, w::WeierstrassModel)\nset_global_tate_model(h::HypersurfaceModel, w::GlobalTateModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#set_weierstrass_model-Tuple{HypersurfaceModel, WeierstrassModel}","page":"Hypersurface models","title":"set_weierstrass_model","text":"set_weierstrass_model(h::HypersurfaceModel, w::WeierstrassModel)\n\nAllows to define the Weierstrass model corresponding to the hypersurface model.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#set_global_tate_model-Tuple{HypersurfaceModel, GlobalTateModel}","page":"Hypersurface models","title":"set_global_tate_model","text":"set_global_tate_model(h::HypersurfaceModel, w::GlobalTateModel)\n\nAllows to define the global Tate model corresponding to the hypersurface model.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"These models can then be accessed with the following functions:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"weierstrass_model(h::HypersurfaceModel)\nglobal_tate_model(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#weierstrass_model-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"weierstrass_model","text":"weierstrass_model(h::HypersurfaceModel)\n\nReturn the Weierstrass model corresponding to the hypersurface model, provided that the latter is known.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#global_tate_model-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"global_tate_model","text":"global_tate_model(h::HypersurfaceModel)\n\nReturn the global Tate model corresponding to the hypersurface model, provided that the latter is known.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Provided that the corresponding Weierstrass model is known for a hypersurface model, the following functionality is available. It returns the attribute in question of the corresponding Weierstrass model.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"discriminant(h::HypersurfaceModel)\nsingular_loci(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#discriminant-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"discriminant","text":"discriminant(h::HypersurfaceModel)\n\nReturn the discriminant of the hypersurface model.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#singular_loci-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"singular_loci","text":"singular_loci(h::HypersurfaceModel)\n\nReturn the singular loci of the hypersurface model, along with the order of vanishing of the Weierstrass sections and discriminant (f g Delta)` at each locus. Also the refined Tate fiber type is returned.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#Welcome-to-FTheoryTools","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/#Goal","page":"Welcome to FTheoryTools","title":"Goal","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"We aim to automate a number of recurring and (at least in part) tedious computations in F-theory model building as described in large detail in Timo Weigand (2018). Specifically, we focus on the following setups:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"4d F-theory compactifications,\ndefined by a global and singular Weierstrass model as codimension 1 locus of a toric ambient space Y,\nwhich can be crepantly resolved.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Some of the techniques/algorithms extend naturally to more general settings. For example, it is not at all necessary to restrict to 4-dimensional settings (or alternatively, base spaces of dimension 3). Indeed, the current implementation does allow for arbitrary base dimension. For more extensions that we might address in the future, please take a look at the section \"possible future extensions\" below.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"We aim for the following workflow:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"User input:\nWeierstrass polynomial P_W,\nData defining the toric ambient space Y (if applicable),\nChoice of resolved phase (if applicable),\nGenerating sections (for operatornameU(1) symmetries).\nOutput:\nSingular loci in codimension 1, 2, and 3,\nDefining data of resolved geometry,\n(Pictures of) fibre diagrams of resolved fibre over the originally singular loci, including intersections of operatornameU(1)-sections,\nGauge group,\nTopological data (e.g., Euler number).","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#Status","page":"Welcome to FTheoryTools","title":"Status","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"This project just began, and is therefore in its experimental stage. Upcoming tasks include, but are not limited, to the following:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"The irrelevant ideal, SR ideal, and ideal of linear relations may need to be modified when the exceptional coordinate \"e\" is included in the blowup. They are currently set up to work when e is eliminated.\nDecide whether to stick with global blowups or use charts.\nConsolidate notation about sections and line bundles in the documentation.\nThe Kodaira type function assumes that the singular locus is given by a single coordinate.\nThe Kodaira type function only works for codimension 1.\nModify the ambientspacefrombase function to return ring maps from the base to the ambient space and all other constructors/types to appropriately carry that around, then fix the corresponding bit of code in analyze_fibers.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#Tutorial","page":"Welcome to FTheoryTools","title":"Tutorial","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"We provide a tutorial for FTheoryTools in OSCAR.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#Possible-future-extensions","page":"Welcome to FTheoryTools","title":"Possible future extensions","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Future extensions include, but are not necessarily limited to, the following:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Specify a G_4-flux and work out the chiral spectra,\nSpecify a gauge potential and work out (candidates for) the line bundles whose cohomologies encode the vector-like spectra,\nOther singularity types (non-minimal, terminal, etc.,\nBase blowups for singularity resolution.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#Contact","page":"Welcome to FTheoryTools","title":"Contact","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Martin Bies,\nAndrew Turner.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#Acknowledgements","page":"Welcome to FTheoryTools","title":"Acknowledgements","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"We appreciate insightful discussions with Mirjam Cvetič. The work of Andrew Turner is supported by DOE (HEP) Award DE-SC001352.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/exact/#Exact-real-and-complex-numbers","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Exact real and complex numbers are provided by Calcium. Internally, a number z is represented as an element of an extension field of the rational numbers. That is,","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"z in mathbbQ(a_1ldotsa_n)","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"where a_1 ldots a_n are symbolically defined algebraic or transcendental real or complex numbers such as pi, sqrt2 or e^sqrt2 pi i. The user does not normally need to worry about the details of the internal representation; Calcium constructs extension numbers and fields automatically as needed to perform operations.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"The user must create a CalciumField instance which represents the mathematical domain mathbbC. This parent object holds a cache of extension numbers and fields used to represent individual elements. It also stores various options for evaluation (documented further below).","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Library Element type Parent type\nCalcium ca CalciumField","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Please note the following:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"It is in the nature of exact complex arithmetic that some operations must be implemented using incomplete heuristics. For example, testing whether an element is zero will not always succeed. When Calcium is unable to perform a task, Nemo will throw an exception. This ensures that Calcium fields behave exactly and never silently return wrong results.\nCalcium elements can optionally hold special non-numerical values:\nUnsigned infinity hat infty\nSigned infinities (pm infty, pm i infty, and more generally e^i theta cdot infty)\nUndefined\nUnknown\nBy default, such special values are disallowed so that a CalciumField represents the mathematical field mathbbC, and any operation that would result in a special value (for example, 1 0 = hat infty) will throw an exception. To allow special values, pass extended=true to the CalciumField constructor.\nCalciumField instances only support single-threaded use. You must create a separate parent object for each thread to do parallel computation.\nWhen performing an operation involving two ca operands with different parent objects, Nemo will arbitrarily coerce the operands (and hence the result) to one of the parents.","category":"page"},{"location":"Nemo/exact/#Calcium-field-options","page":"Exact real and complex numbers","title":"Calcium field options","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"The CalciumField parent stores various options that affect simplification power, performance, or appearance. The user can override any of the default values using C = CalciumField(options=dict) where dict is a dictionary with Symbol => Int pairs. To retrieve the option values as a dictionary (including any default values not set by the user), call options(C).","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"The following options are supported:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Option Explanation\n:verbose Enable debug output\n:print_flags Flags controlling print style\n:mpoly_ord Monomial order for polynomials\n:prec_limit Precision limit for numerical evaluation\n:qqbar_deg_limit Degree limit for algebraic numbers\n:low_prec Initial precision for numerical evaluation\n:smooth_limit Factor size limit for smooth integer factorization\n:lll_prec Precision for integer relation detection\n:pow_limit Maximum exponent for in-field powering\n:use_gb Enable Gröbner basis computation\n:gb_length_limit Maximum ideal basis length during Gröbner basis computation\n:gb_poly_length_limit Maximum polynomial length during Gröbner basis computation\n:gb_poly_bits_limit Maximum bit size during Gröbner basis computation\n:gb_vieta_limit Maximum degree to use Vieta's formulas\n:trig_form Default form of trigonometric functions","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"An important function of these options is to control how hard Calcium will try to find an answer before it gives up. For example:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Setting :prec_limit => 65536 will allow Calcium to use up to 65536 bits of precision (instead of the default 4096) to prove inequalities.\nSetting :qqbar_deg_limit => typemax(Int) (instead of the default 120) will force most calculations involving algebraic numbers to run to completion, no matter how long this will take.\nSetting :use_gb => 0 (instead of the default 1) disables use of Gröbner bases. In general, this will negatively impact Calcium's ability to simplify field elements and prove equalities, but it can speed up calculations where Gröbner bases are unnecessary.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"For a detailed explanation, refer to the following section in the Calcium documentation: https://fredrikj.net/calcium/ca.html#context-options","category":"page"},{"location":"Nemo/exact/#Basic-examples","page":"Exact real and complex numbers","title":"Basic examples","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> C = CalciumField()\nExact Complex Field\n\njulia> exp(C(pi) * C(1im)) + 1\n0\n\njulia> log(C(-1))\n3.14159*I {a*b where a = 3.14159 [Pi], b = I [b^2+1=0]}\n\njulia> log(C(-1)) ^ 2\n-9.86960 {-a^2 where a = 3.14159 [Pi], b = I [b^2+1=0]}\n\njulia> log(C(10)^23) // log(C(100))\n11.5000 {23/2}\n\njulia> 4*atan(C(1)//5) - atan(C(1)//239) == C(pi)//4\ntrue\n\njulia> Cx, x = polynomial_ring(C, \"x\")\n(Univariate Polynomial Ring in x over Exact Complex Field, x)\n\njulia> (a, b) = (sqrt(C(2)), sqrt(C(3)))\n(1.41421 {a where a = 1.41421 [a^2-2=0]}, 1.73205 {a where a = 1.73205 [a^2-3=0]})\n\njulia> (x-a-b)*(x-a+b)*(x+a-b)*(x+a+b)\nx^4 + (-10)*x^2 + 1","category":"page"},{"location":"Nemo/exact/#Conversions-and-numerical-evaluation","page":"Exact real and complex numbers","title":"Conversions and numerical evaluation","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Calcium numbers can created from integers (ZZ), rationals (QQ) and algebraic numbers (QQbar), and through the application of arithmetic operations and transcendental functions.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Calcium numbers can be converted to integers, rational and algebraic fields provided that the values are integer, rational or algebraic. An exception is thrown if the value does not belong to the target domain, if Calcium is unable to prove that the value belongs to the target domain, or if Calcium is unable to compute the explicit value because of evaluation limits.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> QQ(C(1))\n1\n\njulia> QQBar(sqrt(C(2)) // 2)\nRoot 0.707107 of 2x^2 - 1\n\njulia> QQ(C(pi))\nERROR: unable to convert to a rational number\n\njulia> QQ(C(10) ^ C(10^9))\nERROR: unable to convert to a rational number","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"To compute arbitrary-precision numerical enclosures, convert to ArbField or AcbField:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> CC = AcbField(64);\n\njulia> CC(exp(C(1im)))\n[0.54030230586813971740 +/- 9.37e-22] + [0.84147098480789650665 +/- 2.51e-21]*im","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"The constructor","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"(R::AcbField)(a::ca; parts::Bool=false)","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"returns an enclosure of the complex number a. It attempts to obtain a relative accuracy of prec bits where prec is the precision of the target field, but it is not guaranteed that this goal is achieved.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"If parts is set to true, it attempts to achieve the target accuracy for both real and imaginary parts. This can be significantly more expensive if one part is smaller than the other, or if the number is nontrivially purely real or purely imaginary (in which case an exact proof attempt is made).","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> x = sin(C(1), form=:exponential)\n0.841471 + 0e-24*I {(-a^2*b+b)/(2*a) where a = 0.540302 + 0.841471*I [Exp(1.00000*I {b})], b = I [b^2+1=0]}\n\njulia> AcbField(64)(x)\n[0.84147098480789650665 +/- 2.51e-21] + [+/- 4.77e-29]*im\n\njulia> AcbField(64)(x, parts=true)\n[0.84147098480789650665 +/- 2.51e-21]","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"The constructor","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"(R::ArbField)(a::ca; check::Bool=true)","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"returns a real enclosure. If check is set to true (default), the number a is verified to be real, and an exception is thrown if this cannot be determined. With check set to false, this function returns an enclosure of the real part of a without checking that the imaginary part is zero. This can be significantly faster.","category":"page"},{"location":"Nemo/exact/#Comparisons-and-properties","page":"Exact real and complex numbers","title":"Comparisons and properties","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Except where otherwise noted, predicate functions such as iszero, ==, < and isreal act on the mathematical values of Calcium field elements. For example, although evaluating x = sqrt2 sqrt3 and y = sqrt6 results in different internal representations (x in mathbbQ(sqrt3 sqrt2) and y in mathbbQ(sqrt6)), the numbers compare as equal:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> x = sqrt(C(2)) * sqrt(C(3))\n2.44949 {a*b where a = 1.73205 [a^2-3=0], b = 1.41421 [b^2-2=0]}\n\njulia> y = sqrt(C(6))\n2.44949 {a where a = 2.44949 [a^2-6=0]}\n\njulia> x == y\ntrue\n\njulia> iszero(x - y)\ntrue\n\njulia> isinteger(x - y)\ntrue","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Predicate functions return true if the property is provably true and false if the property if provably false. If Calcium is unable to prove the truth value, an exception is thrown. For example, with default settings, Calcium is currently able to prove that e^e^-1000 ne 1, but it fails to prove e^e^-3000 ne 1:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> x = exp(exp(C(-1000)))\n1.00000 {a where a = 1.00000 [Exp(5.07596e-435 {b})], b = 5.07596e-435 [Exp(-1000)]}\n\njulia> x == 1\nfalse\n\njulia> x = exp(exp(C(-3000)))\n1.00000 {a where a = 1.00000 [Exp(1.30784e-1303 {b})], b = 1.30784e-1303 [Exp(-3000)]}\n\njulia> x == 1\nERROR: Unable to perform operation (failed deciding truth of a predicate): isequal\n...","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"In this case, we can get an answer by allowing a higher working precision:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> C2 = CalciumField(options=Dict(:prec_limit => 10^5));\n\njulia> exp(exp(C2(-3000))) == 1\nfalse","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Real numbers can be ordered and sorted the usual way. We illustrate finding square roots that are well-approximated by integers:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> sort([sqrt(C(n)) for n=0:10], by=x -> abs(x - floor(x + C(1)//2)))\n11-element Vector{ca}:\n 0\n 1\n 2\n 3\n 3.16228 {a where a = 3.16228 [a^2-10=0]}\n 2.82843 {2*a where a = 1.41421 [a^2-2=0]}\n 2.23607 {a where a = 2.23607 [a^2-5=0]}\n 1.73205 {a where a = 1.73205 [a^2-3=0]}\n 2.64575 {a where a = 2.64575 [a^2-7=0]}\n 1.41421 {a where a = 1.41421 [a^2-2=0]}\n 2.44949 {a where a = 2.44949 [a^2-6=0]}","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"As currently implemented, order comparisons involving nonreal numbers yield false (in both directions) rather than throwing an exception:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> C(1im) < C(1im)\nfalse\n\njulia> C(1im) > C(1im)\nfalse","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"This behavior may be changed or may become configurable in the future.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Interface","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"iszero(a::ca)\nisone(a::ca)\nis_algebraic(a::ca)\nis_rational(a::ca)\nisinteger(a::ca)\nisreal(a::ca)\nis_imaginary(a::ca)","category":"page"},{"location":"Nemo/exact/#iszero-Tuple{ca}","page":"Exact real and complex numbers","title":"iszero","text":"iszero(a::ca)\n\nReturn whether a is the number 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isone-Tuple{ca}","page":"Exact real and complex numbers","title":"isone","text":"isone(a::ca)\n\nReturn whether a is the number 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_algebraic-Tuple{ca}","page":"Exact real and complex numbers","title":"is_algebraic","text":"is_algebraic(a::ca)\n\nReturn whether a is an algebraic number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_rational-Tuple{ca}","page":"Exact real and complex numbers","title":"is_rational","text":"is_rational(a::ca)\n\nReturn whether a is a rational number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isinteger-Tuple{ca}","page":"Exact real and complex numbers","title":"isinteger","text":"isinteger(a::ca)\n\nReturn whether a is an integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isreal-Tuple{ca}","page":"Exact real and complex numbers","title":"isreal","text":"isreal(a::ca)\n\nReturn whether a is a real number. This returns false if a is a pure real infinity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_imaginary-Tuple{ca}","page":"Exact real and complex numbers","title":"is_imaginary","text":"is_imaginary(a::ca)\n\nReturn whether a is an imaginary number. This returns false if a is a pure imaginary infinity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#Infinities-and-special-values","page":"Exact real and complex numbers","title":"Infinities and special values","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"By default, CalciumField does not permit creating values that are not numbers, and any non-number value (unsigned infinity, signed infinity, Undefined) will result in an exception. This also applies to the special value Unknown, used in situations where Calcium is unable to prove that a value is a number. To enable special values, use extended=true.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> C = CalciumField()\nExact Complex Field\n\njulia> 1 // C(0)\nERROR: DomainError with UnsignedInfinity:\nNon-number result\n...\n\njulia> Cext = CalciumField(extended=true)\nExact Complex Field (Extended)\n\njulia> 1 // Cext(0)\nUnsignedInfinity","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Note that special values do not satisfy the properties of a mathematical ring or field. You will likely get meaningless results if you put infinities in matrices or polynomials.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"unsigned_infinity(C::CalciumField)\ninfinity(C::CalciumField)\ninfinity(a::ca)\nundefined(C::CalciumField)\nunknown(C::CalciumField)\nis_number(a::ca)\nis_undefined(a::ca)\nisinf(a::ca)\nis_uinf(a::ca)\nis_signed_inf(a::ca)\nis_unknown(a::ca)","category":"page"},{"location":"Nemo/exact/#unsigned_infinity-Tuple{CalciumField}","page":"Exact real and complex numbers","title":"unsigned_infinity","text":"unsigned_infinity(C::CalciumField)\n\nReturn unsigned infinity (hat infty) as an element of C. This throws an exception if C does not allow special values.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#infinity-Tuple{CalciumField}","page":"Exact real and complex numbers","title":"infinity","text":"infinity(C::CalciumField)\n\nReturn positive infinity (+infty) as an element of C. This throws an exception if C does not allow special values.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#infinity-Tuple{ca}","page":"Exact real and complex numbers","title":"infinity","text":"infinity(a::ca)\n\nReturn the signed infinity (a cdot infty). This throws an exception if the parent of a does not allow special values.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#undefined-Tuple{CalciumField}","page":"Exact real and complex numbers","title":"undefined","text":"undefined(C::CalciumField)\n\nReturn the special value Undefined as an element of C. This throws an exception if C does not allow special values.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#unknown-Tuple{CalciumField}","page":"Exact real and complex numbers","title":"unknown","text":"unknown(C::CalciumField)\n\nReturn the special meta-value Unknown as an element of C. This throws an exception if C does not allow special values.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_number-Tuple{ca}","page":"Exact real and complex numbers","title":"is_number","text":"is_number(a::ca)\n\nReturn whether a is a number, i.e. not an infinity or undefined.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_undefined-Tuple{ca}","page":"Exact real and complex numbers","title":"is_undefined","text":"is_undefined(a::ca)\n\nReturn whether a is the special value Undefined.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isinf-Tuple{ca}","page":"Exact real and complex numbers","title":"isinf","text":"isinf(a::ca)\n\nReturn whether a is any infinity (signed or unsigned).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_uinf-Tuple{ca}","page":"Exact real and complex numbers","title":"is_uinf","text":"is_uinf(a::ca)\n\nReturn whether a is unsigned infinity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_signed_inf-Tuple{ca}","page":"Exact real and complex numbers","title":"is_signed_inf","text":"is_signed_inf(a::ca)\n\nReturn whether a is any signed infinity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_unknown-Tuple{ca}","page":"Exact real and complex numbers","title":"is_unknown","text":"is_unknown(a::ca)\n\nReturn whether a is the special value Unknown. This is a representation property and not a mathematical predicate.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#Complex-parts","page":"Exact real and complex numbers","title":"Complex parts","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Functions for computing components of real and complex numbers will perform automatic symbolic simplifications in special cases. In general, such operations will introduce new extension numbers.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> real(C(2+3im))\n2\n\njulia> sign(C(2im))\n1.00000*I {a where a = I [a^2+1=0]}\n\njulia> sign(C(2+3im))\n0.554700 + 0.832050*I {a where a = 0.554700 + 0.832050*I [13*a^4+10*a^2+13=0]}\n\njulia> angle(C(2+2im))\n0.785398 {(a)/4 where a = 3.14159 [Pi]}\n\njulia> angle(C(2+3im))\n0.982794 {a where a = 0.982794 [Arg(2.00000 + 3.00000*I {3*b+2})], b = I [b^2+1=0]}\n\njulia> angle(C(2+3im)) == atan(C(3)//2)\ntrue\n\njulia> floor(C(pi) ^ 100)\n5.18785e+49 {51878483143196131920862615246303013562686760680405}\n\njulia> ZZ(floor(C(pi) ^ 100))\n51878483143196131920862615246303013562686760680405","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Interface","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"real(a::ca)\nimag(a::ca)\nangle(a::ca)\ncsgn(a::ca)\nsign(a::ca)\nabs(a::ca)\nconj(a::ca; form::Symbol=:default)\nfloor(a::ca)\nceil(a::ca)","category":"page"},{"location":"Nemo/exact/#real-Tuple{ca}","page":"Exact real and complex numbers","title":"real","text":"real(a::ca)\n\nReturn the real part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#imag-Tuple{ca}","page":"Exact real and complex numbers","title":"imag","text":"imag(a::ca)\n\nReturn the imaginary part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#angle-Tuple{ca}","page":"Exact real and complex numbers","title":"angle","text":"angle(a::ca)\n\nReturn the complex argument of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#csgn-Tuple{ca}","page":"Exact real and complex numbers","title":"csgn","text":"csgn(a::ca)\n\nReturn the extension of the real sign function taking the value 1 strictly in the right half plane, -1 strictly in the left half plane, and the sign of the imaginary part when on the imaginary axis. Equivalently, operatornamecsgn(x) = x sqrtx^2 except that the value is 0 at zero.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#sign-Tuple{ca}","page":"Exact real and complex numbers","title":"sign","text":"sign(a::ca)\n\nReturn the complex sign of a, defined as zero if a is zero and as a a for any other complex number. This function also extracts the sign when a is a signed infinity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#abs-Tuple{ca}","page":"Exact real and complex numbers","title":"abs","text":"abs(a::ca)\n\nReturn the absolute value of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#conj-Tuple{ca}","page":"Exact real and complex numbers","title":"conj","text":"conj(a::ca; form::Symbol=:default)\n\nReturn the complex conjugate of a. The optional form argument allows specifying the representation. In :shallow form, overlinea is introduced as a new extension number if it no straightforward simplifications are possible. In :deep form, complex conjugation is performed recursively.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#floor-Tuple{ca}","page":"Exact real and complex numbers","title":"floor","text":"floor(a::ca)\n\nReturn the floor function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#ceil-Tuple{ca}","page":"Exact real and complex numbers","title":"ceil","text":"ceil(a::ca)\n\nReturn the ceiling function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#Elementary-and-special-functions","page":"Exact real and complex numbers","title":"Elementary and special functions","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Elementary and special functions generally create new extension numbers. In special cases, simplifications occur automatically.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> exp(C(1))\n2.71828 {a where a = 2.71828 [Exp(1)]}\n\njulia> exp(C(0))\n1\n\njulia> atan(C(1))\n0.785398 {(a)/4 where a = 3.14159 [Pi]}\n\njulia> cos(C(1))^2 + sin(C(1))^2\n1\n\njulia> log(1 // exp(sqrt(C(2))+1)) == -sqrt(C(2)) - 1\ntrue\n\njulia> gamma(C(2+3im))\n-0.0823953 + 0.0917743*I {a where a = -0.0823953 + 0.0917743*I [Gamma(2.00000 + 3.00000*I {3*b+2})], b = I [b^2+1=0]}\n\njulia> gamma(C(5) // 2)\n1.32934 {(3*a)/4 where a = 1.77245 [Sqrt(3.14159 {b})], b = 3.14159 [Pi]}\n\njulia> erf(C(1))\n0.842701 {a where a = 0.842701 [Erf(1)]}\n\njulia> erf(C(1)) + erfc(C(1))\n1","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Some functions allow representing the result in different forms:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> s1 = sin(C(1))\n0.841471 - 0e-24*I {(-a^2*b+b)/(2*a) where a = 0.540302 + 0.841471*I [Exp(1.00000*I {b})], b = I [b^2+1=0]}\n\njulia> s2 = sin(C(1), form=:direct)\n0.841471 {a where a = 0.841471 [Sin(1)]}\n\njulia> s3 = sin(C(1), form=:exponential)\n0.841471 - 0e-24*I {(-a^2*b+b)/(2*a) where a = 0.540302 + 0.841471*I [Exp(1.00000*I {b})], b = I [b^2+1=0]}\n\njulia> s4 = sin(C(1), form=:tangent)\n0.841471 {(2*a)/(a^2+1) where a = 0.546302 [Tan(0.500000 {1/2})]}\n\njulia> s1 == s2 == s3 == s4\ntrue\n\njulia> isreal(s1) && isreal(s2) && isreal(s3) && isreal(s4)\ntrue","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"The exponential form is currently used by default since it tends to be the most useful for symbolic simplification. The :direct and :tangent forms are likely to be better for numerical evaluation. The default behavior of trigonometric functions can be changed using the :trig_form option of CalciumField.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Proving equalities involving transcendental function values is a difficult problem in general. Calcium will sometimes fail even in elementary cases. Here is an example of two constant trigonometric identities where the first succeeds and the second fails:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> a = sqrt(C(2)) + 1;\n\njulia> cos(a) + cos(2*a) + cos(3*a) == sin(7*a//2)//(2*sin(a//2)) - C(1)//2\ntrue\n\njulia> sin(3*a) == 4 * sin(a) * sin(C(pi)//3 - a) * sin(C(pi)//3 + a)\nERROR: Unable to perform operation (failed deciding truth of a predicate): isequal","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"A possible workaround is to fall back on a numerical comparison:","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"julia> abs(cos(a) + cos(2*a) + cos(3*a) - (sin(7*a//2)//(2*sin(a//2)) - C(1)//2)) <= C(10)^-100\ntrue","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Of course, this is not a rigorous proof that the numbers are equal, and CalciumField is overkill here; it would be far more efficient to use ArbField directly to check that the numbers are approximately equal.","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"Interface","category":"page"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"const_pi(C::CalciumField)\nconst_euler(C::CalciumField)\nonei(C::CalciumField)\nsqrt(a::ca)\nexp(a::ca)\nlog(a::ca)\npow(a::ca, b::Int; form::Symbol=:default)\nsin(a::ca; form::Symbol=:default)\ncos(a::ca; form::Symbol=:default)\ntan(a::ca; form::Symbol=:default)\natan(a::ca; form::Symbol=:default)\nasin(a::ca; form::Symbol=:default)\nacos(a::ca; form::Symbol=:default)\ngamma(a::ca)\nerf(a::ca)\nerfi(a::ca)\nerfc(a::ca)","category":"page"},{"location":"Nemo/exact/#const_pi-Tuple{CalciumField}","page":"Exact real and complex numbers","title":"const_pi","text":"const_pi(C::CalciumField)\n\nReturn the constant pi as an element of C.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#const_euler-Tuple{CalciumField}","page":"Exact real and complex numbers","title":"const_euler","text":"const_euler(C::CalciumField)\n\nReturn Euler's constant gamma as an element of C.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#onei-Tuple{CalciumField}","page":"Exact real and complex numbers","title":"onei","text":"onei(C::CalciumField)\n\nReturn the imaginary unit i as an element of C.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#sqrt-Tuple{ca}","page":"Exact real and complex numbers","title":"sqrt","text":"Base.sqrt(a::ca; check::Bool=true)\n\nReturn the principal square root of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#exp-Tuple{ca}","page":"Exact real and complex numbers","title":"exp","text":"exp(a::ca)\n\nReturn the exponential function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#log-Tuple{ca}","page":"Exact real and complex numbers","title":"log","text":"log(a::ca)\n\nReturn the natural logarithm of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#pow-Tuple{ca, Int64}","page":"Exact real and complex numbers","title":"pow","text":"pow(a::ca, b::Int; form::Symbol=:default)\n\nReturn a raised to the integer power b. The optional form argument allows specifying the representation. In :default form, this is equivalent to a ^ b, which may create a new extension number a^b if the exponent b is too large (as determined by the parent option :pow_limit or :prec_limit depending on the case). In :arithmetic form, the exponentiation is performed arithmetically in the field of a, regardless of the size of the exponent b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#sin-Tuple{ca}","page":"Exact real and complex numbers","title":"sin","text":"sin(a::ca; form::Symbol=:default)\n\nReturn the sine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :exponential form, the value is represented using complex exponentials. In :tangent form, the value is represented using tangents. In :direct form, the value is represented directly using a sine or cosine.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#cos-Tuple{ca}","page":"Exact real and complex numbers","title":"cos","text":"cos(a::ca; form::Symbol=:default)\n\nReturn the cosine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :exponential form, the value is represented using complex exponentials. In :tangent form, the value is represented using tangents. In :direct form, the value is represented directly using a sine or cosine.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#tan-Tuple{ca}","page":"Exact real and complex numbers","title":"tan","text":"tan(a::ca; form::Symbol=:default)\n\nReturn the tangent of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :exponential form, the value is represented using complex exponentials. In :direct or :tangent form, the value is represented directly using tangents. In :sine_cosine form, the value is represented using sines or cosines.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#atan-Tuple{ca}","page":"Exact real and complex numbers","title":"atan","text":"atan(a::ca; form::Symbol=:default)\n\nReturn the inverse tangent of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :logarithm form, the value is represented using complex logarithms. In :direct or :arctangent form, the value is represented directly using arctangents.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#asin-Tuple{ca}","page":"Exact real and complex numbers","title":"asin","text":"asin(a::ca; form::Symbol=:default)\n\nReturn the inverse sine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :logarithm form, the value is represented using complex logarithms. In :direct form, the value is represented directly using an inverse sine or cosine.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#acos-Tuple{ca}","page":"Exact real and complex numbers","title":"acos","text":"acos(a::ca; form::Symbol=:default)\n\nReturn the inverse cosine of a. The optional form argument allows specifying the representation. In :default form, the result is determined by the :trig_form option of the parent object. In :logarithm form, the value is represented using complex logarithms. In :direct form, the value is represented directly using an inverse sine or cosine.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#gamma-Tuple{ca}","page":"Exact real and complex numbers","title":"gamma","text":"gamma(a::ca)\n\nReturn the gamma function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#erf-Tuple{ca}","page":"Exact real and complex numbers","title":"erf","text":"erf(a::ca)\n\nReturn the error function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#erfi-Tuple{ca}","page":"Exact real and complex numbers","title":"erfi","text":"erfi(a::ca)\n\nReturn the imaginary error function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#erfc-Tuple{ca}","page":"Exact real and complex numbers","title":"erfc","text":"erfc(a::ca)\n\nReturn the complementary error function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#Rewriting-and-simplification","page":"Exact real and complex numbers","title":"Rewriting and simplification","text":"","category":"section"},{"location":"Nemo/exact/","page":"Exact real and complex numbers","title":"Exact real and complex numbers","text":"complex_normal_form(a::ca; deep::Bool=true)","category":"page"},{"location":"Nemo/exact/#complex_normal_form-Tuple{ca}","page":"Exact real and complex numbers","title":"complex_normal_form","text":"complex_normal_form(a::ca, deep::Bool=true)\n\nReturns the input rewritten using standardizing transformations over the complex numbers:\n\nElementary functions are rewritten in terms of exponentials, roots and logarithms.\nComplex parts are rewritten using logarithms, square roots, and (deep) complex conjugates.\nAlgebraic numbers are rewritten in terms of cyclotomic fields where applicable.\n\nIf deep is set, the rewriting is applied recursively to the tower of extension numbers; otherwise, the rewriting is only applied to the top-level extension numbers.\n\nThe result is not a normal form in the strong sense (the same number can have many possible representations even after applying this transformation), but this transformation can nevertheless be a useful heuristic for simplification.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#Cyclic-Quotient-Singularities","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#Introduction","page":"Cyclic Quotient Singularities","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"Cyclic quotient singularities are quotients of mathbbC^2 by the action of mathbbZnmathbbZ acting via left(beginarrayccxi 00 xi^qendarrayright), where xi is a n-th root of unity, and q and n are integers, such that q is coprime with n, and 0qn.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"For the notation we rely on Jan Arthur Christophersen (1991) and Jan Stevens (1991).","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"warning: Warning\nNote that Jan Arthur Christophersen (1991) and Jan Stevens (1991) use Hirzebruch-Jung continued fraction, which differ from the commonly known continued fraction from literature and used in the rest of OSCAR.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#Constructors","page":"Cyclic Quotient Singularities","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"cyclic_quotient_singularity(n::T, q::T) where {T <: IntegerUnion}","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#cyclic_quotient_singularity-Union{Tuple{T}, Tuple{T, T}} where T<:Union{Integer, ZZRingElem}","page":"Cyclic Quotient Singularities","title":"cyclic_quotient_singularity","text":"cyclic_quotient_singularity(n::ZZRingElem, q::ZZRingElem)\n\nReturn the cyclic quotient singularity for the parameters n and q, with 0qn and q n coprime.\n\nExamples\n\njulia> cqs = cyclic_quotient_singularity(7, 5)\nCyclic quotient singularity Y(7, 5)\n\njulia> is_affine(cqs)\ntrue\n\njulia> is_smooth(cqs)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#Attributes","page":"Cyclic Quotient Singularities","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"continued_fraction_hirzebruch_jung(cqs::CyclicQuotientSingularity)\ndual_continued_fraction_hirzebruch_jung(cqs::CyclicQuotientSingularity)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#continued_fraction_hirzebruch_jung-Tuple{CyclicQuotientSingularity}","page":"Cyclic Quotient Singularities","title":"continued_fraction_hirzebruch_jung","text":"continued_fraction_hirzebruch_jung(cqs::CyclicQuotientSingularity)\n\nReturn the Hirzebruch-Jung continued fraction associated with the cyclic quotient singularity, i.e. the Hirzebruch-Jung continued fraction corresponding to nq.\n\nThe rational number corresponding to a Hirzebruch-Jung continued fraction c_1 c_2ldots c_n is r(c_1 c_2ldots c_n) =\nc_1-frac1r(c_2ldots c_n) where r(c_n) = c_n. Note that this is differs in sign from what is commonly known as continued fraction.\n\nExamples\n\njulia> cqs = cyclic_quotient_singularity(7, 5)\nCyclic quotient singularity Y(7, 5)\n\njulia> cf = continued_fraction_hirzebruch_jung(cqs)\n3-element Vector{ZZRingElem}:\n 2\n 2\n 3\n\njulia> ecf = cf[1]-1//(cf[2]-QQFieldElem(1, cf[3]))\n7//5\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#dual_continued_fraction_hirzebruch_jung-Tuple{CyclicQuotientSingularity}","page":"Cyclic Quotient Singularities","title":"dual_continued_fraction_hirzebruch_jung","text":"dual_continued_fraction_hirzebruch_jung(cqs::CyclicQuotientSingularity)\n\nReturn the dual Hirzebruch-Jung continued fraction associated with the cyclic quotient singularity, i.e. the Hirzebruch-Jung continued fraction corresponding to q(n-q).\n\nThe rational number corresponding to a Hirzebruch-Jung continued fraction c_1 c_2ldots c_n is r(c_1 c_2ldots c_n) =\nc_1-frac1r(c_2ldots c_n) where r(c_n) = c_n. Note that this is differs in sign from what is commonly known as continued fraction.\n\nExamples\n\njulia> cqs = cyclic_quotient_singularity(7, 5)\nCyclic quotient singularity Y(7, 5)\n\njulia> dcf = dual_continued_fraction_hirzebruch_jung(cqs)\n2-element Vector{ZZRingElem}:\n 4\n 2\n\njulia> edcf = dcf[1] - QQFieldElem(1, dcf[2])\n7//2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#Auxiliary-Methods","page":"Cyclic Quotient Singularities","title":"Auxiliary Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"continued_fraction_hirzebruch_jung_to_rational(v::Vector{ZZRingElem})\nrational_to_continued_fraction_hirzebruch_jung(r::QQFieldElem)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#continued_fraction_hirzebruch_jung_to_rational-Tuple{Vector{ZZRingElem}}","page":"Cyclic Quotient Singularities","title":"continued_fraction_hirzebruch_jung_to_rational","text":"continued_fraction_hirzebruch_jung_to_rational(v::Vector{ZZRingElem})\n\nReturn the rational number corresponding to a Hirzebruch-Jung continued fraction given as a vector of (positive) integers.\n\nThe rational number corresponding to a Hirzebruch-Jung continued fraction c_1 c_2ldots c_n is r(c_1 c_2ldots c_n) =\nc_1-frac1r(c_2ldots c_n) where r(c_n) = c_n. Note that this is differs in sign from what is commonly known as continued fraction.\n\nExamples\n\njulia> cqs = cyclic_quotient_singularity(7, 5)\nCyclic quotient singularity Y(7, 5)\n\njulia> v = continued_fraction_hirzebruch_jung(cqs)\n3-element Vector{ZZRingElem}:\n 2\n 2\n 3\n\njulia> continued_fraction_hirzebruch_jung_to_rational(v)\n7//5\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/#rational_to_continued_fraction_hirzebruch_jung-Tuple{QQFieldElem}","page":"Cyclic Quotient Singularities","title":"rational_to_continued_fraction_hirzebruch_jung","text":"rational_to_continued_fraction_hirzebruch_jung(r::QQFieldElem)\n\nEncode a (positive) rational number as a Hirzebruch-Jung continued fraction, i.e. find the Hirzebruch-Jung continued fraction corresponding to the given rational number.\n\nThe rational number corresponding to a Hirzebruch-Jung continued fraction c_1 c_2ldots c_n is r(c_1 c_2ldots c_n) =\nc_1-frac1r(c_2ldots c_n) where r(c_n) = c_n. Note that this is differs in sign from what is commonly known as continued fraction.\n\nExamples\n\njulia> r = QQFieldElem(2464144958, 145732115)\n2464144958//145732115\n\njulia> cf = rational_to_continued_fraction_hirzebruch_jung(r)\n7-element Vector{ZZRingElem}:\n 17\n 11\n 23\n 46\n 18\n 19\n 37\n\njulia> continued_fraction_hirzebruch_jung_to_rational(cf)\n2464144958//145732115\n\njulia> r == continued_fraction_hirzebruch_jung_to_rational(cf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#Line-bundle-cohomology-with-cohomCalg","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"We employ the cohomCalg algorithm Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010) to compute the dimension of line bundle cohomologies as well as vanishing sets.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#Dimensions-of-line-bundle-cohomology","page":"Line bundle cohomology with cohomCalg","title":"Dimensions of line bundle cohomology","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"all_cohomologies(l::ToricLineBundle)\ncohomology(l::ToricLineBundle, i::Int)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#all_cohomologies-Tuple{ToricLineBundle}","page":"Line bundle cohomology with cohomCalg","title":"all_cohomologies","text":"all_cohomologies(l::ToricLineBundle)\n\nComputes the dimension of all sheaf cohomologies of the toric line bundle l by use of the cohomCalg algorithm Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010), Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010) (see also Helmut Roschy, Thorsten Rahn (2010), Shin-Yao Jow (2011) and Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2012)).\n\nExamples\n\njulia> dP3 = del_pezzo_surface(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> all_cohomologies(toric_line_bundle(dP3, [1, 2, 3, 4]))\n3-element Vector{ZZRingElem}:\n 0\n 16\n 0\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#cohomology-Tuple{ToricLineBundle, Int64}","page":"Line bundle cohomology with cohomCalg","title":"cohomology","text":"cohomology(l::ToricLineBundle, i::Int)\n\nComputes the dimension of the i-th sheaf cohomology of the toric line bundle l by use of the cohomCalg algorithm Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010), Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010) (see also Helmut Roschy, Thorsten Rahn (2010), Shin-Yao Jow (2011) and Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2012)).\n\nExamples\n\njulia> dP3 = del_pezzo_surface(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> cohomology(toric_line_bundle(dP3, [4, 1, 1, 1]), 0)\n12\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#Toric-vanishing-sets","page":"Line bundle cohomology with cohomCalg","title":"Toric vanishing sets","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"Vanishing sets describe subsets of the Picard group of toric varieties. Their computations is based on Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010), i.e. this functionality is only available if the toric variety in question is either smooth and complete or alternatively, simplicial and projective. This approach to identify vanishing sets on toric varieties was originally introduced in Martin Bies (2018). As described there, on a technical level, a vanishing set is the complement of a finite family of polyhedra.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"For a toric variety, all vanishing sets are computed as follows:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"vanishing_sets(variety::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#vanishing_sets-Tuple{Oscar.AbstractNormalToricVariety}","page":"Line bundle cohomology with cohomCalg","title":"vanishing_sets","text":"vanishing_sets(variety::AbstractNormalToricVariety)\n\nCompute the vanishing sets of an abstract toric variety v by use of the cohomCalg algorithm.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"The return value is a vector of vanishing sets. This vector has length one larger than the dimension of the variety in question. The first vanishing set in this vector describes all line bundles for which the zero-th sheaf cohomology vanishes. More generally, if a line bundle is contained in the n-th vanishing set, then its n-1-th sheaf cohomology vanishes. The following method checks if a line bundle is contained in a vanishing set:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"contains(tvs::ToricVanishingSet, l::ToricLineBundle)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#contains-Tuple{ToricVanishingSet, ToricLineBundle}","page":"Line bundle cohomology with cohomCalg","title":"contains","text":"contains(tvs::ToricVanishingSet, l::ToricLineBundle)\n\nChecks if the toric line bundle l is contained in the toric vanishing set tvs.\n\nExamples\n\njulia> dP1 = del_pezzo_surface(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(dP1, [3, 2])\nToric line bundle on a normal toric variety\n\njulia> all_cohomologies(l)\n3-element Vector{ZZRingElem}:\n 7\n 0\n 0\n\njulia> vs = vanishing_sets(dP1)\n3-element Vector{ToricVanishingSet}:\n Toric vanishing set for cohomology index 0\n Toric vanishing set for cohomology index 1\n Toric vanishing set for cohomology index 2\n\njulia> contains(vs[1], l)\nfalse\n\njulia> contains(vs[2], l)\ntrue\n\njulia> contains(vs[3], l)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"A vanishing set can in principle cover the entire Picard group. This can be checked with isfull. This methods returns true if the vanishing set is the entire Picard group and false otherwise. Beyond this, we support the following attributes for vanishing sets:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"toric_variety(tvs::ToricVanishingSet)\npolyhedra(tvs::ToricVanishingSet)\ncohomology_index(tvs::ToricVanishingSet)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#toric_variety-Tuple{ToricVanishingSet}","page":"Line bundle cohomology with cohomCalg","title":"toric_variety","text":"toric_variety(tvs::ToricVanishingSet)\n\nReturn the toric variety of the vanishing set tvs.\n\nExamples\n\njulia> dP1 = del_pezzo_surface(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> vs = vanishing_sets(dP1)\n3-element Vector{ToricVanishingSet}:\n Toric vanishing set for cohomology index 0\n Toric vanishing set for cohomology index 1\n Toric vanishing set for cohomology index 2\n\njulia> toric_variety(vs[3])\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#polyhedra-Tuple{ToricVanishingSet}","page":"Line bundle cohomology with cohomCalg","title":"polyhedra","text":"polyhedra(tvs::ToricVanishingSet)\n\nReturn the vector of the polyhedra whose complement defines the vanishing set tvs.\n\nExamples\n\njulia> dP1 = del_pezzo_surface(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> vs = vanishing_sets(dP1)\n3-element Vector{ToricVanishingSet}:\n Toric vanishing set for cohomology index 0\n Toric vanishing set for cohomology index 1\n Toric vanishing set for cohomology index 2\n\njulia> polyhedra(vs[3])\n1-element Vector{Polyhedron{QQFieldElem}}:\n Polyhedron in ambient dimension 2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#cohomology_index-Tuple{ToricVanishingSet}","page":"Line bundle cohomology with cohomCalg","title":"cohomology_index","text":"cohomology_index(tvs::ToricVanishingSet)\n\nReturn the cohomology index of the toric vanishing set tvs.\n\nExamples\n\njulia> dP1 = del_pezzo_surface(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> vs = vanishing_sets(dP1)\n3-element Vector{ToricVanishingSet}:\n Toric vanishing set for cohomology index 0\n Toric vanishing set for cohomology index 1\n Toric vanishing set for cohomology index 2\n\njulia> cohomology_index(vs[3])\n2\n\n\n\n\n\n","category":"method"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/developer/parents/#Parent-objects","page":"Parent objects","title":"Parent objects","text":"","category":"section"},{"location":"Nemo/developer/parents/#The-use-of-parent-objects-in-Nemo","page":"Parent objects","title":"The use of parent objects in Nemo","text":"","category":"section"},{"location":"Nemo/developer/parents/#The-parent/element-model","page":"Parent objects","title":"The parent/element model","text":"","category":"section"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"As for other major computer algebra projects such as Sage and Magma, Nemo uses the parent/element model to manage its mathematical objects.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"As explained in the appendix to the AbstractAlgebra documentation, the standard type/object model used in most programming languages is insufficient for much of mathematics which often requires mathematical structures parameterised by other objects.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"For example a quotient ring by an ideal would be parameterised by the ideal. The ideal is an object in the system and not a type and so parameterised types are not sufficient to represent such quotient rings.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"This means that each mathematical \"domain\" in the system (set, group, ring, field, module, etc.) must be represented by an object in the system, rather than a type. Such objects are called parent objects.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Just as one would write typeof(a) to get the type of an object a in an object/type system of a standard programming language, we write parent(a) to return the parent of the object a.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"When talked about with reference to a parent in this way, the object a is referred to as an element of the parent. Thus the system is divided into elements and parents. For example a polynomial would be an element of a polynomial ring, the latter being the parent of the former.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Naturally the parent/element system leads to some issues in a programming language not built around this model. We discuss some of these issues below.","category":"page"},{"location":"Nemo/developer/parents/#Types-in-the-parent/element-model","page":"Parent objects","title":"Types in the parent/element model","text":"","category":"section"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"As all elements and parents in Nemo are objects, those objects have types which we refer to as the element type and parent type respectively.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"For example, Flint integers have type ZZRingElem and the parent object they all belong to, FlintZZ has type ZZRing.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"More complex parents and elements are parameterised. For example, generic univariate polynomials over a base ring R are parameterised by R. The base ring of a ring S can be obtained by the call base_ring(S).","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"We have found it extremely useful to parameterise the type of both the parent and element objects of such a ring by the type of the elements of the base ring. Thus for example, a generic polynomial with Flint integer coefficients would have type Poly{ZZRingElem}.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"In practice Flint already implements univariate polynomials over Flint integers, and these have type ZZPolyRingElem. But both ZZPolyRingElem and the generic polynomials Poly{ZZRingElem} belong to the abstract type PolyRingElem{ZZRingElem} making it possible to write functions for all univariate polynomials over Flint integers.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Given a specific element type or parent type it is possible to compute one from the other with the functions elem_type and parent_type. For example parent_type(ZZPolyRingElem) returns ZZPolyRing and elem_type(ZZPolyRing) returns ZZPolyRingElem. Similarly parent_type(Generic.Poly{ZZRingElem}) returns Generic.PolyRing{ZZRingElem} and so on.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"These functions are especially useful when writing type assertions or constructing arrays of elements insides function where only the parent object was passed.","category":"page"},{"location":"Nemo/developer/parents/#Other-functions-for-computing-types","page":"Parent objects","title":"Other functions for computing types","text":"","category":"section"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Sometimes one needs to know the type of a polynomial or matrix one would obtain if it were constructed over a given ring or with coefficients/entries of a given element type.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"This is especially important in generic code where it may not even be known which Julia package is being used. The user may be expecting an AbstractAlgebra object, a Nemo object or even some other kind of object to be constructed, depending on which package they are using.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"The function for returning the correct type for a dense matrix is dense_matrix_type to which one can pass either a base ring or an element type. For example, if AbstractAlgebra is being used, dense_matrix_type(ZZ) will return Mat{BigInt} whereas if Nemo is being used it will return ZZMatrix.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"We also have dense_poly_type for univariate polynomials, abs_series_type for absolute series and rel_series_type for relative series.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"In theory such functions should exist for all major object types, however they have in most cases not been implemented yet.","category":"page"},{"location":"Nemo/developer/parents/#Functions-for-creating-objects-of-a-similar-type","page":"Parent objects","title":"Functions for creating objects of a similar type","text":"","category":"section"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"A slightly more consistent interface for creating objects of a type that is suitable for the package currently in use is the similar interface.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"For example, given a matrix M one can create one with the same dimensions but over a different ring R by calling similar(M, R). Likewise one can create one over the same ring with different dimensions r x c by calling similar(M, r, c).","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"The similar system is sophisticated enough to know that there is no native type provided by Flint/Antic for matrices and polynomials over a number field. The system knows that in such cases it must create a generic matrix or polynomial over the given number field.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"A great deal of thought went into the design of the similar system so that developers would not be required to implement similar for every pair of types in the package.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Again this interface should exist for all major Nemo domains, but the functionality is still being implemented in some cases.","category":"page"},{"location":"Nemo/developer/parents/#Changing-base-rings-and-map","page":"Parent objects","title":"Changing base rings and map","text":"","category":"section"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Given a polynomial, matrix or other composite object over a base ring, it is often convenient to create a similar object but with all the entries or coefficients coerced into a different ring.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"For this purpose the function change_base_ring is provided.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Similarly it may be useful to create the matrix or polynomial that results by applying a given map/function/lambda to each of the entries or coefficients.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"For this purpose Julia's map function is overloaded. There are also functions specific to polynomials and matrices called map_coefficients and map_entries respectively, which essentially do the same thing.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Note that the implementation of such functions must make use of the functions discussed above to ensure that a matrix/polynomial of the right type is output.","category":"page"},{"location":"Nemo/developer/parents/#Parent-checking","page":"Parent objects","title":"Parent checking","text":"","category":"section"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"When applying binary operations to a pair of elements of a given ring, it is useful to check that they are in fact elements of the same ring. This is not possible by checking the types alone. For example elements of Z7Z and Z3Z would have the same type but different parents (one parameterised by the integer 7, the other by the integer 3).","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"In order to perform such a check in a function one uses check_parent(a, b) where a and b are the objects one wishes to assert must have the same parent. If not, an exception is raised by check_parent.","category":"page"},{"location":"Nemo/developer/parents/#Parent-object-constructors","page":"Parent objects","title":"Parent object constructors","text":"","category":"section"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Various functions are provided for constructing parent objects. For example a polynomial ring is constructed by calling a polynomial_ring function. Such functions are called parent object constructors.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"In general parent object constructors are intended for the user and should not be used in library code. There are a number of reasons for this.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Firstly, inside the Generic submodule of AbstractAlgebra the only parent object constructors that are directly accessible are the ones inside Generic. Thus if a Nemo function calls a function inside Generic and it creates a parent object using one of the parent object constructors, it will create a parent object for a generic ring rather than a Nemo one.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"One can work around this by calling AbstractAlgebra.polynomial_ring instead of simply polynomial_ring inside Generic, but even safer would be to find another way to construct the polynomials required.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"A second issue is that parent objects are allowed to be as large as one likes and they are cached by the system. They can also perform arbitrary precomputations for the ring/field/module etc. that is being constructed. Over time they tend to accumulate such precomputations, slowing down all generic code which made use of them. Both memory usage and performance may blow out in previously working code.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Thirdly, parent objects must be unique across the system for a given set of parameters. This means they must be cached globally. This is problematic for any future attempts to parallelise library code and in the worst case memory usage can balloon due to swelling caches.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Most parent object constructors take a cached keyword which specifies whether the parent object should be cached or not, but again it is better overall to simply eschew the use of parent object constructors in library code.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Instead, it is recommended to use functions such as similar, zero, zero_matrix, identity_matrix, change_base_ring, map, etc. for constructing polynomials and matrices directly.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"There are also functions that provide alternative ways of constructing objects, e.g. matrix provides a means of creating a matrix over a given ring with given dimensions. The constructor polynomial allows creation of a polynomial over a given base ring with given coefficients and abs_series and rel_series do similar things for absolute and relative series. These should be used in preference to parent object constructors where possible. Additional functions of this type should be added in future.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"However even when using these functions in library code, it is important to remember to pass cached=false so that the cache is not filled up by calls to the library code. But this creates an additional problem, namely that if one uses polynomial say, to construct two polynomials over the same base ring, they will not be compatible in the sense that they will have different parents.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"When one wishes to construct multiple elements in the same group/ring/field, it is convenient to be able to construct a parent just as a user would. For this purpose various light-weight and very safe parent constructors are provided for use in library code.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"For example there are the constructors PolyRing, AbsPowerSeriesRing and RelPowerSeriesRing. These functions return the parent ring R only and no generator (it can be obtained by calling gen(R)). They also set the variable for printing to a default (usually x). Moreover, these parents are not cached, so they are completely safe to use in library code. They can be thousands of times faster than the full parent constructors intended for users.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Here is an example of their use:","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"julia> R = PolyRing(ZZ)\nUnivariate polynomial ring in x over ZZ\n\njulia> p = R([1, 2, 3])\n3*x^2 + 2*x + 1\n\njulia> q = R([2, 3, 4])\n4*x^2 + 3*x + 2\n\njulia> s = p + q\n7*x^2 + 5*x + 3","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Naturally functions like polynomial and matrix and the light-weight parent constructors are missing for other modules in Nemo at present and it is hoped that developers will fill in such infrastructure rather than simply push the can down the road for someone else to fix. Forcing the creating of full parent objects into as few bottlenecks as possible will make it much easier for developers to remove problems associated with such calls when they arise in future.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/developer/conventions/#Conventions","page":"Conventions","title":"Conventions","text":"","category":"section"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"AbstractAlgebra and Nemo have adopted a number of conventions to help maintain a uniform codebase.","category":"page"},{"location":"Nemo/developer/conventions/#Code-conventions","page":"Conventions","title":"Code conventions","text":"","category":"section"},{"location":"Nemo/developer/conventions/#Function-and-type-names","page":"Conventions","title":"Function and type names","text":"","category":"section"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Names of types in Julia follow the convention of CamelCase where the first letter of each word is capitalised, e.g. Int64 and AbstractString.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Function/method names in Julia use all lowercase with underscores between the words, e.g. zip and jacobi_symbol.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"We follow these conventions in Nemo with some exceptions:","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"When interfacing C libraries the types use the same spelling and capitalisation in Nemo as they do in C, e.g. the Flint library's ZZPolyRingElem remains uncapitalised in Nemo.\nTypes such as fpPolyRingElem which don't exist under that name on the C side also use the lowercase convention as they wrap an actual C type which must be split into more than one type on the Julia side. For example zzModPolyRingElem and fpPolyRingElem on the Julia side both represent Flint zzModPolyRingElem's on the C side.\nTypes of rings and fields, modules, maps, etc. are capitalised whether they correspond to a C type or not, e.g. fqPolyRepField for the type of an object representing the field that fqPolyRepFieldElem's belong to.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":".","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"We omit an underscore if the first word of a method is \"is\" or \"has\", e.g. iseven.\nUnderscores are omitted if the method name is already well established without an underscore in Julia itself, e.g. setindex.\nConstructors with the same name as a type use the same spelling and capitalisation as that type, e.g. ZZRingElem(1).\nFunctions for creating rings, fields, modules, maps, etc. (rather than the elements thereof) use CamelCase, e.g. polynomial_ring. We refer to these functions as parent constructors. Note that we do not follow the Julia convention here, e.g. polynomial_ring is a function and not a type constructor (in fact we often return a tuple consisting of a parent object and other objects such as generators with this type of function) yet we capitalise it.\nWe prefer words to not be abbreviated, e.g. denominator instead of den.\nExceptions always exist where the result would be offensive in any major spoken language (example omitted).","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"It is easy to find counterexamples to virtually all these rules. However we have been making efforts to remove the most egregious cases from our codebase over time. As perfect consistency is not possible, work on this has to at times take a back seat.","category":"page"},{"location":"Nemo/developer/conventions/#Use-of-ASCII-characters","page":"Conventions","title":"Use of ASCII characters","text":"","category":"section"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"All code and printed output in Nemo should use ASCII characters only. This is because we have developers who are using versions of the WSL that cannot correctly display non-ASCII characters.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"This extends to function and operator names, which saves people having to learn how to enter them to use the system.","category":"page"},{"location":"Nemo/developer/conventions/#Spacing-and-tabs","page":"Conventions","title":"Spacing and tabs","text":"","category":"section"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"All function bodies and control blocks should be indented using spaces.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"A survey of existing code shows 2, 3 or 4 space indenting commonly used in our files. Values outside this range should not be used.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"When contributing to an existing file, follow the majority convention in that file. Consistency within a file is valued highly.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"If you are new to Nemo development and do not already have a very strong preference, new files should be started with 3 space indenting. This maximises the likelihood that copy and paste between files will be straightforward, though modern editors ease this to some degree.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Function signatures in docstrings should have four spaces before them.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Where possible, line lengths should not exceed 80 characters.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"We use a term/factor convention for spacing. This means that all (additive) terms have spaces before and after them, (multiplicative) factors usually do not.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"In practice this means that +, -, =, ==, !=, <, >, <=, >= all have spaces before and after them. The operators *, /, ^ and unary minus do not.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"As per English, commas are followed by a single space in expressions. This applies for example to function arguments and tuples.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"We do not put spaces immediately inside or before parentheses.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Colons used for ranges do not have spaces before or after them.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Logical operators, &, |, &&, etc. usually have spaces before and after them.","category":"page"},{"location":"Nemo/developer/conventions/#Comments","page":"Conventions","title":"Comments","text":"","category":"section"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Despite appearances to the contrary, we now prefer code comments explaining the algorithm as it proceeds.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"The hash when used for a comment should always be followed by a space. Full sentences are preferred.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"We do not generally use comments in Nemo for questions, complaints or proposals for future improvement. These are better off in a ticket on GitHub with a discussion that will be brought to the attention of all relevant parties.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Any (necessary) limitations of the implementation should be noted in docstrings.","category":"page"},{"location":"Nemo/developer/conventions/#Layout-of-files","page":"Conventions","title":"Layout of files","text":"","category":"section"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"In Nemo, all types are places in special files with the word \"Types\" in their name, e.g. FlintTypes.jl. This is because Julia must be aware of all types before they are used. Separation of types from implementations makes it easy to ensure this happens.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Abstract types should be put in the file called AbstractTypes.jl at the top level of the src directory.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Most implementation files present functions in a particular order, which is as follows:","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"A header stating what the file is for, and if needed, any copyright notices\nFunctions applying to any \"types\" used in the file, e.g. parent_type, elem_type, base_ring, parent, check_parent.\nBasic manipulation, including hashes, predicates, getters/setters, functions for creating special values (e.g. one, zero and the like), deepcopy_internal. These are usually fairly short functions, often a single line.\nIndexing (getindex, setindex), iteration, views.\nString I/O (expressify and file access, etc.)\nArithmetic operations, usually in multiple sections, such as unary operations, binary operations, ad hoc binary operations (e.g. multiplication of a complex object by a scalar), comparisons, ad hoc comparisons, division, etc.\nMore complex functionality separated into sections based on functionality provided, e.g. gcd, interpolation, special functions, solving, etc.\nFunctions for mapping between different types, coercion, changing base ring, etc.\nUnsafe operators, e.g. mul!, add!, addeq! etc.\nRandom generation\nPromotion rules\nParent object call overload (e.g. for implementing R(2) where R is an object representing a ring or field, etc.)\nAdditional constructors, e.g. matrix, which might be used instead of a parent object to construct elements.\nParent object constructors, e.g. polynomial_ring, etc.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"The exact order within the file is less important than generally following something like the above. This aids in finding functions in a file since all files are more or less set out the same way.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"For an example to follow, see the src/Poly.jl and src/generic/Poly.jl files in AbstractAlgebra which form the oldest and most canonical example.","category":"page"},{"location":"Nemo/developer/conventions/","page":"Conventions","title":"Conventions","text":"Headings for sections should be 80 characters wide and formed of hashes in the style that can be seen in each Nemo file.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"CurrentModule = Oscar \nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/localizations/#Localized-Rings-and-Their-Ideals","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"We recall the definition of localization. All rings considered are commutative, with multiplicative identity 1. Let R be a ring, and let U subset R be a multiplicatively closed subset. That is,","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"1 in U text and u v in U Rightarrow ucdot v in U","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Consider the equivalence relation on Rtimes U defined by setting","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"(ru)sim (r u) text iff v(r u-u r)=0 text for some vin U","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Write fracru for the equivalence class of (r u) and RU^-1 for the set of all equivalence classes. Mimicking the standard arithmetic for fractions, RU^-1 can be made into a ring. This ring is called the localization of R at U. It comes equipped with the natural ring homomorphism","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"iota Rto RU^-1 r mapsto fracr1","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Given an R-module M, the analogous construction yields an RU^-1-module MU^-1 which is called the localization of M at U. See the section on modules.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Our focus in this section is on localizing multivariate polynomial rings and their quotients. The starting point for this is to provide functionality for handling (several types of) multiplicatively closed subsets of multivariate polynomial rings. Given such a polynomial ring R and a multiplicatively closed subset U of R whose type is supported by OSCAR, entering localization(R, U) creates the localization of R at U. Given a quotient RQ of R, with projection map p : R to RQ, and given a multiplicatively closed subset U of R, entering localization(RQ, U) creates the localization of RQ at p(U): Since every multiplicatively closed subset of RQ is of type p(U) for some U, there is no need to support an extra type for multiplicatively closed subsets of quotients.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"note: Note\nMost functions described here rely on the computation of standard bases. Recall that OSCAR supports standard bases for multivariate polynomial rings over fields (exact fields supported by OSCAR) and for multivariate polynomial rings over the integers.\t","category":"page"},{"location":"CommutativeAlgebra/localizations/#Types","page":"Localized Rings and Their Ideals","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"The OSCAR types discussed in this section are all parametrized. To simplify the presentation, details on the parameters are omitted.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"All types for multiplicatively closed subsets of rings belong to the abstract type AbsMultSet. For multiplicatively closed subsets of multivariate polynomial rings, there are the abstract subtype AbsPolyMultSet and its concrete descendants MPolyComplementOfKPointIdeal, MPolyComplementOfPrimeIdeal, and MPolyPowersOfElement.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"The general abstract type for localizations of rings is AbsLocalizedRing. For localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocRing. For localizations of quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocRing. ","category":"page"},{"location":"CommutativeAlgebra/localizations/#Constructors","page":"Localized Rings and Their Ideals","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/#Multiplicatively-Closed-Subsets","page":"Localized Rings and Their Ideals","title":"Multiplicatively Closed Subsets","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"In accordance with the above mentioned types, we have the following constructors for multiplicatively closed subsets of multivariate polynomial rings.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":" complement_of_point_ideal(R::MPolyRing, a::Vector)\n complement_of_prime_ideal(P::MPolyIdeal; check::Bool=false)\n powers_of_element(f::MPolyRingElem)","category":"page"},{"location":"CommutativeAlgebra/localizations/#complement_of_point_ideal-Tuple{MPolyRing, Vector}","page":"Localized Rings and Their Ideals","title":"complement_of_point_ideal","text":"complement_of_point_ideal(R::MPolyRing, a::Vector)\n\nGiven a polynomial ring R, say R = Kx_1dots x_n, and given a vector a = (a_1 dots a_n) of n elements of K, return the multiplicatively closed subset Rsetminus m, where m is the maximal ideal \n\nm = langle x_1-a_1dots x_n-a_nrangle subset R\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> U = complement_of_point_ideal(R, [0, 0 ,0])\nComplement\n of maximal ideal corresponding to rational point with coordinates (0, 0, 0)\n in multivariate polynomial ring in 3 variables over QQ\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/#complement_of_prime_ideal-Tuple{MPolyIdeal}","page":"Localized Rings and Their Ideals","title":"complement_of_prime_ideal","text":"complement_of_prime_ideal(P::MPolyIdeal; check::Bool=false)\n\nGiven a prime ideal P of a polynomial ring R, say, return the multiplicatively closed subset Rsetminus P\n\nnote: Note\nIf check is set to true, the function checks whether P is indeed a prime ideal. This may take some time.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> P = ideal(R, [x])\nideal(x)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(x)\n in multivariate polynomial ring in 3 variables over QQ\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/#powers_of_element-Tuple{MPolyRingElem}","page":"Localized Rings and Their Ideals","title":"powers_of_element","text":"powers_of_element(f::MPolyRingElem)\n\nGiven an element f of a polynomial ring, return the multiplicatively closed subset of the polynomial ring which is formed by the powers of f.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> f = x\nx\n\njulia> U = powers_of_element(f)\nMultiplicative subset\n of multivariate polynomial ring in 3 variables over QQ\n given by the products of [x]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"It is also possible to build products of multiplicatively closed sets already given:","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"product(T::AbsMPolyMultSet, U::AbsMPolyMultSet)","category":"page"},{"location":"CommutativeAlgebra/localizations/#product-Tuple{Oscar.AbsMPolyMultSet, Oscar.AbsMPolyMultSet}","page":"Localized Rings and Their Ideals","title":"product","text":"product(T::AbsMPolyMultSet, U::AbsMPolyMultSet)\n\nReturn the product of the multiplicative subsets T and U. \n\nAlternatively, write T*U.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> T = complement_of_point_ideal(R, [0, 0 ,0])\nComplement\n of maximal ideal corresponding to rational point with coordinates (0, 0, 0)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> f = x\nx\n\njulia> U = powers_of_element(f)\nMultiplicative subset\n of multivariate polynomial ring in 3 variables over QQ\n given by the products of [x]\n\njulia> S = product(T, U)\nProduct of the multiplicative sets\n complement of maximal ideal of point (0, 0, 0)\n products of 1 element\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Containment in multiplicatively closed subsets can be checked via the in function:","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"in(f::MPolyRingElem, U::AbsMPolyMultSet)","category":"page"},{"location":"CommutativeAlgebra/localizations/#in-Tuple{MPolyRingElem, Oscar.AbsMPolyMultSet}","page":"Localized Rings and Their Ideals","title":"in","text":"in(f::MPolyRingElem, U::AbsMPolyMultSet)\n\nReturn true if f is contained in U, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> S = complement_of_point_ideal(R, [0, 0 ,0])\nComplement\n of maximal ideal corresponding to rational point with coordinates (0, 0, 0)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> y in S\nfalse\n\njulia> P = ideal(R, [x])\nideal(x)\n\njulia> T = complement_of_prime_ideal(P)\nComplement\n of prime ideal(x)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> y in T\ntrue\n\njulia> U = powers_of_element(x)\nMultiplicative subset\n of multivariate polynomial ring in 3 variables over QQ\n given by the products of [x]\n\njulia> x^3 in U\ntrue\n\njulia> (1+y)*x^2 in product(S, U)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/#Localized-Rings","page":"Localized Rings and Their Ideals","title":"Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"localization(R::MPolyRing, U::AbsMPolyMultSet)","category":"page"},{"location":"CommutativeAlgebra/localizations/#localization-Tuple{MPolyRing, Oscar.AbsMPolyMultSet}","page":"Localized Rings and Their Ideals","title":"localization","text":"localization(R::MPolyRing, U::AbsMPolyMultSet)\n\nReturn the localization of R at U, together with the localization map.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> P = ideal(R, [x])\nideal(x)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(x)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> Rloc, iota = localization(R, U);\n\njulia> Rloc\nLocalization\n of multivariate polynomial ring in 3 variables over QQ\n at complement of prime ideal(x)\n\njulia> iota\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nLocalization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"localization(RQ::MPolyQuoRing, U::AbsMPolyMultSet)","category":"page"},{"location":"CommutativeAlgebra/localizations/#localization-Tuple{MPolyQuoRing, Oscar.AbsMPolyMultSet}","page":"Localized Rings and Their Ideals","title":"localization","text":"localization(RQ::MPolyQuoRing, U::AbsMPolyMultSet)\n\nGiven a quotient RQ of a multivariate polynomial ring R with projection map p : R -> RQ, say, and given a multiplicatively closed subset U of R, return the localization of RQ at p(U), together with the localization map.\n\nExamples\n\njulia> T, t = polynomial_ring(QQ, \"t\");\n\njulia> K, a = number_field(2*t^2-1, \"a\");\n\njulia> R, (x, y) = polynomial_ring(K, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])\nideal(2*x^2 - y^3, 2*x^2 - y^5)\n\njulia> P = ideal(R, [y-1, x-a])\nideal(y - 1, x - a)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(y - 1, x - a)\n in multivariate polynomial ring in 2 variables over number field\n\njulia> RQ, _ = quo(R, I);\n\njulia> RQL, iota = localization(RQ, U);\n\njulia> RQL\nLocalization\n of quotient of multivariate polynomial ring by ideal with 2 generators\n at complement of prime ideal(y - 1, x - a)\n\njulia> iota\nMap from\nRQ to Localization of quotient of multivariate polynomial ring at complement of prime ideal defined by a julia-function\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/#Data-associated-to-Localized-Rings","page":"Localized Rings and Their Ideals","title":"Data associated to Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If Rloc is the localization of a multivariate polynomial ring R at a multiplicatively closed subset U of R, then","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"base_ring(Rloc) refers to R, and\ninverted_set(Rloc) to U.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If RQ is a quotient of a multivariate polynomial ring R, p : R to RQ is the projection map, U is a multiplicatively closed subset of R, and RQL is the localization of RQ at p(U), then","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"base_ring(RQL) refers to R, and\ninverted_set(RQL) to U.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"This reflects the way of creating localizations of quotients of multivariate polynomial rings in OSCAR.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Examples","page":"Localized Rings and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> P = ideal(R, [x])\nideal(x)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(x)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> Rloc, _ = localization(U);\n\njulia> R === base_ring(Rloc)\ntrue\n\njulia> U === inverted_set(Rloc)\ntrue","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"julia> T, t = polynomial_ring(QQ, \"t\");\n\njulia> K, a = number_field(2*t^2-1, \"a\");\n\njulia> R, (x, y) = polynomial_ring(K, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])\nideal(2*x^2 - y^3, 2*x^2 - y^5)\n\njulia> P = ideal(R, [y-1, x-a])\nideal(y - 1, x - a)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(y - 1, x - a)\n in multivariate polynomial ring in 2 variables over number field\n\njulia> RQ, _ = quo(R, I);\n\njulia> RQL, _ = localization(RQ, U);\n\njulia> R == base_ring(RQL)\ntrue\n\njulia> U == inverted_set(RQL)\ntrue","category":"page"},{"location":"CommutativeAlgebra/localizations/#Elements-of-Localized-Rings","page":"Localized Rings and Their Ideals","title":"Elements of Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/#Types-2","page":"Localized Rings and Their Ideals","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"The general abstract type for elements of localizations of rings is AbsLocalizedRingElem. For elements of localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocRingElem. For elements of localizations of quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocRingElem.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Creating-Elements-of-Localized-Rings","page":"Localized Rings and Their Ideals","title":"Creating Elements of Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If Rloc is the localization of a multivariate polynomial ring R at a multiplicatively closed subset U of R, then elements of Rloc are created as (fractions of) images of elements of R under the localization map or by coercing (pairs of) elements of R into fractions. ","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If RQ is a quotient of a multivariate polynomial ring R, p : R to RQ is the projection map, U is a multiplicatively closed subset of R, and RQL is the localization of RQ at p(U), then elements of RQL are created similarly, starting from elements of R.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Examples-2","page":"Localized Rings and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> P = ideal(R, [x])\nideal(x)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(x)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> Rloc, iota = localization(U);\n\njulia> iota(x)\nx\n\njulia> Rloc(x)\nx\n\njulia> f = iota(y)/iota(z)\ny/z\n\njulia> g = Rloc(y, z)\ny/z\n\njulia> X, Y, Z = Rloc.(gens(R));\n\njulia> h = Y/Z\ny/z\n\njulia> f == g == h\ntrue\n\njulia> f+g\n2*y/z\n\njulia> f*g\ny^2/z^2","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"julia> T, t = polynomial_ring(QQ, \"t\");\n\njulia> K, a = number_field(2*t^2-1, \"a\");\n\njulia> R, (x, y) = polynomial_ring(K, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])\nideal(2*x^2 - y^3, 2*x^2 - y^5)\n\njulia> P = ideal(R, [y-1, x-a])\nideal(y - 1, x - a)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(y - 1, x - a)\n in multivariate polynomial ring in 2 variables over number field\n\njulia> RQ, p = quo(R, I);\n\njulia> RQL, iota = Localization(RQ, U);\n\njulia> phi = compose(p, iota);\n\njulia> phi(x)\nx\n\njulia> RQL(x)\nx\n\njulia> f = phi(x)/phi(y)\nx/y\n\njulia> g = RQL(x, y)\nx/y\n\njulia> X, Y = gens(RQL);\n\njulia> h = X/Y\nx/y\n\njulia> f == g == h\ntrue\n\njulia> f+g\n2*x/y\n\njulia> f*g\nx^2/y^2","category":"page"},{"location":"CommutativeAlgebra/localizations/#Data-Associated-to-Elements-of-Localized-Rings","page":"Localized Rings and Their Ideals","title":"Data Associated to Elements of Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If Rloc is a localization of a multivariate polynomial ring R, and f is an element of Rloc, internally represented by a pair (r, u) of elements of R, then ","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"parent(f) refers to Rloc,\nnumerator(f) to r, and\ndenominator(f) to u.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If RQL is a localization of a quotient RQ of a multivariate polynomial ring R, and f is an element of RQL, internally represented by a pair (r, u) of elements of R, then","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"parent(f) refers to RQL,\nnumerator(f) to the image of r in RQ, and\ndenominator(f) to the image of u in RQ.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"That is, the behaviour of the functions numerator and denominator reflects the mathematical viewpoint of representing f by pairs of elements of RQ and not the internal representation of f as pairs of elements of R.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Examples-3","page":"Localized Rings and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> P = ideal(R, [x])\nideal(x)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(x)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> Rloc, iota = localization(U);\n\njulia> f = iota(x)/iota(y)\nx/y\n\njulia> parent(f)\nLocalization\n of multivariate polynomial ring in 3 variables over QQ\n at complement of prime ideal(x)\n\njulia> g = iota(y)/iota(z)\ny/z\n\njulia> r = numerator(f*g)\nx\n\njulia> u = denominator(f*g)\nz\n\njulia> typeof(r) == typeof(u) <: MPolyRingElem\ntrue","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"julia> T, t = polynomial_ring(QQ, \"t\");\n\njulia> K, a = number_field(2*t^2-1, \"a\");\n\njulia> R, (x, y) = polynomial_ring(K, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])\nideal(2*x^2 - y^3, 2*x^2 - y^5)\n\njulia> P = ideal(R, [y-1, x-a])\nideal(y - 1, x - a)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(y - 1, x - a)\n in multivariate polynomial ring in 2 variables over number field\n\njulia> RQ, p = quo(R, I);\n\njulia> RQL, iota = Localization(RQ, U);\n\njulia> phi = compose(p, iota);\n\njulia> f = phi(x)\nx\n\njulia> parent(f)\nLocalization\n of quotient of multivariate polynomial ring by ideal with 2 generators\n at complement of prime ideal(y - 1, x - a)\n\njulia> g = f/phi(y)\nx/y\n\njulia> r = numerator(f*g)\nx^2\n\njulia> u = denominator(f*g)\ny\n\njulia> typeof(r) == typeof(u) <: MPolyQuoRingElem\ntrue","category":"page"},{"location":"CommutativeAlgebra/localizations/#Tests-on-Elements-of-Localized-Rings","page":"Localized Rings and Their Ideals","title":"Tests on Elements of Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"is_unit(f::MPolyLocRingElem)","category":"page"},{"location":"CommutativeAlgebra/localizations/#is_unit-Tuple{MPolyLocRingElem}","page":"Localized Rings and Their Ideals","title":"is_unit","text":"is_unit(f::MPolyLocRingElem)\n\nReturn true, if f is a unit of parent(f), false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> P = ideal(R, [x])\nideal(x)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(x)\n in multivariate polynomial ring in 3 variables over QQ\n\njulia> Rloc, iota = localization(U);\n\njulia> is_unit(iota(x))\nfalse\n\njulia> is_unit(iota(y))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"is_unit(f::MPolyQuoLocRingElem)","category":"page"},{"location":"CommutativeAlgebra/localizations/#is_unit-Tuple{MPolyQuoLocRingElem}","page":"Localized Rings and Their Ideals","title":"is_unit","text":"is_unit(f::MPolyQuoLocRingElem)\n\nReturn true, if f is a unit of parent(f), true otherwise.\n\nExamples\n\njulia> T, t = polynomial_ring(QQ, \"t\");\n\njulia> K, a = number_field(2*t^2-1, \"a\");\n\njulia> R, (x, y) = polynomial_ring(K, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [2*x^2-y^3, 2*x^2-y^5])\nideal(2*x^2 - y^3, 2*x^2 - y^5)\n\njulia> P = ideal(R, [y-1, x-a])\nideal(y - 1, x - a)\n\njulia> U = complement_of_prime_ideal(P)\nComplement\n of prime ideal(y - 1, x - a)\n in multivariate polynomial ring in 2 variables over number field\n\njulia> RQ, p = quo(R, I);\n\njulia> RQL, iota = Localization(RQ, U);\n\njulia> is_unit(iota(p(x)))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/#Homomorphisms-from-Localized-Rings","page":"Localized Rings and Their Ideals","title":"Homomorphisms from Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"The general abstract type for ring homomorphisms starting from localized rings is AbsLocalizedRingHom. For ring homomorphisms starting from localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocalizedRingHom. For ring homomorphisms starting from quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocalizedRingHom. We describe the construction of such homomorphisms. Let","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"R be a multivariate polynomial ring\nU be a multiplicatively closed subset of R,\nRQ = R/I be a quotient of R with projection map p : R to RQ,\nRloc (RQL) be the localization of R at U (of RQ at p(U)), and\nS be another ring.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Then, to give a ring homomorphism PHI from Rloc to S (fromRQL to S) is the same as to give a ring homomorphism phi from R to S which sends elements of U to units in S (and elements of I to zero). That is, PHI is determined by composing it with the localization map R to Rloc (by composing it with the composition of the localization map RQ to RQL and the projection map R to RQ). The constructors below take this into account.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"hom(Rloc::MPolyLocRing, S::Ring, F::Map)","category":"page"},{"location":"CommutativeAlgebra/localizations/#hom-Tuple{MPolyLocRing, Ring, Map}","page":"Localized Rings and Their Ideals","title":"hom","text":"hom(Rloc::MPolyLocRing, S::Ring, phi::Map)\n\nGiven a localized ring Rlocof type MPolyLocRing, say Rloc is the localization of a multivariate polynomial ring R at the multiplicatively closed subset U of R, and given a homomorphism phi from R to S sending elements of U to units in S, return the homomorphism from Rloc to S whose composition with the localization map is phi.\n\nhom(Rloc::MPolyLocRing, S::Ring, V::Vector)\n\nGiven a localized ring Rloc as above, and given a vector V of nvars elements of S, let phi be the homomorphism from R to S which is determined by the entries of V as the images of the generators of R, and proceed as above.\n\nhom(RQL::MPolyQuoLocRing, S::Ring, phi::Map)\n\nGiven a localized ring RQLof type MPolyQuoLocRing, say RQL is the localization of a quotient ring RQ of a multivariate polynomial ring R at the multiplicatively closed subset U of R, and given a homomorphism phi from R to S sending elements of U to units in S and elements of the modulus of RQ to zero, return the homomorphism from Rloc to S whose composition with the localization map RQ -> RQL and the projection map R -> RQ is phi.\n\nhom(RQL::MPolyQuoLocRing, S::Ring, V::Vector)\n\nGiven a localized ring RQLas above, and given a vector V of nvars elements of S, let phi be the homomorphism from R to S which is determined by the entries of V as the images of the generators of R, and proceed as above.\n\nwarning: Warning\nExcept from the case where the type of U is <: MPolyPowersOfElement, the condition on phi requiring that elements of U are send to units in S is not checked by the hom constructor.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> I = ideal(R, [y-x^2, z-x^3]);\n\njulia> RQ, p = quo(R, I);\n\njulia> UR = complement_of_point_ideal(R, [0, 0, 0]);\n\njulia> RQL, _ = localization(RQ, UR);\n\njulia> T, (t,) = polynomial_ring(QQ, [\"t\"]);\n\njulia> UT = complement_of_point_ideal(T, [0]);\n\njulia> TL, _ = localization(T, UT);\n\njulia> PHI = hom(RQL, TL, TL.([t, t^2, t^3]))\nRing homomorphism\n from localization of quotient of multivariate polynomial ring at complement of maximal ideal\n to localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal\ndefined by\n x -> t\n y -> t^2\n z -> t^3\n\njulia> PSI = hom(TL, RQL, RQL.([x]))\nRing homomorphism\n from localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal\n to localization of quotient of multivariate polynomial ring at complement of maximal ideal\ndefined by\n t -> x\n\njulia> PHI(RQL(z))\nt^3\n\njulia> PSI(TL(t))\nx\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Given a ring homomorphism PHI from Rloc to S (from RQL to S), domain(PHI) and codomain(PHI) refer to Rloc and S (RQL and S), respectively. The corresponding homomorphism phi from R to S is recovered as follows:","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"restricted_map(PHI::MPolyLocalizedRingHom)","category":"page"},{"location":"CommutativeAlgebra/localizations/#restricted_map-Tuple{MPolyLocalizedRingHom}","page":"Localized Rings and Their Ideals","title":"restricted_map","text":"restricted_map(PHI::MPolyLocalizedRingHom)\n\nrestricted_map(PHI::MPolyQuoLocalizedRingHom)\n\nGiven a ring homomorphism PHI starting from a localized multivariate polynomial ring (a localized quotient of a multivariate polynomial ring), return the composition of PHI with the localization map (with the composition of the localization map and the projection map).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> I = ideal(R, [y-x^2, z-x^3]);\n\njulia> RQ, p = quo(R, I);\n\njulia> UR = complement_of_point_ideal(R, [0, 0, 0]);\n\njulia> RQL, _ = localization(RQ, UR);\n\njulia> T, (t,) = polynomial_ring(QQ, [\"t\"]);\n\njulia> UT = complement_of_point_ideal(T, [0]);\n\njulia> TL, _ = localization(T, UT);\n\njulia> PHI = hom(RQL, TL, TL.([t, t^2, t^3]));\n\njulia> PSI = hom(TL, RQL, RQL.([x]));\n\njulia> phi = restricted_map(PHI)\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nLocalization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal\n\njulia> psi = restricted_map(PSI)\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 1 variable over QQ\nCodomain:\n=========\nLocalization of quotient of multivariate polynomial ring at complement of maximal ideal\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/localizations/#Ideals-in-Localized-Rings","page":"Localized Rings and Their Ideals","title":"Ideals in Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/#Types-3","page":"Localized Rings and Their Ideals","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"The general abstract type for ideals in localized rings is AbsLocalizedIdeal. For ideals in localizations of multivariate polynomial rings, there is the concrete subtype MPolyLocalizedIdeal. For ideals in localizations of quotients of multivariate polynomial rings, there is the concrete subtype MPolyQuoLocalizedIdeal.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Constructors-2","page":"Localized Rings and Their Ideals","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Given a localization Rloc of a multivariate polynomial ring R, and given a vector V of elements of Rloc (of R), the ideal of Rloc which is generated by (the images) of the entries of V is created by entering ideal(Rloc, V). The construction of ideals in localizations of quotients of multivariate polynomial rings is similar..","category":"page"},{"location":"CommutativeAlgebra/localizations/#Examples-4","page":"Localized Rings and Their Ideals","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> f = x^3+y^4\nx^3 + y^4\n\njulia> V = [derivative(f, i) for i=1:2]\n2-element Vector{QQMPolyRingElem}:\n 3*x^2\n 4*y^3\n\njulia> U = complement_of_point_ideal(R, [0, 0]);\n\njulia> Rloc, _ = localization(R, U);\n\njulia> MI = ideal(Rloc, V)\nIdeal\n of localized ring\nwith 2 generators\n 3*x^2\n 4*y^3","category":"page"},{"location":"CommutativeAlgebra/localizations/#Data-Associated-to-Ideals","page":"Localized Rings and Their Ideals","title":"Data Associated to Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If I is an ideal of a localized multivariate polynomial ring Rloc, then","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"base_ring(I) refers to Rloc,\ngens(I) to the generators of I,\nngens(I) to the number of these generators, and\ngen(I, k) as well as I[k] to the k-th such generator.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Similarly, if I is an ideal of a localized quotient of a multivariate polynomial ring.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Operations-on-Ideals","page":"Localized Rings and Their Ideals","title":"Operations on Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If I, J are ideals of a localized multivariate polynomial ring Rloc, then","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"I^k refers to the k-th power of I, \nI+J, I*J, and intersect(I, J) to the sum, product, and intersection of I and J, and\nquotient(I, J) as well as I:J to the ideal quotient of I by J.","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"Similarly, if I and J are ideals of a localized quotient of a multivariate polynomial ring.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Tests-on-Ideals","page":"Localized Rings and Their Ideals","title":"Tests on Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"The usual tests f in J, issubset(I, J), and I == J are available.","category":"page"},{"location":"CommutativeAlgebra/localizations/#Saturation","page":"Localized Rings and Their Ideals","title":"Saturation","text":"","category":"section"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If Rloc is the localization of a multivariate polynomial ring R at a multiplicative subset U of R, then the ideal theory of Rloc is a simplified version of the ideal theory of R (see, for instance, David Eisenbud (1995)). In particular, each ideal I of Rloc is the extension Jcdot Rloc of an ideal J of R. The ideal","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"fin R mid ufin J text for some uin U","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"is independent of the choice of J and is the largest ideal of R which extends to I. It is, thus, the contraction of I to R, that is, the preimage of I under the localization map. We call this ideal the saturation of I over R. In OSCAR, it is obtained by entering saturated_ideal(I).","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"If RQL is the localization of a quotient RQ of a multivariate polynomial ring R, and I is an ideal of RQL, then the return value of saturated_ideal(I) is the preimage of the saturation of I over RQ under the projection map R to RQ (and not the saturation of I over RQ itself).","category":"page"},{"location":"CommutativeAlgebra/localizations/","page":"Localized Rings and Their Ideals","title":"Localized Rings and Their Ideals","text":"saturated_ideal(I::MPolyLocalizedIdeal)","category":"page"},{"location":"CommutativeAlgebra/localizations/#saturated_ideal-Tuple{MPolyLocalizedIdeal}","page":"Localized Rings and Their Ideals","title":"saturated_ideal","text":"saturated_ideal(I::MPolyLocalizedIdeal)\n\nGiven an ideal I of a localization, say, Rloc of a multivariate polynomial ring, say, R, return the saturation of I over R. That is, return the largest ideal of R whose extension to Rloc is I. This is the preimage of I under the localization map.\n\nsaturated_ideal(I::MPolyQuoLocalizedIdeal)\n\nGiven an ideal I of a localization, say, RQL of a quotient, say, RQ of a multivariate polynomial ring, say, R, return the preimage of the saturation of I over RQ under the projection map R -> RQ.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> U = powers_of_element(x)\nMultiplicative subset\n of multivariate polynomial ring in 1 variable over QQ\n given by the products of [x]\n\njulia> Rloc, iota = localization(R, U);\n\njulia> I = ideal(Rloc, [x+x^2])\nIdeal\n of localized ring\nwith 1 generator\n x^2 + x\n\njulia> SI = saturated_ideal(I)\nideal(x + 1)\n\njulia> base_ring(SI)\nMultivariate polynomial ring in 1 variable x\n over rational field\n\njulia> U = complement_of_point_ideal(R, [0])\nComplement\n of maximal ideal corresponding to rational point with coordinates (0)\n in multivariate polynomial ring in 1 variable over QQ\n\njulia> Rloc, iota = localization(R, U);\n\njulia> I = ideal(Rloc, [x+x^2])\nIdeal\n of localized ring\nwith 1 generator\n x^2 + x\n\njulia> saturated_ideal(I)\nideal(x)\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/SubObjectIterator/#SubObjectIterator","page":"SubObjectIterator","title":"SubObjectIterator","text":"","category":"section"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Many of the objects in the field of Polyhedral Geometry mask a BigObject from Polymake.jl. These big objects have properties which can easily be accessed via julia's dot syntax. The return commonly does not adhere to the mathematical or the typing conventions of Oscar; many properties encode information about a collection of mathematical objects within a single data object.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The SubObjectIterator is a precise and flexible tool to directly access and/or process the desired properties of any Polymake.BigObject, but it requires specific interface definitions to work properly for each context. The user can thus profit from an easily understandable and usable iterator.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"This guide is meant to communicate the application of the SubObjectIterator for developers, utilizing existing code as reference and examples.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/#Creating-a-working-SubObjectIterator","page":"SubObjectIterator","title":"Creating a working SubObjectIterator","text":"","category":"section"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The formal definition of the SubObjectIterator in src/PolyhedralGeometry/iterators is:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"struct SubObjectIterator{T} <: AbstractVector{T}\n Obj::Polymake.BigObject\n Acc::Function\n n::Int\n options::NamedTuple\nend","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"An instance can be created by passing values for all fields, while options is optional.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Trivially, Obj is the Polymake.BigObject whose property is to be accessed. The other fields will each be explained in an upcoming section.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/#Length","page":"SubObjectIterator","title":"Length","text":"","category":"section"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"As an AbstractVector, the SubObjectIterator has a length. Due to the nature of Polymake.BigObjects this length is constant for any property. Sometimes the length can easily be derived as a by-product of pre-computations when creating an instance of SubObjectIterator. To avoid performing unnecessary computations afterwards, the value is set at construction in n.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/#Access-function","page":"SubObjectIterator","title":"Access function","text":"","category":"section"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Optimally retrieving and converting the elements varies strongly between the contexts in which a SubObjectIterator is created. Thus its getindex method redirects the call to the (internal) function Acc:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"function Base.getindex(iter::SubObjectIterator{T}, i::Base.Integer) where T\n @boundscheck 1 <= i && i <= iter.n\n return iter.Acc(T, iter.Obj, i; iter.options...)\nend","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"From this call we can see that the access function's signature needs to satisfy certain requirements for the SubObjectIterator to work. The arguments are:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"T: The return type.\niter.Obj: The Polymake.BigObject whose property is to be accessed.\ni: The index.\niter.options: Additional arguments. Will be explained later.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Let us look at an example how we can utilize this interface. The following is the implementation to access the rays of a Cone:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"rays(as::Type{RayVector{T}}, C::Cone) where T = SubObjectIterator{as}(pm_object(C), _ray_cone, nrays(C))\n\n_ray_cone(::Type{T}, C::Polymake.BigObject, i::Base.Integer) where T = T(C.RAYS[i, :])","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Typing r = rays(RayVector{Polymake.Rational}, C) with a Cone C returns a SubObjectIterator over RayVector{Polymake.Rational} elements of length nrays(C) with access function _ray_cone. With the given method of this function, getindex(r, i) returns a RayVector{Polymake.Rational} constructed from the i-th row of the property RAYS of the Polymake.BigObject.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The user does never directly create a SubObjectIterator, so type restrictions made where it is created can be assumed to hold. In our example _ray_cone will always be called with T<:RayVector.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"One can define several methods of the access function to ideally read and process data. Consider facets(as::Type{T}, C::Cone). Depending on the return type we offer three methods:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"_facet_cone(::Type{T}, C::Polymake.BigObject, i::Base.Integer) where T<:Union{Polyhedron, AffineHalfspace} = T(-C.FACETS[[i], :], 0)\n\n_facet_cone(::Type{LinearHalfspace}, C::Polymake.BigObject, i::Base.Integer) = LinearHalfspace(-C.FACETS[[i], :])\n\n_facet_cone(::Type{Cone}, C::Polymake.BigObject, i::Base.Integer) = cone_from_inequalities(-C.FACETS[[i], :])","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/#Additional-Methods","page":"SubObjectIterator","title":"Additional Methods","text":"","category":"section"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The SubObjectIterator can moreover be understood as a mathematical collection the sense that one can","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"ask for specific information encoded in the data or\nuse this collection as an argument for construction another mathematical object.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The first case is covered by adding methods to specific internal functions. Remember implementation of rays discussed above. It makes sense to define a vector_matrix method on its output, encoding the rays of the cone as a single matrix based on a convention applied throughout Oscar. The function's implementation a user calls in this case is evaluated to these lines:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"vector_matrix(iter::SubObjectIterator{<:AbstractVector{Polymake.Rational}}) = matrix(QQ, Matrix{QQFieldElem}(_vector_matrix(Val(iter.Acc), iter.Obj; iter.options...)))\nvector_matrix(iter::SubObjectIterator{<:AbstractVector{Polymake.Integer}}) = matrix(ZZ, _vector_matrix(Val(iter.Acc), iter.Obj; iter.options...))\n_vector_matrix(::Any, ::Polymake.BigObject) = throw(ArgumentError(\"Vector Matrix not defined in this context.\"))","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Two functionalities are defined this way:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The call of vector_matrix(iter) is redirected to _vector_matrix(Val(iter.Acc), iter.Obj). If that method is not defined for the value type of the access function, it falls back to throwing an error.\nThe matrix received from step 1 is converted from Polymake.jl format to Oscar format.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"So by defining the following we have a fully functional vector_matrix method in the context of rays:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"_vector_matrix(::Val{_ray_cone}, C::Polymake.BigObject) = C.RAYS","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The second case is solved with defining a special _matrix_for_polymake method. One just hast to name the internal function that returns the desired matrix. This way one has the ability to precisely control how the iterator works internally in specific contexts, even if there happen to be multiple additional matrix functions.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Again, the call matrix_for_polymake(iter) will either redirect to the defined method or fall back to throwing an error if there is none:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"function matrix_for_polymake(iter::SubObjectIterator)\n if hasmethod(_matrix_for_polymake, Tuple{Val{iter.Acc}})\n return _matrix_for_polymake(Val(iter.Acc))(Val(iter.Acc), iter.Obj; iter.options...)\n else\n throw(ArgumentError(\"Matrix for Polymake not defined in this context.\"))\n end\nend","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"For rays(C::Cone) this reduces the implementation to the following line:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"_matrix_for_polymake(::Val{_ray_cone}) = _vector_matrix","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"With matrix_for_polymake the output of rays can be handled as a usual matrix and constructors or other functions can easily be extended by additionally allowing SubObjectIterator as an argument type. E.g. the signature of one of the Cone constructors now looks like this while the body has not changed:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Cone(R::Union{SubObjectIterator{<:RayVector}, Oscar.MatElem, AbstractMatrix}, L::Union{SubObjectIterator{<:RayVector}, Oscar.MatElem, AbstractMatrix, Nothing} = nothing; non_redundant::Bool = false)","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"There also are linear_matrix_for_polymake and affine_matrix_for_polymake used in the context of linear and affine halfspaces/hyperplanes. Defining this functionality in a context works the same way as for matrix_for_polymake; you can create a new method of _linear_matrix_for_polymake or _affine_matrix_for_polymake. It suffices to define the most relevant of these two; the other one will be derived, if possible. Also, halfspace_matrix_pair is defined in terms of affine_matrix_for_polymake, so this does not need another implementation.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The example code for rays(C::Cone) has covered every line of the implementation by now, but we had different code in between, so let us summarize and take a look at what the whole implementation actually looks like:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"rays(as::Type{RayVector{T}}, C::Cone) where T = SubObjectIterator{as}(pm_object(C), _ray_cone, nrays(C))\n\n_ray_cone(::Type{T}, C::Polymake.BigObject, i::Base.Integer) where T = T(C.RAYS[i, :])\n\n_vector_matrix(::Val{_ray_cone}, C::Polymake.BigObject) = C.RAYS\n\n_matrix_for_polymake(::Val{_ray_cone}) = _vector_matrix","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/#options","page":"SubObjectIterator","title":"options","text":"","category":"section"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"Sometimes you need further arguments to specify the returned data. These arguments are set at construction of the SubObjectIterator and later passed to the corresponding functions as keyword arguments.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"A good example how to use this is faces(C::Cone, face_dim::Int). It is not enough to know that our SubObjectIterator is set in the context of faces of cones; face_dim will be relevant for any type of access occurring in the future.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"function faces(C::Cone, face_dim::Int)\n n = face_dim - length(lineality_space(C))\n n < 1 && return nothing\n return SubObjectIterator{Cone}(C.pm_cone, _face_cone, size(Polymake.polytope.faces_of_dim(pm_object(C), n), 1), (f_dim = n,))\nend","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"When this method is called with meaningful input, it creates a SubObjectIterator where the last argument is a NamedTuple specifying that f_dim = n. The information encoded in this NamedTuple will be passed as keyword arguments when calling the access function or any additional method (reconsider their definitions). This allows us to directly ask for that data when implementing these methods:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"function _face_cone(::Type{Cone}, C::Polymake.BigObject, i::Base.Integer; f_dim::Int = 0)\n return Cone(Polymake.polytope.Cone(RAYS = C.RAYS[collect(Polymake.to_one_based_indexing(Polymake.polytope.faces_of_dim(C, f_dim)[i])), :], LINEALITY_SPACE = C.LINEALITY_SPACE))\nend\n\nfunction _ray_indices(::Val{_face_cone}, C::Polymake.BigObject; f_dim::Int = 0)\n f = Polymake.to_one_based_indexing(Polymake.polytope.faces_of_dim(C, f_dim))\n return IncidenceMatrix([collect(f[i]) for i in 1:length(f)])\nend","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/#Extending-the-interface","page":"SubObjectIterator","title":"Extending the interface","text":"","category":"section"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The additional methods offer an intuitive way of interaction for the user, but their current selection is not carved in stone. You can easily add more similar methods by extending the list that is iterated over to generate the code. Which list that is usually depends on the output format. vector_matrix returns matrices with either integer or rational elements. The same capabilities hold for point_matrix and generator_matrix:","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"for (sym, name) in ((\"point_matrix\", \"Point Matrix\"), (\"vector_matrix\", \"Vector Matrix\"), (\"generator_matrix\", \"Generator Matrix\"))\n M = Symbol(sym)\n _M = Symbol(string(\"_\", sym))\n @eval begin\n $M(iter::SubObjectIterator{<:AbstractVector{Polymake.Rational}}) = matrix(QQ, Matrix{QQFieldElem}($_M(Val(iter.Acc), iter.Obj; iter.options...)))\n $M(iter::SubObjectIterator{<:AbstractVector{Polymake.Integer}}) = matrix(ZZ, $_M(Val(iter.Acc), iter.Obj; iter.options...))\n $_M(::Any, ::Polymake.BigObject) = throw(ArgumentError(string($name, \" not defined in this context.\")))\n end\nend","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"The second string (name) of each pair determines the name that is printed in error messages.","category":"page"},{"location":"DeveloperDocumentation/SubObjectIterator/","page":"SubObjectIterator","title":"SubObjectIterator","text":"If required, one can of course write completely new functions to extend the interface.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/algebraic/#Algebraic-numbers","page":"Algebraic numbers","title":"Algebraic numbers","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Nemo allows working with exact real and complex algebraic numbers.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"The default algebraic number type in Nemo is provided by Calcium. The associated field of algebraic numbers is represented by the constant parent object called CalciumQQBar.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"For convenience we define","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"QQBar = CalciumQQBar","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"so that algebraic numbers can be constructed using QQBar instead of CalciumQQBar. Note that this is the name of a specific parent object, not the name of its type.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Library Element type Parent type\nCalcium qqbar CalciumQQBarField","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Important note on performance","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"The default algebraic number type represents algebraic numbers in canonical form using minimal polynomials. This works well for representing individual algebraic numbers, but it does not provide the best performance for field arithmetic. For fast calculation in overlinemathbbQ, CalciumField should typically be used instead (see the section on Exact real and complex numbers). Alternatively, to compute in a fixed subfield of overlinemathbbQ, you may fix a generator a and construct an Antic number field to represent mathbbQ(a).","category":"page"},{"location":"Nemo/algebraic/#Algebraic-number-functionality","page":"Algebraic numbers","title":"Algebraic number functionality","text":"","category":"section"},{"location":"Nemo/algebraic/#Constructing-algebraic-numbers","page":"Algebraic numbers","title":"Constructing algebraic numbers","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Methods to construct algebraic numbers include:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Conversion from other numbers and through arithmetic operations\nComputing the roots of a given polynomial\nComputing the eigenvalues of a given matrix\nRandom generation\nExact trigonometric functions (see later section)\nGuessing (see later section)","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Examples","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Arithmetic:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> ZZRingElem(QQBar(3))\n3\n\njulia> QQFieldElem(QQBar(3) // 2)\n3//2\n\njulia> QQBar(-1) ^ (QQBar(1) // 3)\nRoot 0.500000 + 0.866025*im of x^2 - x + 1","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Solving the quintic equation:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over QQ, x)\n\njulia> v = roots(QQBar, x^5-x-1)\n5-element Vector{qqbar}:\n Root 1.16730 of x^5 - x - 1\n Root 0.181232 + 1.08395*im of x^5 - x - 1\n Root 0.181232 - 1.08395*im of x^5 - x - 1\n Root -0.764884 + 0.352472*im of x^5 - x - 1\n Root -0.764884 - 0.352472*im of x^5 - x - 1\n\njulia> v[1]^5 - v[1] - 1 == 0\ntrue","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Computing exact eigenvalues of a matrix:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> eigenvalues(ZZ[1 1 0; 0 1 1; 1 0 1], QQBar)\n3-element Vector{qqbar}:\n Root 2.00000 of x - 2\n Root 0.500000 + 0.866025*im of x^2 - x + 1\n Root 0.500000 - 0.866025*im of x^2 - x + 1","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Interface","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"roots(R::CalciumQQBarField, f::ZZPolyRingElem)\nroots(R::CalciumQQBarField, f::QQPolyRingElem)\neigenvalues(A::ZZMatrix, R::CalciumQQBarField)\neigenvalues(A::QQMatrix, R::CalciumQQBarField)\nrand(R::CalciumQQBarField; degree::Int, bits::Int, randtype::Symbol=:null)","category":"page"},{"location":"Nemo/algebraic/#roots-Tuple{CalciumQQBarField, ZZPolyRingElem}","page":"Algebraic numbers","title":"roots","text":"roots(R::CalciumQQBarField, f::ZZPolyRingElem)\n\nReturn all the roots of the polynomial f in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Roots of multiplicity higher than one are repeated according to their multiplicity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#roots-Tuple{CalciumQQBarField, QQPolyRingElem}","page":"Algebraic numbers","title":"roots","text":"roots(R::CalciumQQBarField, f::QQPolyRingElem)\n\nReturn all the roots of the polynomial f in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Roots of multiplicity higher than one are repeated according to their multiplicity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#eigenvalues-Tuple{ZZMatrix, CalciumQQBarField}","page":"Algebraic numbers","title":"eigenvalues","text":"eigenvalues(A::ZZMatrix, R::CalciumQQBarField)\n\nReturn all the eigenvalues of the matrix A in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Eigenvalues of multiplicity higher than one are repeated according to their multiplicity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#eigenvalues-Tuple{QQMatrix, CalciumQQBarField}","page":"Algebraic numbers","title":"eigenvalues","text":"eigenvalues(A::QQMatrix, R::CalciumQQBarField)\n\nReturn all the eigenvalues of the matrix A in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers. Eigenvalues of multiplicity higher than one are repeated according to their multiplicity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#rand-Tuple{CalciumQQBarField}","page":"Algebraic numbers","title":"rand","text":"rand(R::CalciumQQBarField; degree::Int, bits::Int, randtype::Symbol=:null)\n\nReturn a random algebraic number with degree up to degree and coefficients up to bits in size. By default, both real and complex numbers are generated. Set the optional randtype to :real or :nonreal to generate a specific type of number. Note that nonreal numbers require degree at least 2.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#Numerical-evaluation","page":"Algebraic numbers","title":"Numerical evaluation","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Examples","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Algebraic numbers can be evaluated numerically to arbitrary precision by converting to real or complex Arb fields:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> RR = ArbField(64); RR(sqrt(QQBar(2)))\n[1.414213562373095049 +/- 3.45e-19]\n\njulia> CC = AcbField(32); CC(QQBar(-1) ^ (QQBar(1) // 4))\n[0.707106781 +/- 2.74e-10] + [0.707106781 +/- 2.74e-10]*im","category":"page"},{"location":"Nemo/algebraic/#Minimal-polynomials,-conjugates,-and-properties","page":"Algebraic numbers","title":"Minimal polynomials, conjugates, and properties","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Examples","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Retrieving the minimal polynomial and algebraic conjugates of a given algebraic number:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> minpoly(polynomial_ring(ZZ, \"x\")[1], QQBar(1+2im))\nx^2 - 2*x + 5\n\njulia> conjugates(QQBar(1+2im))\n2-element Vector{qqbar}:\n Root 1.00000 + 2.00000*im of x^2 - 2x + 5\n Root 1.00000 - 2.00000*im of x^2 - 2x + 5","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Interface","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"iszero(x::qqbar)\nisone(x::qqbar)\nisinteger(x::qqbar)\nis_rational(x::qqbar)\nisreal(x::qqbar)\ndegree(x::qqbar)\nis_algebraic_integer(x::qqbar)\nminpoly(R::ZZPolyRing, x::qqbar)\nminpoly(R::QQPolyRing, x::qqbar)\nconjugates(a::qqbar)\ndenominator(x::qqbar)\nnumerator(x::qqbar)\nheight(x::qqbar)\nheight_bits(x::qqbar)","category":"page"},{"location":"Nemo/algebraic/#iszero-Tuple{qqbar}","page":"Algebraic numbers","title":"iszero","text":"iszero(x::qqbar)\n\nReturn whether x is the number 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#isone-Tuple{qqbar}","page":"Algebraic numbers","title":"isone","text":"isone(x::qqbar)\n\nReturn whether x is the number 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#isinteger-Tuple{qqbar}","page":"Algebraic numbers","title":"isinteger","text":"isinteger(x::qqbar)\n\nReturn whether x is an integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_rational-Tuple{qqbar}","page":"Algebraic numbers","title":"is_rational","text":"is_rational(x::qqbar)\n\nReturn whether x is a rational number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#isreal-Tuple{qqbar}","page":"Algebraic numbers","title":"isreal","text":"isreal(x::qqbar)\n\nReturn whether x is a real number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#degree-Tuple{qqbar}","page":"Algebraic numbers","title":"degree","text":"degree(x::qqbar)\n\nReturn the degree of the minimal polynomial of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_algebraic_integer-Tuple{qqbar}","page":"Algebraic numbers","title":"is_algebraic_integer","text":"is_algebraic_integer(x::qqbar)\n\nReturn whether x is an algebraic integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#minpoly-Tuple{ZZPolyRing, qqbar}","page":"Algebraic numbers","title":"minpoly","text":"minpoly(R::ZZPolyRing, x::qqbar)\n\nReturn the minimal polynomial of x as an element of the polynomial ring R.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#minpoly-Tuple{QQPolyRing, qqbar}","page":"Algebraic numbers","title":"minpoly","text":"minpoly(R::ZZPolyRing, x::qqbar)\n\nReturn the minimal polynomial of x as an element of the polynomial ring R.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#conjugates-Tuple{qqbar}","page":"Algebraic numbers","title":"conjugates","text":"conjugates(a::qqbar)\n\nReturn all the roots of the polynomial f in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#denominator-Tuple{qqbar}","page":"Algebraic numbers","title":"denominator","text":"denominator(x::qqbar)\n\nReturn the denominator of x, defined as the leading coefficient of the minimal polynomial of x. The result is returned as an ZZRingElem.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#numerator-Tuple{qqbar}","page":"Algebraic numbers","title":"numerator","text":"numerator(x::qqbar)\n\nReturn the numerator of x, defined as x multiplied by its denominator. The result is an algebraic integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#height-Tuple{qqbar}","page":"Algebraic numbers","title":"height","text":"height(x::qqbar)\n\nReturn the height of the algebraic number x. The result is an ZZRingElem integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#height_bits-Tuple{qqbar}","page":"Algebraic numbers","title":"height_bits","text":"height_bits(x::qqbar)\n\nReturn the height of the algebraic number x measured in bits. The result is a Julia integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#Complex-parts","page":"Algebraic numbers","title":"Complex parts","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Examples","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> real(sqrt(QQBar(1im)))\nRoot 0.707107 of 2x^2 - 1\n\njulia> abs(sqrt(QQBar(1im)))\nRoot 1.00000 of x - 1\n\njulia> floor(sqrt(QQBar(1000)))\nRoot 31.0000 of x - 31\n\njulia> sign(QQBar(-10-20im))\nRoot -0.447214 - 0.894427*im of 5x^4 + 6x^2 + 5","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Interface","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"real(a::qqbar)\nimag(a::qqbar)\nabs(a::qqbar)\nabs2(a::qqbar)\nconj(a::qqbar)\nsign(a::qqbar)\ncsgn(a::qqbar)\nsign_real(a::qqbar)\nsign_imag(a::qqbar)\nfloor(a::qqbar)\nceil(a::qqbar)","category":"page"},{"location":"Nemo/algebraic/#real-Tuple{qqbar}","page":"Algebraic numbers","title":"real","text":"real(a::qqbar)\n\nReturn the real part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#imag-Tuple{qqbar}","page":"Algebraic numbers","title":"imag","text":"imag(a::qqbar)\n\nReturn the imaginary part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#abs-Tuple{qqbar}","page":"Algebraic numbers","title":"abs","text":"abs(a::qqbar)\n\nReturn the absolute value of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#abs2-Tuple{qqbar}","page":"Algebraic numbers","title":"abs2","text":"abs2(a::qqbar)\n\nReturn the squared absolute value of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#conj-Tuple{qqbar}","page":"Algebraic numbers","title":"conj","text":"conj(a::qqbar)\n\nReturn the complex conjugate of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#sign-Tuple{qqbar}","page":"Algebraic numbers","title":"sign","text":"sign(a::qqbar)\n\nReturn the complex sign of a, defined as zero if a is zero and as a a otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#csgn-Tuple{qqbar}","page":"Algebraic numbers","title":"csgn","text":"csgn(a::qqbar)\n\nReturn the extension of the real sign function taking the value 1 strictly in the right half plane, -1 strictly in the left half plane, and the sign of the imaginary part when on the imaginary axis. Equivalently, operatornamecsgn(x) = x sqrtx^2 except that the value is 0 at zero. The value is returned as a Julia integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#sign_real-Tuple{qqbar}","page":"Algebraic numbers","title":"sign_real","text":"sign_real(a::qqbar)\n\nReturn the sign of the real part of a as a Julia integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#sign_imag-Tuple{qqbar}","page":"Algebraic numbers","title":"sign_imag","text":"sign_imag(a::qqbar)\n\nReturn the sign of the imaginary part of a as a Julia integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#floor-Tuple{qqbar}","page":"Algebraic numbers","title":"floor","text":"floor(a::qqbar)\n\nReturn the floor function of a as an algebraic number. Use ZZRingElem(floor(a)) to construct a Nemo integer instead.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#ceil-Tuple{qqbar}","page":"Algebraic numbers","title":"ceil","text":"ceil(a::qqbar)\n\nReturn the ceiling function of b as an algebraic number. Use ZZRingElem(ceil(a)) to construct a Nemo integer instead.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#Comparing-algebraic-numbers","page":"Algebraic numbers","title":"Comparing algebraic numbers","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"The operators == and != check exactly for equality.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"We provide various comparison functions for ordering algebraic numbers:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Standard comparison for real numbers (<, isless)\nReal parts\nImaginary parts\nAbsolute values\nAbsolute values of real or imaginary parts\nRoot sort order ","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"The standard comparison will throw if either argument is nonreal.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"The various comparisons for complex parts are provided as separate operations since these functions are far more efficient than explicitly computing the complex parts and then doing real comparisons.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"The root sort order is a total order for complex algebraic numbers used to order the output of roots and conjugates canonically. We define this order as follows: real roots come first, in descending order. Nonreal roots are subsequently ordered first by real part in descending order, then in ascending order by the absolute value of the imaginary part, and then in descending order of the sign of the imaginary part. This implies that complex conjugate roots are adjacent, with the root in the upper half plane first.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Examples","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> 1 < sqrt(QQBar(2)) < QQBar(3)//2\ntrue\n\njulia> x = QQBar(3+4im)\nRoot 3.00000 + 4.00000*im of x^2 - 6x + 25\n\njulia> is_equal_abs(x, -x)\ntrue\n\njulia> is_equal_abs_imag(x, 2-x)\ntrue\n\njulia> is_less_real(x, x // 2)\nfalse","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Interface","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"is_equal_real(a::qqbar, b::qqbar)\nis_equal_imag(a::qqbar, b::qqbar)\nis_equal_abs(a::qqbar, b::qqbar)\nis_equal_abs_real(a::qqbar, b::qqbar)\nis_equal_abs_imag(a::qqbar, b::qqbar)\nis_less_real(a::qqbar, b::qqbar)\nis_less_imag(a::qqbar, b::qqbar)\nis_less_abs(a::qqbar, b::qqbar)\nis_less_abs_real(a::qqbar, b::qqbar)\nis_less_abs_imag(a::qqbar, b::qqbar)\nis_less_root_order(a::qqbar, b::qqbar)","category":"page"},{"location":"Nemo/algebraic/#is_equal_real-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_equal_real","text":"is_equal_real(a::qqbar, b::qqbar)\n\nCompares the real parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_equal_imag-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_equal_imag","text":"is_equal_imag(a::qqbar, b::qqbar)\n\nCompares the imaginary parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_equal_abs-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_equal_abs","text":"is_equal_abs(a::qqbar, b::qqbar)\n\nCompares the absolute values of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_equal_abs_real-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_equal_abs_real","text":"is_equal_abs_real(a::qqbar, b::qqbar)\n\nCompares the absolute values of the real parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_equal_abs_imag-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_equal_abs_imag","text":"is_equal_abs_imag(a::qqbar, b::qqbar)\n\nCompares the absolute values of the imaginary parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_real-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_less_real","text":"is_less_real(a::qqbar, b::qqbar)\n\nCompares the real parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_imag-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_less_imag","text":"is_less_imag(a::qqbar, b::qqbar)\n\nCompares the imaginary parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_abs-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_less_abs","text":"is_less_abs(a::qqbar, b::qqbar)\n\nCompares the absolute values of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_abs_real-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_less_abs_real","text":"is_less_abs_real(a::qqbar, b::qqbar)\n\nCompares the absolute values of the real parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_abs_imag-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_less_abs_imag","text":"is_less_abs_imag(a::qqbar, b::qqbar)\n\nCompares the absolute values of the imaginary parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_root_order-Tuple{qqbar, qqbar}","page":"Algebraic numbers","title":"is_less_root_order","text":"is_less_root_order(a::qqbar, b::qqbar)\n\nCompares the a and b in root sort order.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#Roots-and-trigonometric-functions","page":"Algebraic numbers","title":"Roots and trigonometric functions","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Examples","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> root(QQBar(2), 5)\nRoot 1.14870 of x^5 - 2\n\njulia> sinpi(QQBar(7) // 13)\nRoot 0.992709 of 4096x^12 - 13312x^10 + 16640x^8 - 9984x^6 + 2912x^4 - 364x^2 + 13\n\njulia> tanpi(atanpi(sqrt(QQBar(2)) + 1))\nRoot 2.41421 of x^2 - 2x - 1\n\njulia> root_of_unity(QQBar, 5)\nRoot 0.309017 + 0.951057*im of x^4 + x^3 + x^2 + x + 1\n\njulia> root_of_unity(QQBar, 5, 4)\nRoot 0.309017 - 0.951057*im of x^4 + x^3 + x^2 + x + 1\n\njulia> w = (1 - sqrt(QQBar(-3)))//2\nRoot 0.500000 - 0.866025*im of x^2 - x + 1\n\njulia> is_root_of_unity(w)\ntrue\n\njulia> is_root_of_unity(w + 1)\nfalse\n\njulia> root_of_unity_as_args(w)\n(6, 5)","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Interface","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"sqrt(a::qqbar)\nroot(a::qqbar, n::Int)\nroot_of_unity(C::CalciumQQBarField, n::Int)\nroot_of_unity(C::CalciumQQBarField, n::Int, k::Int)\nis_root_of_unity(a::qqbar)\nroot_of_unity_as_args(a::qqbar)\nexp_pi_i(a::qqbar)\nlog_pi_i(a::qqbar)\nsinpi(a::qqbar)\ncospi(a::qqbar)\ntanpi(a::qqbar)\nasinpi(a::qqbar)\nacospi(a::qqbar)\natanpi(a::qqbar)","category":"page"},{"location":"Nemo/algebraic/#sqrt-Tuple{qqbar}","page":"Algebraic numbers","title":"sqrt","text":"sqrt(a::qqbar; check::Bool=true)\n\nReturn the principal square root of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#root-Tuple{qqbar, Int64}","page":"Algebraic numbers","title":"root","text":"root(a::qqbar, n::Int)\n\nReturn the principal n-th root of a. Requires positive n.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#root_of_unity-Tuple{CalciumQQBarField, Int64}","page":"Algebraic numbers","title":"root_of_unity","text":"root_of_unity(C::CalciumQQBarField, n::Int)\n\nReturn the root of unity e^2 pi i n as an element of the field of algebraic numbers C.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#root_of_unity-Tuple{CalciumQQBarField, Int64, Int64}","page":"Algebraic numbers","title":"root_of_unity","text":"root_of_unity(C::CalciumQQBarField, n::Int, k::Int)\n\nReturn the root of unity e^2 pi i k n as an element of the field of algebraic numbers C.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_root_of_unity-Tuple{qqbar}","page":"Algebraic numbers","title":"is_root_of_unity","text":"is_root_of_unity(a::qqbar)\n\nReturn whether the given algebraic number is a root of unity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#root_of_unity_as_args-Tuple{qqbar}","page":"Algebraic numbers","title":"root_of_unity_as_args","text":"root_of_unity_as_args(a::qqbar)\n\nReturn a pair of integers (q, p) such that the given a equals e^2 pi i p q. The denominator q will be minimal, with 0 le p q. Throws if a is not a root of unity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#exp_pi_i-Tuple{qqbar}","page":"Algebraic numbers","title":"exp_pi_i","text":"exp_pi_i(a::qqbar)\n\nReturn e^pi i a as an algebraic number. Throws if this value is transcendental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#log_pi_i-Tuple{qqbar}","page":"Algebraic numbers","title":"log_pi_i","text":"log_pi_i(a::qqbar)\n\nReturn log(a) (pi i) as an algebraic number. Throws if this value is transcendental or undefined.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#sinpi-Tuple{qqbar}","page":"Algebraic numbers","title":"sinpi","text":"sinpi(a::qqbar)\n\nReturn sin(pi a) as an algebraic number. Throws if this value is transcendental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#cospi-Tuple{qqbar}","page":"Algebraic numbers","title":"cospi","text":"cospi(a::qqbar)\n\nReturn cos(pi a) as an algebraic number. Throws if this value is transcendental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#tanpi-Tuple{qqbar}","page":"Algebraic numbers","title":"tanpi","text":"tanpi(a::qqbar)\n\nReturn tan(pi a) as an algebraic number. Throws if this value is transcendental or undefined.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#asinpi-Tuple{qqbar}","page":"Algebraic numbers","title":"asinpi","text":"asinpi(a::qqbar)\n\nReturn operatornameasin(a) pi as an algebraic number. Throws if this value is transcendental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#acospi-Tuple{qqbar}","page":"Algebraic numbers","title":"acospi","text":"acospi(a::qqbar)\n\nReturn operatornameacos(a) pi as an algebraic number. Throws if this value is transcendental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#atanpi-Tuple{qqbar}","page":"Algebraic numbers","title":"atanpi","text":"atanpi(a::qqbar)\n\nReturn operatornameatan(a) pi as an algebraic number. Throws if this value is transcendental or undefined.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#Guessing","page":"Algebraic numbers","title":"Guessing","text":"","category":"section"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Examples","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"An algebraic number can be recovered from a numerical value:","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> RR = ArbField(53); guess(QQBar, RR(\"1.41421356 +/- 1e-6\"), 2)\nRoot 1.41421 of x^2 - 2","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Warning: the input should be an enclosure. If you have a floating-point approximation, you should add an error estimate; otherwise, the only algebraic number that can be guessed is the binary floating-point number itself.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> RR = ArbField(128);\n\njulia> x = RR(0.1); # note: 53-bit binary approximation of 1//10 without radius\n\njulia> guess(QQBar, x, 1)\nRoot 0.100000 of 36028797018963968x - 3602879701896397\n\njulia> guess(QQBar, x + RR(\"+/- 1e-10\"), 1)\nRoot 0.100000 of 10x - 1","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Interface","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"guess(R::CalciumQQBarField, x::arb, maxdeg::Int, maxbits::Int=0)\nguess(R::CalciumQQBarField, x::acb, maxdeg::Int, maxbits::Int=0)","category":"page"},{"location":"Nemo/algebraic/#guess","page":"Algebraic numbers","title":"guess","text":"guess(R::CalciumQQBarField, x::acb, maxdeg::Int, maxbits::Int=0)\n\nTry to reconstruct an algebraic number from a given numerical enclosure x. The algorithm looks for candidates up to degree maxdeg and with coefficients up to size maxbits (which defaults to the precision of x if not given). Throws if no suitable algebraic number can be found.\n\nGuessing typically requires high precision to succeed, and it does not make much sense to call this function with input precision smaller than O(maxdeg cdot maxbits). If this function succeeds, then the output is guaranteed to be contained in the enclosure x, but failure does not prove that such an algebraic number with the specified parameters does not exist.\n\nThis function does a single iteration with the target parameters. For best performance, one should invoke this function repeatedly with successively larger parameters when the size of the intended solution is unknown or may be much smaller than a worst-case bound.\n\n\n\n\n\n","category":"function"},{"location":"Nemo/algebraic/#guess-2","page":"Algebraic numbers","title":"guess","text":"guess(R::CalciumQQBarField, x::acb, maxdeg::Int, maxbits::Int=0)\n\nTry to reconstruct an algebraic number from a given numerical enclosure x. The algorithm looks for candidates up to degree maxdeg and with coefficients up to size maxbits (which defaults to the precision of x if not given). Throws if no suitable algebraic number can be found.\n\nGuessing typically requires high precision to succeed, and it does not make much sense to call this function with input precision smaller than O(maxdeg cdot maxbits). If this function succeeds, then the output is guaranteed to be contained in the enclosure x, but failure does not prove that such an algebraic number with the specified parameters does not exist.\n\nThis function does a single iteration with the target parameters. For best performance, one should invoke this function repeatedly with successively larger parameters when the size of the intended solution is unknown or may be much smaller than a worst-case bound.\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"CurrentModule = Oscar \nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/#A-Framework-for-Localizing-Rings","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"For the convenience of the developer, we outline a general framework for creating concrete instances of localized rings in OSCAR, addressing relevant abstract types as well as a standardized set of functions whose concrete behaviour must be implemented.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"We roughly follow the outline of the previous subsection on localizing multivariate rings which provides illustrating examples. With regard to notation, the name Rloc will refer to the localization of a commutative ring R with 1.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/#Localized-Rings","page":"A Framework for Localizing Rings","title":"Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"All multiplicatively closed subsets should belong to the AbsMultSet abstract type and all localized rings should belong to the AbsLocalizedRing abstract type.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"The basic functionality that has to be realized for any concrete instance of AbsMultSet is the containment check for elements in multiplicatively closed subsets via the in function.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"For each concrete instance of AbsLocalizedRing, the Localization constructor as well as the functions base_ring and inverted_set need to be implemented. Moreover, as for any other type of rings in OSCAR, methods for the standardized set of functions of OSCAR's general Ring Interface must be supplied.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/#Elements-of-Localized-Rings","page":"A Framework for Localizing Rings","title":"Elements of Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"All elements of localized rings should belong to the AbsLocalizedRingElem abstract type.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"Coercing (pairs of) elements of R into fractions in Rloc must be possible as indicated below:","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":" (Rloc::AbsLocalizedRing)(f::RingElem)\n (Rloc::AbsLocalizedRing)(f::RingElem, g::RingElem; check::Bool=true)","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"The first constructor maps the element f of R to the fraction f//1 in Rloc. The second constructor takes a pair f, g of elements of R to the fraction f//g in Rloc. The default check = true stands for testing whether g is an admissible denominator. As this test is often expensive, it may be convenient to set check = false.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"For any concrete instance of type AbsLocalizedRingElem, methods for the functions parent, numerator, and denominator must be provided. Moreover, if a cancellation function for the type of fractions under consideration is not yet available, such a function should be implemented and named reduce_fraction.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/#Homomorphisms-From-Localized-Rings","page":"A Framework for Localizing Rings","title":"Homomorphisms From Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"The abstract type for homomorphisms from localized rings is MPolyLocalizedRingHom. For each concrete instance, the functions domain and codomain as well as restricted_map must be realized. Here, the latter function is meant to return the composition with the localization map.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/#Ideals-in-Localized-Rings","page":"A Framework for Localizing Rings","title":"Ideals in Localized Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"All ideals in localized rings belong to the abstract type AbsLocalizedIdeal. For a concrete instance, the constructors to be implemented are:","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":" ideal(W::AbsLocalizedRing, f::AbsLocalizedRingElem)\n ideal(W::AbsLocalizedRing, v::Vector{LocalizedRingElemType}) where {LocalizedRingElemType<:AbsLocalizedRingElem}","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"The usual getter functions base_ring, gens, ngens, and gen must be realized.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/ring_localizations/","page":"A Framework for Localizing Rings","title":"A Framework for Localizing Rings","text":"Moreover, a method for ideal membership via the in function is required.","category":"page"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"PolyhedralGeometry/fans/#Polyhedral-Fans","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"","category":"section"},{"location":"PolyhedralGeometry/fans/#Introduction","page":"Polyhedral Fans","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"Let mathbbF be an ordered field; the default is that mathbbF=mathbbQ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.","category":"page"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"A nonempty finite collection mathcalF of (polyhedral) cones in mathbbF^n, for n fixed, is a (polyhedral) fan if","category":"page"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"the set mathcalF is closed with respect to taking faces and\nif CDinmathcalF then Ccap D is a face of both, C and D.","category":"page"},{"location":"PolyhedralGeometry/fans/#Construction","page":"Polyhedral Fans","title":"Construction","text":"","category":"section"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"To construct a polyhedral fan, you must pass the rays of each cone in the fan, along with an IncidenceMatrix encoding which rays generate which cones.","category":"page"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"polyhedral_fan\npolyhedral_fan_from_rays_action","category":"page"},{"location":"PolyhedralGeometry/fans/#polyhedral_fan","page":"Polyhedral Fans","title":"polyhedral_fan","text":"polyhedral_fan(T, Rays::AbstractCollection[RayVector], LS::Union{AbstractCollection[RayVector], Nothing}, Incidence::IncidenceMatrix) where T<:scalar_types\n\nAssemble a polyhedral fan from ray generators, lineality generators, and an IncidenceMatrix indicating which rays form a cone.\n\nArguments\n\nT: Type or parent Field of scalar to use, defaults to QQFieldElem.\nRays::AbstractCollection[RayVector]: Rays generating the cones of the fan; encoded row-wise as representative vectors.\nLS::AbstractCollection[RayVector]: Contains row-wise generators of the lineality space of the fan. (optional argument)\nCones::IncidenceMatrix: An incidence matrix; there is a 1 at position (i,j) if cone i has ray j as extremal ray, and 0 otherwise.\n\nExamples\n\nTo obtain the upper half-space of the plane:\n\njulia> R = [1 0; 1 1; 0 1; -1 0; 0 -1];\n\njulia> IM=IncidenceMatrix([[1,2],[2,3],[3,4],[4,5],[1,5]]);\n\njulia> PF=polyhedral_fan(R,IM)\nPolyhedral fan in ambient dimension 2\n\nPolyhedral fan with lineality space:\n\njulia> R = [1 0 0; 0 0 1];\n\njulia> L = [0 1 0];\n\njulia> IM = IncidenceMatrix([[1],[2]]);\n\njulia> PF=polyhedral_fan(R, L, IM)\nPolyhedral fan in ambient dimension 3\n\njulia> lineality_dim(PF)\n1\n\n\n\n\n\npolyhedral_fan(v::AbstractNormalToricVariety)\n\nReturn the fan of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> polyhedral_fan(p2)\nPolyhedral fan in ambient dimension 2\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/fans/#polyhedral_fan_from_rays_action","page":"Polyhedral Fans","title":"polyhedral_fan_from_rays_action","text":"polyhedral_fan_from_rays_action([::Union{Type{T}, Field} = QQFieldElem,] Rays::AbstractCollection[RayVector], MC_reps::IncidenceMatrix, perms::AbstractVector{PermGroupElem}) where T<:scalar_types\n\nConstruct a polyhedral fan with a group action.\n\nArguments\n\nThe first argument either specifies the Type of its coefficients or their\n\nparent Field.\n\nRays: The rays of the fan\nMC_reps: IncidenceMatrix whose rows give the indices of the rays forming representatives of the maximal cones under the group action.\nperms: A vector of permutations PermGroupElem that form generators of the group acting on the rays of the fan.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"normal_fan(P::Polyhedron{T}) where T<:scalar_types\nface_fan(P::Polyhedron{T}) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/fans/#normal_fan-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"normal_fan","text":"normal_fan(P::Polyhedron)\n\nReturn the normal fan of P. The maximal cones of the normal fan of P are dual to the edge cones at the vertices of P.\n\nExamples\n\nThe rays of a normal fan of a cube point in every positive and negative unit direction.\n\njulia> C = cube(3);\n\njulia> NF = normal_fan(C)\nPolyhedral fan in ambient dimension 3\n\njulia> rays(NF)\n6-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0, 0]\n [-1, 0, 0]\n [0, 1, 0]\n [0, -1, 0]\n [0, 0, 1]\n [0, 0, -1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#face_fan-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"face_fan","text":"face_fan(P::Polyhedron)\n\nReturn the face fan of P. The polytope P has to contain the origin, then the maximal cones of the face fan of P are the cones over the facets of P.\n\nExamples\n\nBy definition, this bounded polyhedron's number of facets equals the amount of maximal cones of its face fan.\n\njulia> C = cross_polytope(3);\n\njulia> FF = face_fan(C)\nPolyhedral fan in ambient dimension 3\n\njulia> n_maximal_cones(FF) == nfacets(C)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#Auxiliary-functions","page":"Polyhedral Fans","title":"Auxiliary functions","text":"","category":"section"},{"location":"PolyhedralGeometry/fans/","page":"Polyhedral Fans","title":"Polyhedral Fans","text":"ambient_dim(PF::PolyhedralFan)\ndim(PF::PolyhedralFan)\nf_vector(PF::PolyhedralFan)\nis_complete(PF::PolyhedralFan)\nis_pointed(PF::PolyhedralFan)\nis_regular(PF::PolyhedralFan)\nis_simplicial(PF::PolyhedralFan)\nis_smooth(PF::PolyhedralFan{QQFieldElem})\nlineality_dim(PF::PolyhedralFan)\nlineality_space(PF::PolyhedralFan{T}) where T<:scalar_types\nmaximal_cones(PF::PolyhedralFan{T}) where T<:scalar_types\ncones(PF::PolyhedralFan{T}, cone_dim::Int) where T<:scalar_types\ncones(PF::PolyhedralFan)\nn_maximal_cones(PF::PolyhedralFan)\nn_cones(PF::PolyhedralFan)\nnrays(PF::PolyhedralFan)\nrays(PF::PolyhedralFan{T}) where T<:scalar_types\nrays_modulo_lineality(PF::PolyhedralFan{T}) where T<:scalar_types\nprimitive_collections(PF::PolyhedralFan)\nstar_subdivision(PF::PolyhedralFan{T}, n::Int) where T<:scalar_types\nstar_subdivision(PF::PolyhedralFan{T}, new_ray::AbstractVector{<:IntegerUnion}) where T<:scalar_types\n*(PF1::PolyhedralFan{QQFieldElem}, PF2::PolyhedralFan{QQFieldElem})","category":"page"},{"location":"PolyhedralGeometry/fans/#ambient_dim-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"ambient_dim","text":"ambient_dim(PF::PolyhedralFan)\n\nReturn the ambient dimension PF, which is the dimension of the embedding space.\n\nThis is equal to the dimension of the fan if and only if the fan is full-dimensional.\n\nExamples\n\nThe normal fan of the 4-cube is embedded in the same ambient space.\n\njulia> ambient_dim(normal_fan(cube(4)))\n4\n\n\n\n\n\nambient_dim(T::TropicalVariety{M, EMB})\nambient_dim(T::TropicalCurve{M, EMB})\nambient_dim(T::TropicalHypersurface{M, EMB})\nambient_dim(T::TropicalLinearSpace{M, EMB})\n\nReturn the ambient dimension of T if it is embedded. Otherwise an error is thrown.\n\nExamples\n\nA tropical hypersurface in mathbbR^n is of ambient dimension n\n\njulia> RR = TropicalSemiring(min);\n\njulia> S,(x,y) = RR[\"x\",\"y\"];\n\njulia> f = x+y+1;\n\njulia> tropicalLine = TropicalHypersurface(f);\n\njulia> ambient_dim(tropicalLine)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#dim-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"dim","text":"dim(PF::PolyhedralFan)\n\nReturn the dimension of PF.\n\nExamples\n\nThis fan in the plane contains a 2-dimensional cone and is thus 2-dimensional itself.\n\njulia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]));\n\njulia> dim(PF)\n2\n\n\n\n\n\ndim(T::TropicalVariety{M, EMB})\ndim(T::TropicalCurve{M, EMB})\ndim(T::TropicalHypersurface{M, EMB})\ndim(T::TropicalLinearSpace{M, EMB})\n\nReturn the dimension of T.\n\nExamples\n\nA tropical hypersurface in mathbbR^n is always of dimension n-1\n\njulia> RR = TropicalSemiring(min);\n\njulia> S,(x,y) = RR[\"x\",\"y\"];\n\njulia> f = x+y+1;\n\njulia> tropicalLine = TropicalHypersurface(f);\n\njulia> dim(tropicalLine)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#f_vector-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"f_vector","text":"f_vector(PF::PolyhedralFan)\n\nCompute the vector (f₁f₂f_dim(PF)-1)` where f_i is the number of faces of PF of dimension i.\n\nExamples\n\nThe f-vector of the normal fan of a polytope is the reverse of the f-vector of the polytope.\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> f_vector(c)\n3-element Vector{ZZRingElem}:\n 8\n 12\n 6\n\n\njulia> nfc = normal_fan(c)\nPolyhedral fan in ambient dimension 3\n\njulia> f_vector(nfc)\n3-element Vector{ZZRingElem}:\n 6\n 12\n 8\n\n\n\n\n\nf_vector(T::TropicalVariety{M, EMB})\nf_vector(T::TropicalCurve{M, EMB})\nf_vector(T::TropicalHypersurface{M, EMB})\nf_vector(T::TropicalLinearSpace{M, EMB})\n\nReturn the f-Vector of T.\n\nExamples\n\nA tropical hypersurface in mathbbR^n is of lineality dimension n\n\njulia> RR = TropicalSemiring(min);\n\njulia> S,(x,y) = RR[\"x\",\"y\"];\n\njulia> f = x+y+1;\n\njulia> tropicalLine = TropicalHypersurface(f);\n\njulia> f_vector(tropicalLine)\n2-element Vector{Int64}:\n 1\n 3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#is_complete-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"is_complete","text":"is_complete(PF::PolyhedralFan)\n\nDetermine whether PF is complete, i.e. its support, the set-theoretic union of its cones, covers the whole space.\n\nExamples\n\nNormal fans of polytopes are complete.\n\njulia> is_complete(normal_fan(cube(3)))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#is_pointed-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"is_pointed","text":"is_pointed(PF::PolyhedralFan)\n\nDetermine whether PF is pointed, i.e. all its cones are pointed.\n\nExamples\n\nThe normal fan of a non-fulldimensional polytope is not pointed.\n\njulia> C = convex_hull([0 0; 1 0])\nPolyhedron in ambient dimension 2\n\njulia> is_fulldimensional(C)\nfalse\n\njulia> nf = normal_fan(C)\nPolyhedral fan in ambient dimension 2\n\njulia> is_pointed(nf)\nfalse\n\njulia> lineality_dim(nf)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#is_regular-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"is_regular","text":"is_regular(PF::PolyhedralFan)\n\nDetermine whether PF is regular, i.e. the normal fan of a polytope.\n\nExamples\n\nThis fan is not complete and thus not regular.\n\njulia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]));\n\njulia> is_regular(PF)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#is_simplicial-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"is_simplicial","text":"is_simplicial(PF::PolyhedralFan)\n\nDetermine whether PF is simplicial, i.e. every cone should be generated by a basis of the ambient space.\n\nExamples\n\nThe normal_fan of the cube is simplicial, while the face_fan is not.\n\njulia> is_simplicial(normal_fan(cube(3)))\ntrue\n\njulia> is_simplicial(face_fan(cube(3)))\nfalse\n\n\n\n\n\nis_simplicial(T::TropicalVariety{M, EMB})\nis_simplicial(T::TropicalCurve{M, EMB})\nis_simplicial(T::TropicalHypersurface{M, EMB})\nis_simplicial(T::TropicalLinearSpace{M, EMB})\n\nReturn true if T is a simplicial polyhedral complex, false otherwise.\n\nExamples\n\nA tropical hypersurface in mathbbR^n is of lineality dimension n\n\njulia> RR = TropicalSemiring(min);\n\njulia> S,(x,y) = RR[\"x\",\"y\"];\n\njulia> f = x+y+1;\n\njulia> tropicalLine = TropicalHypersurface(f);\n\njulia> is_simplicial(tropicalLine)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#is_smooth-Tuple{PolyhedralFan{QQFieldElem}}","page":"Polyhedral Fans","title":"is_smooth","text":"is_smooth(PF::PolyhedralFan{QQFieldElem})\n\nDetermine whether PF is smooth.\n\nExamples\n\nEven though the cones of this fan cover the positive orthant together, one of these und thus the whole fan is not smooth.\n\njulia> PF = polyhedral_fan([0 1; 2 1; 1 0], IncidenceMatrix([[1, 2], [2, 3]]));\n\njulia> is_smooth(PF)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#lineality_dim-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"lineality_dim","text":"lineality_dim(PF::PolyhedralFan)\n\nReturn the dimension of the lineality space of the polyhedral fan PF, i.e. the dimension of the largest linear subspace.\n\nExamples\n\nThe dimension of the lineality space is zero if and only if the fan is pointed.\n\njulia> C = convex_hull([0 0; 1 0])\nPolyhedron in ambient dimension 2\n\njulia> is_fulldimensional(C)\nfalse\n\njulia> nf = normal_fan(C)\nPolyhedral fan in ambient dimension 2\n\njulia> is_pointed(nf)\nfalse\n\njulia> lineality_dim(nf)\n1\n\n\n\n\n\nlineality_dim(T::TropicalVariety{M, EMB})\nlineality_dim(T::TropicalCurve{M, EMB})\nlineality_dim(T::TropicalHypersurface{M, EMB})\nlineality_dim(T::TropicalLinearSpace{M, EMB})\n\nReturn the dimension of the lineality space of T if it is embedded. Otherwise an error is thrown.\n\nExamples\n\nA tropical hypersurface in mathbbR^n is of lineality dimension n\n\njulia> RR = TropicalSemiring(min);\n\njulia> S,(x,y) = RR[\"x\",\"y\"];\n\njulia> f = x+y;\n\njulia> tropicalAndAffineLine = TropicalHypersurface(f);\n\njulia> lineality_dim(tropicalAndAffineLine)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#lineality_space-Union{Tuple{PolyhedralFan{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"lineality_space","text":"lineality_space(PF::PolyhedralFan)\n\nReturn a non-redundant matrix whose rows are generators of the lineality space of PF.\n\nExamples\n\nThis fan consists of two cones, one containing all the points with y 0 and one containing all the points with y 0. The fan's lineality is the common lineality of these two cones, i.e. in x-direction.\n\njulia> PF = polyhedral_fan([1 0; 0 1; -1 0; 0 -1], IncidenceMatrix([[1, 2, 3], [3, 4, 1]]))\nPolyhedral fan in ambient dimension 2\n\njulia> lineality_space(PF)\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n\n\n\n\n\nlineality_space(T::TropicalVariety{M, EMB})\nlineality_space(T::TropicalCurve{M, EMB})\nlineality_space(T::TropicalHypersurface{M, EMB})\nlineality_space(T::TropicalLinearSpace{M, EMB})\n\nReturn the lineality space of T if it is embedded. Otherwise an error is thrown.\n\nExamples\n\nA tropical hypersurface in mathbbR^n is of lineality spaceension n\n\njulia> RR = TropicalSemiring(min);\n\njulia> S,(x,y) = RR[\"x\",\"y\"];\n\njulia> f = x+y;\n\njulia> tropicalAndAffineLine = TropicalHypersurface(f);\n\njulia> lineality_space(tropicalAndAffineLine)\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [-1, -1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#maximal_cones-Union{Tuple{PolyhedralFan{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"maximal_cones","text":"maximal_cones(PF::PolyhedralFan)\n\nReturn the maximal cones of PF.\n\nExamples\n\nHere we ask for the the number of rays for each maximal cone of the face fan of the 3-cube and use that maximal_cones returns an iterator.\n\njulia> PF = face_fan(cube(3));\n\njulia> for c in maximal_cones(PF)\n println(nrays(c))\n end\n4\n4\n4\n4\n4\n4\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#cones-Union{Tuple{T}, Tuple{PolyhedralFan{T}, Int64}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"cones","text":"cones(PF::PolyhedralFan, cone_dim::Int)\n\nReturn an iterator over the cones of PF of dimension cone_dim.\n\nExamples\n\nThe 12 edges of the 3-cube correspond to the 2-dimensional cones of its face fan:\n\njulia> PF = face_fan(cube(3));\n\njulia> cones(PF, 2)\n12-element SubObjectIterator{Cone{QQFieldElem}}:\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n Polyhedral cone in ambient dimension 3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#cones-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"cones","text":"cones(PF::PolyhedralFan)\n\nReturn the ray indices of all non-zero-dimensional cones in a polyhedral fan.\n\nExamples\n\njulia> PF = face_fan(cube(2))\nPolyhedral fan in ambient dimension 2\n\njulia> cones(PF)\n8×4 IncidenceMatrix\n[1, 3]\n[2, 4]\n[1, 2]\n[3, 4]\n[1]\n[3]\n[2]\n[4]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#n_maximal_cones-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"n_maximal_cones","text":"n_maximal_cones(PF::PolyhedralFan)\n\nReturn the number of maximal cones of PF.\n\nExamples\n\nThe cones given in this construction are non-redundant. Thus there are two maximal cones.\n\njulia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]));\n\njulia> n_maximal_cones(PF)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#n_cones-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"n_cones","text":"n_cones(PF::PolyhedralFan)\n\nReturn the number of cones of PF.\n\nExamples\n\nThe cones given in this construction are non-redundant. There are six cones in this fan.\n\njulia> PF = polyhedral_fan([1 0; 0 1; -1 -1], IncidenceMatrix([[1, 2], [3]]))\nPolyhedral fan in ambient dimension 2\n\njulia> n_cones(PF)\n4\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#nrays-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"nrays","text":"nrays(PF::PolyhedralFan)\n\nReturn the number of rays of PF.\n\nExamples\n\nThe 3-cube has 8 vertices. Accordingly, its face fan has 8 rays.\n\njulia> nrays(face_fan(cube(3)))\n8\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#rays-Union{Tuple{PolyhedralFan{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"rays","text":"rays(PF::PolyhedralFan)\n\nReturn the rays of PF.\n\nExamples\n\nThe rays of a normal fan of a cube point in every positive and negative unit direction.\n\njulia> C = cube(3);\n\njulia> NF = normal_fan(C);\n\njulia> rays(NF)\n6-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0, 0]\n [-1, 0, 0]\n [0, 1, 0]\n [0, -1, 0]\n [0, 0, 1]\n [0, 0, -1]\n\nAs for the Cone, the rays may be converted to a matrix using the matrix(ring, ...) function.\n\njulia> C = cube(3);\n\njulia> NF = normal_fan(C);\n\njulia> matrix(QQ, rays(NF))\n[ 1 0 0]\n[-1 0 0]\n[ 0 1 0]\n[ 0 -1 0]\n[ 0 0 1]\n[ 0 0 -1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#rays_modulo_lineality-Union{Tuple{PolyhedralFan{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"rays_modulo_lineality","text":"rays_modulo_lineality(as, F::PolyhedralFan)\n\nReturn the rays of the polyhedral fan F up to lineality as a NamedTuple with two iterators. If F has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of F/L. The iterator lineality_basis gives a basis of the lineality space L.\n\nExamples\n\njulia> P = convex_hull(QQFieldElem, [0 0; 1 0])\nPolyhedron in ambient dimension 2\n\njulia> NF = normal_fan(P)\nPolyhedral fan in ambient dimension 2\n\njulia> rmlF = rays_modulo_lineality(NF)\n(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0], [-1, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])\n\njulia> rmlF.rays_modulo_lineality\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [-1, 0]\n\njulia> rmlF.lineality_basis\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [0, 1]\n\njulia> rays(NF)\n0-element SubObjectIterator{RayVector{QQFieldElem}}\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#primitive_collections-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"primitive_collections","text":"primitive_collections(PF::PolyhedralFan)\n\nReturn the primitive collections of a polyhedral fan.\n\nExamples\n\njulia> primitive_collections(normal_fan(simplex(3)))\n1-element Vector{Set{Int64}}:\n Set([4, 2, 3, 1])\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#star_subdivision-Union{Tuple{T}, Tuple{PolyhedralFan{T}, Int64}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"star_subdivision","text":"star_subdivision(PF::PolyhedralFan, n::Int)\n\nReturn the star subdivision of a polyhedral fan at its n-th torus orbit. Note that this torus orbit need not be maximal. We follow definition 3.3.17 of David A. Cox, John B. Little, Henry K. Schenck (2011).\n\nExamples\n\njulia> star = star_subdivision(normal_fan(simplex(3)), 1)\nPolyhedral fan in ambient dimension 3\n\njulia> rays(star)\n5-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [-1, -1, -1]\n [1, 1, 1]\n\njulia> ray_indices(maximal_cones(star))\n6×5 IncidenceMatrix\n[2, 3, 5]\n[1, 3, 5]\n[1, 2, 5]\n[2, 3, 4]\n[1, 3, 4]\n[1, 2, 4]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#star_subdivision-Union{Tuple{T}, Tuple{PolyhedralFan{T}, AbstractVector{<:Union{Integer, ZZRingElem}}}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Fans","title":"star_subdivision","text":"star_subdivision(PF::PolyhedralFan, new_ray::AbstractVector{<:IntegerUnion})\n\nReturn the star subdivision of a polyhedral fan by a primitive element of the underlying lattice. We follow the definition at the top of page 515 in David A. Cox, John B. Little, Henry K. Schenck (2011).\n\nExamples\n\njulia> fan = normal_fan(simplex(3))\nPolyhedral fan in ambient dimension 3\n\njulia> new_ray = [1, 1, 1];\n\njulia> star = star_subdivision(fan, new_ray)\nPolyhedral fan in ambient dimension 3\n\njulia> rays(star)\n5-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [-1, -1, -1]\n [1, 1, 1]\n\njulia> ray_indices(maximal_cones(star))\n6×5 IncidenceMatrix\n[2, 3, 5]\n[1, 3, 5]\n[1, 2, 5]\n[2, 3, 4]\n[1, 3, 4]\n[1, 2, 4]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#*-Tuple{PolyhedralFan{QQFieldElem}, PolyhedralFan{QQFieldElem}}","page":"Polyhedral Fans","title":"*","text":"*(PF1::PolyhedralFan{QQFieldElem}, PF2::PolyhedralFan{QQFieldElem})\n\nReturn the Cartesian/direct product of two polyhedral fans.\n\nExamples\n\njulia> normal_fan(simplex(2))*normal_fan(simplex(3))\nPolyhedral fan in ambient dimension 5\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Total-ring-of-fractions","page":"Total ring of fractions","title":"Total ring of fractions","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"AbstractAlgebra.jl provides a module, implemented in src/generic/TotalFraction.jl, for the total ring of fractions of a ring.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"The total ring of fractions of a ring R is the localisation of R at the non-zero divisors of R, the latter being a multiplicative subset of R.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"There are no restrictions on the ring except the function is_zero_divisor must be defined and effective for R.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"In particular, we do not assume that all elements of R which are not zero divisors are units in R. This has the effect of making exact division impossible generically in the total ring of fractions of R.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"This in turn limits the usefulness of the total ring of fractions as a ring in AbstractAlgebra as a great deal of generic code relies on divexact. Should this be a limitation, the user can define their own divexact function for the total ring of fractions in question.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Note that in most cases a*inv(b) is not a sufficient definition of divexact(a, b) due to the possibility that b is not a unit in the total ring of fractions.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"It is also possible to construct a total ring of fractions of R without the is_zero_divisor function existing for R, but some functions such as is_unit, inv, rand and ad hoc arithmetic operations involving rational numbers are not available for the total ring of fractions. One must also construct fractions using the option check=false and it is one's own responsibility to check that the denominator is not a zero divisor.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Note that although the total ring of fractions of an integral domain R is mathematically the same thing as the fraction field of R, these will be different objects in AbstractAlgebra and have different types.","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Generic-total-ring-of-fraction-types","page":"Total ring of fractions","title":"Generic total ring of fraction types","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"AbstractAlgebra.jl implements a generic type for elements of a total ring of fractions, namelyGeneric.TotFrac{T} where T is the type of elements of the base ring. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Parent objects of such elements have type Generic.TotFracRing{T}.","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Abstract-types","page":"Total ring of fractions","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"The types for elements of a total ring of fractions belong directly to the abstract type RingElem and the type for the total ring of fractions parent object belongs directly to the abstract type Ring.","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Total-ring-of-fractions-constructors","page":"Total ring of fractions","title":"Total ring of fractions constructors","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"In order to construct fractions in a total ring of fractions in AbstractAlgebra.jl, one must first construct the parent object for the total ring of fractions itself. This is accomplished with the following constructor.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"total_ring_of_fractions(R::Ring; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Given a base ring R return the parent object of the total ring of fractions of R. By default the parent object S will depend only on R and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Here are some examples of creating a total ring of fractions and making use of the resulting parent objects to coerce various elements into the ring.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Examples","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = total_ring_of_fractions(R)\nTotal ring of fractions of Univariate polynomial ring in x over integers\n\njulia> f = S()\n0\n\njulia> g = S(123)\n123\n\njulia> h = S(BigInt(1234))\n1234\n\njulia> k = S(x + 1)\nx + 1","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Fraction-constructors","page":"Total ring of fractions","title":"Fraction constructors","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"One can construct fractions using the total ring of fractions parent object, as for any ring or field.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"(R::TotFracRing)() # constructs zero\n(R::TotFracRing)(c::Integer)\n(R::TotFracRing)(c::elem_type(R))\n(R::TotFracRing{T})(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Although one cannot use the double slash operator // to construct elements of a total ring of fractions, as no parent has been specified, one can use the double slash operator to construct elements of a total ring of fractions so long as one of the arguments to the double slash operator is already in the total ring of fractions in question.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Examples","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = total_ring_of_fractions(R)\nTotal ring of fractions of Univariate polynomial ring in x over rationals\n\njulia> f = S(x + 1)\nx + 1\n\njulia> f//3\n(x + 1)//3\n\njulia> 3//f\n3//(x + 1)\n\njulia> f//x\n(x + 1)//x","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Functions-for-types-and-parents-of-total-rings-of-fractions","page":"Total ring of fractions","title":"Functions for types and parents of total rings of fractions","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Total rings of fractions in AbstractAlgebra.jl implement the Ring interface except for the divexact function which is not generically possible to implement.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"base_ring(R::TotFracRing)\nbase_ring(a::TotFrac)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Return the base ring of which the total ring of fractions was constructed.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"parent(a::TotFrac)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Return the total ring of fractions that the given fraction belongs to.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"characteristic(R::TotFracRing)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Return the characteristic of the base ring of the total ring of fractions. If the characteristic is not known an exception is raised.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Examples","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = total_ring_of_fractions(R)\nTotal ring of fractions of Univariate polynomial ring in x over rationals\n\njulia> f = S(x + 1)\nx + 1\n\njulia> U = base_ring(S)\nUnivariate polynomial ring in x over rationals\n\njulia> V = base_ring(f)\nUnivariate polynomial ring in x over rationals\n\njulia> T = parent(f)\nTotal ring of fractions of Univariate polynomial ring in x over rationals\n\njulia> m = characteristic(S)\n0","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Total-ring-of-fractions-functions","page":"Total ring of fractions","title":"Total ring of fractions functions","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/#Basic-functions","page":"Total ring of fractions","title":"Basic functions","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Total rings of fractions implement the Ring interface.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"zero(R::TotFracRing)\none(R::TotFracRing)\niszero(a::TotFrac)\nisone(a::TotFrac)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"inv(a::T) where T <: TotFrac","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"They also implement some of the following functions which would usually be associated with the field and fraction field interfaces.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"is_unit(f::TotFrac)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"numerator(a::TotFrac)\ndenominator(a::TotFrac)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Examples","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = total_ring_of_fractions(R)\nTotal ring of fractions of Univariate polynomial ring in x over rationals\n\njulia> f = S(x + 1)\nx + 1\n\njulia> g = f//(x^3 + 3x + 1)\n(x + 1)//(x^3 + 3*x + 1)\n\njulia> h = zero(S)\n0\n\njulia> k = one(S)\n1\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> r = deepcopy(f)\nx + 1\n\njulia> n = numerator(g)\nx + 1\n\njulia> d = denominator(g)\nx^3 + 3*x + 1","category":"page"},{"location":"AbstractAlgebra/total_fraction/#Random-generation","page":"Total ring of fractions","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Random fractions can be generated using rand. The parameters passed after the total ring of fractions tell rand how to generate random elements of the base ring.","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"rand(R::TotFracRing, v...)","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"Examples","category":"page"},{"location":"AbstractAlgebra/total_fraction/","page":"Total ring of fractions","title":"Total ring of fractions","text":"julia> R = residue_ring(ZZ, 12)\nResidue ring of integers modulo 12\n\njulia> K = total_ring_of_fractions(R)\nTotal ring of fractions of Residue ring of integers modulo 12\n\njulia> f = rand(K, 0:11)\n7//5\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = total_ring_of_fractions(R)\nTotal ring of fractions of Univariate polynomial ring in x over integers\n\njulia> g = rand(S, -1:3, -10:10)\n(4*x + 4)//(-4*x^2 - x + 4)","category":"page"},{"location":"AbstractAlgebra/euclidean_interface/","page":"Euclidean Ring Interface","title":"Euclidean Ring Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = :(using AbstractAlgebra)","category":"page"},{"location":"AbstractAlgebra/euclidean_interface/#Euclidean-Ring-Interface","page":"Euclidean Ring Interface","title":"Euclidean Ring Interface","text":"","category":"section"},{"location":"AbstractAlgebra/euclidean_interface/","page":"Euclidean Ring Interface","title":"Euclidean Ring Interface","text":"If a ring provides a meaningful Euclidean structure such that a useful Euclidean remainder can be computed practically, various additional functionality is provided by AbstractAlgebra.jl for those rings. This functionality depends on the following functions existing. An implementation must provide divrem, and the remaining are optional as generic fallbacks exist.","category":"page"},{"location":"AbstractAlgebra/euclidean_interface/","page":"Euclidean Ring Interface","title":"Euclidean Ring Interface","text":"Base.divrem(f::T, g::T) where T <: RingElem\nmod(f::T, g::T) where T <: RingElem\nBase.div(f::T, g::T) where T <: RingElem\nmulmod(f::T, g::T, m::T) where T <: RingElem\npowermod(f::T, e::Int, m::T) where T <: RingElem\ninvmod(f::T, m::T) where T <: RingElem\ndivides(f::T, g::T) where T <: RingElem\nremove(f::T, p::T) where T <: RingElem\nvaluation(f::T, p::T) where T <: RingElem\ngcd(f::T, g::T) where T <: RingElem\ngcd(f::T, g::T, hs::T...) where T <: RingElem\ngcd(fs::AbstractArray{<:T}) where T <: RingElem\nlcm(f::T, g::T) where T <: RingElem\nlcm(f::T, g::T, hs::T...) where T <: RingElem\nlcm(fs::AbstractArray{<:T}) where T <: RingElem\ngcdx(f::T, g::T) where T <: RingElem\ngcdinv(f::T, g::T) where T <: RingElem\ncrt(r1::T, m1::T, r2::T, m2::T; check::Bool=true) where T <: RingElement\ncrt(r::Vector{T}, m::Vector{T}; check::Bool=true) where T <: RingElement\ncrt_with_lcm(r1::T, m1::T, r2::T, m2::T; check::Bool=true) where T <: RingElement\ncrt_with_lcm(r::Vector{T}, m::Vector{T}; check::Bool=true) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/euclidean_interface/#divrem-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"divrem","text":"divrem(f::T, g::T) where T <: RingElem\n\nReturn a pair q, r consisting of the Euclidean quotient and remainder of f by g. A DivideError should be thrown if g is zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#mod-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"mod","text":"mod(f::T, g::T) where T <: RingElem\n\nReturn the Euclidean remainder of f by g. A DivideError should be thrown if g is zero.\n\nnote: Note\nFor best compatibility with the internal assumptions made by AbstractAlgebra, the Euclidean remainder function should provide unique representatives for the residue classes; the mod function should satisfymod(a_1, b) = mod(a_2, b) if and only if b divides a_1 - a_2, and\nmod(0, b) = 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#div-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"div","text":"div(f::T, g::T) where T <: RingElem\n\nReturn the Euclidean quotient of f by g. A DivideError should be thrown if g is zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#mulmod-Union{Tuple{T}, Tuple{T, T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"mulmod","text":"mulmod(f::T, g::T, m::T) where T <: RingElem\n\nReturn mod(f*g, m) but possibly computed more efficiently.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#powermod-Union{Tuple{T}, Tuple{T, Int64, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"powermod","text":"powermod(f::T, e::Int, m::T) where T <: RingElem\n\nReturn mod(f^e, m) but possibly computed more efficiently.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#invmod-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"invmod","text":"invmod(f::T, m::T) where T <: RingElem\n\nReturn an inverse of f modulo m, meaning that isone(mod(invmod(f,m)*f,m)) returns true.\n\nIf such an inverse doesn't exist, a NotInvertibleError should be thrown.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#divides-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"divides","text":"divides(f::T, g::T) where T <: RingElem\n\nReturn a pair, flag, q, where flag is set to true if g divides f, in which case q is set to the quotient, or flag is set to false and q is set to zero(f).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#remove-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"remove","text":"remove(f::T, p::T) where T <: RingElem\n\nReturn a pair v, q where p^v is the highest power of p dividing f and q is the cofactor after f is divided by this power.\n\nSee also valuation, which only returns the valuation.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#valuation-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"valuation","text":"valuation(f::T, p::T) where T <: RingElem\n\nReturn v where p^v is the highest power of p dividing f.\n\nSee also remove.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#gcd-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"gcd","text":"gcd(a::T, b::T) where T <: RingElem\n\nReturn a greatest common divisor of a and b, i.e., an element g which is a common divisor of a and b, and with the property that any other common divisor of a and b divides g.\n\nnote: Note\nFor best compatibility with the internal assumptions made by AbstractAlgebra, the return is expected to be unit-normalized in such a way that if the return is a unit, that unit should be one.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#gcd-Union{Tuple{T}, Tuple{T, T, Vararg{T}}} where T<:RingElem","page":"Euclidean Ring Interface","title":"gcd","text":"gcd(f::T, g::T, hs::T...) where T <: RingElem\n\nReturn a greatest common divisor of f, g and the elements in hs.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#gcd-Union{Tuple{AbstractArray{<:T}}, Tuple{T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"gcd","text":"gcd(fs::AbstractArray{<:T}) where T <: RingElem\n\nReturn a greatest common divisor of the elements in fs. Requires that fs is not empty.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#lcm-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"lcm","text":"lcm(f::T, g::T) where T <: RingElem\n\nReturn a least common multiple of f and g, i.e., an element d which is a common multiple of f and g, and with the property that any other common multiple of f and g is a multiple of d.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#lcm-Union{Tuple{T}, Tuple{T, T, Vararg{T}}} where T<:RingElem","page":"Euclidean Ring Interface","title":"lcm","text":"lcm(f::T, g::T, hs::T...) where T <: RingElem\n\nReturn a least common multiple of f, g and the elements in hs.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#lcm-Union{Tuple{AbstractArray{<:T}}, Tuple{T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"lcm","text":"lcm(fs::AbstractArray{<:T}) where T <: RingElem\n\nReturn a least common multiple of the elements in fs. Requires that fs is not empty.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#gcdx-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"gcdx","text":"gcdx(f::T, g::T) where T <: RingElem\n\nReturn a triple d, s, t such that d = gcd(f g) and d = sf + tg, with s loosely reduced modulo gd and t loosely reduced modulo fd.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#gcdinv-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"gcdinv","text":"gcdinv(f::T, g::T) where T <: RingElem\n\nReturn a tuple d, s such that d = gcd(f g) and s = (fd)^-1 pmodgd. Note that d = 1 iff f is invertible modulo g, in which case s = f^-1 pmodg.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#crt-Union{Tuple{T}, NTuple{4, T}} where T<:RingElement","page":"Euclidean Ring Interface","title":"crt","text":"crt(r1::T, m1::T, r2::T, m2::T; check::Bool=true) where T <: RingElement\n\nReturn an element congruent to r_1 modulo m_1 and r_2 modulo m_2. If check = true and no solution exists, an error is thrown.\n\nIf T is a fixed precision integer type (like Int), the result will be correct if abs(ri) <= abs(mi) and abs(m1 * m2) < typemax(T).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#crt-Union{Tuple{T}, Tuple{Vector{T}, Vector{T}}} where T<:RingElement","page":"Euclidean Ring Interface","title":"crt","text":"crt(r::Vector{T}, m::Vector{T}; check::Bool=true) where T <: RingElement\n\nReturn an element congruent to r_i modulo m_i for each i.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#crt_with_lcm-Union{Tuple{T}, NTuple{4, T}} where T<:RingElement","page":"Euclidean Ring Interface","title":"crt_with_lcm","text":"crt_with_lcm(r1::T, m1::T, r2::T, m2::T; check::Bool=true) where T <: RingElement\n\nReturn a tuple consisting of an element congruent to r_1 modulo m_1 and r_2 modulo m_2 and the least common multiple of m_1 and m_2. If check = true and no solution exists, an error is thrown.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#crt_with_lcm-Union{Tuple{T}, Tuple{Vector{T}, Vector{T}}} where T<:RingElement","page":"Euclidean Ring Interface","title":"crt_with_lcm","text":"crt_with_lcm(r::Vector{T}, m::Vector{T}; check::Bool=true) where T <: RingElement\n\nReturn a tuple consisting of an element congruent to r_i modulo m_i for each i and the least common multiple of the m_i.\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Creating-PBW-Algebras","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Types","page":"Creating PBW-Algebras","title":"Types","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"PBW-algebras are modelled by objects of type PBWAlgRing{T, S} <: NCRing, their elements are objects of type PBWAlgElem{T, S} <: NCRingElem. Here, T is the element type of the field over which the PBW-algebra is defined (the type S is added for internal use).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Constructors","page":"Creating PBW-Algebras","title":"Constructors","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"The basic constructor below allows one to build PBW-algebras:","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"pbw_algebra(R::MPolyRing{T}, rel, ord::MonomialOrdering) where T","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#pbw_algebra-Union{Tuple{T}, Tuple{MPolyRing{T}, Any, MonomialOrdering}} where T","page":"Creating PBW-Algebras","title":"pbw_algebra","text":"pbw_algebra(R::MPolyRing{T}, rel, ord::MonomialOrdering; check::Bool = true) where T\n\nGiven a multivariate polynomial ring R over a field, say R=Kx_1 dots x_n, given a strictly upper triangular matrix rel with entries in R of type c_ij cdot x_ix_j+d_ij, where the c_ij are nonzero scalars and where we think of the x_jx_i = c_ij cdot x_ix_j+d_ij as setting up relations in the free associative algebra Klangle x_1 dots x_nrangle, and given an ordering ord on textMon(x_1 dots x_n), return the PBW-algebra\n\nA = Klangle x_1 dots x_n mid x_jx_i = c_ij cdot x_ix_j+d_ij 1leq ij leq n rangle\n\nnote: Note\nThe input data gives indeed rise to a PBW-algebra if:The ordering ord is admissible for A.\nThe standard monomials in Klangle x_1 dots x_nrangle represent a K-basis for A.See the definition of PBW-algebras in the OSCAR documentation for details.\n\nnote: Note\nThe K-basis condition above is checked by default. This check may be skipped by passing check = false.\n\nExamples\n\njulia> R, (x, y, z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [x*y, x*z, y*z + 1];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)))\n(PBW-algebra over Rational field in x, y, z with relations y*x = x*y, z*x = x*z, z*y = y*z + 1, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z])\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Some PBW-algebras are predefined in OSCAR.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Weyl-Algebras","page":"Creating PBW-Algebras","title":"Weyl Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"The n-th Weyl algebra over a field K is the PBW-algebra","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"D_n(K)=K langle x_1ldots x_n partial _1dots partial _n mid partial_i x_i=x_ipartial _i +1 partial _i x_j=x_j partial _i text for ineq jrangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Here, we tacitly assume that","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"x_j x_i=x_i x _j text and partial _j partial_i=partial_i partial _j text for all ij","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Note that any global monomial ordering on textMon_2n(x partial) is admissible for D_n(K).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"The constructor below returns the algebras equipped with degrevlex.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":" weyl_algebra(K::Ring, xs::AbstractVector{<:VarName})","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#weyl_algebra-Tuple{Ring, AbstractVector{<:Union{Char, AbstractString, Symbol}}}","page":"Creating PBW-Algebras","title":"weyl_algebra","text":"weyl_algebra(K::Ring, xs::AbstractVector{<:VarName})\n\nGiven a field K and a vector xs of, say, n Strings, Symbols, or Characters, return the n-th Weyl algebra over K.\n\nThe generators of the returned algebra print according to the entries of xs. See the example below.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"])\n(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])\n\njulia> dx*x\nx*dx + 1\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Universal-Enveloping-Algebras-of-Finite-Dimensional-Lie-Algebras","page":"Creating PBW-Algebras","title":"Universal Enveloping Algebras of Finite Dimensional Lie Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Let mathfrak g be an n-dimensional Lie algebra over a field K, and let x_1 dots x_n be a K-basis of mathfrak g. Consider n indeterminates which are also denoted by x_1 dots x_n. The universal enveloping algebra of mathfrak g is the PBW-algebra","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"U(mathfrak g)=K langle x_1ldots x_n mid x_jx_i = x_ix_j+x_j x_i 1leq ij leq n rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"where x_j x_i corresponds to evaluating the Lie bracket x_j x_i_mathfrak g. That the standard monomials in U(mathfrak g) indeed form a K-basis for U(mathfrak g) is the content of the Poincartexte-Birkhoff-Witt theorem (the names PBW-basis and PBW-algebra are derived from this fact).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Note that any degree compatible global monomial ordering on N^n is admissible for U(mathfrak g).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"The constructors below return the algebras equipped with degrevlex.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Quantized-Enveloping-Algebras","page":"Creating PBW-Algebras","title":"Quantized Enveloping Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Non-Standard-Quantum-Deformation-of-so_3","page":"Creating PBW-Algebras","title":"Non-Standard Quantum Deformation of so_3","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Data-Associated-to-PBW-Algebras","page":"Creating PBW-Algebras","title":"Data Associated to PBW-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Given a PBW-algebra A over a field K, ","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"coefficient_ring(A) refers to K,\ngens(A) to the generators of A,\nngens(A) to the number of these generators, and\ngen(A, i) as well as A[i] to the i-th such generator.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Examples","page":"Creating PBW-Algebras","title":"Examples","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"julia> R, (x,y,z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [x*y, x*z, y*z + 1];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));\n\njulia> coefficient_ring(A)\nRational field\n\njulia> gens(A)\n3-element Vector{PBWAlgElem{QQFieldElem, Singular.n_Q}}:\n x\n y\n z\n\njulia> gen(A, 2)\ny\n\njulia> A[3]\nz \n\njulia> ngens(A)\n3\n","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Elements-of-PBW-Algebras","page":"Creating PBW-Algebras","title":"Elements of PBW-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Elements of PBW-algebras are stored and printed in their standard representation.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Constructors-2","page":"Creating PBW-Algebras","title":"Constructors","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"One way to create elements of a PBW-algebra A over a field K is to build them up from the generators of A using basic arithmetic as shown below:","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Examples-2","page":"Creating PBW-Algebras","title":"Examples","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"julia> R, (x,y,z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [x*y, x*z, y*z + 1];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));\n\njulia> f = 3*x^2+z*y\n3*x^2 + y*z + 1\n","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Alternatively, there is the following constructor:","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"(A::PBWAlgRing)(cs::AbstractVector, es::AbstractVector{Vector{Int}})","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Its return value is the element of A whose standard representation is built from the elements of cs as coefficients, and the elements of es as exponents.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Examples-3","page":"Creating PBW-Algebras","title":"Examples","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"julia> R, (x,y,z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [x*y, x*z, y*z + 1];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));\n\njulia> f = 3*x^2+z*y\n3*x^2 + y*z + 1\n\njulia> g = A(QQ.([3, 1, 1]), [[2, 0, 0], [0, 1, 1], [0, 0, 0]])\n3*x^2 + y*z + 1\n\njulia> f == g\ntrue\n","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"An often more effective way to create elements is to use the corresponding build context as indicated below:","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"julia> R, (x,y,z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [x*y, x*z, y*z + 1];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x,y,z) = pbw_algebra(R, REL, deglex(gens(R)));\n\njulia> B = build_ctx(A);\n\njulia> for i = 1:5 push_term!(B, QQ(i), [i+1, i, i-1]) end\n\njulia> finish(B)\n5*x^6*y^5*z^4 + 4*x^5*y^4*z^3 + 3*x^4*y^3*z^2 + 2*x^3*y^2*z + x^2*y\n","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Special-Elements","page":"Creating PBW-Algebras","title":"Special Elements","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Given a PBW-algebra A, zero(A) and one(A) refer to the additive and multiplicative identity of A, respectively. Relevant test calls on an element f of A are iszero(f) and isone(f).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Data-Associated-to-Elements-of-PBW-algebras","page":"Creating PBW-Algebras","title":"Data Associated to Elements of PBW-algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"Given an element f of a PBW-algebra A, ","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"parent(f) refers to A,","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#Opposite-Algebras","page":"Creating PBW-Algebras","title":"Opposite Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"opposite_algebra(A::PBWAlgRing)","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/#opposite_algebra-Tuple{PBWAlgRing}","page":"Creating PBW-Algebras","title":"opposite_algebra","text":"opposite_algebra(A::PBWAlgRing)\n\nReturn the opposite algebra of A.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"])\n(Weyl-algebra over Rational field in variables (x, y), PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, dx, dy])\n\njulia> Dop, opp = opposite_algebra(D);\n\njulia> Dop\nPBW-algebra over Rational field in dy, dx, y, x with relations dx*dy = dy*dx, y*dy = dy*y + 1, x*dy = dy*x, y*dx = dx*y, x*dx = dx*x + 1, x*y = y*x\n\njulia> opp\nMap to opposite of Weyl-algebra over Rational field in variables (x, y)\n\njulia> opp(dx*x)\ndx*x + 1\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"If a map opp from a PBW-algebra to its opposite algebra is given, then inv(opp) refers to the inverse of opp.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/developer/topics/#Specific-topics","page":"Specific topics","title":"Specific topics","text":"","category":"section"},{"location":"Nemo/developer/topics/#Julia-arithmetic","page":"Specific topics","title":"Julia arithmetic","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"At the console, Julia arithmetic is often defined in a way that a numerical person would expect. For example, 3/1 returns a floating point number 3.0, sqrt(4) returns the floating point number 2.0 and exp(0) returns the floating point number 1.0.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In each case the ring is changed from the input to the output of the function. Whilst this is often what one expects to happen in a computer algebra system, these are not the definitions one would want for algebraic operations.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In this section we describe the alternatives we have implemented to allow algebraic computations, particularly for rings and fields.","category":"page"},{"location":"Nemo/developer/topics/#divexact-and-divides","page":"Specific topics","title":"divexact and divides","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Nemo implements numerous kinds of division:","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"floating point division using the / operator as per Julia\nexact division in a ring using divexact and divides\nquotient field element construction using // as per Julia\nEuclidean division using div, rem, divrem, mod and %","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The expression divexact(a, b) for a and b in a ring R returns a value c in R such that a = bc. If such an element of R does not exist, an exception is raised.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"To instead test whether such an element exists, divides(a, b) returns a tuple (flag, q) where flag is a boolean saying whether such an exact quotient exists in the ring and if so q is such a quotient.","category":"page"},{"location":"Nemo/developer/topics/#Euclidean-division","page":"Specific topics","title":"Euclidean division","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Nemo must provide Euclidean division, i.e. given a and b in a Euclidean ring R it must be able to find q and r such that a = bq + r with r smaller than a with respect to some fixed Euclidean function on R. There are some restrictions imposed by Julia however.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Firstly, % is a constant alias of rem in Julia, so these are not actually two independent functions but the same function.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Julia defines div, rem and divrem for integers as a triple of functions that return Euclidean quotient and remainder, where the remainder has the same sign as the dividend, e.g. rem(1, 3) == 1 but rem(-2, 3) == -2. In other words, this triple of functions gives Euclidean division, but without a consistent set of representatives.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"When using Nemo at the console (or indeed inside any other package without importing the internal Nemo definitions) div, rem and divrem return the same values as Julia and these functions follows the Julia convention of making the sign of the remainder the same as the dividend over ZZ, e.g. rem(ZZ(1), ZZ(3)) == 1 but rem(ZZ(-2), ZZ(3)) == -2.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Internally to Nemo however, this is not convenient. For example, Hermite normal form over ZZ will only return a unique result if there is a consistent choice of representatives for the Euclidean division. This applies to the generic HNF code in AbstractAlgebra, but similar problems exist for the generic finitely presented module code in AbstractAlgebra, even when used over Nemo integers. Thus the Julia definition of rem will not suffice.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Furthermore, as Nemo wraps Flint, it is convenient that Euclidean division inside Nemo should operate the way Flint operates. This is critical if for example one wants the result of a Hermite normal form coming from Flint to be reduced using the same definition of Euclidean remainder as used elsewhere throughout the Nemo module and to return the same answers as the generic HNF code in AbstractAlgebra for example.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In particular, Flint defines Euclidean remainder over the integers in line with the Julia function mod, namely by returning the smallest remainder with the same sign as the divisor, i.e. mod(1, 3) == 1 but mod(1, -3) == -2.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Therefore internally, Nemo chooses div, mod and divrem to be a consistent triple of functions for Euclidean division, with mod defined as per Julia. Thus in particular, div and divrem behave differently to Julia inside of Nemo itself, viz. Nemo.divrem(-1, 3) == (-1, 2).","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The same definitions for div, mod and divrem are used internally to AbstractAlgebra as well, even for Julia integers, so that AbstractAlgebra and Nemo are both consistent internally. However, both AbstractAlgebra and Nemo export definitions in line with Julia so that behaviour at the console is consistent.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The Nemo developers have given considerable thought to this compromise and the current situation has evolved over many iterations to the current state. We do not consider this to be a situation that needs 'fixing', though we are acutely aware that many tickets will be opened complaining about some inconsistency.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"When reflecting on the choice we have made, one must consider the following:","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Nemo must internally behave as Flint does for consistency\nThere are also functions such as powmod, invmod that reduce as per mod\nHNF requires a consistent set of representatives for uniqueness over ZZ","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Also note that Julia's rem does not provide symmetric mod, a misconception that often arises. The issues here are independent of the decision to use positive remainder (for positive modulus) in Flint, rather than symmetric mod.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"We are aware that the conventions we have chosen have inconsistencies with Julia and do not have the nice property that div, rem and divrem are a triple of Euclidean functions inside Nemo. However, we are sure that the convention we have chosen is one of only two sensible possibilities, and switching to the other convention (apart from being a huge amount of effort) would only succeed in replacing one kind of inconsistency with another.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"As a consequence of these choices, div, mod and divrem are a triple of functions for all Euclidean division across Nemo, not just for the integers. As generic code must use a consistent set of functions, we ask that developers respect this choice by using these three functions in all generic code. The functions rem and % should only be used for Julia integers, and only when one specifically wants the Julia definition.","category":"page"},{"location":"Nemo/developer/topics/#sqrt,-inv-and-exp","page":"Specific topics","title":"sqrt, inv and exp","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"As mentioned above, Julia does not perform computations within a given ring, but often returns a numerical result when given an exact input.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Whilst this is often what a user expects, it makes operations such as power series square root, inversion or exponentiation more tricky over an exact ring.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Therefore, AbstractAlgebra defines sqrt, inv and exp internally in a strictly algebraic way, returning a result only if it exists in the ring of the input and otherwise raising an exception.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"For example, AbstractAlgebra.sqrt(4) == 2, AbstractAlgebra.inv(-1) == -1 and AbstractAlgebra.exp(0) == 1.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Naturally these definitions are not so terribly useful to a user and are only needed for internal consistency. Therefore, of course these definitions are not exported by AbstractAlgebra so that the behaviour at the console is not affected by these definitions.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"There is currently some inconsistency in that Nemo follows the Julia numerical definitions internally rather than following the algebraic definitions provided internally in AbstractAlgebra. This may or may not change in future.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"It is worth recalling that Julia provides isqrt for integer square root. This is not sufficient to solve our problem as we require square root for all rings, not just integers. We don't feel that developers will want to type isqrt rather than sqrt internally for all rings.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"A number of changes are expected to be made with regard to the behaviour of root taking and division functions, including the ability to specify high performance alternatives that do not check the exactness of the computation. These changes are being discussed on the Nemo ticket https://github.com/Nemocas/Nemo.jl/issues/862 In particular, the table given there by thofma represents the current consensus on the changes that will be made in the future.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Note that many of the above issues with exact computations in rings exist for all the Julia transcendental functions, sin, cos, log, etc., of which there are many. If we ever add some kind of generic power series functions for these, we may extend the internal definitions to include exact algebraic versions of all these functions. At least for now this is not a pressing issue.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The way that AbstractAlgebra deals with functions which must have a different definition inside the module than what it exports is as follows. Firstly, we do not import the functions from Base or export the functions at all. Internally we make our definitions as we want them, but then we overload the Base version explicitly to do what the console version of the function should do. This is done by explicitly defining Base.sqrt(::ZZRingElem) for example without explicitly importing sqrt from Base, etc.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In the Generic module discussed below, we import the definitions from AbstractAlgebra rather than Base.","category":"page"},{"location":"Nemo/developer/topics/#Determinant","page":"Specific topics","title":"Determinant","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Another function which Nemo handles differently to Julia is det for determinant of matrices. If the input is an integer matrix, Nemo outputs an integer rather than a floating point number for the determinant.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"However, this is not such an acute problem as Julia's det has now been placed in LinearAlgebra rather than Base. Moreover, Nemo has its own matrices and so does not conflict with the definition of det for Julia matrices.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"It is important for developers to understand this difference however. It is not generally wise to use the Julia linear algebra functionality on the Julia matrices underlying generic Nemo matrices for this reason.","category":"page"},{"location":"Nemo/developer/topics/#The-Generic-submodule","page":"Specific topics","title":"The Generic submodule","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In AbstractAlgebra we define a submodule called Generic. The purpose of this module is to allow generic constructions over a given base ring. For example in Nemo, R, x = Generic.polynomial_ring(ZZ, \"x\") will construct a generic polynomial ring over Nemo integers instead of constructing a Flint polynomial ring.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In other words x will have the type Generic.Poly{ZZRingElem} instead of the usual ZZPolyRingElem.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The ability to construct generic polynomials and matrices and the like is useful for test code and for tracking down bugs in basic arithmetic. It is also useful for performance comparison of arithmetic defined for generic ring constructions vs the specialised implementations provided by C libraries like Flint.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Whilst most developers will not need to use the Generic module specifically, unless they have such needs, all Nemo developers need to understand how to define new generic ring constructions and functions for them. They also need to understand some subtleties that arise because of this mechanism.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Firstly, a generic construction like polynomial_ring must be defined inside the Generic submodule of AbstractAlgebra. All files inside the src/generic directory of AbstractAlgebra exist for this purpose. However, exporting from that submodule will not export the functionality to the Nemo user.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"To do this, one must add a function polynomial_ring for example, in src/Poly.jl, say, which calls Generic.polynomial_ring. Then one needs to export polynomial_ring from AbstractAlgebra (also in that file).","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Similarly, all functions provided for generic polynomial rings are not automatically available, even when exported from the Generic submodule. Two additional things are required, namely an import from Generic into AbstractAlgebra and then an export from AbstractAlgebra to the user.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"An exception to this is if there is a function with the same name in AbstractAlgebra (i.e. in the top level src directory). In this case it is sufficient to simply import that function into Generic in the file src/Generic.jl.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In the former case, two large lists exist in src/AbstractAlgebra.jl with these imports and exports. These are kept in alphabetical order to prevent duplicate imports/exports being added over time.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"If one wishes to extend a definition provided by Base, one can simply overload Base.blah inside the Generic submodule directly. Exceptions to this include the div, mod, divrem, sqrt, inv and exp functions mentioned above.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"For AbstractAlgebra types, one still defines these exceptions blah by overloading Base.blah directly inside Generic. However, for the versions that would conflict with the Julia definition (e.g. the definition for Int), we instead define AbstractAlgebra.blah for that specific type and a fallback AbstractAlgebra.blah(a) = Base.blah(a) which calls the Base version of the function for all other types. Of course we do not export blah from AbstractAlgebra.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In order to make the AbstractAlgebra version available in Generic (rather than the Base version), we do not import blah from Base inside Generic, but instead import it from AbstractAlgebra. One can see these imports for the exceptional functions blah in the file src/Generic.jl.","category":"page"},{"location":"Nemo/developer/topics/#Unsafe-operations-and-aliasing","page":"Specific topics","title":"Unsafe operations and aliasing","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"As with most object oriented languages that overload arithmetic operators, Julia creates new objects when doing an arithmetic operation. For example, BigInt(3) + BigInt(5) creates a new BigInt object to return the value BigInt(8). This can be problematic when accumulating many such operations in a single coefficient of a polynomial or entry of a matrix due to the large number of temporary objects the garbage collector must allocate and clean up.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"To speed up such accumulations, Nemo provides numerous unsafe operators, which mutate the existing elements of the polynomial, matrix, etc. These include functions such as add!, addeq!, mul!, zero! and addmul!.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"These functions take as their first argument the object that should be modified with the return value.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Note that functions such as sub!, submul! and subeq! are not in the official interface and not provided consistently, thus generic code cannot rely on them existing. So far it has always been the case that when doing accumulation where subtraction is needed rather than addition, that a single negation can be performed outside the accumulation loop and then the additive versions of the functions can be called inside the loop where the performance matters.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"If we encounter cases in future where this is not the case, it may be necessary to add the versions that do subtraction to the interface. However, this can only be done if all rings in Nemo support it. One cannot define a fallback which turns a subtraction into a negation and an addition, as then the old performance characteristics of a new object being created per operation will result, meaning that the developer will not be able to reason about the likely performance of unsafe operators.","category":"page"},{"location":"Nemo/developer/topics/#Interaction-of-unsafe-operators-and-immutable-types","page":"Specific topics","title":"Interaction of unsafe operators and immutable types","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Because not all objects in Nemo are mutable, the unsafe operators somehow have to support immutable objects. This is done by also returning the \"modified\" return value from the unsafe operators. Naturally, this return value is not a mutated version of the original value, as that is not possible. However, it does allow the unsafe operators to accept immutable values in their first argument. Instead of modifying this value, the old value is replaced with the return value of the unsafe operator.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In order to make this work correctly, every single call to an unsafe operator must assign the return value to the original location. This requires discipline on the part of the developer using unsafe operators.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"For example, to set the existing value a to a + b one must write","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"a = addeq!(a, b)","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"i.e. one must have an explicit assignment to the left of the addeq! call and indeed all the unsafe operator calls.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In the case of a mutable type, addeq! will simply modify the original a. The modified object will be returned and assigned to the exact same variable, which has no effect.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In the case of an immutable type, addeq! does not modify the original object a as this is impossible, but it still returns the new value and assigns it to a which is what one wants.","category":"page"},{"location":"Nemo/developer/topics/#Aliasing-rules-and-mutation","page":"Specific topics","title":"Aliasing rules and mutation","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"One must be incredibly careful when mutating an existing value that one owns the value. If the user passes an object to a generic function for example and it changes the object without the user knowing, this can result in incorrect results in user code due to the value of their objects changing from under them.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In the first instance, functions should never modify their inputs. But further problems can also occur if the output of an unsafe operator happens to alias one of the other inputs. Such cases need to be handled exceptionally carefully.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"A second issue arises as Nemo is based on Flint, which has its own aliasing rules which are distinct from the default expectation in Julia. This leads to some interesting corner cases.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In particularly, Flint always allows aliasing of inputs and outputs in its polynomial functions but expects matrix functions to have output matrices that are distinct from their inputs, except in a handful of functions that are specially documented to be inplace operations.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Moreover, when assigning an element to a coefficient of a polynomial or entry of a matrix Flint always makes a copy of the element being assigned to that location. In Julia however, if one assigns an element to some index of an array, the existing object at that location is replaced with the new object. This means that inplace modification of Julia array elements is not safe as it would modify the original object that was assigned to that location, whereas in Flint inplace modification is highly desirable for performance reasons and is completely safe due to the fact that a copy was made when the value was assigned to that location.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"We have developed over a period of many years a set of rules that maximise the performance benefit we get from our unsafe operators, whilst keeping the burden imposed on the programmer to a minimum. It has been a very difficult task to arrive at the set of rules we have whilst respecting correctness of our code, and it would be extremely hard to change any of them.","category":"page"},{"location":"Nemo/developer/topics/#Arithmetic-operations-return-a-new-object","page":"Specific topics","title":"Arithmetic operations return a new object","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In order to make it easy for the Nemo developer to create a completely new object when one is needed, e.g. for accumulating values using unsafe operators, we developed the following rules.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Whenever an arithmetic operation is used, i.e. +, -, *, unary minus and ^, Nemo always returns a new object, in line with Julia. Naturally, deepcopy also makes a copy of an object which can be used in unsafe functions.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Note that if R is a type and an element a of that type is passed to it, e.g. R(a) then, the Julia convention is that the original object a will be returned rather than a copy of a. This convention ensures there is not an additional cost when coercing values that are already of the right type, e.g in generic code where coercion may or may not be needed depending on the type.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"We extend this convention to parent objects R and elements a of that parent. In particular, R(a) cannot be used to make a copy of a for use in an unsafe function if R is the parent of a.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"All other functions may also return the input object if they wish. In other words, the return value of all other functions is not suitable for use in an unsafe function. Only return values of arithmetic operations and deepcopy or objects freshly created using inner constructors will be suitable for such use.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"This convention has been chosen to maximise performance of Nemo. Low level operations (where performance matters) make a new object, even if the result is the same arithmetically as one of the inputs. But higher level functions will not necessarily make a new object, meaning that they cannot be used with unsafe functions.","category":"page"},{"location":"Nemo/developer/topics/#Aliasing-rules","page":"Specific topics","title":"Aliasing rules","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"We now summarise the aliasing rules used by Nemo and AbstractAlgebra. We are relatively confident by now that following these rules will result in correct code given the constraints mentioned above.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"matrices are viewed as containers which may contain elements that alias one another. Other objects, e.g. polynomials, series, etc., are constructed from objects that do not alias one another, even in part\nstandard unsafe operators, addeq!, mul!, addmul!, zero!, add! which mutate their outputs are allow to be used iff that output is entirely under the control of the caller, i.e. it was created for the purpose of accumulation, but otherwise must not be used\nall arithmetic functions i.e. unary minus, +, -, *, ^, and deepcopy must return new objects and cannot return one of their inputs\nall other functions are allowed to return their inputs as outputs\nmatrix functions with an exclamation mark should not mutate the objects that occur as entries of the output matrix, though should be allowed to arbitrarily replace/swap the entries that appear in the matrix. In other words, these functions should be interpreted as inplace operations, rather than operations that are allowed to mutate the actual entries themselves\nR(a) where R is the parent of a, always just returns a and not a copy\nsetcoeff! and setindex! and getcoeff and getindex should not make copies. Note that this implies that setcoeff! should not be passed an element that aliases another somewhere else, even in part\nConstructors for polynomials, series and similar ring element objects (that are not matrices) that take an array as input, must ensure that the coefficients being placed into the object do not alias, even in part","category":"page"},{"location":"Nemo/developer/topics/#The-SparsePoly-module","page":"Specific topics","title":"The SparsePoly module","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The SparsePoly module in AbstractAlgebra is a generic module for sparse univariate polynomials over a given base ring.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"This module is used internally, e.g. in the generic multivariate gcd code, however it is not particularly suitable for general use.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Firstly, whilst the representation is sparse (recursive) the algorithms used generally are not. This is because the amount of time taken by the Jit in Julia is simply too large (upwards of 6s for the first multivariate gcd).","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Secondly, the order of terms in that representation is not the one which a developer would expect for a sparse univariate format.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"If the Julia Jit is ever made orders of magnitude faster, it may be worth cleaning up this module and making it generally available. But for now, it should be considered internal and heavily incomplete.","category":"page"},{"location":"Nemo/developer/topics/#Parent-object-caching","page":"Specific topics","title":"Parent object caching","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Parent objects in Nemo must be unique given the data that is used to create them. For this purpose most parent objects are cached globally and looked up upon creation. If a parent object with that data already exists, it is returned from the cache instead of creating a new one.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"There are two situations where this can be problematic however.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The first situation is if one is doing some parallel programming. Here global objects are a blight and it may be necessary to turn off caching and simply ensure that that same data is only ever used once when creating parent objects.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"The second situation is when doing multimodular algorithms, where many similar parent objects with different moduli are created. The cache can become overwhelmed slowing the code down or even grinding to a halt.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"In both these situations one can pass false as an additional argument to a parent constructor to avoid caching the parent object it creates. This parameter normally has a default value of true and under normal circumstances doesn't need to be supplied.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Note that special light-weight parent constructors, PolyRing, AbsPowerSeriesRing, RelPowerSeriesRing, etc. are also provided which do not cache.","category":"page"},{"location":"Nemo/developer/topics/#Throw/nothrow-for-check_parent","page":"Specific topics","title":"Throw/nothrow for check_parent","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"By default the check_parent functions throw an exception if parents do not match. However sometimes one would like to know if they match without throwing.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"For this purpose one can pass an additional false argument to check_parent. This suppresses the exception that would be thrown if the parent objects didn't match. Instead the function simply returns true or false to indicate whether they matched or not.","category":"page"},{"location":"Nemo/developer/topics/#Delayed-reduction","page":"Specific topics","title":"Delayed reduction","text":"","category":"section"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"When working in residue rings, various functions will perform an arithmetic operation followed by a reduction modulo the modulus of the residue ring.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Some accumulations, e.g. in linear algebra or polynomial arithmetic, can be dramatically sped up if one can delay the reductions that would happen after each operation in the accumulation.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Some of the Generic code in Nemo is designed to allow such delayed reduction if the ring supports it and to simply use fallbacks that do the reduction after every intermediate operation if they don't.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"To support delayed reduction, a ring must support the delayed reduction interface which we describe here.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Two additional functions must be supplied for the element type. We give examples for the Nemo nf_elem type:","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"mul_red!(z::nf_elem, x::nf_elem, y::nf_elem, red::Bool)","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"This function behaves as per mul! but only performs reduction if the additional boolean argument red is set to true. This function can assume that both the inputs are reduced.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"reduce!(x::nf_elem)","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"This function must perform reduction on an unreduced element (mutating it). Note that it must return the mutated value as per all unsafe operators.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Finally, the add! and addeq! operators must be able to add nonreduced values.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"If one wishes to speed up generic code for rings that provide delayed reduction, one makes use of the function addmul_delayed_reduction! in the accumulation loop. Here is an example for accumulation into a two dimensional matrix element in Generic in a matrix multiplication routine:","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"A[i, j] = base_ring(X)()\nfor k = 1:ncols(X)\n A[i, j] = addmul_delayed_reduction!(A[i, j], x[i, k], y[k, j], C)\nend\nA[i, j] = reduce!(A[i, j])","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Here C is a temporary element of the same type as the other inputs which is used internally in addmul_delayed_reduction! if needed.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Notice the final call to reduce! to reduce the accumulated value after the accumulation loop has finished.","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"Note that mul_red! is never called directly but is called inside the generic implementation of addmul_delayed_reduction! for rings that support delayed reduction. That generic code falls back to a call to addmul! which in turn falls back to mul! and addeq! where delayed reduction or addmul! are not available.","category":"page"},{"location":"Hecke/function_fields/internal/","page":"-","title":"-","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/function_fields/internal/","page":"-","title":"-","text":"Function fields, in Hecke, come in several different types:","category":"page"},{"location":"Hecke/function_fields/internal/","page":"-","title":"-","text":"RationalFunctionField: a field of the form k(x) for a field k.\nFunctionField: a finite extension of a rational function field given by a polynomial.","category":"page"},{"location":"Hecke/function_fields/internal/","page":"-","title":"-","text":"Function fields with the type FunctionField are referred to as simple fields in the rest of this document. They are also referred to as being absolute.","category":"page"},{"location":"Hecke/function_fields/internal/#Absolute-Simple-Fields","page":"-","title":"Absolute Simple Fields","text":"","category":"section"},{"location":"Hecke/function_fields/internal/","page":"-","title":"-","text":"Internally function fields of type FunctionField are essentially represented as a unvariate quotient with the arithmetic provided by the AbstractAlgebra and Nemo packages. As they are defined generically for all AbstractAlgebra, Nemo and Hecke fields k the function field type is implemented in AbstractAlgebra.","category":"page"},{"location":"Hecke/examples/reduction/#Reduction-of-polynomials-over-number-fields-modulo-a-prime-ideal","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"","category":"section"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"Given a polynomial f in Kx and a prime ideal mathfrak p of mathcal O_K, we want to determine the reduction bar f in Fx, where F = mathcal O_Kmathfrak p is the residue field. Concretely, we want to reduce the polynomial f = x^3 + (1 + ζ_7 + ζ_7^2)x^2 + (23 + 55ζ_7^5)x + (ζ_7 + 77)2 over mathbfQ(zeta_7). We begin by defining the cyclomotic field and the polynomial.","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"using Hecke # hide\nK, ζ = cyclotomic_field(7);\nKx, x = K['x'];\nf = x^3 + (1 + ζ + ζ^2)*x^2 + (23 + 55ζ^5)x + (ζ + 77)//2","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"Next we determine the ring of integers mathcal O_K and a prime ideal mathfrak p lying above the prime p = 29.","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"OK = maximal_order(K);\np = 29;\nfrakp = prime_decomposition(OK, p)[1][1]","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"We can now determine the residue field F = mathcalO_Kmathfrak p and the canonical map mathcal O_K to F.","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"F, reduction_map_OK = residue_field(OK, frakp);\nF\nreduction_map_OK","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"Not that the reduction map has domain mathcal O_K and thus cannot be applied to elements of K. We can extend it to the set of mathfrak p-integral elements by invoking the extend function. Not that the domain of the extended map will be the whole K, but the map will throw an error when applied to elements which are not mathfrak p-integral.","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"reduction_map_extended = extend(reduction_map_OK, K)\nreduction_map_extended(K(1//3))\nreduction_map_extended(K(1//29))","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"Finally we can reduce f modulo mathfrak p, which we obtain by applying the reduction map to the coefficients.","category":"page"},{"location":"Hecke/examples/reduction/","page":"Reduction of polynomials over number fields modulo a prime ideal","title":"Reduction of polynomials over number fields modulo a prime ideal","text":"fbar = map_coefficients(reduction_map_extended, f)\nbase_ring(fbar) === F","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#Discriminant-Groups","page":"Discriminant Groups","title":"Discriminant Groups","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#Torsion-Quadratic-Modules","page":"Discriminant Groups","title":"Torsion Quadratic Modules","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"A torsion quadratic module is the quotient MN of two quadratic integer lattices N subseteq M in the quadratic space (VPhi). It inherits a bilinear form","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"b MN times MN to mathbbQ n mathbbZ","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"as well as a quadratic form","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"q MN to mathbbQ m mathbbZ","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"where n mathbbZ = Phi(MN) and m mathbbZ = 2nmathbbZ + sum_x in N mathbbZ Phi (xx).","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"torsion_quadratic_module(M::ZZLat, N::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#torsion_quadratic_module-Tuple{ZZLat, ZZLat}","page":"Discriminant Groups","title":"torsion_quadratic_module","text":"torsion_quadratic_module(M::ZZLat, N::ZZLat; gens::Union{Nothing, Vector{<:Vector}} = nothing,\n snf::Bool = true,\n modulus::QQFieldElem = QQFieldElem(0),\n check::Bool = true) -> TorQuadModule\n\nGiven a Z-lattice M and a sublattice N of M, return the torsion quadratic module MN.\n\nIf gens is set, the images of gens will be used as the generators of the abelian group MN.\n\nIf snf is true, the underlying abelian group will be in Smith normal form. Otherwise, the images of the basis of M will be used as the generators.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#The-underlying-Type","page":"Discriminant Groups","title":"The underlying Type","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"TorQuadModule","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#TorQuadModule","page":"Discriminant Groups","title":"TorQuadModule","text":"TorQuadModule\n\nExamples\n\njulia> A = matrix(ZZ, [[2,0,0,-1],[0,2,0,-1],[0,0,2,-1],[-1,-1,-1,2]]);\n\njulia> L = integer_lattice(gram = A);\n\njulia> T = Hecke.discriminant_group(L)\nFinite quadratic module\n over integer ring\nAbelian group: (Z/2)^2\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form:\n[ 1 1//2]\n[1//2 1]\n\nWe represent torsion quadratic modules as quotients of mathbbZ-lattices by a full rank sublattice.\n\nWe store them as a mathbbZ-lattice M together with a projection p : M -> A onto an abelian group A. The bilinear structure of A is induced via p, that is = with values in mathbbQnmathbbZ, where n is the modulus and depends on the kernel of p.\n\nElements of A are basically just elements of the underlying abelian group. To move between M and A, we use the lift function lift : M -> A and coercion A(m).\n\nExamples\n\njulia> R = rescale(root_lattice(:D,4),2);\n\njulia> D = discriminant_group(R);\n\njulia> A = abelian_group(D)\nGrpAb: (Z/2)^2 x (Z/4)^2\n\njulia> d = D[1]\nElement\n of finite quadratic module: (Z/2)^2 x (Z/4)^2 -> Q/2Z\nwith components [1 0 0 0]\n\njulia> d == D(A(d))\ntrue\n\njulia> lift(d)\n4-element Vector{QQFieldElem}:\n 1\n 1\n 3//2\n 1\n\nN.B. Since there are no elements of mathbbZ-lattices, we think of elements of M as elements of the ambient vector space. Thus if v::Vector is such an element then the coordinates with respec to the basis of M are given by solve_left(basis_matrix(M), v).\n\n\n\n\n\n","category":"type"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"Most of the functionality mirrors that of AbGrp its elements and homomorphisms. Here we display the part that is specific to elements of torsion quadratic modules.","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#Attributes","page":"Discriminant Groups","title":"Attributes","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"abelian_group(T::TorQuadModule)\ncover(T::TorQuadModule)\nrelations(T::TorQuadModule)\nvalue_module(T::TorQuadModule)\nvalue_module_quadratic_form(T::TorQuadModule)\ngram_matrix_bilinear(T::TorQuadModule)\ngram_matrix_quadratic(T::TorQuadModule)\nmodulus_bilinear_form(T::TorQuadModule)\nmodulus_quadratic_form(T::TorQuadModule)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#abelian_group-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"abelian_group","text":"abelian_group(T::TorQuadModule) -> GrpAbFinGen\n\nReturn the underlying abelian group of T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#cover-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"cover","text":"cover(T::TorQuadModule) -> ZZLat\n\nFor T=MN this returns M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#relations-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"relations","text":"relations(T::TorQuadModule) -> ZZLat\n\nFor T=MN this returns N.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#value_module-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"value_module","text":"value_module(T::TorQuadModule) -> QmodnZ\n\nReturn the value module Q/nZ of the bilinear form of T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#value_module_quadratic_form-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"value_module_quadratic_form","text":"value_module_quadratic_form(T::TorQuadModule) -> QmodnZ\n\nReturn the value module Q/mZ of the quadratic form of T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#gram_matrix_bilinear-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"gram_matrix_bilinear","text":"gram_matrix_bilinear(T::TorQuadModule) -> QQMatrix\n\nReturn the gram matrix of the bilinear form of T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#gram_matrix_quadratic-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"gram_matrix_quadratic","text":"gram_matrix_quadratic(T::TorQuadModule) -> QQMatrix\n\nReturn the 'gram matrix' of the quadratic form of T.\n\nThe off diagonal entries are given by the bilinear form whereas the diagonal entries are given by the quadratic form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#modulus_bilinear_form-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"modulus_bilinear_form","text":"modulus_bilinear_form(T::TorQuadModule) -> QQFieldElem\n\nReturn the modulus of the value module of the bilinear form ofT.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#modulus_quadratic_form-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"modulus_quadratic_form","text":"modulus_quadratic_form(T::TorQuadModule) -> QQFieldElem\n\nReturn the modulus of the value module of the quadratic form of T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Elements","page":"Discriminant Groups","title":"Elements","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"quadratic_product(a::TorQuadModuleElem)\ninner_product(a::TorQuadModuleElem, b::TorQuadModuleElem)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#quadratic_product-Tuple{TorQuadModuleElem}","page":"Discriminant Groups","title":"quadratic_product","text":"quadratic_product(a::TorQuadModuleElem) -> QmodnZElem\n\nReturn the quadratic product of a.\n\nIt is defined in terms of a representative: for b + M in MN=T, this returns Phi(bb) + n mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#inner_product-Tuple{TorQuadModuleElem, TorQuadModuleElem}","page":"Discriminant Groups","title":"inner_product","text":"inner_product(a::TorQuadModuleElem, b::TorQuadModuleElem) -> QmodnZElem\n\nReturn the inner product of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Lift-to-the-cover","page":"Discriminant Groups","title":"Lift to the cover","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"lift(a::TorQuadModuleElem)\nrepresentative(::TorQuadModuleElem)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#lift-Tuple{TorQuadModuleElem}","page":"Discriminant Groups","title":"lift","text":"lift(a::TorQuadModuleElem) -> Vector{QQFieldElem}\n\nLift a to the ambient space of cover(parent(a)).\n\nFor a + N in MN this returns the representative a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#representative-Tuple{TorQuadModuleElem}","page":"Discriminant Groups","title":"representative","text":"representative(a::TorQuadModuleElem) -> Vector{QQFieldElem}\n\nFor a + N in MN this returns the representative a. An alias for lift(a).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Orthogonal-submodules","page":"Discriminant Groups","title":"Orthogonal submodules","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"orthogonal_submodule(T::TorQuadModule, S::TorQuadModule)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#orthogonal_submodule-Tuple{TorQuadModule, TorQuadModule}","page":"Discriminant Groups","title":"orthogonal_submodule","text":"orthogonal_submodule(T::TorQuadModule, S::TorQuadModule)-> TorQuadModule\n\nReturn the orthogonal submodule to the submodule S of T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Isometry","page":"Discriminant Groups","title":"Isometry","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"is_isometric_with_isometry(T::TorQuadModule, U::TorQuadModule)\nis_anti_isometric_with_anti_isometry(T::TorQuadModule, U::TorQuadModule)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#is_isometric_with_isometry-Tuple{TorQuadModule, TorQuadModule}","page":"Discriminant Groups","title":"is_isometric_with_isometry","text":"is_isometric_with_isometry(T::TorQuadModule, U::TorQuadModule)\n -> Bool, TorQuadModuleMor\n\nReturn whether the torsion quadratic modules T and U are isometric. If yes, it also returns an isometry T to U.\n\nIf T and U are not semi-regular it requires that they both split into a direct sum of their respective quadratic radical (see radical_quadratic).\n\nIt requires that both T and U have modulus 1: in case one of them do not, they should be rescaled (see rescale).\n\nExamples\n\njulia> T = torsion_quadratic_module(QQ[2//3 2//3 0 0 0;\n 2//3 2//3 2//3 0 2//3;\n 0 2//3 2//3 2//3 0;\n 0 0 2//3 2//3 0;\n 0 2//3 0 0 2//3])\nFinite quadratic module\n over integer ring\nAbelian group: (Z/3)^5\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form:\n[2//3 2//3 0 0 0]\n[2//3 2//3 2//3 0 2//3]\n[ 0 2//3 2//3 2//3 0]\n[ 0 0 2//3 2//3 0]\n[ 0 2//3 0 0 2//3]\n\njulia> U = torsion_quadratic_module(QQ[4//3 0 0 0 0;\n 0 4//3 0 0 0;\n 0 0 4//3 0 0;\n 0 0 0 4//3 0;\n 0 0 0 0 4//3])\nFinite quadratic module\n over integer ring\nAbelian group: (Z/3)^5\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form:\n[4//3 0 0 0 0]\n[ 0 4//3 0 0 0]\n[ 0 0 4//3 0 0]\n[ 0 0 0 4//3 0]\n[ 0 0 0 0 4//3]\n\njulia> bool, phi = is_isometric_with_isometry(T,U)\n(true, Map with following data\nDomain:\n=======\nFinite quadratic module: (Z/3)^5 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: (Z/3)^5 -> Q/2Z)\n\njulia> is_bijective(phi)\ntrue\n\njulia> T2, _ = sub(T, [-T[4], T[2]+T[3]+T[5]])\n(Finite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data\nDomain:\n=======\nFinite quadratic module: (Z/3)^2 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: (Z/3)^5 -> Q/2Z)\n\njulia> U2, _ = sub(T, [T[4], T[2]+T[3]+T[5]])\n(Finite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data\nDomain:\n=======\nFinite quadratic module: (Z/3)^2 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: (Z/3)^5 -> Q/2Z)\n\njulia> bool, phi = is_isometric_with_isometry(U2, T2)\n(true, Map with following data\nDomain:\n=======\nFinite quadratic module: (Z/3)^2 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: (Z/3)^2 -> Q/2Z)\n\njulia> is_bijective(phi)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#is_anti_isometric_with_anti_isometry-Tuple{TorQuadModule, TorQuadModule}","page":"Discriminant Groups","title":"is_anti_isometric_with_anti_isometry","text":"is_anti_isometric_with_anti_isometry(T::TorQuadModule, U::TorQuadModule)\n -> Bool, TorQuadModuleMor\n\nReturn whether there exists an anti-isometry between the torsion quadratic modules T and U. If yes, it returns such an anti-isometry T to U.\n\nIf T and U are not semi-regular it requires that they both split into a direct sum of their respective quadratic radical (see radical_quadratic).\n\nIt requires that both T and U have modulus 1: in case one of them do not, they should be rescaled (see rescale).\n\nExamples\n\njulia> T = torsion_quadratic_module(QQ[4//5;])\nFinite quadratic module\n over integer ring\nAbelian group: Z/5\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form:\n[4//5]\n\njulia> bool, phi = is_anti_isometric_with_anti_isometry(T, T)\n(true, Map with following data\nDomain:\n=======\nFinite quadratic module: Z/5 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: Z/5 -> Q/2Z)\n\njulia> a = gens(T)[1];\n\njulia> a*a == -phi(a)*phi(a)\ntrue\n\njulia> G = matrix(FlintQQ, 6, 6 , [3 3 0 0 0 0;\n 3 3 3 0 3 0;\n 0 3 3 3 0 0;\n 0 0 3 3 0 0;\n 0 3 0 0 3 0;\n 0 0 0 0 0 10]);\n\njulia> V = quadratic_space(QQ, G);\n\njulia> B = matrix(QQ, 6, 6 , [1 0 0 0 0 0;\n 0 1//3 1//3 2//3 1//3 0;\n 0 0 1 0 0 0;\n 0 0 0 1 0 0;\n 0 0 0 0 1 0;\n 0 0 0 0 0 1//5]);\n\n\njulia> M = lattice(V, B);\n\njulia> B2 = matrix(FlintQQ, 6, 6 , [ 1 0 -1 1 0 0;\n 0 0 1 -1 0 0;\n -1 1 1 -1 -1 0;\n 1 -1 -1 2 1 0;\n 0 0 -1 1 1 0;\n 0 0 0 0 0 1]);\n\njulia> N = lattice(V, B2);\n\njulia> T = torsion_quadratic_module(M, N)\nFinite quadratic module\n over integer ring\nAbelian group: Z/15\nBilinear value module: Q/Z\nQuadratic value module: Q/Z\nGram matrix quadratic form:\n[3//5]\n\njulia> bool, phi = is_anti_isometric_with_anti_isometry(T,T)\n(true, Map with following data\nDomain:\n=======\nFinite quadratic module: Z/15 -> Q/Z\nCodomain:\n=========\nFinite quadratic module: Z/15 -> Q/Z)\n\njulia> a = gens(T)[1];\n\njulia> a*a == -phi(a)*phi(a)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Primary-and-elementary-modules","page":"Discriminant Groups","title":"Primary and elementary modules","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"is_primary_with_prime(T::TorQuadModule)\nis_primary(T::TorQuadModule, p::Union{Integer, ZZRingElem})\nis_elementary_with_prime(T::TorQuadModule)\nis_elementary(T::TorQuadModule, p::Union{Integer, ZZRingElem})","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#is_primary_with_prime-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"is_primary_with_prime","text":"is_primary_with_prime(T::TorQuadModule) -> Bool, ZZRingElem\n\nGiven a torsion quadratic module T, return whether the underlying (finite) abelian group of T (see abelian_group) is a p-group for some prime number p. In case it is, p is also returned as second output.\n\nNote that in the case of trivial groups, this function returns (true, 1). If T is not primary, the second return value is -1 by default.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#is_primary-Tuple{TorQuadModule, Union{Integer, ZZRingElem}}","page":"Discriminant Groups","title":"is_primary","text":"is_primary(T::TorQuadModule, p::Union{Integer, ZZRingElem}) -> Bool\n\nGiven a torsion quadratic module T and a prime number p, return whether the underlying (finite) abelian group of T (see abelian_group) is a p-group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#is_elementary_with_prime-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"is_elementary_with_prime","text":"is_elementary_with_prime(T::TorQuadModule) -> Bool, ZZRingElem\n\nGiven a torsion quadratic module T, return whether the underlying (finite) abelian group of T (see abelian_group) is an elementary p-group, for some prime number p. In case it is, p is also returned as second output.\n\nNote that in the case of trivial groups, this function returns (true, 1). If T is not elementary, the second return value is -1 by default.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#is_elementary-Tuple{TorQuadModule, Union{Integer, ZZRingElem}}","page":"Discriminant Groups","title":"is_elementary","text":"is_elementary(T::TorQuadModule, p::Union{Integer, ZZRingElem}) -> Bool\n\nGiven a torsion quadratic module T and a prime number p, return whether the underlying (finite) abelian group of T (see abelian_group) is an elementary p-group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Smith-normal-form","page":"Discriminant Groups","title":"Smith normal form","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"snf(T::TorQuadModule)\nis_snf(T::TorQuadModule)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#snf-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"snf","text":"snf(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMor\n\nGiven a torsion quadratic module T, return a torsion quadratic module S, isometric to T, such that the underlying abelian group of S is in canonical Smith normal form. It comes with an isometry f S to T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#is_snf-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"is_snf","text":"is_snf(T::TorQuadModule) -> Bool\n\nGiven a torsion quadratic module T, return whether its underlying abelian group is in Smith normal form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Discriminant-Groups-2","page":"Discriminant Groups","title":"Discriminant Groups","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"See V. V. Nikulin (1979) for the general theory of discriminant groups. They are particularly useful to work with primitive embeddings of integral integer quadratic lattices.","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#From-a-lattice","page":"Discriminant Groups","title":"From a lattice","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"discriminant_group(::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#discriminant_group-Tuple{ZZLat}","page":"Discriminant Groups","title":"discriminant_group","text":"discriminant_group(L::ZZLat) -> TorQuadModule\n\nReturn the discriminant group of L.\n\nThe discriminant group of an integral lattice L is the finite abelian group D = dual(L)/L.\n\nIt comes equipped with the discriminant bilinear form\n\nD times D to mathbbQ mathbbZ qquad (xy) mapsto Phi(xy) + mathbbZ\n\nIf L is even, then the discriminant group is equipped with the discriminant quadratic form D to mathbbQ 2 mathbbZ x mapsto Phi(xx) + 2mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#From-a-matrix","page":"Discriminant Groups","title":"From a matrix","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"torsion_quadratic_module(q::QQMatrix)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#torsion_quadratic_module-Tuple{QQMatrix}","page":"Discriminant Groups","title":"torsion_quadratic_module","text":"torsion_quadratic_module(q::QQMatrix) -> TorQuadModule\n\nReturn a torsion quadratic module with gram matrix given by q and value module Q/Z. If all the diagonal entries of q have: either even numerator or even denominator, then the value module of the quadratic form is Q/2Z\n\nExample\n\njulia> torsion_quadratic_module(QQ[1//6;])\nFinite quadratic module\n over integer ring\nAbelian group: Z/6\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form:\n[1//6]\n\njulia> torsion_quadratic_module(QQ[1//2;])\nFinite quadratic module\n over integer ring\nAbelian group: Z/2\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form:\n[1//2]\n\njulia> torsion_quadratic_module(QQ[3//2;])\nFinite quadratic module\n over integer ring\nAbelian group: Z/2\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form:\n[3//2]\n\njulia> torsion_quadratic_module(QQ[1//3;])\nFinite quadratic module\n over integer ring\nAbelian group: Z/3\nBilinear value module: Q/Z\nQuadratic value module: Q/Z\nGram matrix quadratic form:\n[1//3]\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Rescaling-the-form","page":"Discriminant Groups","title":"Rescaling the form","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"rescale(T::TorQuadModule, k::RingElement)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#rescale-Tuple{TorQuadModule, RingElement}","page":"Discriminant Groups","title":"rescale","text":"rescale(T::TorQuadModule, k::RingElement) -> TorQuadModule\n\nReturn the torsion quadratic module with quadratic form scaled by k, where k is a non-zero rational number. If the old form was defined modulo n, then the new form is defined modulo n k.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Invariants","page":"Discriminant Groups","title":"Invariants","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"is_degenerate(T::TorQuadModule)\nis_semi_regular(T::TorQuadModule)\nradical_bilinear(T::TorQuadModule)\nradical_quadratic(T::TorQuadModule)\nnormal_form(T::TorQuadModule; partial=false)","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#is_degenerate-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"is_degenerate","text":"is_degenerate(T::TorQuadModule) -> Bool\n\nReturn true if the underlying bilinear form is degenerate.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#is_semi_regular-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"is_semi_regular","text":"is_semi_regular(T::TorQuadModule) -> Bool\n\nReturn whether T is semi-regular, that is its quadratic radical is trivial (see radical_quadratic).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#radical_bilinear-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"radical_bilinear","text":"radical_bilinear(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMor\n\nReturn the radical \\{x \\in T | b(x,T) = 0\\} of the bilinear form b on T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#radical_quadratic-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"radical_quadratic","text":"radical_quadratic(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMor\n\nReturn the radical \\{x \\in T | b(x,T) = 0 and q(x)=0\\} of the quadratic form q on T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#normal_form-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"normal_form","text":"normal_form(T::TorQuadModule; partial=false) -> TorQuadModule, TorQuadModuleMor\n\nReturn the normal form N of the given torsion quadratic module T along with the projection T -> N.\n\nLet K be the radical of the quadratic form of T. Then N = T/K is half-regular. Two half-regular torsion quadratic modules are isometric if and only if they have equal normal forms.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Genus","page":"Discriminant Groups","title":"Genus","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"genus(T::TorQuadModule, signature_pair::Tuple{Int, Int})\nbrown_invariant(T::TorQuadModule)\nis_genus(T::TorQuadModule, signature_pair::Tuple{Int, Int})","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#genus-Tuple{TorQuadModule, Tuple{Int64, Int64}}","page":"Discriminant Groups","title":"genus","text":"genus(T::TorQuadModule, signature_pair::Tuple{Int, Int}) -> ZZGenus\n\nReturn the genus of an integer lattice with discriminant group T and the given signature_pair. If no such genus exists, raise an error.\n\nReference\n\nV. V. Nikulin (1979) Corollary 1.9.4 and 1.16.3.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#brown_invariant-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"brown_invariant","text":"brown_invariant(self::TorQuadModule) -> Nemo.zzModRingElem\n\nReturn the Brown invariant of this torsion quadratic form.\n\nLet (D,q) be a torsion quadratic module with values in Q / 2Z. The Brown invariant Br(D,q) in Z/8Z is defined by the equation\n\nexp left( frac2 pi i 8 Br(q)right) =\n frac1sqrtD sum_x in D exp(i pi q(x))\n\nThe Brown invariant is additive with respect to direct sums of torsion quadratic modules.\n\nExamples\n\njulia> L = integer_lattice(gram=matrix(ZZ, [[2,-1,0,0],[-1,2,-1,-1],[0,-1,2,0],[0,-1,0,2]]));\n\njulia> T = Hecke.discriminant_group(L);\n\njulia> brown_invariant(T)\n4\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#is_genus-Tuple{TorQuadModule, Tuple{Int64, Int64}}","page":"Discriminant Groups","title":"is_genus","text":"is_genus(T::TorQuadModule, signature_pair::Tuple{Int, Int}) -> Bool\n\nReturn if there is an integral lattice with this signature and discriminant form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Categorical-constructions","page":"Discriminant Groups","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"direct_sum(x::Vector{TorQuadModule})\ndirect_product(x::Vector{TorQuadModule})\nbiproduct(x::Vector{TorQuadModule})","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#direct_sum-Tuple{Vector{TorQuadModule}}","page":"Discriminant Groups","title":"direct_sum","text":"direct_sum(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}\ndirect_sum(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}\n\nGiven a collection of torsion quadratic modules T_1 ldots T_n, return their direct sum T = T_1oplus ldots oplus T_n, together with the injections T_i to T.\n\nFor objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct product with the projections T to T_i, one should call direct_product(x). If one wants to obtain T as a biproduct with the injections T_i to T and the projections T to T_i, one should call biproduct(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#direct_product-Tuple{Vector{TorQuadModule}}","page":"Discriminant Groups","title":"direct_product","text":"direct_product(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}\ndirect_product(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}\n\nGiven a collection of torsion quadratic modules T_1 ldots T_n, return their direct product T = T_1times ldots times T_n, together with the projections T to T_i.\n\nFor objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct sum with the inctions T_i to T, one should call direct_sum(x). If one wants to obtain T as a biproduct with the injections T_i to T and the projections T to T_i, one should call biproduct(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#biproduct-Tuple{Vector{TorQuadModule}}","page":"Discriminant Groups","title":"biproduct","text":"biproduct(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}, Vector{TorQuadModuleMor}\nbiproduct(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}, Vector{TorQuadModuleMor}\n\nGiven a collection of torsion quadratic modules T_1 ldots T_n, return their biproduct T = T_1oplus ldots oplus T_n, together with the injections T_i to T and the projections T to T_i.\n\nFor objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct sum with the inctions T_i to T, one should call direct_sum(x). If one wants to obtain T as a direct product with the projections T to T_i, one should call direct_product(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#Submodules","page":"Discriminant Groups","title":"Submodules","text":"","category":"section"},{"location":"Hecke/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"submodules(::TorQuadModule)\nstable_submodules(::TorQuadModule, ::Vector{TorQuadModuleMor})","category":"page"},{"location":"Hecke/quad_forms/discriminant_group/#submodules-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"submodules","text":"submodules(T::TorQuadMod; kw...)\n\nReturn the submodules of T as an iterator. Possible keyword arguments to restrict the submodules:\n\norder::Int: only submodules of order order,\nindex::Int: only submodules of index index,\nsubtype::Vector{Int}: only submodules which are isomorphic as an abelian group to abelian_group(subtype),\nquotype::Vector{Int}: only submodules whose quotient are isomorphic as an abelian to abelian_group(quotype).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/discriminant_group/#stable_submodules-Tuple{TorQuadModule, Vector{TorQuadModuleMor}}","page":"Discriminant Groups","title":"stable_submodules","text":"stable_submodules(T::TorQuadMod, act::Vector{TorQuadModuleMor}; kw...)\n\nReturn the submodules of T stable under the endomorphisms in act as an iterator. Possible keyword arguments to restrict the submodules:\n\nquotype::Vector{Int}: only submodules whose quotient are isomorphic as an abelian group to abelian_group(quotype).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/field_interface/#Field-Interface","page":"Field Interface","title":"Field Interface","text":"","category":"section"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"AbstractAlgebra.jl generic code makes use of a standardised set of functions which it expects to be implemented for all fields. Here we document this interface. All libraries which want to make use of the generic capabilities of AbstractAlgebra.jl must supply all of the required functionality for their fields.","category":"page"},{"location":"AbstractAlgebra/field_interface/#Types","page":"Field Interface","title":"Types","text":"","category":"section"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Most fields must supply two types:","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"a type for the parent object (representing the field itself)\na type for elements of that field","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"For example, the generic fraction field type in AbstractAlgebra.jl provides two types in generic/GenericTypes.jl: ","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Generic.FracField{T} for the parent objects\nGeneric.Frac{T} for the actual fractions","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"The parent type must belong to Field and the element type must belong to FieldElem. Of course, the types may belong to these abstract types transitively.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"For parameterised fields, we advise that the types of both the parent objects and element objects to be parameterised by the types of the elements of the base ring.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"There can be variations on this theme: e.g. in some areas of mathematics there is a notion of a coefficient domain, in which case it may make sense to parameterise all types by the type of elements of this coefficient domain. But note that this may have implications for the ad hoc operators one might like to explicitly implement.","category":"page"},{"location":"AbstractAlgebra/field_interface/#FieldElement-type-union","page":"Field Interface","title":"FieldElement type union","text":"","category":"section"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Because of its lack of multiple inheritance, Julia does not allow Julia Base types to belong to FieldElem. To allow us to work equally with AbstractAlgebra and Julia types that represent elements of fields we define a union type FieldElement in src/julia/JuliaTypes.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"So far, in addition to FieldElem the union type FieldElement includes the Julia types Rational and AbstractFloat.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Most of the generic code in AbstractAlgebra makes use of the union type FieldElement instead of FieldElem so that the generic functions also accept the Julia Base field types.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"note: Note\nOne must be careful when defining ad hoc binary operations for field element types. It is often necessary to define separate versions of the functions for FieldElem then for each of the Julia types separately in order to avoid ambiguity warnings.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Note that even though FieldElement is a union type we still have the following inclusion","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"FieldElement <: RingElement","category":"page"},{"location":"AbstractAlgebra/field_interface/#Parent-object-caches","page":"Field Interface","title":"Parent object caches","text":"","category":"section"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"In many cases, it is desirable to have only one object in the system to represent each field. This means that if the same field is constructed twice, elements of the two fields will be compatible as far as arithmetic is concerned.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"In order to facilitate this, global caches of fields are stored in AbstractAlgebra.jl, usually implemented using dictionaries. For example, the Generic.FracField parent objects are looked up in a dictionary FracDict to see if they have been previously defined.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Whether these global caches are provided or not, depends on both mathematical and algorithmic considerations. E.g. in the case of number fields, it isn't desirable to identify all number fields with the same defining polynomial, as they may be considered with distinct embeddings into one another. In other cases, identifying whether two fields are the same may be prohibitively expensive. Generally, it may only make sense algorithmically to identify two fields if they were constructed from identical data.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"If a global cache is provided, it must be optionally possible to construct the parent objects without caching. This is done by passing a boolean value cached to the inner constructor of the parent object. See generic/GenericTypes.jl for examples of how to construct and handle such caches.","category":"page"},{"location":"AbstractAlgebra/field_interface/#Required-functions-for-all-fields","page":"Field Interface","title":"Required functions for all fields","text":"","category":"section"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"In the following, we list all the functions that are required to be provided for fields in AbstractAlgebra.jl or by external libraries wanting to use AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"We give this interface for fictitious types MyParent for the type of the field parent object R and MyElem for the type of the elements of the field.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"note: Note\nGeneric functions in AbstractAlgebra.jl may not rely on the existence of functions that are not documented here. If they do, those functions will only be available for fields that implement that additional functionality, and should be documented as such.","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"In the first place, all fields are rings and therefore any field type must implement all of the Ring interface. The functionality below is in addition to this basic functionality.","category":"page"},{"location":"AbstractAlgebra/field_interface/#Data-type-and-parent-object-methods","page":"Field Interface","title":"Data type and parent object methods","text":"","category":"section"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"characteristic(R::MyParent)","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Return the characteristic of the field. If the characteristic is not known, an exception is raised.","category":"page"},{"location":"AbstractAlgebra/field_interface/#Basic-manipulation-of-rings-and-elements","page":"Field Interface","title":"Basic manipulation of rings and elements","text":"","category":"section"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"is_unit(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/field_interface/","page":"Field Interface","title":"Field Interface","text":"Return true if the given element is invertible, i.e. nonzero in the field.","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#Enumeration-of-isometries","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"One of the main features of this project is the enumeration of lattices with isometry of finite order with at most two prime divisors. This is the content of Simon Brandhorst, Tommy Hofmann (2023) which has been implemented. We guide the user here to the global aspects of the available theory, and we refer to the paper Simon Brandhorst, Tommy Hofmann (2023) for further reference.","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#Admissible-triples","page":"Enumeration of isometries","title":"Admissible triples","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"Roughly speaking, for a prime number p, a p-admissible triple (A, B, C) is a triple of integer lattices such that, in certain cases, C can be obtained as a primitive extension A perp B to C where one can glue along p-elementary subgroups of the respective discriminant groups of A and B. Note that not all admissible triples satisfy this extension property.","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"For instance, if f is an isometry of an integer lattice C of prime order p, then for A = ker Phi_1(f) and B = ker Phi_p(f), one has that (A, B, C) is p-admissible (see Lemma 4.15. in Simon Brandhorst, Tommy Hofmann (2023)).","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"We say that a triple (AA, BB, CC) of genus symbols for integer lattices is p-admissible if there are some lattices A in AA, B in BB and C in CC such that (A B C) is p-admissible.","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"We use Definition 4.13. and Algorithm 1 of Simon Brandhorst, Tommy Hofmann (2023) to implement the necessary tools for working with admissible triples. Most of the computations consists of local genus symbol manipulations and combinatorics. The code also relies on enumeration of integer genera with given signatures, determinant and bounded scale valuations for the Jordan components at all the relevant primes (see integer_genera).","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"admissible_triples(::ZZGenus, p::Integer)\nis_admissible_triple(::ZZGenus, ::ZZGenus, ::ZZGenus, ::Integer)","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#admissible_triples-Tuple{ZZGenus, Integer}","page":"Enumeration of isometries","title":"admissible_triples","text":"admissible_triples(C::ZZGenus, p::Integer) -> Vector{Tuple{ZZGenus, ZZGenus}}\n\nGiven a mathbb Z-genus C and a prime number p, return all tuples of mathbb Z-genera (A, B) such that (A, B, C) is p-admissible and B is of rank divisible by p-1.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> g = genus(L)\nGenus symbol for integer lattices\nSignatures: (5, 0, 0)\nLocal symbols:\n Local genus symbol at 2: 1^-4 2^1_7\n Local genus symbol at 3: 1^-4 3^1\n\njulia> admissible_triples(g, 5)\n2-element Vector{Tuple{ZZGenus, ZZGenus}}:\n (Genus symbol: II_(5, 0) 2^-1_3 3^1, Genus symbol: II_(0, 0))\n (Genus symbol: II_(1, 0) 2^1_7 3^1 5^1, Genus symbol: II_(4, 0) 5^1)\n\njulia> admissible_triples(g, 2)\n8-element Vector{Tuple{ZZGenus, ZZGenus}}:\n (Genus symbol: II_(5, 0) 2^-1_3 3^1, Genus symbol: II_(0, 0))\n (Genus symbol: II_(4, 0) 2^2_6 3^1, Genus symbol: II_(1, 0) 2^1_1)\n (Genus symbol: II_(3, 0) 2^-3_1 3^1, Genus symbol: II_(2, 0) 2^2_2)\n (Genus symbol: II_(3, 0) 2^3_3, Genus symbol: II_(2, 0) 2^-2 3^1)\n (Genus symbol: II_(2, 0) 2^-2 3^1, Genus symbol: II_(3, 0) 2^3_3)\n (Genus symbol: II_(2, 0) 2^2_2, Genus symbol: II_(3, 0) 2^-3_1 3^1)\n (Genus symbol: II_(1, 0) 2^1_1, Genus symbol: II_(4, 0) 2^2_6 3^1)\n (Genus symbol: II_(0, 0), Genus symbol: II_(5, 0) 2^-1_3 3^1)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/#is_admissible_triple-Tuple{ZZGenus, ZZGenus, ZZGenus, Integer}","page":"Enumeration of isometries","title":"is_admissible_triple","text":"is_admissible_triple(A::ZZGenus, B::ZZGenus, C::ZZGenus, p::Integer) -> Bool\n\nGiven a triple of mathbb Z-genera (A,B,C) and a prime number p, such that the rank of B is divisible by p-1, return whether (A,B,C) is p-admissible.\n\nExamples\n\nA standard example is the following: let (L f) be a lattice with isometry of prime order p, let F= L^f and C= L_f be respectively the invariant and coinvariant sublattices of (L f). Then, the triple of genera (g(F) g(C) g(L)) is p-admissible.\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> F = invariant_lattice(Lf);\n\njulia> C = coinvariant_lattice(Lf);\n\njulia> is_admissible_triple(genus(F), genus(C), genus(Lf), 5)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"Note that admissible triples are mainly used for enumerating lattices with isometry of a given order and in a given genus.","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#Enumeration-functions","page":"Enumeration of isometries","title":"Enumeration functions","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"We give an overview of the functions implemented for the enumeration of the isometries of integral integer lattices. For more details such as the proof of the algorithms and the theory behind them, we refer to the reference paper Simon Brandhorst, Tommy Hofmann (2023).","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#Global-function","page":"Enumeration of isometries","title":"Global function","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"As we will see later, the algorithms from Simon Brandhorst, Tommy Hofmann (2023) are specialized on the requirement for the input and regular users might not be able to choose between the functions available. We therefore provide a general function which allows one to enumerate lattices with isometry of a given order and in a given genus. The only requirements are to provide a genus symbol, or a lattice from this genus, and the order wanted (as long as the number of distinct prime divisors is at most 2).","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"enumerate_classes_of_lattices_with_isometry(::ZZLat, ::IntegerUnion)","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#enumerate_classes_of_lattices_with_isometry-Tuple{ZZLat, Union{Integer, ZZRingElem}}","page":"Enumeration of isometries","title":"enumerate_classes_of_lattices_with_isometry","text":"enumerate_classes_of_lattices_with_isometry(L::ZZLat, order::IntegerUnion)\n -> Vector{ZZLatWithIsom}\nenumerate_classes_of_lattices_with_isometry(G::ZZGenus, order::IntegerUnion)\n -> Vector{ZZLocalGenus}\n\nGiven an integral integer lattice L, return representatives of isomorphism classes of lattice with isometry (M g) where M is in the genus of L, and g has order order. Alternatively, one can input a given genus symbol G for integral integer lattices as an input - the function first computes a representative of G.\n\nNote that currently we support only orders which admit at most 2 prime divisors.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"As a remark: if n = p^dq^e is the chosen order, with p q prime numbers, the previous function computes first iteratively representatives for all classes with isometry in the given genus of order q^e. Then, the function increases iteratively the order up to p^dq^e.","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#Underlying-machinery","page":"Enumeration of isometries","title":"Underlying machinery","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"Here is a list of the algorithmic machinery provided by Simon Brandhorst, Tommy Hofmann (2023) used previously to enumerate lattices with isometry:","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"representatives_of_hermitian_type(::ZZLatWithIsom, ::Int)\nsplitting_of_hermitian_prime_power(::ZZLatWithIsom, ::Int)\nsplitting_of_prime_power(::ZZLatWithIsom, ::Int, ::Int)\nsplitting_of_pure_mixed_prime_power(::ZZLatWithIsom, ::Int)\nsplitting_of_mixed_prime_power(::ZZLatWithIsom, ::Int, ::Int)","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#representatives_of_hermitian_type-Tuple{ZZLatWithIsom, Int64}","page":"Enumeration of isometries","title":"representatives_of_hermitian_type","text":"representatives_of_hermitian_type(Lf::ZZLatWithIsom, m::Int = 1)\n -> Vector{ZZLatWithIsom}\n\nGiven a lattice with isometry (L f) of hermitian type (i.e. the minimal polynomial of f is irreducible cyclotomic) and a positive integer m, return a set of representatives of isomorphism classes of lattices with isometry of hermitian type (M g) and such that the type of (B g^m) is equal to the type of (L f). Note that in this case, the isometries g's are of order nm.\n\nExamples\n\njulia> L = root_lattice(:A,2);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> reps = representatives_of_hermitian_type(Lf, 6)\n1-element Vector{ZZLatWithIsom}:\n Integer lattice with isometry of finite order 6\n\njulia> is_of_hermitian_type(reps[1])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/#splitting_of_hermitian_prime_power-Tuple{ZZLatWithIsom, Int64}","page":"Enumeration of isometries","title":"splitting_of_hermitian_prime_power","text":"splitting_of_hermitian_prime_power(Lf::ZZLatWithIsom, p::Int) -> Vector{ZZLatWithIsom}\n\nGiven a lattice with isometry (L f) of hermitian type with f of order q^e for some prime number q, and given another prime number p neq q, return a set of representatives of the isomorphism classes of lattices with isometry (M g) such that the type of (M g^p) is equal to the type of (L f).\n\nNote that e can be 0.\n\nExamples\n\njulia> L = root_lattice(:A,2);\n\njulia> f = matrix(QQ, 2, 2, [0 1; -1 -1]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> is_of_hermitian_type(Lf)\ntrue\n\njulia> reps = splitting_of_hermitian_prime_power(Lf, 2)\n2-element Vector{ZZLatWithIsom}:\n Integer lattice with isometry of finite order 6\n Integer lattice with isometry of finite order 3\n\njulia> all(is_of_hermitian_type, reps)\ntrue\n\njulia> is_of_same_type(Lf, reps[1]^2)\ntrue\n\njulia> is_of_same_type(Lf, reps[2]^2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/#splitting_of_prime_power-Tuple{ZZLatWithIsom, Int64, Int64}","page":"Enumeration of isometries","title":"splitting_of_prime_power","text":"splitting_of_prime_power(Lf::ZZLatWithIsom, p::Int, b::Int = 0)\n -> Vector{ZZLatWithIsom}\n\nGiven a lattice with isometry (L f) with f of order q^e for some prime number q, a prime number p neq q and an integer b = 0 1, return a set of representatives of the isomorphism classes of lattices with isometry (M g) such that the type of (M g^p) is equal to the type of (L f).\n\nIf b == 1, return only the lattices with isometry (M g) where g is of order pq^e.\n\nNote that e can be 0.\n\nExamples\n\njulia> L = root_lattice(:A,2);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> splitting_of_prime_power(Lf, 2)\n4-element Vector{ZZLatWithIsom}:\n Integer lattice with isometry of finite order 2\n Integer lattice with isometry of finite order 2\n Integer lattice with isometry of finite order 2\n Integer lattice with isometry of finite order 1\n\njulia> splitting_of_prime_power(Lf, 3, 1)\n1-element Vector{ZZLatWithIsom}:\n Integer lattice with isometry of finite order 3\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/#splitting_of_pure_mixed_prime_power-Tuple{ZZLatWithIsom, Int64}","page":"Enumeration of isometries","title":"splitting_of_pure_mixed_prime_power","text":"splitting_of_pure_mixed_prime_power(Lf::ZZLatWithIsom, p::Int)\n -> Vector{ZZLatWithIsom}\n\nGiven a lattice with isometry (L f) and a prime number p, such that prod_i=0^ePhi_p^dq^i(f) is trivial for some d 0 and e geq 0, return a set of representatives of the isomorphism classes of lattices with isometry (M g) such that the type of (M g^p) is equal to the type of (L f).\n\nNote that e can be 0, while d has to be positive.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/#splitting_of_mixed_prime_power-Tuple{ZZLatWithIsom, Int64, Int64}","page":"Enumeration of isometries","title":"splitting_of_mixed_prime_power","text":"splitting_of_mixed_prime_power(Lf::ZZLatWithIsom, p::Int, b::Int = 1)\n -> Vector{ZZLatWithIsom}\n\nGiven a lattice with isometry (L f) and a prime number p such that f is of order p^dq^e for some prime number q neq p, return a set of representatives of the isomorphism classes of lattices with isometry (M g) such that the type of (M g^p) is equal to the type of (L f).\n\nIf b == 1, return only the lattices with isometry (M g) where g is of order p^d+1q^e. \n\nNote that d and e can be both zero.\n\nExamples\n\njulia> L = root_lattice(:E,7);\n\njulia> f = matrix(QQ, 7, 7, [ 1 1 2 1 0 0 1;\n -1 -2 -3 -2 -1 -1 -1;\n 0 1 2 1 1 1 1;\n 0 0 -1 -1 -1 -1 -1;\n 1 1 2 2 2 1 1;\n 0 0 -1 -1 -1 0 0;\n 0 0 0 1 0 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 7 and degree 7\n with isometry of finite order 6\n given by\n [ 1 1 2 1 0 0 1]\n [-1 -2 -3 -2 -1 -1 -1]\n [ 0 1 2 1 1 1 1]\n [ 0 0 -1 -1 -1 -1 -1]\n [ 1 1 2 2 2 1 1]\n [ 0 0 -1 -1 -1 0 0]\n [ 0 0 0 1 0 0 0]\n\njulia> reps = splitting_of_mixed_prime_power(Lf, 2)\n2-element Vector{ZZLatWithIsom}:\n Integer lattice with isometry of finite order 12\n Integer lattice with isometry of finite order 12\n\njulia> all(LL -> is_of_same_type(Lf, LL^2), reps)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"Note that an important feature from the theory in Simon Brandhorst, Tommy Hofmann (2023) is the notion of admissible gluings and equivariant primitive embeddings for admissible triples. In the next chapter, we present the methods regarding Nikulins's theory on primitive embeddings and their equivariant version. We use this basis to introduce the method admissible_equivariant_primitive_extension (Algorithm 2 in Simon Brandhorst, Tommy Hofmann (2023)) which is the major tool making the previous enumeration possible and fast, from an algorithmic point of view.","category":"page"},{"location":"Groups/products/","page":"Products of groups","title":"Products of groups","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/products/#Products-of-groups","page":"Products of groups","title":"Products of groups","text":"","category":"section"},{"location":"Groups/products/#Direct-products","page":"Products of groups","title":"Direct products","text":"","category":"section"},{"location":"Groups/products/","page":"Products of groups","title":"Products of groups","text":"DirectProductGroup\ndirect_product(L::AbstractVector{<:GAPGroup}; morphisms=false)\ninner_direct_product(L::AbstractVector{T}; morphisms=false) where T<:Union{PcGroup,FPGroup}\nnumber_of_factors(G::DirectProductGroup)\ncartesian_power(G::GAPGroup, n::Int)\ninner_cartesian_power(G::T, n::Int; morphisms=false) where T<: GAPGroup\nfactor_of_direct_product(G::DirectProductGroup, j::Int)\nas_perm_group(G::DirectProductGroup)\nas_polycyclic_group(G::DirectProductGroup)\nembedding(G::DirectProductGroup, j::Int)\nprojection(G::DirectProductGroup, j::Int)\nwrite_as_full(G::DirectProductGroup)\nis_full_direct_product(G::DirectProductGroup)","category":"page"},{"location":"Groups/products/#DirectProductGroup","page":"Products of groups","title":"DirectProductGroup","text":"DirectProductGroup\n\nEither direct product of two or more groups of any type, or subgroup of a direct product of groups.\n\n\n\n\n\n","category":"type"},{"location":"Groups/products/#direct_product-Tuple{AbstractVector{<:Oscar.GAPGroup}}","page":"Products of groups","title":"direct_product","text":"direct_product(L::AbstractVector{<:GAPGroup}; morphisms)\ndirect_product(L::GAPGroup...)\n\nReturn the direct product of the groups in the collection L.\n\nThe keyword argument morphisms is false by default. If it is set true, then the output is a triple (G, emb, proj), where emb and proj are the vectors of the embeddings (resp. projections) of the direct product G.\n\nExamples\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> K = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> G = direct_product(H,K)\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\n\njulia> elements(G)\n12-element Vector{Oscar.BasicGAPGroupElem{DirectProductGroup}}:\n ()\n (4,5)\n (2,3)\n (2,3)(4,5)\n (1,2)\n (1,2)(4,5)\n (1,2,3)\n (1,2,3)(4,5)\n (1,3,2)\n (1,3,2)(4,5)\n (1,3)\n (1,3)(4,5)\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#inner_direct_product-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:Union{FPGroup, PcGroup}","page":"Products of groups","title":"inner_direct_product","text":"inner_direct_product(L::AbstractVector{T}; morphisms)\ninner_direct_product(L::T...)\n\nReturn a direct product of groups of the same type T as a group of type T. It works for T of the following types:\n\nPermGroup, PcGroup, FPGroup.\n\nThe keyword argument morphisms is false by default. If it is set true, then the output is a triple (G, emb, proj), where emb and proj are the vectors of the embeddings (resp. projections) of the direct product G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#number_of_factors-Tuple{DirectProductGroup}","page":"Products of groups","title":"number_of_factors","text":"number_of_factors(G::DirectProductGroup)\n\nReturn the number of factors of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#cartesian_power-Tuple{Oscar.GAPGroup, Int64}","page":"Products of groups","title":"cartesian_power","text":"cartesian_power(G::GAPGroup, n::Int)\n\nReturn the direct product of n copies of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#inner_cartesian_power-Union{Tuple{T}, Tuple{T, Int64}} where T<:Oscar.GAPGroup","page":"Products of groups","title":"inner_cartesian_power","text":"inner_cartesian_power(G::T, n::Int; morphisms)\n\nReturn the direct product of n copies of G as group of type T.\n\nThe keyword argument morphisms is false by default. If it is set true, then the output is a triple (G, emb, proj), where emb and proj are the vectors of the embeddings (resp. projections) of the direct product G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#factor_of_direct_product-Tuple{DirectProductGroup, Int64}","page":"Products of groups","title":"factor_of_direct_product","text":"factor_of_direct_product(G::DirectProductGroup, j::Int)\n\nReturn the j-th factor of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#as_perm_group-Tuple{DirectProductGroup}","page":"Products of groups","title":"as_perm_group","text":"as_perm_group(G::DirectProductGroup)\n\nIf G is direct product of permutations groups, return G as permutation group.\n\nExamples\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> K = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> G = direct_product(H,K)\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\n\njulia> as_perm_group(G)\nGroup([ (1,2,3), (1,2), (4,5) ])\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#as_polycyclic_group-Tuple{DirectProductGroup}","page":"Products of groups","title":"as_polycyclic_group","text":"as_polycyclic_group(G::DirectProductGroup)\n\nIf G is direct product of polycyclic groups, return G as polycyclic group.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#embedding-Tuple{DirectProductGroup, Int64}","page":"Products of groups","title":"embedding","text":"embedding(G::DirectProductGroup, j::Int)\n\nReturn the embedding of the j-th component of G into G, for j = 1,...,#factors of G.\n\nExamples\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> K = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> G = direct_product(H,K)\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\n\njulia> emb1 = embedding(G,1)\nGroup homomorphism from\nSym( [ 1 .. 3 ] )\nto\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\n\njulia> h = perm(H,[2,3,1])\n(1,2,3)\n\njulia> emb1(h)\n(1,2,3)\n\njulia> emb2 = embedding(G,2)\nGroup homomorphism from\nSym( [ 1 .. 2 ] )\nto\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\n\njulia> k = perm(K,[2,1])\n(1,2)\n\njulia> emb2(k)\n(4,5)\n\njulia> emb1(h)*emb2(k)\n(1,2,3)(4,5)\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#projection-Tuple{DirectProductGroup, Int64}","page":"Products of groups","title":"projection","text":"projection(G::DirectProductGroup, j::Int)\n\nReturn the projection of G into the j-th component of G, for j = 1,...,#factors of G.\n\nExamples\n\njulia> H = symmetric_group(3)\nSym( [ 1 .. 3 ] )\n\njulia> K = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> G = direct_product(H,K)\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\n\njulia> proj1 = projection(G,1)\nGroup homomorphism from\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\nto\nSym( [ 1 .. 3 ] )\n\njulia> proj2 = projection(G,2)\nGroup homomorphism from\nDirectProduct of\n Sym( [ 1 .. 3 ] )\n Sym( [ 1 .. 2 ] )\nto\nSym( [ 1 .. 2 ] )\n\njulia> g = perm([2,3,1,5,4])\n(1,2,3)(4,5)\n\njulia> proj1(g)\n(1,2,3)\n\njulia> proj2(g)\n(1,2)\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#write_as_full-Tuple{DirectProductGroup}","page":"Products of groups","title":"write_as_full","text":"write_as_full(G::DirectProductGroup)\n\nIf G is a subgroup of the direct product G_1 times G_2 times cdots times G_n such that G has the form H_1 times H_2 times cdots times H_n, for subgroups H_i of G_i, return this full direct product of the H_i.\n\nAn exception is thrown if such H_i do not exist.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#is_full_direct_product-Tuple{DirectProductGroup}","page":"Products of groups","title":"is_full_direct_product","text":"is_full_direct_product(G::DirectProductGroup)\n\nReturn whether G is direct product of its factors (false if it is a proper subgroup).\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#Semidirect-products","page":"Products of groups","title":"Semidirect products","text":"","category":"section"},{"location":"Groups/products/","page":"Products of groups","title":"Products of groups","text":"SemidirectProductGroup{S<:GAPGroup, T<:GAPGroup}\nsemidirect_product(N::S, f::GAPGroupHomomorphism{T,AutomorphismGroup{S}}, H::T) where S <: GAPGroup where T <: GAPGroup\nnormal_subgroup(G::SemidirectProductGroup)\nacting_subgroup(G::SemidirectProductGroup)\nhomomorphism_of_semidirect_product(G::SemidirectProductGroup)\nis_full_semidirect_product(G::SemidirectProductGroup)\nembedding(G::SemidirectProductGroup, n::Int)\nprojection(G::SemidirectProductGroup)","category":"page"},{"location":"Groups/products/#SemidirectProductGroup","page":"Products of groups","title":"SemidirectProductGroup","text":"SemidirectProductGroup{S,T}\n\nSemidirect product of two groups of type S and T respectively, or subgroup of a semidirect product of groups.\n\n\n\n\n\n","category":"type"},{"location":"Groups/products/#semidirect_product-Union{Tuple{S}, Tuple{T}, Tuple{S, GAPGroupHomomorphism{T, AutomorphismGroup{S}}, T}} where {T<:Oscar.GAPGroup, S<:Oscar.GAPGroup}","page":"Products of groups","title":"semidirect_product","text":"semidirect_product(N::S, f::GAPGroupHomomorphism, H::T)\n\nReturn the semidirect product of N and H, of type SemidirectProductGroup{S,T}, where f is a group homomorphism from H to the automorphism group of N.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#normal_subgroup-Tuple{SemidirectProductGroup}","page":"Products of groups","title":"normal_subgroup","text":"normal_subgroup(G::SemidirectProductGroup)\n\nReturn N, where G is the semidirect product of the normal subgroup N and H.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#acting_subgroup-Tuple{SemidirectProductGroup}","page":"Products of groups","title":"acting_subgroup","text":"acting_subgroup(G::SemidirectProductGroup)\n\nReturn H, where G is the semidirect product of the normal subgroup N and H.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#homomorphism_of_semidirect_product-Tuple{SemidirectProductGroup}","page":"Products of groups","title":"homomorphism_of_semidirect_product","text":"homomorphism_of_semidirect_product(G::SemidirectProductGroup)\n\nReturn f, where G is the semidirect product of the normal subgroup N and the group H acting on N via the homomorphism h.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#is_full_semidirect_product-Tuple{SemidirectProductGroup}","page":"Products of groups","title":"is_full_semidirect_product","text":"is_full_semidirect_product(G::SemidirectProductGroup)\n\nReturn whether G is a semidirect product of two groups, instead of a proper subgroup.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#embedding-Tuple{SemidirectProductGroup, Int64}","page":"Products of groups","title":"embedding","text":"embedding(G::SemidirectProductGroup, n::Int)\n\nReturn the embedding of the n-th component of G into G, for n = 1,2. It is not defined for proper subgroups of semidirect products.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#projection-Tuple{SemidirectProductGroup}","page":"Products of groups","title":"projection","text":"projection(G::SemidirectProductGroup)\n\nReturn the projection of G into the second component of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#Wreath-products","page":"Products of groups","title":"Wreath products","text":"","category":"section"},{"location":"Groups/products/","page":"Products of groups","title":"Products of groups","text":"WreathProductGroup\nwreath_product(G::T, H::PermGroup) where T<: GAPGroup\nnormal_subgroup(W::WreathProductGroup)\nacting_subgroup(W::WreathProductGroup)\nhomomorphism_of_wreath_product(G::WreathProductGroup)\nis_full_wreath_product(G::WreathProductGroup)\nprojection(W::WreathProductGroup)\nembedding(W::WreathProductGroup, n::Int)","category":"page"},{"location":"Groups/products/#WreathProductGroup","page":"Products of groups","title":"WreathProductGroup","text":"WreathProductGroup\n\nWreath product of a group G and a group of permutations H, or a generic group H together with the homomorphism a from H to a permutation group.\n\n\n\n\n\n","category":"type"},{"location":"Groups/products/#wreath_product-Union{Tuple{T}, Tuple{T, PermGroup}} where T<:Oscar.GAPGroup","page":"Products of groups","title":"wreath_product","text":"wreath_product(G::T, H::S, a::GAPGroupHomomorphism{S,PermGroup})\nwreath_product(G::T, H::PermGroup) where T<: Group\n\nReturn the wreath product of the group G and the group H, where H acts on n copies of G through the homomorphism a from H to a permutation group, and n is the number of moved points of Image(a).\n\nIf a is not specified, then H must be a group of permutations. In this case, n is NOT the number of moved points, but the degree of H.\n\nIf W is a wreath product of G and H, {g_1, ..., g_n} are elements of G and h in H, the element (g_1, ..., h) of W can be obtained by typing\n\n W(g_1,...,g_n, h).\n\nExamples\n\njulia> G = cyclic_group(3)\n\n\njulia> H = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> W = wreath_product(G,H)\n\n\njulia> a = gen(W,1)\nWreathProductElement(f1, of ...,())\n\njulia> b = gen(W,2)\nWreathProductElement( of ..., of ...,(1,2))\n\njulia> a*b\nWreathProductElement(f1, of ...,(1,2))\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#normal_subgroup-Tuple{WreathProductGroup}","page":"Products of groups","title":"normal_subgroup","text":"normal_subgroup(W::WreathProductGroup)\n\nReturn G, where W is the wreath product of G and H.\n\nExamples\n\njulia> G = cyclic_group(3)\n\n\njulia> H = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> W = wreath_product(G,H)\n\n\njulia> normal_subgroup(W)\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#acting_subgroup-Tuple{WreathProductGroup}","page":"Products of groups","title":"acting_subgroup","text":"acting_subgroup(W::WreathProductGroup)\n\nReturn H, where W is the wreath product of G and H.\n\nExamples\n\njulia> G = cyclic_group(3)\n\n\njulia> H = symmetric_group(2)\nSym( [ 1 .. 2 ] )\n\njulia> W = wreath_product(G,H)\n\n\njulia> acting_subgroup(W)\nSym( [ 1 .. 2 ] )\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#homomorphism_of_wreath_product-Tuple{WreathProductGroup}","page":"Products of groups","title":"homomorphism_of_wreath_product","text":"homomorphism_of_wreath_product(G::WreathProductGroup)\n\nIf W is the wreath product of G and H, then return the homomorphism f from H to Sym(n), where n is the number of copies of G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#is_full_wreath_product-Tuple{WreathProductGroup}","page":"Products of groups","title":"is_full_wreath_product","text":"is_full_wreath_product(G::WreathProductGroup)\n\nReturn whether G is a wreath product of two groups, instead of a proper subgroup.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#projection-Tuple{WreathProductGroup}","page":"Products of groups","title":"projection","text":"projection(G::WreathProductGroup)\n\nReturn the projection of wreath_product(G,H) onto the permutation group H.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#embedding-Tuple{WreathProductGroup, Int64}","page":"Products of groups","title":"embedding","text":"embedding(G::WreathProductGroup, n::Int)\n\nReturn the embedding of the n-th component of G into G.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/fraction_interface/#Fraction-Field-Interface","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"","category":"section"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Fraction fields are supported in AbstractAlgebra.jl, at least for gcd domains. In addition to the standard Ring interface, some additional functions are required to be present for fraction fields.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/#Types-and-parents","page":"Fraction Field Interface","title":"Types and parents","text":"","category":"section"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"AbstractAlgebra provides two abstract types for fraction fields and their elements:","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"FracField{T} is the abstract type for fraction field parent types\nFracElem{T} is the abstract type for types of fractions","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"We have that FracField{T} <: Field and FracElem{T} <: FieldElem.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Note that both abstract types are parameterised. The type T should usually be the type of elements of the base ring of the fraction field.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Fraction fields should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Fraction fields should at least be distinguished based on their base ring.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).","category":"page"},{"location":"AbstractAlgebra/fraction_interface/#Required-functionality-for-fraction-fields","page":"Fraction Field Interface","title":"Required functionality for fraction fields","text":"","category":"section"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"In addition to the required functionality for the Field interface the Fraction Field interface has the following required functions.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"We suppose that R is a fictitious base ring, and that S is the fraction field with parent object S of type MyFracField{T}. We also assume the fractions in the field have type MyFrac{T}, where T is the type of elements of the base ring.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Note that the type T must (transitively) belong to the abstract type RingElem.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/#Constructors","page":"Fraction Field Interface","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"The following constructors create fractions. Note that these constructors don't require construction of the parent object first. This is easier to achieve if the fraction element type doesn't contain a reference to the parent object, but merely contains a reference to the base ring. The parent object can then be constructed on demand.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"//(x::T, y::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Return the fraction xy.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"//(x::T, y::FracElem{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Return xy where x is in the base ring of y.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"//(x::FracElem{T}, y::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Return xy where y is in the base ring of x.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/#Basic-manipulation-of-fields-and-elements","page":"Fraction Field Interface","title":"Basic manipulation of fields and elements","text":"","category":"section"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"numerator(d::MyFrac{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Given a fraction d = ab return a, where ab is in lowest terms with respect to the canonical_unit and gcd functions on the base ring.","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"denominator(d::MyFrac{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/fraction_interface/","page":"Fraction Field Interface","title":"Fraction Field Interface","text":"Given a fraction d = ab return b, where ab is in lowest terms with respect to the canonical_unit and gcd functions on the base ring.","category":"page"},{"location":"AbstractAlgebra/interface_introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AbstractAlgebra/interface_introduction/","page":"Introduction","title":"Introduction","text":"AbstractAlgebra defines a series of interfaces that can be extended with new types that implement those interfaces. For example, if one were implementing a new polynomial ring type, one would implement all of the required functionality described in this chapter for the relevant AbstractAlgebra interfaces. This would include the Ring Interface and the Univariate Polynomial Ring Interface.","category":"page"},{"location":"AbstractAlgebra/interface_introduction/","page":"Introduction","title":"Introduction","text":"Once a new type implements all the required functionality, all the corresponding generic functionality would then function automatically for the new type.","category":"page"},{"location":"AbstractAlgebra/interface_introduction/","page":"Introduction","title":"Introduction","text":"One may then go on to implement some of the optional functionality for performance if the provided generic functionality is insufficient.","category":"page"},{"location":"AbstractAlgebra/interface_introduction/","page":"Introduction","title":"Introduction","text":"AbstractAlgebra tries to provide all generic constructions recursively so that one can have towers of generic constructions. This means that new interfaces should generally only be added if they cooperate with all the existing interfaces, at least so far as the theory exists to do so.","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/","page":"Some Special Ideals","title":"Some Special Ideals","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/#Some-Special-Ideals","page":"Some Special Ideals","title":"Some Special Ideals","text":"","category":"section"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/","page":"Some Special Ideals","title":"Some Special Ideals","text":"This page is still in its development stage. Currently, it only contains the function below:","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/#Grassmann-Plücker-Ideal","page":"Some Special Ideals","title":"Grassmann Plücker Ideal","text":"","category":"section"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/","page":"Some Special Ideals","title":"Some Special Ideals","text":"grassmann_pluecker_ideal","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/#grassmann_pluecker_ideal","page":"Some Special Ideals","title":"grassmann_pluecker_ideal","text":"grassmann_pluecker_ideal([ring::MPolyRing,] subspace_dimension::Int, ambient_dimension::Int)\n\nGiven a ring, an ambient dimension and a subspace dimension return the ideal in the given ring generated by the Plücker relations. If the ring is not specified return the ideal in a multivariate polynomial ring over the rationals.\n\nThe Grassmann-Plücker ideal is the homogeneous ideal generated by the relations defined by the Plücker Embedding of the Grassmannian. That is given Gr(k n) the Moduli space of all k-dimensional subspaces of an n-dimensional vector space, the relations are given by all d times d minors of a d times n matrix. For the algorithm see Bernd Sturmfels (1993).\n\nExamples\n\njulia> grassmann_pluecker_ideal(2, 4)\nideal(x[1]*x[6] - x[2]*x[5] + x[3]*x[4])\n\njulia> R, x = polynomial_ring(residue_ring(ZZ, 7), \"x\" => (1:2, 1:3), ordering=:degrevlex)\n(Multivariate polynomial ring in 6 variables over ZZ/(7), zzModMPolyRingElem[x[1, 1] x[1, 2] x[1, 3]; x[2, 1] x[2, 2] x[2, 3]])\n\njulia> grassmann_pluecker_ideal(R, 2, 4)\nideal(x[1, 2]*x[2, 2] + 6*x[2, 1]*x[1, 3] + x[1, 1]*x[2, 3])\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/#Contact","page":"Some Special Ideals","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/","page":"Some Special Ideals","title":"Some Special Ideals","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/","page":"Some Special Ideals","title":"Some Special Ideals","text":"Wolfram Decker.","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/","page":"Some Special Ideals","title":"Some Special Ideals","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/","page":"Some Special Ideals","title":"Some Special Ideals","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Hecke/orders/orders/#Orders","page":"Orders","title":"Orders","text":"","category":"section"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"Orders, that is, unitary subrings that are free mathbfZ-modules of rank equal to the degree of the number field, are at the core of the arithmetic of number fields. In Hecke, orders are always represented using the module structure, be it the mathbfZ-module structure for orders of absolute numbers fields, or the structure as a module over the maximal order of the base field in the case of relative number fields. In this chapter we mainly deal with orders of absolute fields. However, many functions apply in same way to relative extensions. There are more general definitions of orders in number fields available, but those are (currently) not implemented in Hecke.","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"Among all orders in a fixed field, there is a unique maximal order, called the maximal order, or ring of integers of the number field. It is well known that this is the only order that is a Dedekind domain, hence has a rich ideal structure as well. The maximal order is also the integral closure of mathbfZ in the number field and can also be interpreted as a normalization of any other order.","category":"page"},{"location":"Hecke/orders/orders/#Creation-and-basic-properties","page":"Orders","title":"Creation and basic properties","text":"","category":"section"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"Order(::AnticNumberField, ::Vector{nf_elem})\nOrder(::AnticNumberField, ::FakeFmpqMat)\nOrder(::NfOrdFracIdl)\nEquationOrder(::AnticNumberField)\nMaximalOrder(::AnticNumberField)\nMaximalOrder(::NfOrd)\nlll(::NfOrd)\nany_order(K::AnticNumberField)","category":"page"},{"location":"Hecke/orders/orders/#Order-Tuple{AnticNumberField, Vector{nf_elem}}","page":"Orders","title":"Order","text":"Order(a::Vector{nf_elem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> NfOrd\nOrder(K::AnticNumberField, a::Vector{nf_elem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> NfOrd\n\nReturns the order generated by a. If check is set, it is checked whether a defines an order, in particular the integrality of the elements is checked by computing minimal polynomials. If isbasis is set, then elements are assumed to form a mathbfZ-basis. If cached is set, then the constructed order is cached for future use.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#Order-Tuple{AnticNumberField, FakeFmpqMat}","page":"Orders","title":"Order","text":"Order(K::AnticNumberField, A::FakeFmpqMat; check::Bool = true) -> NfOrd\n\nReturns the order which has basis matrix A with respect to the power basis of K. If check is set, it is checked whether A defines an order.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#Order-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Orders","title":"Order","text":"Order(K::AnticNumberField, A::ZZMatrix, check::Bool = true) -> NfOrd\n\nReturns the order which has basis matrix A with respect to the power basis of K. If check is set, it is checked whether A defines an order.\n\n\n\n\n\nOrder(A::AbsAlgAss{<: NumFieldElem}, M::PMat{<: NumFieldElem, T})\n -> AlgAssRelOrd\n\nReturns the order of A with basis pseudo-matrix M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#EquationOrder-Tuple{AnticNumberField}","page":"Orders","title":"EquationOrder","text":"EquationOrder(K::number_field) -> NumFieldOrd\nequation_order(K::number_field) -> NumFieldOrd\n\nReturns the equation order of the number field K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#MaximalOrder-Tuple{AnticNumberField}","page":"Orders","title":"MaximalOrder","text":"MaximalOrder(K::NumField{QQFieldElem}; discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> NfAbsOrd\n\nReturns the maximal order of K. Additional information can be supplied if they are already known, as the ramified primes or the discriminant of the maximal order.\n\nExample\n\njulia> Qx, x = FlintQQ[\"x\"];\njulia> K, a = number_field(x^3 + 2, \"a\");\njulia> O = MaximalOrder(K);\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#MaximalOrder-Tuple{NfOrd}","page":"Orders","title":"MaximalOrder","text":"MaximalOrder(O::NfAbsOrd; index_divisors::Vector{ZZRingElem}, discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> NfAbsOrd\n\nReturns the maximal order of the number field that contains O. Additional information can be supplied if they are already known, as the ramified primes, the discriminant of the maximal order or a set of integers dividing the index of O in the maximal order.\n\n\n\n\n\nMaximalOrder(O::AlgAssAbsOrd)\n\nGiven an order O, this function returns a maximal order containing O.\n\n\n\n\n\nMaximalOrder(A::AbsAlgAss{QQFieldElem}) -> AlgAssAbsOrd\n\nReturns a maximal order of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#lll-Tuple{NfOrd}","page":"Orders","title":"lll","text":"lll(M::NfAbsOrd) -> NfAbsOrd\n\nThe same order, but with the basis now being LLL reduced wrt. the Minkowski metric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#any_order-Tuple{AnticNumberField}","page":"Orders","title":"any_order","text":"any_order(K::number_field)\n\nReturn some order in K. In case the defining polynomial for K is monic and integral, this just returns the equation order. In the other case mathbb Zalphacap mathbb Z1alpha is returned.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#Example","page":"Orders","title":"Example","text":"","category":"section"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"using Hecke; # hide\nQx, x = polynomial_ring(FlintQQ, \"x\");\nK, a = number_field(x^2 - 2, \"a\");\nO = EquationOrder(K)","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"parent(::NfOrd)\nsignature(::NfOrd)\nnf(::NfOrd)\nbasis(::NfOrd)\nlll_basis(::NfOrd)\nbasis(::NfOrd, ::AnticNumberField)\npseudo_basis(::NfRelOrd)\nbasis_pmatrix(::NfRelOrd)\nbasis_nf(::NfRelOrd)\ninv_coeff_ideals(::NfRelOrd)\nbasis_matrix(::NfAbsOrd)\nbasis_mat_inv(::NfOrd)\ngen_index(::NfOrd)\nis_index_divisor(::NfOrd, ::ZZRingElem)\nminkowski_matrix(::NfOrd, ::Int)\nin(::nf_elem, ::NfOrd)\nnorm_change_const(::NfOrd)\ntrace_matrix(::NfOrd)\n+(::NfAbsOrd, ::NfAbsOrd)\npoverorder(::NfOrd, ::ZZRingElem)\npoverorders(::NfOrd, ::ZZRingElem)\npmaximal_overorder(::NfOrd, ::ZZRingElem)\npradical(::NfAbsOrd, ::Union{Integer, ZZRingElem})\npradical(::NfRelOrd, ::Union{Hecke.NfRelOrdIdl, NfOrdIdl})\nring_of_multipliers(::NfAbsOrdIdl)\n","category":"page"},{"location":"Hecke/orders/orders/#parent-Tuple{NfOrd}","page":"Orders","title":"parent","text":"parent(O::NfAbsOrd) -> NfOrdSet\n\nReturns the parent of mathcal O, that is, the set of orders of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#signature-Tuple{NfOrd}","page":"Orders","title":"signature","text":"signature(O::NumFieldOrd) -> Tuple{Int, Int}\n\nReturns the signature of the ambient number field of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#nf-Tuple{NfOrd}","page":"Orders","title":"nf","text":"nf(O::NumFieldOrd) -> NumField\n\nReturns the ambient number field of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#basis-Tuple{NfOrd}","page":"Orders","title":"basis","text":"basis(O::NfAbsOrd) -> Vector{NfAbsOrdElem}\n\nReturns the mathbf Z-basis of mathcal O.\n\n\n\n\n\nbasis(I::NfAbsOrdFracIdl) -> Vector{nf_elem}\n\nReturns the mathbf Z-basis of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#lll_basis-Tuple{NfOrd}","page":"Orders","title":"lll_basis","text":"lll_basis(M::NumFieldOrd) -> Vector{NumFieldElem}\n\nA basis for M that is reduced using the LLL algorithm for the Minkowski metric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#basis-Tuple{NfOrd, AnticNumberField}","page":"Orders","title":"basis","text":"basis(O::NfOrd, K::AnticNumberField) -> Vector{nf_elem}\n\nReturns the mathbf Z-basis elements of mathcal O as elements of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#pseudo_basis-Tuple{Hecke.NfRelOrd}","page":"Orders","title":"pseudo_basis","text":" pseudo_basis(O::NfRelOrd{T, S}) -> Vector{Tuple{NumFieldElem{T}, S}}\n\nReturns the pseudo-basis of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#basis_pmatrix-Tuple{Hecke.NfRelOrd}","page":"Orders","title":"basis_pmatrix","text":" basis_pmatrix(O::NfRelOrd) -> PMat\n\nReturns the basis pseudo-matrix of mathcal O with respect to the power basis of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#basis_nf-Tuple{Hecke.NfRelOrd}","page":"Orders","title":"basis_nf","text":" basis_nf(O::NfRelOrd) -> Vector{NumFieldElem}\n\nReturns the elements of the pseudo-basis of mathcal O as elements of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#inv_coeff_ideals-Tuple{Hecke.NfRelOrd}","page":"Orders","title":"inv_coeff_ideals","text":" inv_coeff_ideals(O::NfRelOrd{T, S}) -> Vector{S}\n\nReturns the inverses of the coefficient ideals of the pseudo basis of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#basis_matrix-Tuple{NfAbsOrd}","page":"Orders","title":"basis_matrix","text":"basis_matrix(O::NfAbsOrd) -> FakeFmpqMat\n\nReturns the basis matrix of mathcal O with respect to the basis of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#basis_mat_inv-Tuple{NfOrd}","page":"Orders","title":"basis_mat_inv","text":"basis_mat_inv(O::NfAbsOrd) -> FakeFmpqMat\n\nReturns the inverse of the basis matrix of mathcal O.\n\n\n\n\n\nbasis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat\n\nReturn the inverse of the basis matrix of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#gen_index-Tuple{NfOrd}","page":"Orders","title":"gen_index","text":"gen_index(O::NfOrd) -> QQFieldElem\n\nReturns the generalized index of mathcal O with respect to the equation order of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#is_index_divisor-Tuple{NfOrd, ZZRingElem}","page":"Orders","title":"is_index_divisor","text":"is_index_divisor(O::NfOrd, d::ZZRingElem) -> Bool\nis_index_divisor(O::NfOrd, d::Int) -> Bool\n\nReturns whether d is a divisor of the index of mathcal O. It is assumed that mathcal O contains the equation order of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#minkowski_matrix-Tuple{NfOrd, Int64}","page":"Orders","title":"minkowski_matrix","text":"minkowski_matrix(O::NfAbsOrd, abs_tol::Int = 64) -> arb_mat\n\nReturns the Minkowski matrix of mathcal O. Thus if mathcal O has degree d, then the result is a matrix in operatornameMat_dtimes d(mathbf R). The entries of the matrix are real balls of type arb with radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#in-Tuple{nf_elem, NfOrd}","page":"Orders","title":"in","text":"in(a::NumFieldElem, O::NumFieldOrd) -> Bool\n\nChecks whether a lies in mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#norm_change_const-Tuple{NfOrd}","page":"Orders","title":"norm_change_const","text":"norm_change_const(O::NfOrd) -> (Float64, Float64)\n\nReturns (c_1 c_2) in mathbf R_0^2 such that for all x = sum_i=1^d x_i omega_i in mathcal O we have T_2(x) leq c_1 cdot sum_i^d x_i^2 and sum_i^d x_i^2 leq c_2 cdot T_2(x), where (omega_i)_i is the mathbf Z-basis of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#trace_matrix-Tuple{NfOrd}","page":"Orders","title":"trace_matrix","text":"trace_matrix(O::NfAbsOrd) -> ZZMatrix\n\nReturns the trace matrix of mathcal O, that is, the matrix (operatornametr_Kmathbf Q(b_i cdot b_j))_1 leq i j leq d.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#+-Tuple{NfAbsOrd, NfAbsOrd}","page":"Orders","title":"+","text":"+(R::NfOrd, S::NfOrd) -> NfOrd\n\nGiven two orders R, S of K, this function returns the smallest order containing both R and S. It is assumed that R, S contain the ambient equation order and have coprime index.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#poverorder-Tuple{NfOrd, ZZRingElem}","page":"Orders","title":"poverorder","text":"poverorder(O::NfOrd, p::ZZRingElem) -> NfOrd\npoverorder(O::NfOrd, p::Integer) -> NfOrd\n\nThis function tries to find an order that is locally larger than mathcal O at the prime p: If p divides the index mathcal O_K mathcal O, this function will return an order R such that v_p( mathcal O_K R) v_p( mathcal O_K mathcal O). Otherwise mathcal O is returned.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#poverorders-Tuple{NfOrd, ZZRingElem}","page":"Orders","title":"poverorders","text":"poverorders(O, p) -> Vector{Ord}\n\nReturns all p-overorders of O, that is all overorders M, such that the index of O in M is a p-power.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#pmaximal_overorder-Tuple{NfOrd, ZZRingElem}","page":"Orders","title":"pmaximal_overorder","text":"pmaximal_overorder(O::NfOrd, p::ZZRingElem) -> NfOrd\npmaximal_overorder(O::NfOrd, p::Integer) -> NfOrd\n\nThis function finds a p-maximal order R containing mathcal O. That is, the index mathcal O_K R is not divisible by p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#pradical-Tuple{NfAbsOrd, Union{Integer, ZZRingElem}}","page":"Orders","title":"pradical","text":"pradical(O::NfOrd, p::{ZZRingElem|Integer}) -> NfAbsOrdIdl\n\nGiven a prime number p, this function returns the p-radical sqrtpmathcal O of mathcal O, which is just x in mathcal O mid exists k in mathbf Z_geq 0 colon x^k in pmathcal O . It is not checked that p is prime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#pradical-Tuple{Hecke.NfRelOrd, Union{Hecke.NfRelOrdIdl, NfOrdIdl}}","page":"Orders","title":"pradical","text":" pradical(O::NfRelOrd, P::NfOrdIdl) -> NfRelOrdIdl\n\nGiven a prime ideal P, this function returns the P-radical sqrtPmathcal O of mathcal O, which is just x in mathcal O mid exists k in mathbf Z_geq 0 colon x^k in Pmathcal O . It is not checked that P is prime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#ring_of_multipliers-Tuple{NfAbsOrdIdl}","page":"Orders","title":"ring_of_multipliers","text":"ring_of_multipliers(I::NfAbsOrdIdl) -> NfAbsOrd\n\nComputes the order (I I), which is the set of all x in K with xI subseteq I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#Invariants","page":"Orders","title":"Invariants","text":"","category":"section"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"discriminant(::NfOrd)\ndiscriminant(::NfAbsOrd)\nreduced_discriminant(::NfOrd)\ndegree(::NfOrd)\nindex(::NfOrd)\ndifferent(::NfOrd)\ncodifferent(::NfOrd)\nis_gorenstein(::NfOrd)\nis_bass(::NfOrd)\nis_equation_order(::NfOrd)\nzeta_log_residue(::NfOrd, ::Float64)\nramified_primes(::NfOrd)","category":"page"},{"location":"Hecke/orders/orders/#discriminant-Tuple{NfOrd}","page":"Orders","title":"discriminant","text":"discriminant(O::NfOrd) -> ZZRingElem\n\nReturns the discriminant of mathcal O.\n\n\n\n\n\ndiscriminant(E::EllCrv) -> FieldElem\n\nReturn the discriminant of E.\n\n\n\n\n\ndiscriminant(C::HypellCrv{T}) -> T\n\nCompute the discriminant of C.\n\n\n\n\n\ndiscriminant(O::AlgssRelOrd)\n\nReturns the discriminant of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#discriminant-Tuple{NfAbsOrd}","page":"Orders","title":"discriminant","text":"discriminant(O::NfOrd) -> ZZRingElem\n\nReturns the discriminant of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#reduced_discriminant-Tuple{NfOrd}","page":"Orders","title":"reduced_discriminant","text":"reduced_discriminant(O::NfOrd) -> ZZRingElem\n\nReturns the reduced discriminant, that is, the largest elementary divisor of the trace matrix of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#degree-Tuple{NfOrd}","page":"Orders","title":"degree","text":"degree(O::NumFieldOrd) -> Int\n\nReturns the degree of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#index-Tuple{NfOrd}","page":"Orders","title":"index","text":"index(O::NfOrd) -> ZZRingElem\n\nAssuming that the order mathcal O contains the equation order mathbf Zalpha of the ambient number field, this function returns the index mathcal O mathbf Z.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#different-Tuple{NfOrd}","page":"Orders","title":"different","text":"different(R::NfAbsOrd) -> NfAbsOrdIdl\n\nThe different ideal of R, that is, the ideal generated by all differents of elements in R. For Gorenstein orders, this is also the inverse ideal of the co-different.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#codifferent-Tuple{NfOrd}","page":"Orders","title":"codifferent","text":"codifferent(R::NfAbsOrd) -> NfOrdIdl\n\nThe codifferent ideal of R, i.e. the trace-dual of R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#is_gorenstein-Tuple{NfOrd}","page":"Orders","title":"is_gorenstein","text":"is_gorenstein(O::NfOrd) -> Bool\n\nReturn whether the order \\mathcal{O} is Gorenstein.\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#is_bass-Tuple{NfOrd}","page":"Orders","title":"is_bass","text":"is_bass(O::NfOrd) -> Bool\n\nReturn whether the order \\mathcal{O} is Bass.\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#is_equation_order-Tuple{NfOrd}","page":"Orders","title":"is_equation_order","text":"is_equation_order(O::NumFieldOrd) -> Bool\n\nReturns whether mathcal O is the equation order of the ambient number field K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#zeta_log_residue-Tuple{NfOrd, Float64}","page":"Orders","title":"zeta_log_residue","text":"zeta_log_residue(O::NfOrd, error::Float64) -> arb\n\nComputes the residue of the zeta function of mathcal O at 1. The output will be an element of type arb with radius less then error.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#ramified_primes-Tuple{NfOrd}","page":"Orders","title":"ramified_primes","text":"ramified_primes(O::NfAbsOrd) -> Vector{ZZRingElem}\n\nReturns the list of prime numbers that divide operatornamedisc(mathcal O).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#Arithmetic","page":"Orders","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"Progress and intermediate results of the functions mentioned here can be obtained via verbose_level, supported are","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"ClassGroup\nUnitGroup","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"All of the functions have a very similar interface: they return an abelian group and a map converting elements of the group into the objects required. The maps also allow a point-wise inverse to server as the discrete logarithm map. For more information on abelian group, see here, for ideals, here.","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"torsion_unit_group(::NfOrd)\nunit_group(::NfOrd)\nunit_group_fac_elem(::NfOrd)\nsunit_group(::Vector{NfOrdIdl})\nsunit_group_fac_elem(::Vector{NfOrdIdl})\nsunit_mod_units_group_fac_elem(::Vector{NfOrdIdl})\nclass_group(::NfOrd)\npicard_group(::NfOrd)\nnarrow_class_group(::NfOrd)","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"For the processing of units, there are a couple of helper functions also available:","category":"page"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"is_independent","category":"page"},{"location":"Hecke/orders/orders/#is_independent","page":"Orders","title":"is_independent","text":"is_independent{T}(x::Vector{T})\n\nGiven an array of non-zero units in a number field, returns whether they are multiplicatively independent.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/orders/orders/#Predicates","page":"Orders","title":"Predicates","text":"","category":"section"},{"location":"Hecke/orders/orders/","page":"Orders","title":"Orders","text":"Hecke.is_contained(::NfAbsOrd, ::NfAbsOrd)\nis_maximal(::NfAbsOrd)","category":"page"},{"location":"Hecke/orders/orders/#is_contained-Tuple{NfAbsOrd, NfAbsOrd}","page":"Orders","title":"is_contained","text":"is_contained(R::NfAbsOrd, S::NfAbsOrd) -> Bool\n\nChecks if R is contained in S.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/orders/#is_maximal-Tuple{NfAbsOrd}","page":"Orders","title":"is_maximal","text":"is_maximal(R::NfAbsOrd) -> Bool\n\nTests if the order R is maximal. This might trigger the computation of the maximal order.\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/permgroup/#Permutation-groups","page":"Permutation groups","title":"Permutation groups","text":"","category":"section"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"Permutation groups can be defined as symmetric groups, alternating groups or their subgroups.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"PermGroup\nPermGroupElem\nsymmetric_group\nis_natural_symmetric_group(G::GAPGroup)\nis_isomorphic_with_symmetric_group(G::GAPGroup)\nalternating_group\nis_natural_alternating_group(G::GAPGroup)\nis_isomorphic_with_alternating_group(G::GAPGroup)\npermutation_group\n@permutation_group\nprojective_general_linear_group\nprojective_special_linear_group\nprojective_symplectic_group\nprojective_orthogonal_group\nprojective_special_orthogonal_group\nprojective_omega_group\nprojective_unitary_group\nprojective_special_unitary_group","category":"page"},{"location":"Groups/permgroup/#PermGroup","page":"Permutation groups","title":"PermGroup","text":"PermGroup\n\nGroups of permutations. Every group of this type is a subgroup of Sym(n) for some n.\n\nExamples\n\nsymmetric_group(n::Int): the symmetric group Sym(n)\nalternating_group(n::Int): the alternating group Alt(n)\nsubgroups of Sym(n)\ndihedral_group(PermGroup, n::Int): the dihedral group of order n as a group of permutations. Same holds replacing dihedral_group by quaternion_group\n\nIf G is a permutation group and x is a permutation, G(x) returns a permutation x with parent G; an exception is thrown if x does not embed into G.\n\njulia> G=symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> x=cperm([1,2,3])\n(1,2,3)\n\njulia> parent(x)\nSym( [ 1 .. 3 ] )\n\njulia> y=G(x)\n(1,2,3)\n\njulia> parent(y)\nSym( [ 1 .. 5 ] )\n\nIf G is a permutation group and x is a vector of integers, G(x) returns a PermGroupElem with parent G; an exception is thrown if the element does not embed into G.\n\nExamples\n\njulia> G = symmetric_group(6)\nSym( [ 1 .. 6 ] )\n\njulia> x = G([2,4,6,1,3,5])\n(1,2,4)(3,6,5)\n\njulia> parent(x)\nSym( [ 1 .. 6 ] )\n\n\n\n\n\n","category":"type"},{"location":"Groups/permgroup/#PermGroupElem","page":"Permutation groups","title":"PermGroupElem","text":"PermGroupElem\n\nElement of a group of permutations. It is displayed as product of disjoint cycles.\n\nAssumptions:\n\nfor x,y in Sym(n), the product xy is read from left to right;\nfor x in Sym(n) and i in {1,...,n}, i^x and x(i) return the image of i under the action of x.\n\n\n\n\n\n","category":"type"},{"location":"Groups/permgroup/#symmetric_group","page":"Permutation groups","title":"symmetric_group","text":"symmetric_group(n::Int)\n\nReturn the full symmetric group on the set {1, 2, ..., n}.\n\nExamples\n\njulia> G = symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> order(G)\n120\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#is_natural_symmetric_group-Tuple{Oscar.GAPGroup}","page":"Permutation groups","title":"is_natural_symmetric_group","text":"is_natural_symmetric_group(G::GAPGroup)\n\nReturn true if G is a permutation group acting as the symmetric group on its moved points, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#is_isomorphic_with_symmetric_group-Tuple{Oscar.GAPGroup}","page":"Permutation groups","title":"is_isomorphic_with_symmetric_group","text":"is_isomorphic_with_symmetric_group(G::GAPGroup)\n\nReturn true if G is isomorphic with a symmetric group, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#alternating_group","page":"Permutation groups","title":"alternating_group","text":"alternating_group(n::Int)\n\nReturn the full alternating group on the set {1, 2, ..., n}..\n\nExamples\n\njulia> G = alternating_group(5)\nAlt( [ 1 .. 5 ] )\n\njulia> order(G)\n60\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#is_natural_alternating_group-Tuple{Oscar.GAPGroup}","page":"Permutation groups","title":"is_natural_alternating_group","text":"is_natural_alternating_group(G::GAPGroup)\n\nReturn true if G is a permutation group acting as the alternating group on its moved points, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#is_isomorphic_with_alternating_group-Tuple{Oscar.GAPGroup}","page":"Permutation groups","title":"is_isomorphic_with_alternating_group","text":"is_isomorphic_with_alternating_group(G::GAPGroup)\n\nReturn true if G is isomorphic with an alternating group, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#permutation_group","page":"Permutation groups","title":"permutation_group","text":"permutation_group(n::IntegerUnion, perms::Vector{PermGroupElem})\n\nReturn the permutation group of degree n that is generated by the elements in perms.\n\nExamples\n\njulia> x = cperm([1,2,3], [4,5]); y = cperm([1,4]);\n\njulia> permutation_group(5, [x, y])\nGroup([ (1,2,3)(4,5), (1,4) ])\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#@permutation_group","page":"Permutation groups","title":"@permutation_group","text":"@permutation_group(n, gens...)\n\nInput the permutation group of degree n with generators gens..., given by permutations in cycle notation.\n\nExamples\n\njulia> g = @permutation_group(7, (1,2), (1,2,3)(4,5))\nGroup([ (1,2), (1,2,3)(4,5) ])\n\njulia> degree(g)\n7\n\n\n\n\n\n","category":"macro"},{"location":"Groups/permgroup/#projective_general_linear_group","page":"Permutation groups","title":"projective_general_linear_group","text":"projective_general_linear_group(n::Int, q::Int)\n\nReturn the factor group of general_linear_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.\n\nExamples\n\njulia> g = projective_general_linear_group(2, 3)\nGroup([ (3,4), (1,2,4) ])\n\njulia> order(g)\n24\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#projective_special_linear_group","page":"Permutation groups","title":"projective_special_linear_group","text":"projective_special_linear_group(n::Int, q::Int)\n\nReturn the factor group of special_linear_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.\n\nExamples\n\njulia> g = projective_special_linear_group(2, 3)\nGroup([ (2,3,4), (1,2)(3,4) ])\n\njulia> order(g)\n12\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#projective_symplectic_group","page":"Permutation groups","title":"projective_symplectic_group","text":"projective_symplectic_group(n::Int, q::Int)\n\nReturn the factor group of symplectic_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.\n\nExamples\n\njulia> g = projective_symplectic_group(2, 3)\nGroup([ (2,3,4), (1,2)(3,4) ])\n\njulia> order(g)\n12\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#projective_orthogonal_group","page":"Permutation groups","title":"projective_orthogonal_group","text":"projective_orthogonal_group(e::Int, n::Int, q::Int)\n\nReturn the factor group of orthogonal_group, called with the same parameters, by its scalar matrices.\n\nAs for orthogonal_group, e can be omitted if n is odd.\n\nExamples\n\njulia> g = projective_orthogonal_group(1, 4, 3); order(g)\n576\n\njulia> g = projective_orthogonal_group(3, 3); order(g)\n24\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#projective_special_orthogonal_group","page":"Permutation groups","title":"projective_special_orthogonal_group","text":"projective_special_orthogonal_group(e::Int, n::Int, q::Int)\n\nReturn the factor group of special_orthogonal_group, called with the same parameters, by its scalar matrices.\n\nAs for special_orthogonal_group, e can be omitted if n is odd.\n\nExamples\n\njulia> g = projective_special_orthogonal_group(1, 4, 3); order(g)\n288\n\njulia> g = projective_special_orthogonal_group(3, 3); order(g)\n24\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#projective_omega_group","page":"Permutation groups","title":"projective_omega_group","text":"projective_omega_group(e::Int, n::Int, q::Int)\n\nReturn the factor group of omega_group, called with the same parameters, by its scalar matrices.\n\nAs for omega_group, e can be omitted if n is odd.\n\nExamples\n\njulia> g = projective_omega_group(1, 4, 3); order(g)\n144\n\njulia> g = projective_omega_group(3, 3); order(g)\n12\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#projective_unitary_group","page":"Permutation groups","title":"projective_unitary_group","text":"projective_unitary_group(n::Int, q::Int)\n\nReturn the factor group of unitary_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.\n\nExamples\n\njulia> g = projective_unitary_group(2, 3)\nGroup([ (3,4)(5,8)(6,9)(7,10), (1,2,6)(3,7,10)(4,8,5) ])\n\njulia> order(g)\n24\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#projective_special_unitary_group","page":"Permutation groups","title":"projective_special_unitary_group","text":"projective_special_unitary_group(n::Int, q::Int)\n\nReturn the factor group of special_unitary_group, called with the same parameters, by its scalar matrices. The group is represented as a permutation group.\n\nExamples\n\njulia> g = projective_special_unitary_group(2, 3)\nGroup([ (2,9,6)(3,8,10)(4,7,5), (1,2)(5,10)(6,9)(7,8) ])\n\njulia> order(g)\n12\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"In OSCAR, every permutation group has a degree n, that corresponds to the size of the set on which G acts.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"degree(x::PermGroup)","category":"page"},{"location":"Groups/permgroup/#degree-Tuple{PermGroup}","page":"Permutation groups","title":"degree","text":"degree(G::PermGroup) -> Int\n\nReturn the degree of G as a permutation group, that is, an integer n that is stored in G, with the following meaning.\n\nG embeds into symmetric_group(n).\nTwo permutation groups of different degrees are regarded as not equal, even if they contain the same permutations.\nSubgroups constructed with derived_subgroup, sylow_subgroup, etc., get the same degree as the given group.\nThe range 1:degree(G) is used as the default set of points on which G and its element acts.\n\nnote: Note\nThe degree of a group of permutations is not necessarily equal to the largest moved point of the group G. For example, the trivial subgroup of symmetric_group(n) has degree n even though it fixes n.\n\nExamples\n\njulia> degree(symmetric_group(4))\n4\n\njulia> t4 = trivial_subgroup(symmetric_group(4))[1];\n\njulia> degree(t4)\n4\n\njulia> t4 == trivial_subgroup(symmetric_group(5))[1]\nfalse\n\njulia> show(Vector(gen(symmetric_group(4), 2)))\n[2, 1, 3, 4]\njulia> show(Vector(gen(symmetric_group(5), 2)))\n[2, 1, 3, 4, 5]\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#Permutations","page":"Permutation groups","title":"Permutations","text":"","category":"section"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"Permutations in OSCAR are displayed as products of disjoint cycles, as in GAP. An explicit permutation can be built using the functions perm, cperm, or @perm.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"perm\ncperm\n@perm","category":"page"},{"location":"Groups/permgroup/#perm","page":"Permutation groups","title":"perm","text":"perm(L::AbstractVector{<:IntegerUnion})\n\nReturn the permutation x which maps every i from 1 to n= length(L) to Li. The parent of x is set to symmetric_group(n). An exception is thrown if L does not contain every integer from 1 to n exactly once.\n\nThe parent group of x is set to symmetric_group(n).\n\nExamples\n\njulia> x = perm([2,4,6,1,3,5])\n(1,2,4)(3,6,5)\n\njulia> parent(x)\nSym( [ 1 .. 6 ] )\n\n\n\n\n\nperm(G::PermGroup, L::AbstractVector{<:IntegerUnion})\n(G::PermGroup)(L::AbstractVector{<:IntegerUnion})\n\nReturn the permutation x which maps every i from 1 to n= length(L) to Li. The parent of x is G. An exception is thrown if x is not contained in G or L does not contain every integer from 1 to n exactly once.\n\nExamples\n\njulia> perm(symmetric_group(6),[2,4,6,1,3,5])\n(1,2,4)(3,6,5)\n\nEquivalent permutations can be created using cperm and @perm\n\njulia> x = perm(symmetric_group(8),[2,3,1,5,4,7,8,6])\n(1,2,3)(4,5)(6,7,8)\n\njulia> y = cperm([1,2,3],[4,5],[6,7,8])\n(1,2,3)(4,5)(6,7,8)\n\njulia> x == y\ntrue\n\njulia> z = @perm (1,2,3)(4,5)(6,7,8)\n(1,2,3)(4,5)(6,7,8)\n\njulia> x == z\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#cperm","page":"Permutation groups","title":"cperm","text":"cperm(L::AbstractVector{<:T}...) where T <: IntegerUnion\ncperm(G::PermGroup, L::AbstractVector{<:T}...)\ncperm(L::Vector{Vector{T}}) where T <: IntegerUnion\ncperm(g::PermGroup,L::Vector{Vector{T}}) where T <: IntegerUnion\n\nFor given lists a_1 a_2 ldots a_n b_1 b_2 ldots b_m ldots of positive integers, return the permutation x = (a_1 a_2 ldots a_n) * (b_1 b_2 ldots b_m) * ldots. Arrays of the form [n, n+1, ..., n+k] can be replaced by n:n+k.\n\nThe parent of x is G. If G is not specified then the parent of x is set to symmetric_group(n), where n is the largest integer that occurs in an entry of L.\n\nAn exception is thrown if x is not contained in G or one of the given vectors is empty or contains duplicates.\n\nExamples\n\njulia> cperm([1,2,3],4:7)\n(1,2,3)(4,5,6,7)\n\njulia> cperm([1,2],[2,3])\n(1,3,2)\n\njulia> cperm()\n()\n\njulia> p = cperm([1,2,3],[7])\n(1,2,3)\n\njulia> degree(p)\n7\n\nTwo permutations coincide if, and only if, they move the same points and their parent groups have the same degree.\n\njulia> G=symmetric_group(5);\n\njulia> A=alternating_group(5);\n\njulia> x=cperm(G,[1,2,3]);\n\njulia> y=cperm(A,[1,2,3]);\n\njulia> z=cperm([1,2,3]); parent(z)\nSym( [ 1 .. 3 ] )\n\njulia> x==y\ntrue\n\njulia> x==z\nfalse\n\nIn the example above, x and y are equal because both act on a set of cardinality 5, while x and z are different because x belongs to Sym(5) and z belongs to Sym(3).\n\ncperm can also handle cycles passed in inside of a vector\n\njulia> x = cperm([[1,2],[3,4]])\n(1,2)(3,4)\n\njulia> y = cperm([1,2],[3,4])\n(1,2)(3,4)\n\njulia> x == y\ntrue\n\njulia> G=symmetric_group(5)\nSym( [ 1 .. 5 ] )\n\njulia> x = cperm(G,[[1,2],[3,4]])\n(1,2)(3,4)\n\njulia> parent(x)\nSym( [ 1 .. 5 ] )\n\nEquivalent permutations can be created using perm and @perm:\n\njulia> x = cperm([1,2,3],[4,5],[6,7,8])\n(1,2,3)(4,5)(6,7,8)\n\njulia> y = perm(symmetric_group(8),[2,3,1,5,4,7,8,6])\n(1,2,3)(4,5)(6,7,8)\n\njulia> x == y\ntrue\n\njulia> z = @perm (1,2,3)(4,5)(6,7,8)\n(1,2,3)(4,5)(6,7,8)\n\njulia> x == z\ntrue\n\nAt the moment, the input vectors of the function cperm need not be disjoint.\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#@perm","page":"Permutation groups","title":"@perm","text":"@perm ex\n\nInput a permutation in cycle notation. Supports arbitrary expressions for generating the integer entries of the cycles. The parent group is inferred to be the symmetric group with a degree of the highest integer referenced in the permutation.\n\nThe actual work is done by cperm. Thus, for the time being, cycles which are not disjoint actually are supported.\n\nExamples\n\njulia> x = @perm (1,2,3)(4,5)(factorial(3),7,8)\n(1,2,3)(4,5)(6,7,8)\n\njulia> parent(x)\nSym( [ 1 .. 8 ] )\n\njulia> y = cperm([1,2,3],[4,5],[6,7,8])\n(1,2,3)(4,5)(6,7,8)\n\njulia> x == y\ntrue\n\njulia> z = perm(symmetric_group(8),[2,3,1,5,4,7,8,6])\n(1,2,3)(4,5)(6,7,8)\n\njulia> x == z\ntrue\n\n\n\n\n\n@perm n gens\n\nInput a list of permutations in cycle notation, created as elements of the symmetric group of degree n, i.e., symmetric_group(n), by invoking cperm suitably.\n\nExamples\n\njulia> gens = @perm 14 [\n (1,10)\n (2,11)\n (3,12)\n (4,13)\n (5,14)\n (6,8)\n (7,9)\n (1,2,3,4,5,6,7)(8,9,10,11,12,13,14)\n (1,2)(10,11)\n ]\n9-element Vector{PermGroupElem}:\n (1,10)\n (2,11)\n (3,12)\n (4,13)\n (5,14)\n (6,8)\n (7,9)\n (1,2,3,4,5,6,7)(8,9,10,11,12,13,14)\n (1,2)(10,11)\n \njulia> parent(gens[1])\nSym( [ 1 .. 14 ] )\n\n\n\n\n\n","category":"macro"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"The function Vector{T} works in the opposite way with respect to perm:","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"Vector(x::PermGroupElem, n::Int = x.parent.deg)","category":"page"},{"location":"Groups/permgroup/#Vector","page":"Permutation groups","title":"Vector","text":"Vector{T}(x::PermGroupElem, n::Int = x.parent.deg) where T <: IntegerUnion\nVector(x::PermGroupElem, n::Int = x.parent.deg)\n\nReturn the list of length n that contains x(i) at position i. If not specified, T is set as Int.\n\nExamples\n\njulia> pi = cperm(1:3)\n(1,2,3)\njulia> Vector(pi)\n3-element Vector{Int64}:\n 2\n 3\n 1\njulia> Vector(pi, 2)\n2-element Vector{Int64}:\n 2\n 3\njulia> Vector(pi, 4)\n4-element Vector{Int64}:\n 2\n 3\n 1\n 4\njulia> Vector{ZZRingElem}(pi, 2)\n2-element Vector{ZZRingElem}:\n 2\n 3\n\n\n\n\n\n","category":"type"},{"location":"Groups/permgroup/#Operations-on-permutations","page":"Permutation groups","title":"Operations on permutations","text":"","category":"section"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"sign(g::PermGroupElem)\nisodd(g::PermGroupElem)\niseven(g::PermGroupElem)\ncycle_structure(g::PermGroupElem)","category":"page"},{"location":"Groups/permgroup/#sign-Tuple{PermGroupElem}","page":"Permutation groups","title":"sign","text":"sign(g::PermGroupElem) -> Int\n\nReturn the sign of the permutation g.\n\nThe sign of a permutation g is defined as (-1)^k where k is the number of cycles of g of even length.\n\nExamples\n\njulia> sign(cperm(1:2))\n-1\n\njulia> sign(cperm(1:3))\n1\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#isodd-Tuple{PermGroupElem}","page":"Permutation groups","title":"isodd","text":"isodd(g::PermGroupElem)\n\nReturn true if the permutation g is odd, false otherwise.\n\nA permutation is odd if it has an odd number of cycles of even length. Equivalently, a permutation is odd if it has sign -1.\n\nExamples\n\njulia> isodd(cperm(1:2))\ntrue\n\njulia> isodd(cperm(1:3))\nfalse\n\njulia> isodd(cperm(1:2,3:4))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#iseven-Tuple{PermGroupElem}","page":"Permutation groups","title":"iseven","text":"iseven(g::PermGroupElem)\n\nReturn true if the permutation g is even, false otherwise.\n\nA permutation is even if it has an even number of cycles of even length. Equivalently, a permutation is even if it has sign +1.\n\nExamples\n\njulia> iseven(cperm(1:2))\nfalse\n\njulia> iseven(cperm(1:3))\ntrue\n\njulia> iseven(cperm(1:2,3:4))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#cycle_structure-Tuple{PermGroupElem}","page":"Permutation groups","title":"cycle_structure","text":"cycle_structure(g::PermGroupElem) -> CycleType\n\nReturn the cycle structure of the permutation g as a cycle type. A cycle type behaves similar to a vector of pairs k => n indicating that there are n cycles of length k.\n\nExamples\n\njulia> g = cperm(1:3, 4:5, 6:7, 8:10, 11:15)\n(1,2,3)(4,5)(6,7)(8,9,10)(11,12,13,14,15)\n\njulia> cycle_structure(g)\n3-element Oscar.CycleType:\n 2 => 2\n 3 => 2\n 5 => 1\n\njulia> g = cperm()\n()\n\njulia> cycle_structure(g)\n1-element Oscar.CycleType:\n 1 => 1\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#Permutations-as-functions","page":"Permutation groups","title":"Permutations as functions","text":"","category":"section"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"A permutation can be viewed as a function on the set {1,...,n}, hence it can be evaluated on integers.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"note: Note\nThe multiplication between permutations works from the left to the right. So, if x and y are permutations and n is an integer, then (x*y)(n) = (y(x(n)), NOT x(y(n)). This works also if the argument is not in the range 1:n; in such a case, the output coincides with the input.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"julia> x = cperm([1,2,3,4,5]);\n\njulia> x(2)\n3\n\njulia> x(6)\n6","category":"page"},{"location":"Groups/permgroup/#Operations-for-permutation-groups","page":"Permutation groups","title":"Operations for permutation groups","text":"","category":"section"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"cycle_structures(G::PermGroup)\nis_transitive(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\ntransitivity(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\nis_primitive(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\nis_regular(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\nis_semiregular(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\nrank_action(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\nblocks(G::PermGroup, L::AbstractVector{Int} = moved_points(G))\nmaximal_blocks(G::PermGroup, L::AbstractVector{Int} = moved_points(G))\nminimal_block_reps(G::PermGroup, L::AbstractVector{Int} = moved_points(G))\nall_blocks(G::PermGroup)","category":"page"},{"location":"Groups/permgroup/#cycle_structures-Tuple{PermGroup}","page":"Permutation groups","title":"cycle_structures","text":"cycle_structures(G::PermGroup) -> Set{CycleType}\n\nReturn the set of cycle structures of elements in G, see cycle_structure.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> sort!(collect(cycle_structures(g)))\n3-element Vector{Oscar.CycleType}:\n [1 => 1, 2 => 1]\n [1 => 3]\n [3 => 1]\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#is_transitive","page":"Permutation groups","title":"is_transitive","text":"is_transitive(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\n\nReturn whether G acts transitively on L, that is, L is an orbit of G.\n\nExamples\n\njulia> G = symmetric_group(6);\n\njulia> is_transitive(G)\ntrue\n\njulia> is_transitive(sylow_subgroup(G, 2)[1])\nfalse\n\njulia> is_transitive(stabilizer(G, 1)[1])\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#transitivity","page":"Permutation groups","title":"transitivity","text":"transitivity(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\n\nReturn the maximum k such that G acts k-transitively on L, that is, every k-tuple of points in L can be mapped simultaneously to every other k-tuple by an element of G.\n\nThe output is 0 if G acts intransitively on L, and an exception is thrown if G does not act on L.\n\nExamples\n\njulia> transitivity(mathieu_group(24))\n5\n\njulia> transitivity(symmetric_group(6))\n6\n\njulia> transitivity(symmetric_group(6), 1:7)\n0\n\njulia> transitivity(symmetric_group(6), 1:5)\nERROR: ArgumentError: the group does not act\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#is_primitive","page":"Permutation groups","title":"is_primitive","text":"is_primitive(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\n\nReturn whether the action of G on L is primitive, that is, the action is transitive and the point stabilizers are maximal in G.\n\nExamples\n\njulia> G = alternating_group(6);\n\njulia> mx = filter(is_transitive, maximal_subgroup_reps(G))\n3-element Vector{PermGroup}:\n Group([ (1,2)(3,4), (1,2)(5,6), (1,3,5)(2,4,6), (1,3)(2,4) ])\n Group([ (1,2,3), (4,5,6), (1,2)(4,5), (1,5,2,4)(3,6) ])\n PSL(2,5)\n\njulia> [(order(H), is_primitive(H)) for H in mx]\n3-element Vector{Tuple{ZZRingElem, Bool}}:\n (24, 0)\n (36, 0)\n (60, 1)\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#is_regular","page":"Permutation groups","title":"is_regular","text":"is_regular(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\n\nReturn whether the action of G on L is regular (i.e., transitive and semiregular).\n\nExamples\n\njulia> G = symmetric_group(6);\n\njulia> H = sub(G, [G([2, 3, 4, 5, 6, 1])])[1]\nGroup([ (1,2,3,4,5,6) ])\n\njulia> is_regular(H)\ntrue\n\njulia> is_regular(G)\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#is_semiregular","page":"Permutation groups","title":"is_semiregular","text":"is_semiregular(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\n\nReturn whether the action of G on L is semiregular (i.e., the stabilizer of each point is the identity).\n\nExamples\n\njulia> G = symmetric_group(6);\n\njulia> H = sub(G, [G([2, 3, 1, 5, 6, 4])])[1]\nGroup([ (1,2,3)(4,5,6) ])\n\njulia> is_semiregular(H)\ntrue\n\njulia> is_regular(H)\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#rank_action","page":"Permutation groups","title":"rank_action","text":"rank_action(G::PermGroup, L::AbstractVector{Int} = 1:degree(G))\n\nReturn the rank of the transitive action of G on L. This is defined as the number of G-orbits in the action on ordered pairs of points in L, and is equal to the number of orbits of the stabilizer of a point in L on L, see Peter J. Cameron (1999) Section 1.11.\n\nAn exception is thrown if G is not transitive on L.\n\nExamples\n\njulia> G = symmetric_group(4); rank_action(G) # 4-transitive\n2\n\njulia> H = sylow_subgroup(G, 2)[1]\nGroup([ (1,2), (3,4), (1,3)(2,4) ])\n\njulia> rank_action(H) # not 2-transitive\n3\n\njulia> K = stabilizer(G, 1)[1]\nGroup([ (2,4,3), (3,4) ])\n\njulia> rank_action(K, 2:4) # 2-transitive\n2\n\njulia> rank_action(K, 3:5)\nERROR: ArgumentError: the group is not transitive\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#blocks","page":"Permutation groups","title":"blocks","text":"blocks(G::PermGroup, L::AbstractVector{Int} = moved_points(G))\n\nReturn a G-set that is a block system for the action of G on L, i.e., a non-trivial partition of L preserved by the action of G.\n\nHere, L must be a subvector of 1:degree(G) on which G acts transitively. G may move points outside L, in this case the restriction of the action of the set stabilizer of L in G to L is considered.\n\nAn exception is thrown if this action is not transitive.\n\nExamples\n\njulia> g = sylow_subgroup(symmetric_group(4), 2)[1]\nGroup([ (1,2), (3,4), (1,3)(2,4) ])\n\njulia> collect(blocks(g))\n2-element Vector{Vector{Int64}}:\n [1, 2]\n [3, 4]\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#maximal_blocks","page":"Permutation groups","title":"maximal_blocks","text":"maximal_blocks(G::PermGroup, L::AbstractVector{Int} = moved_points(G))\n\nReturn a G-set that is a maximal block system for the action of G on L, i.e., a maximal non-trivial partition of L preserved by the action of G.\n\nHere, L must be a subvector of 1:degree(G) on which G acts transitively. G may move points outside L, in this case the restriction of the action of the set stabilizer of L in G to L is considered.\n\nAn exception is thrown if this action is not transitive.\n\nExamples\n\njulia> G = transitive_group(8, 2)\n4[x]2\n\njulia> collect(maximal_blocks(G))\n2-element Vector{Vector{Int64}}:\n [1, 2, 3, 8]\n [4, 5, 6, 7]\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#minimal_block_reps","page":"Permutation groups","title":"minimal_block_reps","text":"minimal_block_reps(G::PermGroup, L::AbstractVector{Int} = moved_points(G))\n\nReturn a vector of block representatives for all minimal non-trivial block systems for the action of G on L.\n\nHere, L must be a subvector of 1:degree(G) on which G acts transitively. G may move points outside L, in this case the restriction of the action of the set stabilizer of L in G to L is considered.\n\nAn exception is thrown if this action is not transitive.\n\nExamples\n\njulia> G = transitive_group(8, 2)\n4[x]2\n\njulia> minimal_block_reps(G)\n3-element Vector{Vector{Int64}}:\n [1, 3]\n [1, 5]\n [1, 7]\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/permgroup/#all_blocks-Tuple{PermGroup}","page":"Permutation groups","title":"all_blocks","text":"all_blocks(G::PermGroup)\n\nReturn a vector of smallest representatives of all block systems for the action of G on the set of moved points of G.\n\nExamples\n\njulia> G = transitive_group(8, 2)\n4[x]2\n\njulia> all_blocks(G)\n6-element Vector{Vector{Int64}}:\n [1, 2, 3, 8]\n [1, 5]\n [1, 3, 5, 7]\n [1, 3]\n [1, 3, 4, 6]\n [1, 7]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#Cycle-structures","page":"Permutation groups","title":"Cycle structures","text":"","category":"section"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"For a permutation, its cycle structure cycle_structure determines the degree, order, number of moved points, sign.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"degree(::CycleType)\niseven(::CycleType)\nisodd(::CycleType)\norder(::Type{T}, c::CycleType) where T\nsign(::CycleType)","category":"page"},{"location":"Groups/permgroup/#degree-Tuple{Oscar.CycleType}","page":"Permutation groups","title":"degree","text":"degree(c::CycleType) -> Int\n\nReturn the degree of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> degree(cycle_structure(x)) == degree(g), gens(g))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#iseven-Tuple{Oscar.CycleType}","page":"Permutation groups","title":"iseven","text":"iseven(c::CycleType) -> Bool\n\nReturn whether the permutations with cycle structure c are even.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> iseven(cycle_structure(x)) == iseven(x), gens(g))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#isodd-Tuple{Oscar.CycleType}","page":"Permutation groups","title":"isodd","text":"isodd(c::CycleType) -> Bool\n\nReturn whether the permutations with cycle structure c are odd.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> isodd(cycle_structure(x)) == isodd(x), gens(g))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#order-Union{Tuple{T}, Tuple{Type{T}, Oscar.CycleType}} where T","page":"Permutation groups","title":"order","text":"order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion\n\nReturn the order of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> order(cycle_structure(x)) == order(x), gens(g))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/#sign-Tuple{Oscar.CycleType}","page":"Permutation groups","title":"sign","text":"sign(c::CycleType) -> Int\n\nReturn the sign of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> sign(cycle_structure(x)) == sign(x), gens(g))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/fraction/#Fraction-fields","page":"Fraction fields","title":"Fraction fields","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"Nemo allows the creation of fraction fields over any ring R. We don't require R to be an integral domain, however no attempt is made to deal with the general case. Two fractions ab and cd are equal in Nemo iff ad = bc. Thus, in practice, a greatest common divisor function is currently required for the ring R.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"In order to make the representation ab unique for printing, we have a notion of canonical unit for elements of a ring R. When canonicalising ab, each of the elements a and b is first divided by the canonical unit of b.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"The canonical_unit function is defined for elements of every Nemo ring. It must have the properties","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"canonical_unit(u) == u\ncanonical_unit(a*b) == canonical_unit(a)*canonical_unit(b)","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"for any unit u of the ring in question, and a and b arbitrary elements of the ring.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"For example, the canonical unit of an integer is its sign. Thus a fraction of integers always has positive denominator after canonicalisation.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"The canonical unit of a polynomial is the canonical unit of its leading coefficient, etc.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"There are two different kinds of implementation of fraction fields in Nemo: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of fractions over specific rings, usually provided by C/C++ libraries.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"The following table shows each of the fraction types available in Nemo, the base ring R, and the Julia/Nemo types for that kind of fraction (the type information is mainly of concern to developers).","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl Generic.Frac{T} Generic.FracField{T}\nmathbbZ Flint QQFieldElem QQField","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"All fraction element types belong to the abstract type FracElem and all of the fraction field types belong to the abstract type FracField. This enables one to write generic functions that can accept any Nemo fraction type.","category":"page"},{"location":"Nemo/fraction/#Fraction-functionality","page":"Fraction fields","title":"Fraction functionality","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"All fraction types in Nemo provide functionality for fields described in AbstractAlgebra.jl:","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"In addition all the fraction field functionality of AbstractAlgebra.jl is provided, along with generic fractions fields as described here:","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/fraction","category":"page"},{"location":"Nemo/fraction/#Basic-manipulation","page":"Fraction fields","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"sign(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#sign-Tuple{QQFieldElem}","page":"Fraction fields","title":"sign","text":"sign(a::QQFieldElem)\n\nReturn the sign of a (-1, 0 or 1) as a fraction.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"height(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#height-Tuple{QQFieldElem}","page":"Fraction fields","title":"height","text":"height(a::QQFieldElem)\n\nReturn the height of the fraction a, namely the largest of the absolute values of the numerator and denominator.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"height_bits(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#height_bits-Tuple{QQFieldElem}","page":"Fraction fields","title":"height_bits","text":"height_bits(a::QQFieldElem)\n\nReturn the number of bits of the height of the fraction a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"<<(::QQFieldElem, ::Int)","category":"page"},{"location":"Nemo/fraction/#<<-Tuple{QQFieldElem, Int64}","page":"Fraction fields","title":"<<","text":"<<(a::QQFieldElem, b::Int)\n\nReturn a times 2^b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":">>(::QQFieldElem, ::Int)","category":"page"},{"location":"Nemo/fraction/#>>-Tuple{QQFieldElem, Int64}","page":"Fraction fields","title":">>","text":">>(a::QQFieldElem, b::Int)\n\nReturn a2^b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"floor(::QQFieldElem)\nceil(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#floor-Tuple{QQFieldElem}","page":"Fraction fields","title":"floor","text":"floor(a::QQFieldElem)\n\nReturn the greatest integer that is less than or equal to a. The result is returned as a rational with denominator 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/#ceil-Tuple{QQFieldElem}","page":"Fraction fields","title":"ceil","text":"ceil(a::QQFieldElem)\n\nReturn the least integer that is greater than or equal to a. The result is returned as a rational with denominator 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"Examples","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"julia> d = abs(ZZ(11)//3)\n11//3\n\njulia> 4 <= ZZ(7)//ZZ(3)\nfalse","category":"page"},{"location":"Nemo/fraction/#Modular-arithmetic","page":"Fraction fields","title":"Modular arithmetic","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"The following functions are available for rationals.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"mod(a::QQFieldElem, b::ZZRingElem)","category":"page"},{"location":"Nemo/fraction/#mod-Tuple{QQFieldElem, ZZRingElem}","page":"Fraction fields","title":"mod","text":"mod(a::QQFieldElem, b::ZZRingElem)\nmod(a::QQFieldElem, b::Integer)\n\nReturn a pmodb where b is an integer coprime to the denominator of a.\n\nExamples\n\njulia> mod(-ZZ(2)//3, 7)\n4\n\njulia> mod(ZZ(1)//2, ZZ(5))\n3\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/#Rational-Reconstruction","page":"Fraction fields","title":"Rational Reconstruction","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"Rational reconstruction is available for rational numbers.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"reconstruct(::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/fraction/#reconstruct-Tuple{ZZRingElem, ZZRingElem}","page":"Fraction fields","title":"reconstruct","text":"reconstruct(a::ZZRingElem, b::ZZRingElem)\nreconstruct(a::ZZRingElem, b::Integer)\nreconstruct(a::Integer, b::ZZRingElem)\nreconstruct(a::Integer, b::Integer)\n\nAttempt to return a rational number nd such that 0 leq n leq lfloorsqrtm2rfloor and 0 d leq lfloorsqrtm2rfloor such that gcd(n d) = 1 and a equiv nd^-1 pmodm. If no solution exists, an exception is thrown.\n\nExamples\n\njulia> a = reconstruct(7, 13)\n1//2\n\njulia> b = reconstruct(ZZ(15), 31)\n-1//2\n\njulia> c = reconstruct(ZZ(123), ZZ(237))\n9//2\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/#Rational-enumeration","page":"Fraction fields","title":"Rational enumeration","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"Various methods exist to enumerate rationals.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"next_minimal(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#next_minimal-Tuple{QQFieldElem}","page":"Fraction fields","title":"next_minimal","text":"next_minimal(a::QQFieldElem)\n\nGiven a, return the next rational number in the sequence obtained by enumerating all positive denominators q, and for each q enumerating the numerators 1 le p q in order and generating both pq and qp, but skipping all gcd(pq) neq 1. Starting with zero, this generates every nonnegative rational number once and only once, with the first few entries being 0 1 12 2 13 3 23 32 14 4 34 43 ldots. This enumeration produces the rational numbers in order of minimal height. It has the disadvantage of being somewhat slower to compute than the Calkin-Wilf enumeration. If a 0 we throw a DomainError().\n\nExamples\n\njulia> next_minimal(ZZ(2)//3)\n3//2\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"next_signed_minimal(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#next_signed_minimal-Tuple{QQFieldElem}","page":"Fraction fields","title":"next_signed_minimal","text":"next_signed_minimal(a::QQFieldElem)\n\nGiven a signed rational number a assumed to be in canonical form, return the next element in the minimal-height sequence generated by next_minimal but with negative numbers interleaved. The sequence begins 0 1 -1 12 -12 2 -2 13 -13 ldots. Starting with zero, this generates every rational number once and only once, in order of minimal height.\n\nExamples\n\njulia> next_signed_minimal(-ZZ(21)//31)\n31//21\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"next_calkin_wilf(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#next_calkin_wilf-Tuple{QQFieldElem}","page":"Fraction fields","title":"next_calkin_wilf","text":"next_calkin_wilf(a::QQFieldElem)\n\nReturn the next number after a in the breadth-first traversal of the Calkin-Wilf tree. Starting with zero, this generates every nonnegative rational number once and only once, with the first few entries being 0 1 12 2 13 32 23 3 14 43 35 52 25 ldots. Despite the appearance of the initial entries, the Calkin-Wilf enumeration does not produce the rational numbers in order of height: some small fractions will appear late in the sequence. This order has the advantage of being faster to produce than the minimal-height order.\n\nExamples\n\njulia> next_calkin_wilf(ZZ(321)//113)\n113//244\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"next_signed_calkin_wilf(::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#next_signed_calkin_wilf-Tuple{QQFieldElem}","page":"Fraction fields","title":"next_signed_calkin_wilf","text":"next_signed_calkin_wilf(a::QQFieldElem)\n\nGiven a signed rational number a returns the next element in the Calkin-Wilf sequence with negative numbers interleaved. The sequence begins 0 1 -1 12 -12 2 -2 13 -13 ldots. Starting with zero, this generates every rational number once and only once, but not in order of minimal height.\n\nExamples\n\njulia> next_signed_calkin_wilf(-ZZ(51)//(17))\n1//4\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/#Random-generation","page":"Fraction fields","title":"Random generation","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"rand_bits(::QQField, b::Int)","category":"page"},{"location":"Nemo/fraction/#rand_bits-Tuple{QQField, Int64}","page":"Fraction fields","title":"rand_bits","text":"rand_bits(::QQField, b::Int)\n\nReturn a random signed rational whose numerator and denominator both have b bits before canonicalisation. Note that the resulting numerator and denominator can be smaller than b bits.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/#Special-functions","page":"Fraction fields","title":"Special functions","text":"","category":"section"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"The following special functions are available for specific rings in Nemo.","category":"page"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"harmonic(::Int)","category":"page"},{"location":"Nemo/fraction/#harmonic-Tuple{Int64}","page":"Fraction fields","title":"harmonic","text":"harmonic(n::Int)\n\nReturn the harmonic number H_n = 1 + 12 + 13 + cdots + 1n. Table lookup is used for H_n whose numerator and denominator fit in a single limb. For larger n, a divide and conquer strategy is used.\n\nExamples\n\njulia> a = harmonic(12)\n86021//27720\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"bernoulli(::Int)","category":"page"},{"location":"Nemo/fraction/#bernoulli-Tuple{Int64}","page":"Fraction fields","title":"bernoulli","text":"bernoulli(n::Int)\n\nReturn the Bernoulli number B_n for nonnegative n.\n\nSee also bernoulli_cache.\n\nExamples\n\njulia> d = bernoulli(12)\n-691//2730\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"bernoulli_cache(::Int)","category":"page"},{"location":"Nemo/fraction/#bernoulli_cache-Tuple{Int64}","page":"Fraction fields","title":"bernoulli_cache","text":"bernoulli_cache(n::Int)\n\nPrecomputes and caches all the Bernoulli numbers up to B_n. This is much faster than repeatedly calling bernoulli(k). Once cached, subsequent calls to bernoulli(k) for any k le n will read from the cache, making them virtually free.\n\nSee also bernoulli.\n\nExamples\n\njulia> bernoulli_cache(100)\n\njulia> e = bernoulli(100)\n-94598037819122125295227433069493721872702841533066936133385696204311395415197247711//33330\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"dedekind_sum(::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/fraction/#dedekind_sum-Tuple{ZZRingElem, ZZRingElem}","page":"Fraction fields","title":"dedekind_sum","text":"dedekind_sum(h::ZZRingElem, k::ZZRingElem)\n\nReturn the Dedekind sum s(hk) for arbitrary h and k.\n\nExamples\n\njulia> b = dedekind_sum(12, 13)\n-11//13\n\njulia> c = dedekind_sum(-120, ZZ(1305))\n-575//522\n\n\n\n\n\n","category":"method"},{"location":"Nemo/fraction/","page":"Fraction fields","title":"Fraction fields","text":"simplest_between(::QQFieldElem, ::QQFieldElem)","category":"page"},{"location":"Nemo/fraction/#simplest_between-Tuple{QQFieldElem, QQFieldElem}","page":"Fraction fields","title":"simplest_between","text":" simplest_between(l::QQFieldElem, r::QQFieldElem)\n\nReturn the simplest fraction in the closed interval l r. A canonical fraction a_1 b_1 is defined to be simpler than a_2 b_2 if and only if b_1 b_2 or b_1 = b_2 and a_1 a_2.\n\nExamples\n\njulia> simplest_between(QQ(1//10), QQ(3//10))\n1//4\n\n\n\n\n\n","category":"method"},{"location":"General/other/#Notes-for-users-of-other-computer-algebra-systems","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"","category":"section"},{"location":"General/other/#General-differences","page":"Notes for users of other computer algebra systems","title":"General differences","text":"","category":"section"},{"location":"General/other/","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"Julia evaluates 2^100 to 0 because 2 is regarded as a 64 bit integer. Write ZZRingElem(2)^100 to get a long.\nTODO: add more hints of this kind","category":"page"},{"location":"General/other/#Notes-for-GAP-users","page":"Notes for users of other computer algebra systems","title":"Notes for GAP users","text":"","category":"section"},{"location":"General/other/","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"This section describes differences between GAP and Oscar. (Hints about using GAP in Oscar can be found in the section about GAP Integration.)","category":"page"},{"location":"General/other/","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"The syntax of the languages is slightly different.\nIn GAP, equality of two objects is checked with =, and one assigns a value to a variable with :=. In Julia, equality is checked with ==, and = denotes assignment. Similarly, inequality of objects is checked with <> in GAP and with != in Julia.\nIn GAP, the operator not is used to negate boolean expressions, whereas ! is used in Julia.\nIn GAP, object identity is checked with the function IsIdenticalObj, whereas the infix operator === (with negation !==) is used in Julia.\nIn GAP, if statements have the form\nif condition1 then\n statements1\nelif condition2 then\n statements2\nelse\n statements3\nfi;\nwhereas the Julia syntax is\nif condition1\n statements1\nelseif condition2\n statements2\nelse\n statements3\nend\nSimilarly, GAP's for loops have the form\nfor var in list do\n statements\nod;\nwhereas the Julia syntax is\nfor var in list\n statements\nend\n(The situation with while loops is analogous.)\nVariable names in GAP and Julia are recommended to be written in camel case and snake case, respectively, see Naming conventions. For example, the GAP function SylowSubgroup corresponds to Oscar's sylow_subgroup.\nThus the GAP rule that the names of user variables should start with a lowercase letter, in order to avoid clashes with system variables, does not make sense in Julia.\nMoreover, global Oscar variables are not write protected, contrary to most global GAP variables. Thus there is always the danger that assignments overwrite Julia functions. For example, it is tempting to use gens, hom, and map as names for variables, but Julia or Oscar define them already.\n(Also copying some lines of code from an Oscar function into a Julia session can be dangerous in this sense, because some names of local variables of the function may coincide with the names of global variables.)\nGAP provides natural embeddings of many algebraic structures. For example, two finite fields of the same characteristic are embedded into each other whenever this makes sense, and the elements of the smaller field are regarded also as elements of the larger field. Analogously, subfields of cyclotomic fields are naturally embedded into each other, and in fact their elements are internally represented w.r.t. the smallest possible cyclotomic field.\nIn Oscar, this is not the case. Each element of an algebraic structure has a parent, and operations involving several elements (such as arithmetic operations) are usually restricted to the situation that their parents coincide. One has to explicitly coerce a given element into a different parent if necessary.\nThe consequences can be quite subtle. Each permutation group in Oscar has a fixed degree, and the function is_transitive checks whether its argument is transitive on the points from 1 to the degree. In GAP, however, the function IsTransitive, called with a permutation group, checks whether this group is transitive on the points which are moved by it. Thus the group generated by the permutation (1, 2, 4) is regarded as transitive in GAP but as intransitive in Oscar.","category":"page"},{"location":"General/other/#Notes-for-Singular-users","page":"Notes for users of other computer algebra systems","title":"Notes for Singular users","text":"","category":"section"},{"location":"General/other/","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"TODO\nTODO: also talk about how to use it from OSCAR?","category":"page"},{"location":"General/other/#Notes-for-Polymake-users","page":"Notes for users of other computer algebra systems","title":"Notes for Polymake users","text":"","category":"section"},{"location":"General/other/","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"OSCAR (and Julia) is 1-based, meaning that it counts from 1, rather than from 0 like polymake. For most properties we have taken care of the translation but be aware that it might pop up at some point and generate confusion.\nFor convenience, Polymake.jl provides Polymake.to_one_based_indexing and Polymake.to_zero_based_indexing.\nPolyhedra and polyhedral complexes in OSCAR are represented inhomogeneously, i.e. without the leading 1 for vertices or 0 for rays. Hence constructors take points, rays, and lineality generators separately.\nuser_methods cannot be accessed via Julia's dot syntax, i.e. something like\nc = Polymake.polytope.cube(3)\nc.AMBIENT_DIM\nwill not work. Instead user_methods are attached as Julia functions in their respective application. They are always written in lowercase. In the example the following works:\nc = Polymake.polytope.cube(3)\nPolymake.polytope.ambient_dim(c)","category":"page"},{"location":"General/other/#Notes-for-Magma-users","page":"Notes for users of other computer algebra systems","title":"Notes for Magma users","text":"","category":"section"},{"location":"General/other/","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"TODO","category":"page"},{"location":"General/other/#Notes-for-SageMath-users","page":"Notes for users of other computer algebra systems","title":"Notes for SageMath users","text":"","category":"section"},{"location":"General/other/","page":"Notes for users of other computer algebra systems","title":"Notes for users of other computer algebra systems","text":"TODO","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"We introduce here the necessary definitions and results which lie behind the methods presented. Most of the content is taken from V. V. Nikulin (1979).","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#Primitive-embeddings-in-even-lattices","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/primembed/#Nikulin's-theory","page":"Primitive embeddings in even lattices","title":"Nikulin's theory","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"Given an embedding icolon Shookrightarrow T of non-degenerate integral integer lattices, we call i primitive if its cokernel Ti(S) is torsion free. Two primitive embeddings i_1colon Shookrightarrow M_1 and i_2colon S hookrightarrow M_2 of S into two lattices M_1 and M_2 are called isomorphic if there exists an isometry M_1 to M_2 which restricts to the identity of S. Moreover, if there exists an isometry between M_1 and M_2 which maps S to itself (not necessarily identically), we say that i_1 and i_2 defines isomorphic primitive sublattices V. V. Nikulin (1979).","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"In his paper, V. V. Nikulin gives necessary and sufficient condition for an even integral lattice M to embed primitively into an even unimodular lattice with given invariants (see Theorem 1.12.2 in V. V. Nikulin (1979)). More generally, the author also provides methods to compute primitive embeddings of any even lattice into an even lattice in a given genus (see Proposition 1.15.1 in V. V. Nikulin (1979)). In the latter proposition, it is explained how to classify such embeddings as isomorphic embeddings or as isomorphic sublattices.","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"Such a method can be algorithmically implemented, however it tends to be slow and inefficient in general for large rank or determinant. But, in the case where the discriminant groups are (elementary) p-groups, the method can be more efficient.","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"We provide 4 kinds of output:","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"A boolean, which only returns whether there exists a primitive embedding;\nA single primitive embedding as soon as the algorithm computes one;\nA list of representatives of isomorphism classes of primitive embeddings;\nA list of representatives of isomorphism classes of primitive sublattices.","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"primitive_embeddings(::ZZLat, ::ZZLat)","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#primitive_embeddings-Tuple{ZZLat, ZZLat}","page":"Primitive embeddings in even lattices","title":"primitive_embeddings","text":"primitive_embeddings(L::ZZLat, M::ZZLat; classification::Symbol = :sublat,\n check::Bool = true)\n -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}\n\nGiven an even integer lattice L, which is unique in its genus, and an even integer lattice M, return whether M embeds primitively in L.\n\nThe first input of the function is a boolean T stating whether or not M embeds primitively in L. The second output V consists on triples (L', M', N') where L' is isometric to L, M' is a primitive sublattice of L' isometric to M, and N' is the orthogonal complement of M' in L'.\n\nIf T == false, then V will always be the empty list. If T == true, then the content of V actually depends on the value of the symbol classification. There are 4 possibilities:\n\nclassification = :none: V is the empty list;\nclassification = :first: V consists on the first primitive embedding found;\nclassification = :sublat: V consists on representatives for all isomorphism classes of primitive embeddings of M in L, up to the actions of barO(M) and O(q) where q is the discriminant group of L;\nclassification = :emb: V consists on representatives for all isomorphism classes of primitive sublattices of L isometric to M up to the action of O(q) where q is the discriminant group of L.\n\nIf check is set to true, the function determines whether L is in fact unique in its genus.\n\nExamples\n\nWe can use such primitive embeddings algorithm to classify embedding in unimodular lattices\n\njulia> E8 = root_lattice(:E,8);\n\njulia> A4 = root_lattice(:A,4);\n\njulia> bool, pe = primitive_embeddings(E8, A4)\n(true, Tuple{ZZLat, ZZLat, ZZLat}[(Integer lattice of rank 8 and degree 8, Integer lattice of rank 4 and degree 8, Integer lattice of rank 4 and degree 8)])\n\njulia> pe\n1-element Vector{Tuple{ZZLat, ZZLat, ZZLat}}:\n (Integer lattice of rank 8 and degree 8, Integer lattice of rank 4 and degree 8, Integer lattice of rank 4 and degree 8)\n\njulia> genus(pe[1][2]) == genus(pe[1][3])\ntrue\n\nTo be understood here that there exists a unique class of embedding of the root lattice A_4 in the root lattice E_8, and the orthogonal primitive sublattice is isometric to A_4.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"Note that the previous two functions require the first lattice of the input to be unique in its genus. Otherwise, one can specify a genus, or its invariants, as a first input:","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"primitive_embeddings(::ZZGenus, ::ZZLat)\nprimitive_embeddings(::TorQuadModule, ::Tuple{Int, Int},\n::ZZLat)","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#primitive_embeddings-Tuple{ZZGenus, ZZLat}","page":"Primitive embeddings in even lattices","title":"primitive_embeddings","text":"primitive_embeddings(G::ZZGenus, M::ZZLat; classification::Symbol = :sublat)\n -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}\n\nGiven a genus symbol G for even integer lattices and an even integer lattice M, return whether M embeds primitively in a lattice in G.\n\nThe first input of the function is a boolean T stating whether or not M embeds primitively in a lattice in G. The second output V consists on triples (L', M', N') where L' is a lattice in G, M' is a sublattice of L' isometric to M, and N' is the orthogonal complement of M' in L'.\n\nIf T == false, then V will always be the empty list. If T == true, then the content of V actually depends on the value of the symbol classification. There are 4 possibilities:\n\nclassification = :none: V is the empty list;\nclassification = :first: V consists on the first primitive embedding found;\nclassification = :sublat: V consists on representatives for all isomorphism classes of primitive embeddings of M in lattices in G, up to the actions of barO(M) and O(q) where q is the discriminant of a lattice in G;\nclassification = :emb: V consists on representatives for all isomorphism classes of primitive sublattices of lattices in G isometric to M, up to the action of O(q) where q is the discriminant group of a lattice in G.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/#primitive_embeddings-Tuple{TorQuadModule, Tuple{Int64, Int64}, ZZLat}","page":"Primitive embeddings in even lattices","title":"primitive_embeddings","text":"primitive_embeddings(q::TorQuadModule, sign::Tuple{Int, Int}, M::ZZLat;\n classification::Symbol = :sublat)\n -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}\n\nGiven a tuple sign of non-negative integers and a torsion quadratic module q which define a genus symbol G for even integer lattices, return whether the even integer lattice M embeds primitively in a lattice in G.\n\nThe first input of the function is a boolean T stating whether or not M embeds primitively in a lattice in G. The second output V consists on triples (L', M', N') where L' is a lattice in G, M' is a sublattice of L' isometric to M, and N' is the orthogonal complement of M' in L'.\n\nIf T == false, then V will always be the empty list. If T == true, then the content of V actually depends on the value of the symbol classification. There are 4 possibilities:\n\nclassification = :none: V is the empty list;\nclassification = :first: V consists on the first primitive embedding found;\nclassification = :sublat: V consists on representatives for all isomorphism classes of primitive embeddings of M in lattices in G, up to the actions of barO(M) and O(q) where q is the discriminant group of a lattice in G;\nclassification = :emb: V consists on representatives for all isomorphism classes of primitive sublattices of lattices in G isometric to M, up to the action of O(q) where q is the discriminant group of a lattice in G.\n\nIf the pair (q, sign) does not define a non-empty genus for integer lattices, an error is thrown.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"In order to compute such primitive embeddings of a lattice M into a lattice L, one first computes the possible genera for the orthogonal of M in L (after embedding), and for each lattice N in such a genus, one computes isomorphism classes of primitive extensions of M perp N modulo barO(N) (and barO(M) in the case of classification of primitive sublattices of L isometric to M).","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"We recall that a primitive extension of the orthogonal direct sum of two integral integer lattices M and N is an overlattice L of Mperp N such that both M and N embed primitively in L (via the natural embeddings MN to Mperp Nsubseteq L). Such primitive extensions are obtained, and classified, by looking for gluings between anti-isometric subgroups of the respective discriminant groups of M and N. The construction of an overlattice is determined by the graph of such glue map. ","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#Admissible-equivariant-primitive-extensions","page":"Primitive embeddings in even lattices","title":"Admissible equivariant primitive extensions","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"The following function is an interesting tool provided by Simon Brandhorst, Tommy Hofmann (2023). Given a triple of integer lattices with isometry ((A, a), (B, b), (C, c)) and two prime numbers p and q (possibly equal), if (A, B, C) is p-admissible, this function returns representatives of isomorphism classes of equivariant primitive extensions (A a)perp (B b)to (D d) such that the type of (D d^p) is equal to the type of (C c) (see type(::ZZLatWithIsom)).","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"admissible_equivariant_primitive_extensions(::ZZLatWithIsom, ::ZZLatWithIsom, ::ZZLatWithIsom, ::Integer, ::Integer)","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#admissible_equivariant_primitive_extensions-Tuple{ZZLatWithIsom, ZZLatWithIsom, ZZLatWithIsom, Integer, Integer}","page":"Primitive embeddings in even lattices","title":"admissible_equivariant_primitive_extensions","text":"admissible_equivariant_primitive_extensions(Afa::ZZLatWithIsom,\n Bfb::ZZLatWithIsom,\n Cfc::ZZLatWithIsom,\n p::Integer,\n q::Integer = p; check::Bool = true)\n -> Vector{ZZLatWithIsom}\n\nGiven a triple of lattices with isometry (A, fa), (B, fb) and (C, fc) and a prime number p, such that (A, B, C) is p-admissible, return a set of representatives of the double coset G_Bbackslash SG_A where:\n\nG_A and G_B are the respective images of the morphisms O(A fa) to O(q_A barfa) and O(B fb) to O(q_B barfb);\nS is the set of all primitive extensions A perp B subseteq C with isometry fc where pcdot C subseteq Aperp B and such that the type of (C fc^q) is equal to the type of (C, fc).\n\nIf check == true the input triple is checked to a p-admissible triple of integral lattices (with isometry) with fA and fB having relatively coprime irreducible minimal polynomials and imposing that A and B are orthogonal if A, B and C lie in the same ambient quadratic space.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Primitive embeddings in even lattices","title":"Primitive embeddings in even lattices","text":"An equivariant primitive extension of a pair of integer lattices with isometries (M f_M) and (N f_N) is a primitive extension of M and N obtained by gluing two subgroups which are respectively barf_M and barf_N stable along a glue map which commutes with these two actions. If such a gluing exists, then the overlattice L of Mperp N is equipped with an isometry f_L which preserves both M and N, and restricts to f_M and f_N respectively.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/grouplib/#Group-libraries","page":"Group libraries","title":"Group libraries","text":"","category":"section"},{"location":"Groups/grouplib/#Transitive-permutation-groups-of-small-degree","page":"Group libraries","title":"Transitive permutation groups of small degree","text":"","category":"section"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"TODO: explain about the scope of this.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"TODO: give proper attribution to the transgrp package (in particular, cite it)","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The arrangement and the names of the groups of degree up to 15 is the same as given in John H. Conway, Alexander Hulpke, John McKay (1998). With the exception of the symmetric and alternating group (which are represented as symmetric_group and alternating_group) the generators for these groups also conform to this paper with the only difference that 0 (which is not permitted in GAP for permutations to act on) is always replaced by the degree.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The arrangement for all degrees is intended to be equal to the arrangement within the systems GAP and Magma, thus it should be safe to refer to particular (classes of) groups by their index numbers.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"all_transitive_groups\nhas_number_transitive_groups\nhas_transitive_group_identification\nhas_transitive_groups\nnumber_transitive_groups\ntransitive_group\ntransitive_group_identification","category":"page"},{"location":"Groups/grouplib/#all_transitive_groups","page":"Group libraries","title":"all_transitive_groups","text":"all_transitive_groups(L...)\n\nReturn the list of all transitive groups (up to permutation isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:\n\nfunc => intval selects groups for which the function func returns intval\nfunc => list selects groups for which the function func returns any element inside list\nfunc selects groups for which the function func returns true\n!func selects groups for which the function func returns false\n\nThe following functions are currently supported as values for func:\n\ndegree\nis_abelian\nis_almostsimple\nis_cyclic\nis_nilpotent\nis_perfect\nis_primitive\nis_quasisimple\nis_simple\nis_sporadic_simple\nis_solvable\nis_supersolvable\nis_transitive\nnumber_conjugacy_classes\nnumber_moved_points\norder\ntransitivity\n\nThe type of the returned groups is PermGroup.\n\nExamples\n\njulia> all_transitive_groups(degree => 3:5, is_abelian)\n4-element Vector{PermGroup}:\n A3\n C(4) = 4\n E(4) = 2[x]2\n C(5) = 5\n\nreturns the list of all abelian transitive groups acting on 3, 4 or 5 points.\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_number_transitive_groups","page":"Group libraries","title":"has_number_transitive_groups","text":"has_number_transitive_groups(deg::Int)\n\nReturn whether the number transitive groups groups of degree deg are available for use via number_transitive_groups.\n\nExamples\n\njulia> has_number_transitive_groups(30)\ntrue\n\njulia> has_number_transitive_groups(64)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_transitive_group_identification","page":"Group libraries","title":"has_transitive_group_identification","text":"has_transitive_group_identification(deg::Int)\n\nReturn whether identification of transitive groups groups of degree deg is available via transitive_group_identification.\n\nExamples\n\njulia> has_transitive_group_identification(30)\ntrue\n\njulia> has_transitive_group_identification(64)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_transitive_groups","page":"Group libraries","title":"has_transitive_groups","text":"has_transitive_groups(deg::Int)\n\nReturn whether the transitive groups groups of degree deg are available for use. This function should be used to test for the scope of the library available.\n\nExamples\n\njulia> has_transitive_groups(30)\ntrue\n\njulia> has_transitive_groups(64)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#number_transitive_groups","page":"Group libraries","title":"number_transitive_groups","text":"number_transitive_groups(deg::Int)\n\nReturn the number of transitive groups of degree deg, up to permutation isomorphism.\n\nExamples\n\njulia> number_transitive_groups(30)\n5712\n\njulia> number_transitive_groups(64)\nERROR: ArgumentError: the number of transitive groups of degree 64 is not available\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#transitive_group","page":"Group libraries","title":"transitive_group","text":"transitive_group(deg::Int, i::Int)\n\nReturn the i-th group in the catalogue of transitive groups over the set {1, ..., deg} in GAP's Transitive Groups Library. The output is a group of type PermGroup.\n\nExamples\n\njulia> transitive_group(5,4)\nA5\n\njulia> transitive_group(5,6)\nERROR: ArgumentError: there are only 5 transitive groups of degree 5, not 6\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#transitive_group_identification","page":"Group libraries","title":"transitive_group_identification","text":"transitive_group_identification(G::PermGroup)\n\nReturn a pair (d,n) such that G is permutation isomorphic with transitive_group(d,n), where G acts transitively on d points.\n\nIf G is not transitive on its moved points, or if the transitive groups of degree d are not available, an exception is thrown.\n\nExamples\n\njulia> G = symmetric_group(7); m = transitive_group_identification(G)\n(7, 7)\n\njulia> order(transitive_group(m...)) == order(G)\ntrue\n\njulia> S = sub(G, [perm([1, 3, 4, 5, 2])])[1]\nGroup([ (2,3,4,5) ])\n\njulia> is_transitive(S)\nfalse\n\njulia> is_transitive(S, moved_points(S))\ntrue\n\njulia> m = transitive_group_identification(S)\n(4, 1)\n\njulia> order(transitive_group(m...)) == order(S)\ntrue\n\njulia> transitive_group_identification(symmetric_group(64))\nERROR: ArgumentError: identification of transitive groups of degree 64 are not available\n\njulia> S = sub(G, [perm([1,3,4,5,2,7,6])])[1];\n\njulia> transitive_group_identification(S)\nERROR: ArgumentError: group is not transitive on its moved points\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#Primitive-permutation-groups-of-small-degree","page":"Group libraries","title":"Primitive permutation groups of small degree","text":"","category":"section"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"TODO: explain about the scope of this.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"TODO: give proper attribution to the primitive groups library (in particular, cite it)","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"all_primitive_groups\nhas_number_primitive_groups\nhas_primitive_group_identification\nhas_primitive_groups\nnumber_primitive_groups\nprimitive_group\nprimitive_group_identification","category":"page"},{"location":"Groups/grouplib/#all_primitive_groups","page":"Group libraries","title":"all_primitive_groups","text":"all_primitive_groups(L...)\n\nReturn the list of all primitive permutation groups (up to permutation isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:\n\nfunc => intval selects groups for which the function func returns intval\nfunc => list selects groups for which the function func returns any element inside list\nfunc selects groups for which the function func returns true\n!func selects groups for which the function func returns false\n\nThe following functions are currently supported as values for func:\n\ndegree\nis_abelian\nis_almostsimple\nis_cyclic\nis_nilpotent\nis_perfect\nis_primitive\nis_quasisimple\nis_simple\nis_sporadic_simple\nis_solvable\nis_supersolvable\nis_transitive\nnumber_conjugacy_classes\nnumber_moved_points\norder\ntransitivity\n\nThe type of the returned groups is PermGroup.\n\nExamples\n\njulia> all_primitive_groups(degree => 3:5, is_abelian)\n2-element Vector{PermGroup}:\n A(3)\n C(5)\n\nreturns the list of all abelian primitive permutation groups acting on 3, 4 or 5 points.\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_number_primitive_groups","page":"Group libraries","title":"has_number_primitive_groups","text":"has_number_primitive_groups(deg::Int)\n\nReturn true if the number of primitive permutation groups of degree deg is available via number_primitive_groups, otherwise false.\n\nCurrently the number of primitive permutation groups is available up to degree 4095.\n\nExamples\n\njulia> has_number_primitive_groups(50)\ntrue\n\njulia> has_number_primitive_groups(5000)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_primitive_group_identification","page":"Group libraries","title":"has_primitive_group_identification","text":"has_primitive_group_identification(deg::Int)\n\nReturn true if identification is supported for the primitive permutation groups of degree deg via primitive_group_identification, otherwise false.\n\nCurrently identification is available for all primitive permutation groups up to degree 4095.\n\nExamples\n\njulia> has_primitive_group_identification(50)\ntrue\n\njulia> has_primitive_group_identification(5000)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_primitive_groups","page":"Group libraries","title":"has_primitive_groups","text":"has_primitive_groups(deg::Int)\n\nReturn true if the primitive permutation groups of degree deg are available via primitive_group and all_primitive_groups, otherwise false.\n\nCurrently all primitive permutation groups up to degree 4095 are available.\n\nExamples\n\njulia> has_primitive_groups(50)\ntrue\n\njulia> has_primitive_groups(5000)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#number_primitive_groups","page":"Group libraries","title":"number_primitive_groups","text":"number_primitive_groups(deg::Int)\n\nReturn the number of primitive permutation groups of degree deg, up to permutation isomorphism.\n\nExamples\n\njulia> number_primitive_groups(10)\n9\n\njulia> number_primitive_groups(4096)\nERROR: ArgumentError: the number of primitive permutation groups of degree 4096 is not available\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#primitive_group","page":"Group libraries","title":"primitive_group","text":"primitive_group(deg::Int, i::Int)\n\nReturn the i-th group in the catalogue of primitive permutation groups over the set {1, ..., deg} in GAP's library of primitive permutation groups. The output is a group of type PermGroup.\n\nExamples\n\njulia> primitive_group(10,1)\nA(5)\n\njulia> primitive_group(10,10)\nERROR: ArgumentError: there are only 9 primitive permutation groups of degree 10, not 10\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#primitive_group_identification","page":"Group libraries","title":"primitive_group_identification","text":"primitive_group_identification(G::PermGroup)\n\nReturn a pair (d,n) such that G is permutation isomorphic with primitive_group(d,n), where G acts primitively on d points.\n\nIf G is not primitive on its moved points, or if the primitive permutation groups of degree d are not available, an exception is thrown.\n\nExamples\n\njulia> G = symmetric_group(7); m = primitive_group_identification(G)\n(7, 7)\n\njulia> order(primitive_group(m...)) == order(G)\ntrue\n\njulia> S = stabilizer(G, 1)[1]\nGroup([ (2,7,6,5,4,3), (6,7) ])\n\njulia> is_primitive(S)\nfalse\n\njulia> is_primitive(S, moved_points(S))\ntrue\n\njulia> m = primitive_group_identification(S)\n(6, 4)\n\njulia> order(primitive_group(m...)) == order(S)\ntrue\n\njulia> primitive_group_identification(symmetric_group(4096))\nERROR: ArgumentError: identification of primitive permutation groups of degree 4096 is not available\n\njulia> S = sub(G, [perm([1,3,4,5,2,7,6])])[1];\n\njulia> primitive_group_identification(S)\nERROR: ArgumentError: group is not primitive on its moved points\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#Perfect-groups-of-small-order","page":"Group libraries","title":"Perfect groups of small order","text":"","category":"section"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The functions in this section are wrappers for the GAP library of finite perfect groups which provides, up to isomorphism, a list of all perfect groups whose sizes are less than 2cdot 10^6. The groups of most orders up to 10^6 have been enumerated by Derek Holt and Wilhelm Plesken, see Derek F. Holt, W. Plesken (1989). For orders n = 86016, 368640, or 737280 this work only counted the groups (but did not explicitly list them), the groups of orders n = 61440, 122880, 172032, 245760, 344064, 491520, 688128, or 983040 were omitted.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"Several additional groups omitted from the book Derek F. Holt, W. Plesken (1989) have also been included. Two groups – one of order 450000 with a factor group of type A_6 and the one of order 962280 – were found by Jack Schmidt in","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"Two groups of order 243000 and one each of orders 729000, 871200, 878460","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"were found in 2020 by Alexander Hulpke.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The perfect groups of size less than 2cdot 10^6 which had not been classified in the work of Holt and Plesken have been enumerated by Alexander Hulpke. They are stored directly and provide less construction information in their names.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"As all groups are stored by presentations, a permutation representation is obtained by coset enumeration. Note that some of the library groups do not have a faithful permutation representation of small degree. Computations in these groups may be rather time consuming.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"has_number_perfect_groups\nhas_perfect_group_identification\nhas_perfect_groups\nnumber_perfect_groups\norders_perfect_groups\nperfect_group\nperfect_group_identification","category":"page"},{"location":"Groups/grouplib/#has_number_perfect_groups","page":"Group libraries","title":"has_number_perfect_groups","text":"has_number_perfect_groups(n::Int)\n\nReturn true if the number of perfect groups of order n are available via number_perfect_groups, otherwise false.\n\nCurrently the number of perfect groups is available up to order 2 cdot 10^6.\n\nExamples\n\njulia> has_number_perfect_groups(7200)\ntrue\n\njulia> has_number_perfect_groups(2*10^6+1)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_perfect_group_identification","page":"Group libraries","title":"has_perfect_group_identification","text":"has_perfect_group_identification(n::Int)\n\nReturn true if identification is supported for the perfect groups of order n via perfect_group_identification, otherwise false.\n\nCurrently identification is available for all perfect groups up to order 2 cdot 10^6.\n\nExamples\n\njulia> has_perfect_group_identification(7200)\ntrue\n\njulia> has_perfect_group_identification(2*10^6+1)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_perfect_groups","page":"Group libraries","title":"has_perfect_groups","text":"has_perfect_groups(deg::Int)\n\nReturn true if the perfect groups of order n are available via perfect_group and all_perfect_groups, otherwise false.\n\nCurrently all perfect groups up to order 2 cdot 10^6 are available.\n\nExamples\n\njulia> has_perfect_groups(7200)\ntrue\n\njulia> has_perfect_groups(2*10^6+1)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#number_perfect_groups","page":"Group libraries","title":"number_perfect_groups","text":"number_perfect_groups(n::IntegerUnion)\n\nReturn the number of perfect groups of order n, up to isomorphism.\n\nExamples\n\njulia> number_perfect_groups(60)\n1\n\njulia> number_perfect_groups(1966080)\n7344\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#orders_perfect_groups","page":"Group libraries","title":"orders_perfect_groups","text":"orders_perfect_groups()\n\nReturn a sorted vector of all numbers to 2 cdot 10^6 that occur as orders of perfect groups.\n\nExamples\n\njulia> orders_perfect_groups()[1:10]\n10-element Vector{Int64}:\n 1\n 60\n 120\n 168\n 336\n 360\n 504\n 660\n 720\n 960\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#perfect_group","page":"Group libraries","title":"perfect_group","text":"perfect_group(::Type{T} = PermGroup, n::IntegerUnion, k::IntegerUnion)\n\nReturn the k-th group of order n and type T in the catalogue of perfect groups in GAP's Perfect Groups Library. The type T can be either PermGroup or FPGroup.\n\nExamples\n\njulia> perfect_group(60, 1)\nA5\n\njulia> gens(ans)\n2-element Vector{PermGroupElem}:\n (1,2)(4,5)\n (2,3,4)\n\njulia> perfect_group(FPGroup, 60, 1)\nA5\n\njulia> gens(ans)\n2-element Vector{FPGroupElem}:\n a\n b\n\njulia> perfect_group(60, 2)\nERROR: ArgumentError: there are only 1 perfect groups of order 60\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#perfect_group_identification","page":"Group libraries","title":"perfect_group_identification","text":"perfect_group_identification(G::GAPGroup)\n\nReturn (n, m) such that G is isomorphic with perfect_group(n, m). If G is not perfect, an exception is thrown.\n\nExamples\n\njulia> perfect_group_identification(alternating_group(5))\n(60, 1)\n\njulia> perfect_group_identification(SL(2,7))\n(336, 1)\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#Groups-of-small-order","page":"Group libraries","title":"Groups of small order","text":"","category":"section"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"TODO: explain about the scope of this.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"TODO: give proper attribution to the smallgrp package and other things used (in particular, cite it)","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"all_small_groups\nhas_number_small_groups\nhas_small_group_identification\nhas_small_groups\nnumber_small_groups\nsmall_group\nsmall_group_identification","category":"page"},{"location":"Groups/grouplib/#all_small_groups","page":"Group libraries","title":"all_small_groups","text":"all_small_groups(L...)\n\nReturn the list of all groups (up to isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:\n\nfunc => intval selects groups for which the function func returns intval\nfunc => list selects groups for which the function func returns any element inside list\nfunc selects groups for which the function func returns true\n!func selects groups for which the function func returns false\n\nAs a special case, the first argument may also be one of the following:\n\nintval selects groups whose order equals intval; this is equivalent to order => intval\nintlist selects groups whose order is in intlist; this is equivalent to order => intlist\n\nNote that at least one of the conditions must impose a limit on the group order, otherwise an exception is thrown.\n\nThe following functions are currently supported as values for func:\n\nis_abelian\nis_almostsimple\nis_cyclic\nis_nilpotent\nis_perfect\nis_quasisimple\nis_simple\nis_sporadic_simple\nis_solvable\nis_supersolvable\nnumber_conjugacy_classes\norder\n\nThe type of the returned groups is PcGroup if the group is solvable, PermGroup otherwise.\n\nExamples\n\nList all abelian non-cyclic groups of order 12:\n\njulia> all_small_groups(12, !is_cyclic, is_abelian)\n1-element Vector{PcGroup}:\n \n\nList groups of order 1 to 10 which are not abelian:\n\njulia> all_small_groups(1:10, !is_abelian)\n4-element Vector{PcGroup}:\n \n \n \n \n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_number_small_groups","page":"Group libraries","title":"has_number_small_groups","text":"has_number_small_groups(n::IntegerUnion)\n\nReturn true if the number of groups of order n is known, otherwise false.\n\nExamples\n\njulia> has_number_small_groups(1024)\ntrue\n\njulia> has_number_small_groups(2048)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_small_group_identification","page":"Group libraries","title":"has_small_group_identification","text":"has_small_group_identification(n::IntegerUnion)\n\nReturn true if identification for groups of order n is available via small_group_identification, otherwise false.\n\nExamples\n\njulia> has_small_group_identification(256)\ntrue\n\njulia> has_small_group_identification(512)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_small_groups","page":"Group libraries","title":"has_small_groups","text":"has_small_groups(n::IntegerUnion)\n\nReturn true if the groups of order n are available via small_group and all_small_groups, otherwise false.\n\nExamples\n\njulia> has_small_groups(512)\ntrue\n\njulia> has_small_groups(1024)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#number_small_groups","page":"Group libraries","title":"number_small_groups","text":"number_small_groups(n::IntegerUnion)\n\nReturn the number of groups of order n, up to isomorphism.\n\nExamples\n\njulia> number_small_groups(8)\n5\n\njulia> number_small_groups(4096)\nERROR: ArgumentError: the number of groups of order 4096 is not available\n\njulia> number_small_groups(next_prime(ZZRingElem(2)^64))\n1\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#small_group","page":"Group libraries","title":"small_group","text":"small_group(::Type{T}, n::IntegerUnion, i::IntegerUnion) where T\nsmall_group(n::IntegerUnion, i::IntegerUnion)\n\nReturn the i-th group of order n in the Small Groups Library. If a type T is specified then an attempt is made to return the result with that type. If T is omitted then the resulting group will have type PcGroup if it is solvable, otherwise it will be of type PermGroup.\n\nExamples\n\njulia> small_group(60, 4)\n\n\njulia> small_group(60, 5)\nGroup([ (1,2,3,4,5), (1,2,3) ])\n\njulia> small_group(PcGroup, 60, 4)\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#small_group_identification","page":"Group libraries","title":"small_group_identification","text":"small_group_identification(G::Group)\n\nReturn a pair of integer (n, m), where G is isomorphic with small_group(n, m).\n\nExamples\n\njulia> small_group_identification(alternating_group(5))\n(60, 5)\n\njulia> small_group_identification(symmetric_group(20))\nERROR: ArgumentError: identification is not available for groups of order 2432902008176640000\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#Atlas-of-Group-Representations","page":"Group libraries","title":"Atlas of Group Representations","text":"","category":"section"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The functions in this section give access to data in the Atlas of Group Representations R. A. Wilson, P. Walsh, J. Tripp, I. Suleiman, R. A. Parker, S. P. Norton, S. Nickerson, S. Linton, J. Bray, R. Abbott (). The isomorphism types of the groups in question are specified via names for the groups, which coincide with the names of the corresponding character tables in the library of character tables, see character_table(id::String, p::Int = 0).","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"number_atlas_groups\nall_atlas_group_infos\natlas_group\natlas_subgroup","category":"page"},{"location":"Groups/grouplib/#number_atlas_groups","page":"Group libraries","title":"number_atlas_groups","text":"number_atlas_groups([::Type{T}, ]name::String) where T <: Union{PermGroup, MatrixGroup}\n\nReturn the number of groups from the Atlas of Group Representations whose isomorphism type is given by name and have the type T.\n\nExamples\n\njulia> number_atlas_groups(\"A5\")\n18\n\njulia> number_atlas_groups(PermGroup, \"A5\")\n3\n\njulia> number_atlas_groups(MatrixGroup, \"A5\")\n15\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#all_atlas_group_infos","page":"Group libraries","title":"all_atlas_group_infos","text":"all_atlas_group_infos(name::String, L...)\n\nReturn the vector of dictionaries that describe Atlas groups whose isomorphism types are given by name and which satisfy the conditions in L. These conditions may be of one of the following forms:\n\nfunc => intval selects groups for which the function func returns intval\nfunc => list selects groups for which the function func returns any element inside list\nfunc selects groups for which the function func returns true\n!func selects groups for which the function func returns false\n\nThe following functions are currently supported as values for func:\n\nFor permutation groups\n\ndegree\nis_primitive\nis_transitive\nrank_action\ntransitivity\n\nand for matrix groups\n\nbase_ring\ncharacter\ncharacteristic\ndim\n\nExamples\n\njulia> info = all_atlas_group_infos(\"A5\", degree => [5, 6])\n2-element Vector{Dict{Symbol, Any}}:\n Dict(:repname => \"A5G1-p5B0\", :degree => 5, :name => \"A5\")\n Dict(:repname => \"A5G1-p6B0\", :degree => 6, :name => \"A5\")\n\njulia> atlas_group(info[1])\nGroup([ (1,2)(3,4), (1,3,5) ])\n\njulia> info = all_atlas_group_infos(\"A5\", dim => 4, characteristic => 3)\n1-element Vector{Dict{Symbol, Any}}:\n Dict(:dim => 4, :repname => \"A5G1-f3r4B0\", :name => \"A5\")\n\njulia> atlas_group(info[1])\nMatrix group of degree 4 over Finite field of degree 1 over GF(3)\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#atlas_group","page":"Group libraries","title":"atlas_group","text":"atlas_group([::Type{T}, ]name::String) where T <: Union{PermGroup, MatrixGroup}\n\nReturn a group from the Atlas of Group Representations whose isomorphism type is given by name and have the type T. If T is not given then PermGroup is chosen if a permutation group for name is available, and MatrixGroup otherwise.\n\nExamples\n\njulia> atlas_group(\"A5\") # alternating group A5\nGroup([ (1,2)(3,4), (1,3,5) ])\n\njulia> atlas_group(MatrixGroup, \"A5\")\nMatrix group of degree 4 over Finite field of degree 1 over GF(2)\n\njulia> atlas_group(\"M11\") # Mathieu group M11\nGroup([ (2,10)(4,11)(5,7)(8,9), (1,4,3,8)(2,5,6,9) ])\n\njulia> atlas_group(\"M\") # Monster group M\nERROR: ArgumentError: the group atlas does not provide a representation for M\n\n\n\n\n\natlas_group(info::Dict)\n\nReturn the group from the Atlas of Group Representations that is defined by info. Typically, info is obtained from all_atlas_group_infos.\n\nExamples\n\njulia> info = all_atlas_group_infos(\"A5\", degree => 5)\n1-element Vector{Dict{Symbol, Any}}:\n Dict(:repname => \"A5G1-p5B0\", :degree => 5, :name => \"A5\")\n\njulia> atlas_group(info[1])\nGroup([ (1,2)(3,4), (1,3,5) ])\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#atlas_subgroup","page":"Group libraries","title":"atlas_subgroup","text":"atlas_subgroup(G::GAPGroup, nr::Int)\natlas_subgroup([::Type{T}, ]name::String, nr::Int) where T <: Union{PermGroup, MatrixGroup}\natlas_subgroup(info::Dict, nr::Int)\n\nReturn a pair (H, emb) where H is a representative of the nr-th class of maximal subgroups of the group G, and emb is an embedding of H into G.\n\nThe group G can be given as the first argument, in this case it is assumed that G has been created with atlas_group. Otherwise G is the group obtained by calling atlas_group with (T and) name or with info.\n\nIf the Atlas of Group Representations does not provide the information to compute G or to compute generators of H from G then an exception is thrown.\n\nExamples\n\njulia> g = atlas_group(\"M11\"); # Mathieu group M11\n\njulia> h1, emb = atlas_subgroup(g, 1); h1\nGroup([ (1,4)(2,10)(3,7)(6,9), (1,6,10,7,11,3,9,2)(4,5) ])\n\njulia> order(h1) # largest maximal subgroup of M11\n720\n\njulia> h2, emb = atlas_subgroup(\"M11\", 1); h2\nGroup([ (1,4)(2,10)(3,7)(6,9), (1,6,10,7,11,3,9,2)(4,5) ])\n\njulia> h3, emb = atlas_subgroup(MatrixGroup, \"M11\", 1 ); h3\nMatrix group of degree 10 over Finite field of degree 1 over GF(2)\n\njulia> info = all_atlas_group_infos(\"M11\", degree => 11);\n\njulia> h4, emb = atlas_subgroup(info[1], 1); h4\nGroup([ (1,4)(2,10)(3,7)(6,9), (1,6,10,7,11,3,9,2)(4,5) ])\n\n\n\n\n\n","category":"function"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"StraightLinePrograms/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"This is the documentation of the straight-line programs (SLP) implementation by Rafael Fourquet. Originally this was supposed to become a separate Julia module, however it has now been incorporated into the OSCAR core.","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"The main SLP type is SLProgram, to which other types can \"compile\" (or \"transpile\"). The easiest way to create an SLProgram is to combine \"generators\":","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"julia> using Oscar;\n\njulia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;\n\njulia> x, y, z = SLP.gens(SLProgram, 3)\n3-element Vector{SLProgram{Union{}}}:\n x\n y\n z\n\njulia> p = (x*y^2 + 1.3*z)^-1\n#1 = ^ y 2 ==> y^2\n#2 = * x #1 ==> (x*y^2)\n#3 = * 1.3 z ==> (1.3*z)\n#4 = + #2 #3 ==> ((x*y^2) + (1.3*z))\n#5 = ^ #4 -1 ==> ((x*y^2) + (1.3*z))^-1\nreturn: #5","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"On the right side of the above output is the representation of the computation so far. It's done via another SLP type (tentatively) called Lazy which represent \"formulas\" as trees:","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"julia> using Oscar;\n\njulia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;\n\njulia> x, y, z = SLP.gens(SLProgram, 3);\n\njulia> p = (x*y^2 + 1.3*z)^-1;\n\njulia> X, Y, Z = SLP.gens(Lazy, 3)\n3-element Vector{Lazy}:\n x\n y\n z\n\njulia> q = (X*Y^2 + 1.3*Z)^-1\n((x*y^2) + (1.3*z))^-1\n\njulia> f = SLP.evaluate(p, [X, Y, Z])\n((x*y^2) + (1.3*z))^-1\n\njulia> SLP.evaluate(f, [X, Y, Z]) == f\ntrue\n\njulia> SLP.evaluate(p, Any[x, y, z]) == p\ntrue\n\njulia> dump(q) # q::Lazy is a tree\nOscar.StraightLinePrograms.Lazy\n x: Oscar.StraightLinePrograms.Exp\n p: Oscar.StraightLinePrograms.Plus\n xs: Array{Oscar.StraightLinePrograms.LazyRec}((2,))\n 1: Oscar.StraightLinePrograms.Times\n xs: Array{Oscar.StraightLinePrograms.LazyRec}((2,))\n 1: Oscar.StraightLinePrograms.Input\n n: Int64 1\n 2: Oscar.StraightLinePrograms.Exp\n p: Oscar.StraightLinePrograms.Input\n n: Int64 2\n e: Int64 2\n 2: Oscar.StraightLinePrograms.Times\n xs: Array{Oscar.StraightLinePrograms.LazyRec}((2,))\n 1: Oscar.StraightLinePrograms.Const{Float64}\n c: Float64 1.3\n 2: Oscar.StraightLinePrograms.Input\n n: Int64 3\n e: Int64 -1\n gens: Array{Symbol}((3,))\n 1: Symbol x\n 2: Symbol y\n 3: Symbol z","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"Evaluation of SLPs is done via evaluate, which can take a vector of anything which supports the operations used in the SLP (e.g. *, + and ^ in this example; - is also supported but division not yet). Note that currently, the eltype of the input vector for SLProgram must be a supertype of any intermediate computation (so it's always safe to pass a Vector{Any}).","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"julia> using Oscar;\n\njulia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;\n\njulia> x, y, z = SLP.gens(SLProgram, 3);\n\njulia> p = (x*y^2 + 1.3*z)^-1;\n\njulia> X, Y, Z = SLP.gens(Lazy, 3);\n\n\njulia> SLP.evaluate(p, [2.0, 3.0, 5.0])\n0.04081632653061224\n\njulia> SLP.evaluate(X*Y^2, ['a', 'b'])\n\"abb\"","category":"page"},{"location":"StraightLinePrograms/intro/#Returning-multiple-values","page":"Introduction","title":"Returning multiple values","text":"","category":"section"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"There is a low-level interface to return multiple values from an SLProgram; for example, to return the second and last intermediate values from p above, we would \"assign\" these values to positions #1 and #2, delete all other positions (via the \"keep\" operation), and return the resulting array (the one used for intermediate computations):","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"julia> using Oscar;\n\njulia> using Oscar.StraightLinePrograms; const SLP = Oscar.StraightLinePrograms;\n\njulia> x, y, z = SLP.gens(SLProgram, 3);\n\njulia> p = (x*y^2 + 1.3*z)^-1;\n\njulia> X, Y, Z = SLP.gens(Lazy, 3);\n\n\njulia> SLP.pushop!(p, SLP.assign, SLP.Arg(2), SLP.Arg(1))\n SLP.pushop!(p, SLP.assign, SLP.Arg(5), SLP.Arg(2))\n SLP.pushop!(p, SLP.keep, SLP.Arg(2))\n SLP.setmultireturn!(p)\n#1 = ^ y 2 ==> y^2\n#2 = * x #1 ==> (x*y^2)\n#3 = * 1.3 z ==> (1.3*z)\n#4 = + #2 #3 ==> ((x*y^2) + (1.3*z))\n#5 = ^ #4 -1 ==> ((x*y^2) + (1.3*z))^-1\n#1 = #2 ==> (x*y^2)\n#2 = #5 ==> ((x*y^2) + (1.3*z))^-1\nkeep: #1..#2\nreturn: [#1, #2]\n\njulia> SLP.evaluate(p, [X, Y, Z])\nlist([(x*y^2), ((x*y^2) + (1.3*z))^-1])","category":"page"},{"location":"StraightLinePrograms/intro/#Straight-line-decisions","page":"Introduction","title":"Straight line decisions","text":"","category":"section"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"A \"decision\" is a special operation which allows to stop prematurely the execution of the program if a condition is false, and the program returns true if no condition failed. Currently, the interface is modeled after GAP's SLPs and defaults to testing the AbstractAlgebra.order of an element. More specifically, test(prg, n::Integer) tests whether the order of the result of prg is equal to n, and dec1 & dec2 chains two programs with a short-circuiting behavior:","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"julia> p1 = SLP.test(x*y^2, 2)\n#1 = ^ y 2 ==> y^2\n#2 = * x #1 ==> (xy^2)\ntest: order(#2) == 2 || return false\nreturn: true\n\njulia> p2 = SLP.test(y, 4)\ntest: order(y) == 4 || return false\nreturn: true\n\njulia> p1 & p2\n#1 = ^ y 2 ==> y^2\n#2 = * x #1 ==> (xy^2)\ntest: order(#2) == 2 || return false\ntest: order(y) == 4 || return false\nreturn: true\n\njulia> SLP.evaluate(p1 & p2, [X, Y])\ntest((xy^2), 2) & test(y, 4)\n\njulia> using AbstractAlgebra; perm1, perm2 = perm\"(1, 4)\", perm\"(1, 3, 4, 2)\";\n\njulia> SLP.evaluate(p1 & p2, [perm1, perm2])\ntrue\n\njulia> SLP.evaluate(p1 & p2, [perm2, perm1])\nfalse","category":"page"},{"location":"StraightLinePrograms/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"Thomas Breuer,\nRaphael Fourquet.","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"StraightLinePrograms/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/mseries/#Multivariate-series","page":"Multivariate series","title":"Multivariate series","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"AbstractAlgebra.jl provide multivariate series over a commutative ring.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Series with capped absolute precision are provided with and without weights.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"For the unweighted case precision in each variable can be set per series, but is capped at some maximum precision which is set when defining the ring.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"For the weighted case, a single precision is set on the ring only. Terms are truncated at that precision (after applying weights).","category":"page"},{"location":"AbstractAlgebra/mseries/#Generic-multivariate-series","page":"Multivariate series","title":"Generic multivariate series","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Generic multivariate series over a commutative ring, AbsMSeries{T} is implemented in src/generic/AbsMSeries.jl.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Such series are capped absolute series and have type Generic.AbsMSeries{T} where T is the type of elements of the coefficient ring.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Internally they consist of a multivariate polynomial. For unweighted series they also contain a vector of precisions, one for each variable.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"For weighted series weights and a precision are stored on the ring only. The vector of precisions in the series objects is ignored.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"See the file src/generic/GenericTypes.jl for details of the type.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"The series are implemented in terms of multivariate polynomials which are used internally to keep track of the coefficients of the series.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Only lex ordering is provided at present both weighted and unweighted, though series print in reverse order to what multivariate polynomials would print, i.e. least significant term first, as would be expected for series.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Parent objects of such series have type Generic.AbsMSeriesRing{T}.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"The symbol representation of the variables and the multivariate polynomial ring is stored in the parent object.","category":"page"},{"location":"AbstractAlgebra/mseries/#Abstract-types","page":"Multivariate series","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Multivariate series element types belong to the abstract type MSeriesElem{T} and the multivariate series ring types belong to the abstract type MSeriesRing{T}. This enables one to write generic functions that can accept any AbstractAlgebra multivariate series type.","category":"page"},{"location":"AbstractAlgebra/mseries/#Multivariate-series-ring-constructors","page":"Multivariate series","title":"Multivariate series ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"In order to construct multivariate series in AbstractAlgebra.jl, one must first construct the series ring itself. This is accomplished with the following constructors.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"For the unweighted case:","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"power_series_ring(R::Ring, prec::Vector{Int}, s::AbstractVector{<:VarName}; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Given a base ring R and a vector of strings s specifying how the generators (variables) should be printed, along with a vector of precisions, one for each variable, return a tuple U, (x, y, ...) representing the new series ring S and the generators x y ldots of the ring as a tuple. By default the parent object S will depend on R, the precision vector and the variable names x, y, ... and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"In the weighted case:","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"power_series_ring(R::Ring, weights::Vector{Int}, s::AbstractVector{<:VarName}, prec::Int; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Given a base ring R and a vector of strings s specifying how the generators (variables) should be printed, along with a vector of weights, one for each variable and a bound on the (weighted) precision, return a tuple U, (x, y, ...) representing the new series ring S and the generators x y ldots of the ring as a tuple. By default the parent object S will depend on R, the precision, the vector of weights and the variable names x, y, ... and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Here are some examples of creating multivariate series rings and making use of the resulting parent objects to coerce various elements into the series ring.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Note that one can also use the function call O(x^n) with unweighted series to specify the precision in the variable x of a given series expression should be precision n.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"note: Note\nIt is not possible to use x^0 in the O() function, since there is no distinction between x^0 and y^0 as far as the system is concerned. If one wishes to set the precision of a variable to precision 0, one must use the set_precision! function described below.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"If one wants a series with the same precision in all variables, one can use O(R, n) where R is the series ring and n is the desired precision.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"If all the precisions are to be the same, the vector of integers for the precisions can be replaced by a single integer in the constructor.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"julia> R, (x, y) = power_series_ring(ZZ, [2, 3], [\"x\", \"y\"])\n(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(y^3) + O(x^2), y + O(y^3) + O(x^2)])\n\njulia> f = R()\nO(y^3) + O(x^2)\n\njulia> g = R(123)\n123 + O(y^3) + O(x^2)\n\njulia> h = R(BigInt(1234))\n1234 + O(y^3) + O(x^2)\n\njulia> k = R(x + 1)\n1 + x + O(y^3) + O(x^2)\n\njulia> m = x + y + O(y^2)\ny + x + O(y^2) + O(x^2)\n\njulia> R, (x, y) = power_series_ring(ZZ, 3, [\"x\", \"y\"])\n(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(y^3) + O(x^3), y + O(y^3) + O(x^3)])\n\njulia> n = x + y + O(R, 2)\ny + x + O(y^2) + O(x^2)\n\njulia> R, (x, y) = power_series_ring(ZZ, [2, 3], 10, [\"x\", \"y\"])\n(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(10), y + O(10)])\n\njulia> R()\nO(10)\n\njulia> R(x)\nx + O(10)","category":"page"},{"location":"AbstractAlgebra/mseries/#Basic-ring-functionality","page":"Multivariate series","title":"Basic ring functionality","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Once a multivariate series ring is constructed, there are various ways to construct series in that ring.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"The easiest way is simply using the generators returned by the power_series_ring constructor and build up the power series using basic arithmetic, as described in the Ring interface.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"The power series rings in AbstractAlgebra.jl implement the full Ring interface.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"We give some examples of such functionality. ","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"note: Note\nThe divexact function can currently only divide by unit series (i.e. whose constant coefficient is invertible).","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"julia> R, (x,) = power_series_ring(ZZ, [5], [\"x\"])\n(Multivariate power series ring in 1 variable over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(x^5)])\n\njulia> f = x^3 + 3x + 21\n21 + 3*x + x^3 + O(x^5)\n\njulia> h = zero(R)\nO(x^5)\n\njulia> k = one(R)\n1 + O(x^5)\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> n = length(f)\n3\n\njulia> U = base_ring(R)\nIntegers\n\njulia> v = symbols(R)\n1-element Vector{Symbol}:\n :x\n\njulia> T = parent(x + 1)\nMultivariate power series ringin 1 variable x\n over integers\n\njulia> f == deepcopy(f)\ntrue\n\njulia> t = divexact(f*x, 1 + x)\n21*x - 18*x^2 + 18*x^3 - 17*x^4 + O(x^5)\n\njulia> R, (x, y) = power_series_ring(ZZ, [2, 3], 10, [\"x\", \"y\"])\n(Multivariate power series ring in 2 variables over integers, AbstractAlgebra.Generic.AbsMSeries{BigInt, AbstractAlgebra.Generic.MPoly{BigInt}}[x + O(10), y + O(10)])\n\njulia> f = 3x^2*y + 1\n1 + 3*y*x^2 + O(10)\n\njulia> one(R)\n1 + O(10)","category":"page"},{"location":"AbstractAlgebra/mseries/#Power-series-functionality-provided-by-AbstractAlgebra.jl","page":"Multivariate series","title":"Power series functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"The functionality listed below is automatically provided by AbstractAlgebra.jl for absolute series over any commutative ring.","category":"page"},{"location":"AbstractAlgebra/mseries/#Basic-functionality","page":"Multivariate series","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"The following are provided for weighted and unweighted series:","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"nvars(::Generic.AbsMSeriesRing)","category":"page"},{"location":"AbstractAlgebra/mseries/#nvars-Tuple{AbstractAlgebra.Generic.AbsMSeriesRing}","page":"Multivariate series","title":"nvars","text":"nvars(R::AbsMSeriesRing)\n\nReturn the number of variables in the series ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"symbols(::MSeriesRing)","category":"page"},{"location":"AbstractAlgebra/mseries/#symbols-Tuple{AbstractAlgebra.MSeriesRing}","page":"Multivariate series","title":"symbols","text":"symbols(R::MSeriesRing)\n\nReturn a vector of symbols, one for each of the variables of the series ring R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"precision(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#precision-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"precision","text":"precision(a::AbsMSeries)\n\nReturn a vector of precisions, one for each variable in the series ring. If the ring is weighted the weighted precision is returned instead.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"coeff(::Generic.AbsMSeries, ::Int)","category":"page"},{"location":"AbstractAlgebra/mseries/#coeff-Tuple{AbstractAlgebra.Generic.AbsMSeries, Int64}","page":"Multivariate series","title":"coeff","text":"coeff(a::AbsMSeries, n::Int)\n\nReturn the coefficient of the n-th nonzero term of the series (or zero if there are fewer than n nonzero terms). Terms are numbered from the least significant term, i.e. the first term displayed when the series is printed.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"characteristic(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#characteristic-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"characteristic","text":"characteristic(R::FracField{T}) where T <: RingElem\n\nReturn the characteristic of the given field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"gen(::Generic.AbsMSeriesRing, ::Int)","category":"page"},{"location":"AbstractAlgebra/mseries/#gen-Tuple{AbstractAlgebra.Generic.AbsMSeriesRing, Int64}","page":"Multivariate series","title":"gen","text":"gen(R::AbsMSeriesRing, i::Int)\n\nReturn the i-th generator (variable) of the series ring R. Numbering starts from 1 for the most significant variable.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"gens(::Generic.AbsMSeriesRing)","category":"page"},{"location":"AbstractAlgebra/mseries/#gens-Tuple{AbstractAlgebra.Generic.AbsMSeriesRing}","page":"Multivariate series","title":"gens","text":"gens(R::AbsMSeriesRing)\n\nReturn a vector of the generators (variables) of the series ring R, starting with the most significant.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"is_gen(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#is_gen-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"is_gen","text":"is_gen(a::AbsMSeries)\n\nReturn true if the series a is a generator of its parent series ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"is_unit(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#is_unit-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"is_unit","text":"is_unit(a::AbsMSeries)\n\nReturn true if the series is a unit in its series ring, i.e. if its constant term is a unit in the base ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"length(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#length-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"length","text":"length(a::AbsMSeries)\n\nReturn the number of nonzero terms in the series a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"The following are only available for unweighted series.","category":"page"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"max_precision(::Generic.AbsMSeriesRing)","category":"page"},{"location":"AbstractAlgebra/mseries/#max_precision-Tuple{AbstractAlgebra.Generic.AbsMSeriesRing}","page":"Multivariate series","title":"max_precision","text":"max_precision(R::AbsMSeriesRing)\n\nReturn a vector of precision caps, one for each variable in the ring. Arithmetic operations will be performed to precisions not exceeding these values.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"valuation(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#valuation-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"valuation","text":"valuation(a::AbsMSeries)\n\nReturn the valuation of a as a vector of integers, one for each variable.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/#Iteration","page":"Multivariate series","title":"Iteration","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"coefficients(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#coefficients-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"coefficients","text":"coefficients(a::AbsMSeries)\n\nReturn an array of the nonzero coefficients of the series, in the order they would be displayed, i.e. least significant term first.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"exponent_vectors(::Generic.AbsMSeries)","category":"page"},{"location":"AbstractAlgebra/mseries/#exponent_vectors-Tuple{AbstractAlgebra.Generic.AbsMSeries}","page":"Multivariate series","title":"exponent_vectors","text":"exponent_vectors(a::AbsMSeries)\n\nReturn an array of the exponent vectors of the nonzero terms of the series, in the order they would be displayed, i.e. least significant term first.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/#Truncation","page":"Multivariate series","title":"Truncation","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"truncate(::Generic.AbsMSeries, ::Vector{Int})\ntruncate(::Generic.AbsMSeries, ::Int)","category":"page"},{"location":"AbstractAlgebra/mseries/#truncate-Tuple{AbstractAlgebra.Generic.AbsMSeries, Vector{Int64}}","page":"Multivariate series","title":"truncate","text":"truncate(a::AbstractAlgebra.AbsMSeries, prec::Vector{Int})\n\nReturn a truncated to (absolute) precisions given by the vector prec.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/#truncate-Tuple{AbstractAlgebra.Generic.AbsMSeries, Int64}","page":"Multivariate series","title":"truncate","text":"truncate(a::AbstractAlgebra.AbsMSeries, prec::Int)\n\nReturn a truncated to precision prec. This either truncates by weight in the weighted cases or truncates each variable to precision prec in the unweighted case.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/#Exact-division","page":"Multivariate series","title":"Exact division","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"divexact(::Generic.AbsMSeries{T}, ::Generic.AbsMSeries{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mseries/#divexact-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.AbsMSeries{T}, AbstractAlgebra.Generic.AbsMSeries{T}}} where T<:RingElem","page":"Multivariate series","title":"divexact","text":"divexact(x::AbsMSeries{T}, y::AbsMSeries{T}; check::Bool=true) where T <: RingElement\n\nReturn the exact quotient of the series x by the series y. This function currently assumes y is an invertible series.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/#Evaluation","page":"Multivariate series","title":"Evaluation","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"evaluate(::U, ::Vector{Int}, ::Vector{U}) where {T <: RingElement, U <: Generic.AbsMSeries{T}}","category":"page"},{"location":"AbstractAlgebra/mseries/#evaluate-Union{Tuple{U}, Tuple{T}, Tuple{U, Vector{Int64}, Vector{U}}} where {T<:RingElement, U<:(AbstractAlgebra.Generic.AbsMSeries{T})}","page":"Multivariate series","title":"evaluate","text":"evaluate(a::U, vars::Vector{Int}, vals::Vector{U}) where {T <: RingElement, U <: AbsMSeries{T}}\n\nEvaluate the series expression by substituting in the supplied values in the array vals for the corresponding variables with indices given by the array vars. The values must be in the same ring as a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"evaluate(::U, ::Vector{U}, ::Vector{U}) where {T <: RingElement, U <: Generic.AbsMSeries{T}}","category":"page"},{"location":"AbstractAlgebra/mseries/#evaluate-Union{Tuple{U}, Tuple{T}, Tuple{U, Vector{U}, Vector{U}}} where {T<:RingElement, U<:(AbstractAlgebra.Generic.AbsMSeries{T})}","page":"Multivariate series","title":"evaluate","text":"evaluate(a::U, vars::Vector{U}, vals::Vector{U}) where {T <: RingElement, U <: AbsMSeries{T}}\n\nEvaluate the series expression by substituting in the supplied values in the array vals for the corresponding variables given by the array vars. The values must be in the same ring as a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"evaluate(::U, ::Vector{U}) where {T <: RingElement, U <: Generic.AbsMSeries{T}}","category":"page"},{"location":"AbstractAlgebra/mseries/#evaluate-Union{Tuple{U}, Tuple{T}, Tuple{U, Vector{U}}} where {T<:RingElement, U<:(AbstractAlgebra.Generic.AbsMSeries{T})}","page":"Multivariate series","title":"evaluate","text":"evaluate(a::U, vals::Vector{U}) where {T <: RingElement, U <: AbsMSeries{T}}\n\nEvaluate the series expression by substituting in the supplied values in the array vals for the variables the series ring to which a belongs. The values must be in the same ring as a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mseries/#Random-generation","page":"Multivariate series","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/mseries/","page":"Multivariate series","title":"Multivariate series","text":"rand(::MSeriesRing, term_range, v...)","category":"page"},{"location":"AbstractAlgebra/mseries/#rand-Tuple{AbstractAlgebra.MSeriesRing, Any, Vararg{Any}}","page":"Multivariate series","title":"rand","text":"rand(S::MSeriesRing, term_range, v...)\n\nReturn a random element of the series ring S with number of terms in the range given by term_range and where coefficients of the series are randomly generated in the base ring using the data given by v. The exponents of the variable in the terms will be less than the precision caps for the Ring S when it was created.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#Divisors","page":"Divisors","title":"Divisors","text":"","category":"section"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"In order to consider divisors on curves, we restrict our attention to smooth and irreducible curves.","category":"page"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"Let C be an affine or projective plane curve defined by an irreducible equation F. Then any polynomial function G which is not divisible by F will vanish on C only at finitely many points. A way to encode these points together with their intersection multiplicities is to consider a divisor. A divisor on a curve is a formal finite sum of points of the curve with integer coefficients. A natural operation of addition can be defined on the set of divisors of a curve, which turns it into an Abelian group.","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#Constructors","page":"Divisors","title":"Constructors","text":"","category":"section"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"Divisors on curves are here introduced as a dictionary associating a point on the curve to its multiplicity.","category":"page"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"AffineCurveDivisor","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#AffineCurveDivisor","page":"Divisors","title":"AffineCurveDivisor","text":"AffineCurveDivisor(C::AffinePlaneCurve{S}, D::Dict{Point{S}, Int}) where S <: FieldElem\n\nGiven a curve C which is assumed to be smooth and irreducible, return the divisor on the curve C defined by D.\n\nExamples\n\njulia> R, (x,y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^2 + y + x^2)\nAffine plane curve defined by x^2 + y^2 + y\n\njulia> P = Point([QQ(0), QQ(0)])\nPoint with coordinates QQFieldElem[0, 0]\n\njulia> Q = Point([QQ(0), QQ(-1)])\nPoint with coordinates QQFieldElem[0, -1]\n\njulia> Oscar.AffineCurveDivisor(C, Dict(P => 3, Q => -2))\n-2*QQFieldElem[0, -1] + 3*QQFieldElem[0, 0]\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"ProjCurveDivisor","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#ProjCurveDivisor","page":"Divisors","title":"ProjCurveDivisor","text":"ProjCurveDivisor(C::ProjPlaneCurve{S}, D::Dict{Oscar.Geometry.ProjSpcElem{S}, Int}) where S <: FieldElem\n\nGiven a curve C which is assumed to be smooth and irreducible, return the divisor on the curve C defined by D.\n\nExamples\n\njulia> S, (x,y,z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2 + y*z + x^2))\nProjective plane curve defined by x^2 + y^2 + y*z\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])\n(0 : 0 : 1)\n\njulia> Q = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(-1), QQ(1)])\n(0 : -1 : 1)\n\njulia> D = Oscar.ProjCurveDivisor(C, Dict(P => 3, Q => -2))\n-2*(0 : 1 : -1) + 3*(0 : 0 : 1)\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"To define the divisor 0 of the group of divisors, one uses the following method:","category":"page"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"curve_zero_divisor(C::ProjPlaneCurve{S}) where S <: FieldElem\ncurve_zero_divisor(C::AffinePlaneCurve{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#curve_zero_divisor-Union{Tuple{ProjPlaneCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Divisors","title":"curve_zero_divisor","text":"curve_zero_divisor(C::ProjPlaneCurve{S}) where S <: FieldElem\n\nReturn the divisor 0 on the curve C.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#curve_zero_divisor-Union{Tuple{AffinePlaneCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Divisors","title":"curve_zero_divisor","text":"curve_zero_divisor(C::AffinePlaneCurve{S}) where S <: FieldElem\n\nReturn the divisor 0 on the curve C.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#Methods","page":"Divisors","title":"Methods","text":"","category":"section"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"The following functions on divisors of curves are implemented.","category":"page"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"curve(D::Oscar.PlaneCurveModule.CurveDivisor)\ndegree(D::Oscar.PlaneCurveModule.CurveDivisor)\nis_effective(D::Oscar.PlaneCurveModule.CurveDivisor)\nis_linearly_equivalent(D::ProjCurveDivisor, E::ProjCurveDivisor)\nis_principal(D::ProjCurveDivisor{S}) where S <: FieldElem\nprincipal_divisor(D::ProjCurveDivisor{S}) where S <: FieldElem\nglobal_sections(D::ProjCurveDivisor)\ndimension_global_sections(D::ProjCurveDivisor)","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#curve-Tuple{Oscar.PlaneCurveModule.CurveDivisor}","page":"Divisors","title":"curve","text":"curve(D::CurveDivisor)\n\nReturn the curve on which the divisor is considered.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#degree-Tuple{Oscar.PlaneCurveModule.CurveDivisor}","page":"Divisors","title":"degree","text":"degree(D::CurveDivisor)\n\nReturn the degree of the divisor.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#is_effective-Tuple{Oscar.PlaneCurveModule.CurveDivisor}","page":"Divisors","title":"is_effective","text":"is_effective(D::CurveDivisor)\n\nReturn true if D is an effective divisor, false otherwise.\n\nExamples\n\njulia> R, (x,y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> C = AffinePlaneCurve(y^2 + y + x^2)\nAffine plane curve defined by x^2 + y^2 + y\n\njulia> P = Point([QQ(0), QQ(0)])\nPoint with coordinates QQFieldElem[0, 0]\n\njulia> Q = Point([QQ(0), QQ(-1)])\nPoint with coordinates QQFieldElem[0, -1]\n\njulia> D = Oscar.AffineCurveDivisor(C, Dict(P => 3, Q => -2))\n-2*QQFieldElem[0, -1] + 3*QQFieldElem[0, 0]\n\njulia> Oscar.is_effective(D)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#is_linearly_equivalent-Tuple{Oscar.PlaneCurveModule.ProjCurveDivisor, Oscar.PlaneCurveModule.ProjCurveDivisor}","page":"Divisors","title":"is_linearly_equivalent","text":"is_linearly_equivalent(D::ProjCurveDivisor, E::ProjCurveDivisor)\n\nReturn true if the divisors D and E are linearly equivalent, and false otherwise\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))\nProjective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])\n(0 : 1 : 0)\n\njulia> R = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])\n(0 : 0 : 1)\n\njulia> E = Oscar.ProjCurveDivisor(C, P)\n(0 : 1 : 0)\n\njulia> F = Oscar.ProjCurveDivisor(C, R)\n(0 : 0 : 1)\n\njulia> Oscar.is_linearly_equivalent(E, F)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#is_principal-Union{Tuple{Oscar.PlaneCurveModule.ProjCurveDivisor{S}}, Tuple{S}} where S<:FieldElem","page":"Divisors","title":"is_principal","text":"is_principal(D::ProjCurveDivisor{S}) where S <: FieldElem\n\nReturn true if the divisor D is principal, and false otherwise\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))\nProjective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])\n(0 : 1 : 0)\n\njulia> E = Oscar.ProjCurveDivisor(C, P)\n(0 : 1 : 0)\n\njulia> Oscar.is_principal(E)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#principal_divisor-Union{Tuple{Oscar.PlaneCurveModule.ProjCurveDivisor{S}}, Tuple{S}} where S<:FieldElem","page":"Divisors","title":"principal_divisor","text":"principal_divisor(D::ProjCurveDivisor{S}) where S <: FieldElem\n\nIf the divisor D is principal, return a rational function phi such that D is linearly equivalent to the divisor defined by phi.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))\nProjective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])\n(0 : 1 : 0)\n\njulia> R = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])\n(0 : 0 : 1)\n\njulia> E = Oscar.ProjCurveDivisor(C, P, 2)\n2*(0 : 1 : 0)\n\njulia> F = Oscar.ProjCurveDivisor(C, R, 2)\n2*(0 : 0 : 1)\n\njulia> G = 2*E - 2*F\n4*(0 : 1 : 0) - 4*(0 : 0 : 1)\n\njulia> Oscar.principal_divisor(G)\nx^2//z^2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#global_sections-Tuple{Oscar.PlaneCurveModule.ProjCurveDivisor}","page":"Divisors","title":"global_sections","text":"global_sections(D::ProjCurveDivisor)\n\nReturn a set of generators of the global sections of the sheaf associated to the divisor D of a smooth and irreducible projective curve.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2*z - x*(x-z)*(x+3*z)))\nProjective plane curve defined by -x^3 - 2*x^2*z + 3*x*z^2 + y^2*z\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(1), QQ(0)])\n(0 : 1 : 0)\n\njulia> D = Oscar.ProjCurveDivisor(C, P, 4)\n4*(0 : 1 : 0)\n\njulia> Oscar.global_sections(D)\n4-element Vector{AbstractAlgebra.Generic.Frac{QQMPolyRingElem}}:\n 1\n y//z\n x//z\n x^2//z^2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#dimension_global_sections-Tuple{Oscar.PlaneCurveModule.ProjCurveDivisor}","page":"Divisors","title":"dimension_global_sections","text":"dimension_global_sections(D::ProjCurveDivisor)\n\nReturn the dimension of the global sections of the sheaf associated to the divisor D of a smooth and irreducible projective curve.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"In addition, the multiplicity of a polynomial or a fraction at a given point can be computed:","category":"page"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"multiplicity(C::AffinePlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}, P::Point{S}) where {S <: FieldElem, T <: MPolyRingElem{S}}\nmultiplicity(C::AffinePlaneCurve{S}, F::Oscar.MPolyRingElem{S}, P::Point{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#multiplicity-Union{Tuple{T}, Tuple{S}, Tuple{AffinePlaneCurve{S}, AbstractAlgebra.Generic.Frac{T}, Point{S}}} where {S<:FieldElem, T<:MPolyRingElem{S}}","page":"Divisors","title":"multiplicity","text":"multiplicity(C::AffinePlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}, P::Point{S}) where {S <: FieldElem, T <: MPolyRingElem{S}}\nmultiplicity(C::ProjPlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}, P::Oscar.Geometry.ProjSpcElem{S}) where {S <: FieldElem, T <: Oscar.MPolyDecRingElem{S}}\n\nReturn the multiplicity of the rational function phi on the curve C at the point P.\n\nExamples\n\njulia> S, (x,y,z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2 + y*z + x^2))\nProjective plane curve defined by x^2 + y^2 + y*z\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(0), QQ(1)])\n(0 : 0 : 1)\n\njulia> phi = T(x)//T(y)\nx//y\n\njulia> multiplicity(C, phi, P)\n-1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#multiplicity-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, MPolyRingElem{S}, Point{S}}} where S<:FieldElem","page":"Divisors","title":"multiplicity","text":"multiplicity(C::AffinePlaneCurve{S}, F::Oscar.MPolyRingElem{S}, P::Point{S}) where S <: FieldElem\nmultiplicity(C::ProjPlaneCurve{S}, F::Oscar.MPolyDecRingElem{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\n\nReturn the multiplicity of the polynomial F on the curve C at the point P.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"The divisor of a polynomial or a fraction along a plane curve can be computed, but will give only the points which belong to the base field.","category":"page"},{"location":"Experimental/PlaneCurve/divisors/","page":"Divisors","title":"Divisors","text":"divisor(C::AffinePlaneCurve{S}, F::Oscar.MPolyRingElem{S}) where S <: FieldElem\ndivisor(C::AffinePlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}) where {S <: FieldElem, T <: MPolyRingElem{S}}\ndivisor([PP::Oscar.Geometry.ProjSpc{S}], C::ProjPlaneCurve{S}, F::Oscar.MPolyDecRingElem{S}) where S <: FieldElem\ndivisor(PP::Oscar.Geometry.ProjSpc{S}, C::ProjPlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}) where {S <: FieldElem, T <: Oscar.MPolyDecRingElem{S}}","category":"page"},{"location":"Experimental/PlaneCurve/divisors/#divisor-Union{Tuple{S}, Tuple{AffinePlaneCurve{S}, MPolyRingElem{S}}} where S<:FieldElem","page":"Divisors","title":"divisor","text":"divisor(C::AffinePlaneCurve{S}, F::Oscar.MPolyRingElem{S}) where S <: FieldElem\n\nReturn the divisor defined by the polynomial F on the curve C.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#divisor-Union{Tuple{T}, Tuple{S}, Tuple{AffinePlaneCurve{S}, AbstractAlgebra.Generic.Frac{T}}} where {S<:FieldElem, T<:MPolyRingElem{S}}","page":"Divisors","title":"divisor","text":"divisor(C::AffinePlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}) where {S <: FieldElem, T <: MPolyRingElem{S}}\n\nReturn the divisor defined by the rational function phi on the curve C.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#divisor-Union{Tuple{S}, Tuple{Oscar.Geometry.ProjSpc{S}, ProjPlaneCurve{S}, MPolyDecRingElem{S}}} where S<:FieldElem","page":"Divisors","title":"divisor","text":"divisor([PP::Oscar.Geometry.ProjSpc{S}], C::ProjPlaneCurve{S}, F::Oscar.MPolyDecRingElem{S}) where S <: FieldElem\n\nReturn the divisor defined by the polynomial F on the curve C. The points of the divisor are in the projective space PP if specified, or in a new projective space otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/divisors/#divisor-Union{Tuple{T}, Tuple{S}, Tuple{Oscar.Geometry.ProjSpc{S}, ProjPlaneCurve{S}, AbstractAlgebra.Generic.Frac{T}}} where {S<:FieldElem, T<:(MPolyDecRingElem{S})}","page":"Divisors","title":"divisor","text":"divisor(PP::Oscar.Geometry.ProjSpc{S}, C::ProjPlaneCurve{S}, phi::AbstractAlgebra.Generic.Frac{T}) where {S <: FieldElem, T <: Oscar.MPolyDecRingElem{S}}\n\nReturn the divisor defined by the rational function phi on the curve C.\n\nExamples\n\njulia> S, (x,y,z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> C = ProjPlaneCurve(T(y^2 + y*z + x^2))\nProjective plane curve defined by x^2 + y^2 + y*z\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> phi = T(x)//T(y)\nx//y\n\njulia> Oscar.divisor(PP[1], C, phi)\n(0 : 1 : -1) - (0 : 0 : 1)\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"We start our discussion of PBW-algebras by recalling their definition. Let K be a field. Given a set of variables x=x_1 ldots x_n we write leftlangle xrightrangle=langle x_1ldots x_n rangle for the free monoid on x. That is, the elements of langle x rangle are the words in the finite alphabet x, multiplication means concatenation of words, and the identity element is the empty word. The free associative K-algebra generated by x_1dots x_n is the corresponding monoid algebra","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"K langle xrangle= K langle x_1dots x_n rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"We consider quotients of type A = Klangle x_1 dots x_n rangleJ, for some n and some two-sided ideal J of Klangle x_1 dots x_n rangle. In case J is given by a finite set of two-sided generators g_1 dots g_r, we say that A is generated by x_1 dots x_n, subject to the relations g_1 = 0 dots g_r = 0, and write","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"A = Klangle x_1 dots x_n mid g_k=0 1leq k leq r rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"The relations considered in this chapter are \"commutation relations\", written as","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"x_jx_i = c_ijx_ix_j+d_ij","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Working with Gröbner bases requires that we take monomial orderings into account (see the section on Gröbner bases in the commutative algebra chapter for monomial orderings). In our context here, we use the following notation. A standard monomial in K langle x rangle is a word of type x^alpha=x_1^alpha_1cdots x_n^alpha_n where alpha=(alpha_1dotsalpha_n)inmathbb N^n. A standard polynomial in K langle x rangle is a K-linear combination of standard monomials. Each global monomial ordering on Kx gives rise to a (total) well-ordering on the set of standard monomials. Abusing our notation, we denote the induced ordering again by , and refer to it as a global monomial ordering on A. Given , it makes sense to speak of the leading monomial textLM_(f) of a standard polynomial 0neq f in K langle x rangle The notion of a global elimination ordering with respect to a subset of x_1ldots x_n carries over from Kx to A.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Definition. Let A be a K-algebra of type","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"A = Klangle x_1 dots x_n mid x_jx_i = c_ijx_ix_j+d_ij 1leq ij leq n rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"where the c_ijin K are nonzero scalars, and the d_ijin Klangle x_1 dots x_nrangle are standard polynomials. Then A is called a PBW-algebra if the following two conditions hold:","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"(1) There exists a global monomial ordering on A such that","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"d_ij=0 text or x_ix_j textLM_(d_ij) text for all 1leq ij leq n","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"(2) The standard monomials in K langle x rangle represent a K-basis for A. We then refer to this basis as a PBW-basis for A. ","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Every ordering as in (1) is called admissible for the given relations or simply admissible for A.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Given a PBW-algebra A as above, we sometimes abuse our notation by denoting the class of a standard monomial x^alpha in A also by x^alpha, and refer to this class as a standard monomial in A. As these monomials form a K-basis for A, every element 0neq fin A has a unique representation","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"f=sum c_alphax^alpha text with nonzero coefficients c_alphain K","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"We refer to this representation as the standard representation of f, with coefficients c_alpha, and exponents alpha.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nPBW-algebras are also known as G-algebras or algebras of solvable type. See Remark 1 in Viktor Levandovskyy, Hans Schönemann (2003) for a brief historical account.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Proposition. Let A be a PBW-algebra. Then:","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"A is an integral domain,\nA is (left and right) Noetherian.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Given any associative K-algebra A = (A + cdot), its opposite algebra is defined by setting A^textop = (A + ast), where fast g=gcdot f for all f gin A If","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"A = Klangle x_1 dots x_n mid x_jx_i = c_ij x_ix_j+d_ij 1leq ij leq n rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"is a PBW-algebra, then A^textop is again a PBW-algebra in a natural way. Indeed, consider the automorphism textop of Klangle x_1 dots x_nrangle which sends a word x_i_1cdots x_i_r to the \"opposite word\" x^textop=x_i_rcdots x_i_1. Apply this automorphism to the relations of A to obtain the \"opposite relations\"","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"x_ix_j = c_ijx_jx_i+d_ij^textop","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Also, if alpha=(alpha_1 ldots alpha_n)in N^n, then set alpha^textop =(alpha_n ldots alpha_1)in N^n, and if is an admissible monomial ordering for A, then define the \"opposite ordering\" $ >^{\\text{op}}$ by setting","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"alpha ^textop beta Leftrightarrow alpha^textop beta^textop","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"Finally, reverse the order of the variables: set x ^textop=x_n ldots x_1, and consider the free associative K-algebra K langle x^textoprangle = K langle x_ndots x_1 rangle Altogether, we obtain a PBW-algebra which can be naturally identified with A^textop:","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"A ^textop = Klangle x_n dots x_1 mid x_ix_j = c_ijx_jx_i+d_ij^textop 1leq ij leq n rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"with admissible ordering ^textop.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"When implementing functionality for PBW-algebras, taking the opposite algebra into account often allows one to focus on left ideals, left modules, and left Gröbner bases: Given a PBW-algebra A, right Gröbner bases in A are found by computing left Gröbner bases in A^textop. Here, Gröbner bases are considered with respect to an admissible ordering for A and the opposite ordering ^textop for A^textop, respectively. Each left Gröbner basis of a two-sided ideal I is also a right Gröbner basis of I. Moreover, there is an algorithm which, starting from a left Gröbner basis of I, computes a two-sided Gröbner basis of I (see, for example, Wolfram Decker, Christoph Lossen (2006)). ","category":"page"},{"location":"Experimental/intro/#Adding-new-projects-to-experimental","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"","category":"section"},{"location":"Experimental/intro/#Purpose","page":"Adding new projects to experimental","title":"Purpose","text":"","category":"section"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"The folder experimental is for code that is candidate for being added to Oscar. In particular, this includes the following cases:","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"Code from an external package that should be moved to Oscar\nImplementing a new feature from scratch\nIn general: code whose API has not stabilized yet","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"The code in experimental is supposed to be mathematically correct, experimental is a staging area for new features whose interface is still to be stabilized. Also code is allowed to reside in experimental while it is brought up to Oscar standard.","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"danger: Dependencies\nCode from src must never use code from experimental\nSay there are two packages A and B in experimental, and B depends on A. That means that B cannot be moved to src before A. Worse: If A gets abandoned, B might share that fate. So please consider carefully in such situations.","category":"page"},{"location":"Experimental/intro/#Structure","page":"Adding new projects to experimental","title":"Structure","text":"","category":"section"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"For an example of the structure for a new project in experimental have a look at project folders, i.e. experimental/PACKAGE_NAME, that have subfolders docs, src, and test (The first two examples are experimental/{FTheoryTools, PlaneCurve}). The general structure is","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"experimental/PACKAGE_NAME/\n├── README.md\n├── docs\n│   ├── doc.main\n│   └── src\n│   └── DOCUMENTATION.md\n├── src\n│   └── PACKAGE_NAME.jl\n└── test\n └── runtests.jl","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"The files src/PACKAGE_NAME.jl and test/runtests.jl are mandatory as they are used by Oscar.jl to find your code and tests. The file docs/doc.main is used for integrating your documentation in the Oscar manual under the Experimental section. Optionally please provide a README.md describing your project and its goals, especially if you are starting from scratch and don't have any documentation yet.","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"note: Note\nThere are still older projects in experimental from before the introduction of this structure. Thus we mentioned FTheoryTools and PlaneCurve as projects having adopted to the new standard.","category":"page"},{"location":"Experimental/intro/#Useful-functions-for-development","page":"Adding new projects to experimental","title":"Useful functions for development","text":"","category":"section"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"Apart from the hints in the Introduction for new developers, there are some more specialized functions for the structure of the experimental folder.","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"Oscar.test_experimental_module","category":"page"},{"location":"Experimental/intro/#test_experimental_module","page":"Adding new projects to experimental","title":"test_experimental_module","text":"test_experimental_module(project::AbstractString; file::AbstractString=\"runtests\", new::Bool = true)\n\nRun the Oscar tests in the file experimental//test/.jl where file may be a path. The default is to run the entire test suite of the module project.\n\nThe optional parameter new takes the values false and true (default). If true, then the tests are run in a new session, otherwise the currently active session is used.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/intro/#Procedure-for-adding-a-new-feature","page":"Adding new projects to experimental","title":"Procedure for adding a new feature","text":"","category":"section"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"Ideally we envision the procedure to follow along the following lines.","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"The new feature is implemented in the experimental folder.\nFor external authors, a maintainer is assigned to guide the authors such that the implementation adheres to the Developer Style Guide and the Design Decisions. Please get in touch with us as soon as possible, preferably on the OSCAR Slack.\nThe new feature is tested thoroughly, other people are invited to test the new feature.\nIn the end there are three possibilities:\nThe feature is considered done and moved into src as is.\nThe feature is discarded, e.g., because it cannot be maintained.\nParts of the feature are moved into src, others are discarded.","category":"page"},{"location":"Experimental/intro/#Criteria-for-acceptance","page":"Adding new projects to experimental","title":"Criteria for acceptance","text":"","category":"section"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"The main criteria for acceptance are:","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"The code adheres to the Developer Style Guide and the Design Decisions.\nThe new code is well tested.\nIt is clear who maintains the new code, i.e. the original authors commit to maintaining the code in the future.","category":"page"},{"location":"Hecke/function_fields/basics/#Creation-of-number-fields","page":"-","title":"Creation of number fields","text":"","category":"section"},{"location":"Hecke/function_fields/basics/","page":"-","title":"-","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/function_fields/basics/","page":"-","title":"-","text":"For details on creation of rational function fields and extensions thereof, refer to the AbstractAlgebra documentation which can be found here https://nemocas.github.io/AbstractAlgebra.jl/stable/function_field/.","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/mpolynomial/#Multivariate-polynomials","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"","category":"section"},{"location":"Nemo/mpolynomial/#Introduction","page":"Multivariate polynomials","title":"Introduction","text":"","category":"section"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"Nemo allow the creation of sparse, distributed multivariate polynomials over any computable ring R. There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of polynomials over numerous specific rings, usually provided by C/C++ libraries.","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"The following table shows each of the polynomial types available in Nemo, the base ring R, and the Julia/Nemo types for that kind of polynomial (the type information is mainly of concern to developers).","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl Generic.MPoly{T} Generic.MPolyRing{T}\nmathbbZ Flint ZZMPolyRingElem ZZMPolyRing\nmathbbZnmathbbZ (small n) Flint zzModMPolyRingElem zzModMPolyRing\nmathbbQ Flint QQMPolyRingElem QQMPolyRing\nmathbbZpmathbbZ (small prime p) Flint fpMPolyRingElem fpMPolyRing\nmathbbF_p^n (small p) Flint fqPolyRepMPolyRingElem fqPolyRepMPolyRing","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"The string representation of the variables and the base ring R of a generic polynomial is stored in its parent object. ","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"All polynomial element types belong to the abstract type MPolyRingElem and all of the polynomial ring types belong to the abstract type MPolyRing. This enables one to write generic functions that can accept any Nemo multivariate polynomial type.","category":"page"},{"location":"Nemo/mpolynomial/#Polynomial-functionality","page":"Multivariate polynomials","title":"Polynomial functionality","text":"","category":"section"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"All multivariate polynomial types in Nemo provide the multivariate polynomial functionality described by AbstractAlgebra:","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/mpolynomial","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"Generic multivariate polynomials are also available.","category":"page"},{"location":"Nemo/mpolynomial/","page":"Multivariate polynomials","title":"Multivariate polynomials","text":"We describe here only functions that are in addition to that guaranteed by AbstractAlgebra.jl, for specific coefficient rings.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/","page":"Auxiliary functions","title":"Auxiliary functions","text":"CurrentModule = Oscar","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#Auxiliary-functions","page":"Auxiliary functions","title":"Auxiliary functions","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#Geometric-data","page":"Auxiliary functions","title":"Geometric data","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/","page":"Auxiliary functions","title":"Auxiliary functions","text":"facets(P::Polyhedron)\nvertices(P::Polyhedron)\nrays(P::Polyhedron)\nrays_modulo_lineality(P::Polyhedron{T}) where T<:scalar_types\nminimal_faces(P::Polyhedron{T}) where T<:scalar_types\naffine_hull(P::Polyhedron{T}) where T<:scalar_types\nambient_dim(P::Polyhedron)\ndim(P::Polyhedron)\ncodim(P::Polyhedron)\nis_bounded(P::Polyhedron)\nis_feasible(P::Polyhedron)\nis_fulldimensional(P::Polyhedron)\nis_lattice_polytope(P::Polyhedron{QQFieldElem})\nlineality_dim(P::Polyhedron)\nlineality_space(P::Polyhedron{T}) where T<:scalar_types\nrecession_cone(P::Polyhedron{T}) where T<:scalar_types\nrelative_interior_point(P::Polyhedron{T}) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#facets-Tuple{Polyhedron}","page":"Auxiliary functions","title":"facets","text":"facets(as::Type{T} = AffineHalfspace, P::Polyhedron)\n\nReturn the facets of P in the format defined by as.\n\nThe allowed values for as are\n\nHalfspace,\nPolyhedron,\nPair.\n\nExamples\n\nWe can retrieve the six facets of the 3-dimensional cube this way:\n\njulia> C = cube(3);\n\njulia> facets(Polyhedron, C)\n6-element SubObjectIterator{Polyhedron{QQFieldElem}}:\n Polyhedron in ambient dimension 3\n Polyhedron in ambient dimension 3\n Polyhedron in ambient dimension 3\n Polyhedron in ambient dimension 3\n Polyhedron in ambient dimension 3\n Polyhedron in ambient dimension 3\n\njulia> facets(Halfspace, C)\n6-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:\n-x₁ ≦ 1\nx₁ ≦ 1\n-x₂ ≦ 1\nx₂ ≦ 1\n-x₃ ≦ 1\nx₃ ≦ 1\n\n\n\n\n\nfacets(P::Polyhedron)\n\nReturn the facets of P as halfspaces.\n\nExamples\n\nWe can retrieve the six facets of the 3-dimensional cube this way:\n\njulia> C = cube(3);\n\njulia> facets(C)\n6-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:\n-x₁ ≦ 1\nx₁ ≦ 1\n-x₂ ≦ 1\nx₂ ≦ 1\n-x₃ ≦ 1\nx₃ ≦ 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#vertices-Tuple{Polyhedron}","page":"Auxiliary functions","title":"vertices","text":"vertices(P::Polyhedron)\n\nReturn an iterator over the vertices of a polyhedron P as points.\n\nExamples\n\nThe following code computes the vertices of the Minkowski sum of a triangle and a square:\n\njulia> P = simplex(2) + cube(2);\n\njulia> vertices(P)\n5-element SubObjectIterator{PointVector{QQFieldElem}}:\n [-1, -1]\n [2, -1]\n [2, 1]\n [-1, 2]\n [1, 2]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#rays-Tuple{Polyhedron}","page":"Auxiliary functions","title":"rays","text":"rays(P::Polyhedron)\n\nReturn minimal set of generators of the cone of unbounded directions of P (i.e. its rays) as points.\n\nExamples\n\nWe can verify that the positive orthant of the plane is generated by the two rays in positive unit direction:\n\njulia> PO = convex_hull([0 0], [1 0; 0 1]);\n\njulia> rays(PO)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [0, 1]\n\njulia> matrix(QQ, rays(PO))\n[1 0]\n[0 1]\n\njulia> matrix(ZZ, rays(PO))\n[1 0]\n[0 1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#rays_modulo_lineality-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"rays_modulo_lineality","text":"rays_modulo_lineality(as, P::Polyhedron)\n\nReturn the rays of the recession cone of P up to lineality as a NamedTuple with two iterators. If P has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of P/L. The iterator lineality_basis gives a basis of the lineality space L.\n\nExamples\n\njulia> P = convex_hull([0 0 1], [0 1 0], [1 0 0])\nPolyhedron in ambient dimension 3\n\njulia> rmlP = rays_modulo_lineality(P)\n(rays_modulo_lineality = RayVector{QQFieldElem}[[0, 1, 0]], lineality_basis = RayVector{QQFieldElem}[[1, 0, 0]])\n\njulia> rmlP.rays_modulo_lineality\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [0, 1, 0]\n\njulia> rmlP.lineality_basis\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0, 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#minimal_faces-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"minimal_faces","text":"minimal_faces(as, P::Polyhedron)\n\nReturn the minimal faces of a polyhedron as a NamedTuple with two iterators. For a polyhedron without lineality, the base_points are the vertices. If P has lineality L, then every minimal face is an affine translation p+L, where p is only unique modulo L. The return type is a dict, the key :base_points gives an iterator over such p, and the key :lineality_basis lets one access a basis for the lineality space L of P.\n\nExamples\n\nThe polyhedron P is just a line through the origin:\n\njulia> P = convex_hull([0 0], nothing, [1 0])\nPolyhedron in ambient dimension 2\n\njulia> lineality_dim(P)\n1\n\njulia> vertices(P)\n0-element SubObjectIterator{PointVector{QQFieldElem}}\n\njulia> minimal_faces(P)\n(base_points = PointVector{QQFieldElem}[[0, 0]], lineality_basis = RayVector{QQFieldElem}[[1, 0]])\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#affine_hull-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"affine_hull","text":"affine_hull(P::Polytope)\n\nReturn the (affine) hyperplanes generating the affine hull of P.\n\nExamples\n\nThis triangle in mathbbR^4 is contained in the plane defined by P = (x_1 x_2 x_3 x_4) x_3 = 2 x_4 = 5 .\n\njulia> t = convex_hull([0 0 2 5; 1 0 2 5; 0 1 2 5]);\n\njulia> affine_hull(t)\n2-element SubObjectIterator{AffineHyperplane{QQFieldElem}} over the Hyperplanes of R^4 described by:\nx₃ = 2\nx₄ = 5\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#ambient_dim-Tuple{Polyhedron}","page":"Auxiliary functions","title":"ambient_dim","text":"ambient_dim(P::Polyhedron)\n\nReturn the ambient dimension of P.\n\nExamples\n\njulia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];\n\njulia> P = convex_hull(V);\n\njulia> ambient_dim(P)\n3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#dim-Tuple{Polyhedron}","page":"Auxiliary functions","title":"dim","text":"dim(P::Polyhedron)\n\nReturn the dimension of P.\n\nExamples\n\njulia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];\n\njulia> P = convex_hull(V);\n\njulia> dim(P)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#codim-Tuple{Polyhedron}","page":"Auxiliary functions","title":"codim","text":"codim(P::Polyhedron)\n\nReturn the codimension of P.\n\nExamples\n\njulia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];\n\njulia> P = convex_hull(V);\n\njulia> codim(P)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_bounded-Tuple{Polyhedron}","page":"Auxiliary functions","title":"is_bounded","text":"is_bounded(P::Polyhedron)\n\nCheck whether P is bounded.\n\nExamples\n\njulia> P = polyhedron([1 -3; -1 1; -1 0; 0 -1],[1,1,1,1]);\n\njulia> is_bounded(P)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_feasible-Tuple{Polyhedron}","page":"Auxiliary functions","title":"is_feasible","text":"is_feasible(P::Polyhedron)\n\nCheck whether P is feasible, i.e. non-empty.\n\nExamples\n\njulia> P = polyhedron([1 -1; -1 1; -1 0; 0 -1],[-1,-1,1,1]);\n\njulia> is_feasible(P)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_fulldimensional-Tuple{Polyhedron}","page":"Auxiliary functions","title":"is_fulldimensional","text":"is_fulldimensional(P::Polyhedron)\n\nCheck whether P is full-dimensional.\n\nExamples\n\njulia> V = [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1];\n\njulia> is_fulldimensional(convex_hull(V))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_lattice_polytope-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"is_lattice_polytope","text":"is_lattice_polytope(P::Polyhedron{QQFieldElem})\n\nCheck whether P is a lattice polytope, i.e. it is bounded and has integral vertices.\n\nExamples\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> is_lattice_polytope(c)\ntrue\n\njulia> c = cube(3, 0, 4//3)\nPolyhedron in ambient dimension 3\n\njulia> is_lattice_polytope(c)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#lineality_dim-Tuple{Polyhedron}","page":"Auxiliary functions","title":"lineality_dim","text":"lineality_dim(P::Polyhedron)\n\nReturn the dimension of the lineality space, i.e. the dimension of the largest affine subspace contained in P.\n\nExamples\n\nPolyhedron with one lineality direction.\n\njulia> C = convex_hull([0 0], [1 0], [1 1])\nPolyhedron in ambient dimension 2\n\njulia> lineality_dim(C)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#lineality_space-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"lineality_space","text":"lineality_space(P::Polyhedron)\n\nReturn a matrix whose row span is the lineality space of P.\n\nExamples\n\nDespite not being reflected in this construction of the upper half-plane, its lineality in x-direction is recognized:\n\njulia> UH = convex_hull([0 0],[0 1; 1 0; -1 0]);\n\njulia> lineality_space(UH)\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#recession_cone-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"recession_cone","text":"recession_cone(P::Polyhedron)\n\nReturn the recession cone of P.\n\nExamples\n\njulia> P = polyhedron([1 -2; -1 1; -1 0; 0 -1],[2,1,1,1]);\n\njulia> vertices(P)\n3-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, -1]\n [-1, 0]\n [-1, -1]\n\njulia> recession_cone(P)\nPolyhedral cone in ambient dimension 2\n\njulia> rays(recession_cone(P))\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 1//2]\n [1, 1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#relative_interior_point-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"relative_interior_point","text":"relative_interior_point(P::Polyhedron)\n\nCompute a point in the relative interior point of P, i.e. a point in P not contained in any facet.\n\nExamples\n\nThe square -11^3 has the origin as a relative interior point.\n\njulia> square = cube(2)\nPolyhedron in ambient dimension 2\n\njulia> relative_interior_point(square)\n2-element PointVector{QQFieldElem}:\n 0\n 0\n\njulia> vertices(square)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [-1, -1]\n [1, -1]\n [-1, 1]\n [1, 1]\n\njulia> matrix(QQ, vertices(square))\n[-1 -1]\n[ 1 -1]\n[-1 1]\n[ 1 1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#Combinatorial-data","page":"Auxiliary functions","title":"Combinatorial data","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/","page":"Auxiliary functions","title":"Auxiliary functions","text":"nfacets(P::Polyhedron)\nnvertices(P::Polyhedron)\nf_vector(P::Polyhedron)\ng_vector(P::Polyhedron)\nh_vector(P::Polyhedron)","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#nfacets-Tuple{Polyhedron}","page":"Auxiliary functions","title":"nfacets","text":"nfacets(P::Polyhedron)\n\nReturn the number of facets of P.\n\nExamples\n\nThe number of facets of the 5-dimensional cross polytope can be retrieved via the following line:\n\njulia> nfacets(cross_polytope(5))\n32\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#nvertices-Tuple{Polyhedron}","page":"Auxiliary functions","title":"nvertices","text":"nvertices(P::Polyhedron)\n\nReturn the number of vertices of P.\n\nExamples\n\nThe 3-cube's number of vertices can be obtained with this input:\n\njulia> C = cube(3);\n\njulia> nvertices(C)\n8\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#f_vector-Tuple{Polyhedron}","page":"Auxiliary functions","title":"f_vector","text":"f_vector(P::Polyhedron)\n\nReturn the vector (f₀f₁f₂f_(dim(P)-1))` where f_i is the number of faces of P of dimension i.\n\nExamples\n\nHere we compute the f-vector of the 5-cube:\n\njulia> f_vector(cube(5))\n5-element Vector{ZZRingElem}:\n 32\n 80\n 80\n 40\n 10\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#g_vector-Tuple{Polyhedron}","page":"Auxiliary functions","title":"g_vector","text":"g_vector(P::Polyhedron)\n\nReturn the (toric) g-vector of a polytope. Defined by g_0 = 1 and g_k = h_k - h_k-1, for 1 leq k leq lceil (d+1)2rceil where h is the h-vector and d=dim(P). Undefined for unbounded polyhedra.\n\nExamples\n\njulia> g_vector(cross_polytope(3))\n2-element Vector{ZZRingElem}:\n 1\n 2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#h_vector-Tuple{Polyhedron}","page":"Auxiliary functions","title":"h_vector","text":"h_vector(P::Polyhedron)\n\nReturn the (toric) h-vector of a polytope. For simplicial polytopes this is a linear transformation of the f-vector. Undefined for unbounded polyhedra.\n\nExamples\n\njulia> h_vector(cross_polytope(3))\n4-element Vector{ZZRingElem}:\n 1\n 3\n 3\n 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#Groups","page":"Auxiliary functions","title":"Groups","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/","page":"Auxiliary functions","title":"Auxiliary functions","text":"linear_symmetries(P::Polyhedron)\ncombinatorial_symmetries(P::Polyhedron)\nautomorphism_group(P::Polyhedron)\nautomorphism_group_generators(P::Polyhedron)\nautomorphism_group(IM::IncidenceMatrix)\nautomorphism_group_generators(IM::IncidenceMatrix)","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#linear_symmetries-Tuple{Polyhedron}","page":"Auxiliary functions","title":"linear_symmetries","text":"linear_symmetries(P::Polyhedron)\n\nGet the group of linear symmetries on the vertices of a polyhedron. These are morphisms of the form xmapsto Ax+b,with A a matrix and b a vector, that preserve the polyhedron P. The result is given as permutations of the vertices (or rather vertex indices) of P.\n\nExamples\n\nThe 3-dimensional cube has 48 linear symmetries.\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> G = linear_symmetries(c)\nGroup([ (3,5)(4,6), (2,3)(6,7), (1,2)(3,4)(5,6)(7,8) ])\n\njulia> order(G)\n48\n\nThe quadrangle one obtains from moving one vertex of the square out along the diagonal has two linear symmetries.\n\njulia> quad = convex_hull([0 0; 1 0; 2 2; 0 1])\nPolyhedron in ambient dimension 2\n\njulia> G = linear_symmetries(quad)\nGroup([ (2,4) ])\n\njulia> order(G)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#combinatorial_symmetries-Tuple{Polyhedron}","page":"Auxiliary functions","title":"combinatorial_symmetries","text":"combinatorial_symmetries(P::Polyhedron)\n\nCompute the combinatorial symmetries (i.e., automorphisms of the face lattice) of a given polytope P. The result is given as permutations of the vertices (or rather vertex indices) of P. This group contains the linear_symmetries as a subgroup.\n\nExamples\n\nThe quadrangle one obtains from moving one vertex of the square out along the diagonal has eight combinatorial symmetries, but only two linear symmetries.\n\njulia> quad = convex_hull([0 0; 1 0; 2 2; 0 1])\nPolyhedron in ambient dimension 2\n\njulia> G = combinatorial_symmetries(quad)\nGroup([ (2,4), (1,2)(3,4) ])\n\njulia> order(G)\n8\n\njulia> G = linear_symmetries(quad)\nGroup([ (2,4) ])\n\njulia> order(G)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#automorphism_group-Tuple{Polyhedron}","page":"Auxiliary functions","title":"automorphism_group","text":"automorphism_group(P::Polyhedron; type = :combinatorial, action = :all)\n\nCompute the group of automorphisms of a polyhedron. The parameters and return values are the same as for automorphism_group_generators(P::Polyhedron; type = :combinatorial, action = :all) except that groups are returned instead of generators of groups.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#automorphism_group_generators-Tuple{Polyhedron}","page":"Auxiliary functions","title":"automorphism_group_generators","text":"automorphism_group_generators(P::Polyhedron; type = :combinatorial, action = :all)\n\nCompute generators of the group of automorphisms of a polyhedron.\n\nThe optional parameter type takes two values:\n\n:combinatorial (default) – Return the combinatorial symmetries, the automorphisms of the face lattice.\n:linear – Return the linear automorphisms.\n\nThe optional parameter action takes three values:\n\n:all (default) – Return the generators of the permutation action on both vertices and facets as a Dict{Symbol, Vector{PermGroupElem}}.\n:on_vertices – Only return generators of the permutation action on the vertices.\n:on_facets – Only return generators of the permutation action on the facets.\n\nThe return value is a Dict{Symbol, Vector{PermGroupElem}} with two entries, one for the key :on_vertices containing the generators for the action permuting the vertices, and :on_facets for the facets.\n\nExamples\n\nCompute the automorphisms of the 3dim cube:\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> automorphism_group_generators(c)\nDict{Symbol, Vector{PermGroupElem}} with 2 entries:\n :on_vertices => [(3,5)(4,6), (2,3)(6,7), (1,2)(3,4)(5,6)(7,8)]\n :on_facets => [(3,5)(4,6), (1,3)(2,4), (1,2)]\n\njulia> automorphism_group_generators(c; action = :on_vertices)\n3-element Vector{PermGroupElem}:\n (3,5)(4,6)\n (2,3)(6,7)\n (1,2)(3,4)(5,6)(7,8)\n\njulia> automorphism_group_generators(c; action = :on_facets)\n3-element Vector{PermGroupElem}:\n (3,5)(4,6)\n (1,3)(2,4)\n (1,2)\n\nCompute the automorphisms of a non-quadratic quadrangle. Since it has less symmetry than the square, it has less linear symmetries.\n\njulia> quad = convex_hull([0 0; 1 0; 2 2; 0 1])\nPolyhedron in ambient dimension 2\n\njulia> automorphism_group_generators(quad)\nDict{Symbol, Vector{PermGroupElem}} with 2 entries:\n :on_vertices => [(2,4), (1,2)(3,4)]\n :on_facets => [(1,2)(3,4), (1,3)]\n\njulia> automorphism_group_generators(quad; type = :combinatorial)\nDict{Symbol, Vector{PermGroupElem}} with 2 entries:\n :on_vertices => [(2,4), (1,2)(3,4)]\n :on_facets => [(1,2)(3,4), (1,3)]\n\njulia> automorphism_group_generators(quad; type = :linear)\nDict{Symbol, Vector{PermGroupElem}} with 2 entries:\n :on_vertices => [(2,4)]\n :on_facets => [(1,2)(3,4)]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#automorphism_group-Tuple{IncidenceMatrix}","page":"Auxiliary functions","title":"automorphism_group","text":"automorphism_group(IM::IncidenceMatrix; action = :all)\n\nCompute the group of automorphisms of an IncidenceMatrix. The parameters and return values are the same as for automorphism_group_generators(IM::IncidenceMatrix; action = :all) except that groups are returned instead of generators of groups.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#automorphism_group_generators-Tuple{IncidenceMatrix}","page":"Auxiliary functions","title":"automorphism_group_generators","text":"automorphism_group_generators(IM::IncidenceMatrix; action = :all)\n\nCompute the generators of the group of automorphisms of an IncidenceMatrix. \n\nThe optional parameter action takes three values:\n\n:all (default) – Return the generators of the permutation action on both columns and rows as a Dict{Symbol, Vector{PermGroupElem}}.\n:on_cols – Only return generators of the permutation action on the columns.\n:on_rows – Only return generators of the permutation action on the rows.\n\nExamples\n\nCompute the automorphisms of the incidence matrix of the 3dim cube:\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> IM = vertex_indices(facets(c))\n6×8 IncidenceMatrix\n[1, 3, 5, 7]\n[2, 4, 6, 8]\n[1, 2, 5, 6]\n[3, 4, 7, 8]\n[1, 2, 3, 4]\n[5, 6, 7, 8]\n\n\njulia> automorphism_group_generators(IM)\nDict{Symbol, Vector{PermGroupElem}} with 2 entries:\n :on_cols => [(3,5)(4,6), (2,3)(6,7), (1,2)(3,4)(5,6)(7,8)]\n :on_rows => [(3,5)(4,6), (1,3)(2,4), (1,2)]\n\njulia> automorphism_group_generators(IM; action = :on_rows)\n3-element Vector{PermGroupElem}:\n (3,5)(4,6)\n (1,3)(2,4)\n (1,2)\n\njulia> automorphism_group_generators(IM; action = :on_cols)\n3-element Vector{PermGroupElem}:\n (3,5)(4,6)\n (2,3)(6,7)\n (1,2)(3,4)(5,6)(7,8)\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#Other","page":"Auxiliary functions","title":"Other","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/","page":"Auxiliary functions","title":"Auxiliary functions","text":"all_triangulations\nboundary_lattice_points(P::Polyhedron{QQFieldElem})\nBase.in(v::AbstractVector, P::Polyhedron)\nBase.issubset(P::Polyhedron{T}, Q::Polyhedron{T}) where T<:scalar_types\nehrhart_polynomial(P::Polyhedron{QQFieldElem})\nehrhart_polynomial(R::QQPolyRing, P::Polyhedron{QQFieldElem})\nh_star_polynomial(P::Polyhedron{QQFieldElem})\nh_star_polynomial(R::QQPolyRing, P::Polyhedron{QQFieldElem})\ninterior_lattice_points(P::Polyhedron{QQFieldElem})\nis_normal(P::Polyhedron{QQFieldElem})\nis_simple(P::Polyhedron)\nis_smooth(P::Polyhedron{QQFieldElem})\nis_very_ample(P::Polyhedron{QQFieldElem})\nlattice_points(P::Polyhedron{QQFieldElem})\nlattice_volume(P::Polyhedron{QQFieldElem})\nnormalized_volume(P::Polyhedron{T}) where T<:scalar_types\npolarize(P::Polyhedron{T}) where T<:scalar_types\nproject_full(P::Polyhedron{T}) where T<:scalar_types\nprint_constraints(A::AnyVecOrMat, b::AbstractVector; trivial::Bool = false)\nprint_constraints(P::Polyhedron; trivial::Bool = false)\nregular_triangulations\nregular_triangulation\nsecondary_polytope\nsolve_ineq(as::Type{T}, A::ZZMatrix, b::ZZMatrix) where {T}\nsolve_mixed(as::Type{T}, A::ZZMatrix, b::ZZMatrix, C::ZZMatrix, d::ZZMatrix) where {T}\nsolve_mixed(as::Type{T}, A::ZZMatrix, b::ZZMatrix, C::ZZMatrix) where {T}\nsolve_non_negative(as::Type{T}, A::ZZMatrix, b::ZZMatrix) where {T}\nsupport_function(P::Polyhedron{T}; convention::Symbol = :max) where T<:scalar_types\nvolume(P::Polyhedron{T}) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#all_triangulations","page":"Auxiliary functions","title":"all_triangulations","text":"all_triangulations(pts::AbstractCollection[PointVector]; full=false)\n\nCompute all triangulations on the points given as the rows of pts. Optionally select full=true to output full triangulations only, i.e. those that use all given points.\n\nThe return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.\n\nExamples\n\njulia> c = cube(2,0,1)\nPolyhedron in ambient dimension 2\n\njulia> V = vertices(c)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [1, 0]\n [0, 1]\n [1, 1]\n\njulia> all_triangulations(V)\n2-element Vector{Vector{Vector{Int64}}}:\n [[1, 2, 3], [2, 3, 4]]\n [[1, 2, 4], [1, 3, 4]]\n\n\n\n\n\nall_triangulations(P::Polyhedron)\n\nCompute all triangulations that can be formed using the vertices of the given bounded and full-dimensional polytope P.\n\nThe return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.\n\nExamples\n\njulia> c = cube(2,0,1)\nPolyhedron in ambient dimension 2\n\njulia> all_triangulations(c)\n2-element Vector{Vector{Vector{Int64}}}:\n [[1, 2, 3], [2, 3, 4]]\n [[1, 2, 4], [1, 3, 4]]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#boundary_lattice_points-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"boundary_lattice_points","text":"boundary_lattice_points(P::Polyhedron{QQFieldElem})\n\nReturn the integer points contained in the boundary of the bounded polyhedron P.\n\nExamples\n\njulia> c = polarize(cube(3))\nPolyhedron in ambient dimension 3\n\njulia> boundary_lattice_points(c)\n6-element SubObjectIterator{PointVector{ZZRingElem}}:\n [-1, 0, 0]\n [0, -1, 0]\n [0, 0, -1]\n [0, 0, 1]\n [0, 1, 0]\n [1, 0, 0]\n\njulia> matrix(ZZ, boundary_lattice_points(c))\n[-1 0 0]\n[ 0 -1 0]\n[ 0 0 -1]\n[ 0 0 1]\n[ 0 1 0]\n[ 1 0 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#in-Tuple{AbstractVector, Polyhedron}","page":"Auxiliary functions","title":"in","text":"in(v::AbstractVector, P::Polyhedron)\n\nCheck whether the vector v is contained in the polyhedron P.\n\nExamples\n\nThe positive orthant only contains vectors with non-negative entries:\n\njulia> PO = polyhedron([-1 0; 0 -1], [0, 0]);\n\njulia> [1, 2] in PO\ntrue\n\njulia> [1, -2] in PO\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#issubset-Union{Tuple{T}, Tuple{Polyhedron{T}, Polyhedron{T}}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"issubset","text":"issubset(P::Polyhedron, Q::Polyhedron)\n\nCheck whether P is a subset of the polyhedron Q.\n\nExamples\n\njulia> P = cube(3,0,1)\nPolyhedron in ambient dimension 3\n\njulia> Q = cube(3,-1,2)\nPolyhedron in ambient dimension 3\n\njulia> issubset(P, Q)\ntrue\n\njulia> issubset(Q, P)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#ehrhart_polynomial-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"ehrhart_polynomial","text":"ehrhart_polynomial(P::Polyhedron{QQFieldElem})\n\nCompute the Ehrhart polynomial of P.\n\nExamples\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> ehrhart_polynomial(c)\n8*x^3 + 12*x^2 + 6*x + 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#ehrhart_polynomial-Tuple{QQPolyRing, Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"ehrhart_polynomial","text":"ehrhart_polynomial(R::QQMPolyRing, P::Polyhedron{QQFieldElem})\n\nCompute the Ehrhart polynomial of P and return it as a polynomial in R.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over QQ, x)\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> ehrhart_polynomial(R, c)\n8*x^3 + 12*x^2 + 6*x + 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#h_star_polynomial-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"h_star_polynomial","text":"h_star_polynomial(P::Polyhedron)\n\nCompute the h^* polynomial of P.\n\nExamples\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> h_star_polynomial(c)\nx^3 + 23*x^2 + 23*x + 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#h_star_polynomial-Tuple{QQPolyRing, Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"h_star_polynomial","text":"h_star_polynomial(R::QQMPolyRing, P::Polyhedron)\n\nCompute the h^* polynomial of P and return it as a polynomial in R.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over QQ, x)\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> h_star_polynomial(R, c)\nx^3 + 23*x^2 + 23*x + 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#interior_lattice_points-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"interior_lattice_points","text":"interior_lattice_points(P::Polyhedron{QQFieldElem})\n\nReturn the integer points contained in the interior of the bounded polyhedron P.\n\nExamples\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> interior_lattice_points(c)\n1-element SubObjectIterator{PointVector{ZZRingElem}}:\n [0, 0, 0]\n\njulia> matrix(ZZ, interior_lattice_points(c))\n[0 0 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_normal-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"is_normal","text":"is_normal(P::Polyhedron{QQFieldElem})\n\nCheck whether P is normal.\n\nExamples\n\nThe 3-cube is normal.\n\njulia> C = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> is_normal(C)\ntrue\n\nBut this pyramid is not:\n\njulia> P = convex_hull([0 0 0; 0 1 1; 1 1 0; 1 0 1]);\n\njulia> is_normal(P)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_simple-Tuple{Polyhedron}","page":"Auxiliary functions","title":"is_simple","text":"is_simple(P::Polyhedron)\n\nCheck whether P is simple.\n\nExamples\n\njulia> c = cube(2,0,1)\nPolyhedron in ambient dimension 2\n\njulia> is_simple(c)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_smooth-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"is_smooth","text":"is_smooth(P::Polyhedron{QQFieldElem})\n\nCheck whether P is smooth.\n\nExamples\n\nA cube is always smooth.\n\njulia> C = cube(8);\n\njulia> is_smooth(C)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_very_ample-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"is_very_ample","text":"is_very_ample(P::Polyhedron{QQFieldElem})\n\nCheck whether P is very ample.\n\nExamples\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> is_very_ample(c)\ntrue\n\njulia> P = convex_hull([0 0 0; 1 1 0; 1 0 1; 0 1 1])\nPolyhedron in ambient dimension 3\n\njulia> is_very_ample(P)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#lattice_points-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"lattice_points","text":"lattice_points(P::Polyhedron{QQFieldElem})\n\nReturn the integer points contained in the bounded polyhedron P.\n\nExamples\n\njulia> S = 2 * simplex(2);\n\njulia> lattice_points(S)\n6-element SubObjectIterator{PointVector{ZZRingElem}}:\n [0, 0]\n [0, 1]\n [0, 2]\n [1, 0]\n [1, 1]\n [2, 0]\n\njulia> matrix(ZZ, lattice_points(S))\n[0 0]\n[0 1]\n[0 2]\n[1 0]\n[1 1]\n[2 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#lattice_volume-Tuple{Polyhedron{QQFieldElem}}","page":"Auxiliary functions","title":"lattice_volume","text":"lattice_volume(P::Polyhedron{QQFieldElem})\n\nReturn the lattice volume of P.\n\nExamples\n\njulia> C = cube(2);\n\njulia> lattice_volume(C)\n8\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#normalized_volume-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"normalized_volume","text":"normalized_volume(P::Polyhedron)\n\nReturn the (normalized) volume of P.\n\nExamples\n\njulia> C = cube(2);\n\njulia> normalized_volume(C)\n8\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#polarize-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"polarize","text":"polarize(P::Polyhedron)\n\nReturn the polar dual of the polyhedron P, consisting of all linear functions whose evaluation on P does not exceed 1.\n\nExamples\n\njulia> square = cube(2)\nPolyhedron in ambient dimension 2\n\njulia> P = polarize(square)\nPolyhedron in ambient dimension 2\n\njulia> vertices(P)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 0]\n [-1, 0]\n [0, 1]\n [0, -1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#project_full-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"project_full","text":"project_full(P::Polyhedron)\n\nProject the polyhedron down such that it becomes full dimensional in the new ambient space.\n\nExamples\n\njulia> P = convex_hull([1 0 0; 0 0 0])\nPolyhedron in ambient dimension 3\n\njulia> is_fulldimensional(P)\nfalse\n\njulia> p = project_full(P)\nPolyhedron in ambient dimension 1\n\njulia> is_fulldimensional(p)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#print_constraints-Tuple{Union{MatElem, AbstractVecOrMat}, AbstractVector}","page":"Auxiliary functions","title":"print_constraints","text":"print_constraints(A::AnyVecOrMat, b::AbstractVector; trivial::Bool = false, numbered::Bool = false)\n\nPretty print the constraints given by P(Ab) = x Ax b .\n\nTrivial inequalities are counted but omitted. They are included if trivial is set to true.\n\nExamples\n\njulia> print_constraints([-1 0 4 5; 4 4 4 3; 1 0 0 0; 0 0 0 0; 0 0 0 0; 9 9 9 9], [0, 1, 2, 3, -4, 5]; numbered = true)\n1: -x₁ + 4*x₃ + 5*x₄ ≦ 0\n2: 4*x₁ + 4*x₂ + 4*x₃ + 3*x₄ ≦ 1\n3: x₁ ≦ 2\n5: 0 ≦ -4\n6: 9*x₁ + 9*x₂ + 9*x₃ + 9*x₄ ≦ 5\n\njulia> print_constraints([-1 0 4 5; 4 4 4 3; 1 0 0 0; 0 0 0 0; 0 0 0 0; 9 9 9 9], [0, 1, 2, 3, -4, 5]; trivial = true)\n-x₁ + 4*x₃ + 5*x₄ ≦ 0\n4*x₁ + 4*x₂ + 4*x₃ + 3*x₄ ≦ 1\nx₁ ≦ 2\n0 ≦ 3\n0 ≦ -4\n9*x₁ + 9*x₂ + 9*x₃ + 9*x₄ ≦ 5\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#print_constraints-Tuple{Polyhedron}","page":"Auxiliary functions","title":"print_constraints","text":"print_constraints(P::Polyhedron; trivial::Bool = false, numbered::Bool = false)\n\nPretty print the constraints given by P(Ab) = x Ax b .\n\nTrivial inequalities are counted but omitted. They are included if trivial is set to true.\n\nExamples\n\nThe 3-cube is given by -1 x_i 1 i 1 2 3.\n\njulia> print_constraints(cube(3))\n-x₁ ≦ 1\nx₁ ≦ 1\n-x₂ ≦ 1\nx₂ ≦ 1\n-x₃ ≦ 1\nx₃ ≦ 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#regular_triangulations","page":"Auxiliary functions","title":"regular_triangulations","text":"regular_triangulations(pts::AbstractCollection[PointVector]; full=false)\n\nCompute all regular triangulations on the points given as the rows of pts.\n\nA triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope). Optionally specify full, i.e. that every triangulation must use all points.\n\nThe return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.\n\nExamples\n\njulia> c = cube(2,0,1)\nPolyhedron in ambient dimension 2\n\njulia> V = vertices(c)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [1, 0]\n [0, 1]\n [1, 1]\n\njulia> regular_triangulations(V)\n2-element Vector{Vector{Vector{Int64}}}:\n [[1, 2, 3], [2, 3, 4]]\n [[1, 2, 4], [1, 3, 4]]\n\n\n\n\n\nregular_triangulations(P::Polyhedron)\n\nCompute all regular triangulations that can be formed using the vertices of the given bounded and full-dimensional polytope P.\n\nA triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope).\n\nThe return type is a Vector{Vector{Vector{Int}}} where each Vector{Vector{Int}} encodes a triangulation, in which a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.\n\nExamples\n\njulia> c = cube(2,0,1)\nPolyhedron in ambient dimension 2\n\njulia> regular_triangulations(c)\n2-element Vector{Vector{Vector{Int64}}}:\n [[1, 2, 3], [2, 3, 4]]\n [[1, 2, 4], [1, 3, 4]]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#regular_triangulation","page":"Auxiliary functions","title":"regular_triangulation","text":"regular_triangulation(pts::AbstractCollection[PointVector]; full=false)\n\nComputes ONE regular triangulations on the points given as the rows of pts.\n\nA triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope). Optionally specify full, i.e. that every triangulation must use all points.\n\nAs for regular_triangulation(pts::AnyVecOrMat; full=false) the return type is Vector{Vector{Vector{Int}}}. Here, only one triangulation is computed, so the outer vector is of length one. Its entry of type Vector{Vector{Int}} encodes the triangulation in question. Recall that a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.\n\nExamples\n\njulia> c = cube(2,0,1)\nPolyhedron in ambient dimension 2\n\njulia> V = vertices(c)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [1, 0]\n [0, 1]\n [1, 1]\n\njulia> regular_triangulation(V)\n1-element Vector{Vector{Vector{Int64}}}:\n [[1, 2, 3], [2, 3, 4]]\n\n\n\n\n\nregular_triangulation(P::Polyhedron)\n\nComputes ONE regular triangulations that can be formed using the vertices of the given bounded and full-dimensional polytope P.\n\nA triangulation is regular if it can be induced by weights, i.e. attach a weight to every point, take the convex hull of these new vectors and then take the subdivision corresponding to the facets visible from below (lower envelope).\n\nAs for regular_triangulations(P::Polyhedron) the return type is Vector{Vector{Vector{Int}}}. Here, only one triangulation is computed, so the outer vector is of length one. Its entry of type Vector{Vector{Int}} encodes the triangulation in question. Recall that a Vector{Int} encodes a simplex as the set of indices of the vertices of the simplex. I.e. the Vector{Int} [1,2,4] corresponds to the simplex that is the convex hull of the first, second, and fourth input point.\n\nExamples\n\njulia> c = cube(2,0,1)\nPolyhedron in ambient dimension 2\n\njulia> regular_triangulation(c)\n1-element Vector{Vector{Vector{Int64}}}:\n [[1, 2, 3], [2, 3, 4]]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#secondary_polytope","page":"Auxiliary functions","title":"secondary_polytope","text":"secondary_polytope(P::Polyhedron)\n\nCompute the secondary polytope of a polyhedron, i.e. the convex hull of all the gkz vectors of all its (regular) triangulations. A triangulation here means only using the vertices of P.\n\nExamples\n\nCompute the secondary polytope of the cube.\n\njulia> c = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> sc = secondary_polytope(c)\nPolyhedron in ambient dimension 8\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#solve_ineq-Union{Tuple{T}, Tuple{Type{T}, ZZMatrix, ZZMatrix}} where T","page":"Auxiliary functions","title":"solve_ineq","text":"solve_ineq(as::Type{T}, A::ZZMatrix, b::ZZMatrix) where {T}\n\nSolve Ax=b, assumes finite set of solutions.\n\nThe output type may be specified in the variable as:\n\nZZMatrix (default) a matrix with integers is returned.\nSubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.\n\nExamples\n\nThe following gives the vertices of the square. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.\n\njulia> A = ZZMatrix([1 0; 0 1; -1 0; 0 -1]);\n\njulia> b = zero_matrix(FlintZZ, 4,1); b[1,1]=1; b[2,1]=1; b[3,1]=0; b[4,1]=0;\n\njulia> sortslices(Matrix{BigInt}(solve_ineq(A, b)), dims=1)\n4×2 Matrix{BigInt}:\n 0 0\n 0 1\n 1 0\n 1 1\n\njulia> typeof(solve_ineq(A,b))\nZZMatrix\n\njulia> typeof(solve_ineq(ZZMatrix, A,b))\nZZMatrix\n\njulia> typeof(solve_ineq(SubObjectIterator{PointVector{ZZRingElem}}, A,b))\nSubObjectIterator{PointVector{ZZRingElem}}\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#solve_mixed-Union{Tuple{T}, Tuple{Type{T}, Vararg{ZZMatrix, 4}}} where T","page":"Auxiliary functions","title":"solve_mixed","text":"solve_mixed(as::Type{T}, A::ZZMatrix, b::ZZMatrix, C::ZZMatrix, d::ZZMatrix) where {T}\n\nSolve Ax = b under Cx = d, assumes a finite solution set.\n\nThe output type may be specified in the variable as:\n\nZZMatrix (default) a matrix with integers is returned.\nSubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.\n\nExamples\n\nFind all (x_1 x_2)inmathbbZ^2 such that x_1+x_2=7, x_1ge 2, and x_2ge 3. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.\n\njulia> A = ZZMatrix([1 1]);\n\njulia> b = zero_matrix(FlintZZ, 1,1); b[1,1]=7;\n\njulia> C = ZZMatrix([1 0; 0 1]);\n\njulia> d = zero_matrix(FlintZZ,2,1); d[1,1]=2; d[2,1]=3;\n\njulia> sortslices(Matrix{BigInt}(solve_mixed(A, b, C, d)), dims=1)\n3×2 Matrix{BigInt}:\n 2 5\n 3 4\n 4 3\n\njulia> typeof(solve_mixed(A, b, C, d))\nZZMatrix\n\njulia> typeof(solve_mixed(ZZMatrix, A, b, C, d))\nZZMatrix\n\njulia> typeof(solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C, d))\nSubObjectIterator{PointVector{ZZRingElem}}\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#solve_mixed-Union{Tuple{T}, Tuple{Type{T}, ZZMatrix, ZZMatrix, ZZMatrix}} where T","page":"Auxiliary functions","title":"solve_mixed","text":"solve_mixed(as::Type{T}, A::ZZMatrix, b::ZZMatrix, C::ZZMatrix) where {T}\n\nSolve Ax = b under Cx = 0, assumes a finite solution set.\n\nThe output type may be specified in the variable as:\n\nZZMatrix (default) a matrix with integers is returned.\nSubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.\n\nExamples\n\nFind all (x_1 x_2)inmathbbZ^2_ge 0 such that x_1+x_2=3. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.\n\njulia> A = ZZMatrix([1 1]);\n\njulia> b = zero_matrix(FlintZZ, 1,1); b[1,1]=3;\n\njulia> C = ZZMatrix([1 0; 0 1]);\n\njulia> sortslices(Matrix{BigInt}(solve_mixed(A, b, C)), dims=1)\n4×2 Matrix{BigInt}:\n 0 3\n 1 2\n 2 1\n 3 0\n\njulia> typeof(solve_mixed(A, b, C))\nZZMatrix\n\njulia> typeof(solve_mixed(ZZMatrix, A, b, C))\nZZMatrix\n\njulia> typeof(solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C))\nSubObjectIterator{PointVector{ZZRingElem}}\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#solve_non_negative-Union{Tuple{T}, Tuple{Type{T}, ZZMatrix, ZZMatrix}} where T","page":"Auxiliary functions","title":"solve_non_negative","text":"solve_non_negative(as::Type{T}, A::ZZMatrix, b::ZZMatrix) where {T}\n\nFind all solutions to Ax = b, x=0. Assumes a finite set of solutions.\n\nThe output type may be specified in the variable as:\n\nZZMatrix (default) a matrix with integers is returned.\nSubObjectIterator{PointVector{ZZRingElem}} an iterator over integer points is returned.\n\nExamples\n\nFind all (x_1 x_2)inmathbbZ^2_ge 0 such that x_1+x_2=3. The solutions are the rows of the output. Note that the output can be permuted, hence we sort it.\n\njulia> A = ZZMatrix([1 1]);\n\njulia> b = zero_matrix(FlintZZ, 1,1); b[1,1]=3;\n\njulia> sortslices(Matrix{BigInt}(solve_non_negative(A, b)), dims=1)\n4×2 Matrix{BigInt}:\n 0 3\n 1 2\n 2 1\n 3 0\n\njulia> typeof(solve_non_negative(A,b))\nZZMatrix\n\njulia> typeof(solve_non_negative(ZZMatrix, A,b))\nZZMatrix\n\njulia> typeof(solve_non_negative(SubObjectIterator{PointVector{ZZRingElem}}, A,b))\nSubObjectIterator{PointVector{ZZRingElem}}\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#support_function-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"support_function","text":"support_function(P::Polyhedron; convention::Symbol = :max)\n\nProduce a function h(ω) = maxdot(xω) x in P. max may be changed to min by setting convention = :min.\n\nExamples\n\njulia> P = cube(3) + simplex(3);\n\njulia> φ = support_function(P);\n\njulia> φ([1,2,3])\n9\n\njulia> ψ = support_function(P, convention = :min);\n\njulia> ψ([1,2,3])\n-6\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#volume-Union{Tuple{Polyhedron{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"volume","text":"volume(P::Polyhedron)\n\nReturn the (Euclidean) volume of P.\n\nExamples\n\njulia> C = cube(2);\n\njulia> volume(C)\n4\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"CurrentModule = Oscar","category":"page"},{"location":"NumberTheory/abelian_closure/#Abelian-closure-of-the-rationals","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"","category":"section"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"The abelian closure mathbfQ^textab is the maximal abelian extension of mathbfQ inside a fixed algebraic closure and can explicitly described as","category":"page"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"mathbfQ^mathrmab = mathbfQ(zeta_n mid n in mathbfN)","category":"page"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"the union of all cyclotomic extensions. Here for n in mathbfN we denote by zeta_n a primitive n-th root of unity.","category":"page"},{"location":"NumberTheory/abelian_closure/#Creation-of-the-abelian-closure-and-elements","page":"Abelian closure of the rationals","title":"Creation of the abelian closure and elements","text":"","category":"section"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"abelian_closure(::QQField)","category":"page"},{"location":"NumberTheory/abelian_closure/#abelian_closure-Tuple{QQField}","page":"Abelian closure of the rationals","title":"abelian_closure","text":"abelian_closure(QQ::RationalField)\n\nReturn a pair (K, z) consisting of the abelian closure K of the rationals and a generator z that can be used to construct primitive roots of unity in K.\n\nAn optional keyword argument sparse can be set to true to switch to a sparse representation. Depending on the application this can be much faster or slower.\n\nExamples\n\njulia> K, z = abelian_closure(QQ);\n\njulia> z(36)\nzeta(36)\n\njulia> K, z = abelian_closure(QQ, sparse = true);\n\njulia> z(36)\n-zeta(36, 9)*zeta(36, 4)^4 - zeta(36, 9)*zeta(36, 4)\n\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"Given the abelian closure, the generator can be recovered as follows:","category":"page"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"gen(::QQAbField)","category":"page"},{"location":"NumberTheory/abelian_closure/#gen-Tuple{QQAbField}","page":"Abelian closure of the rationals","title":"gen","text":"gen(M::SubquoModule{T}, i::Int) where T\n\nReturn the ith generator of M.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/abelian_closure/#Printing","page":"Abelian closure of the rationals","title":"Printing","text":"","category":"section"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"The n-th primitive root of the abelian closure of will by default be printed as z(n). The printing can be manipulated using the following functions:","category":"page"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"gen(::QQAbField, ::String)\nset_variable!(::QQAbField, ::String)\nget_variable(::QQAbField)","category":"page"},{"location":"NumberTheory/abelian_closure/#gen-Tuple{QQAbField, String}","page":"Abelian closure of the rationals","title":"gen","text":"gen(K::QQAbField, s::String)\n\nReturn the generator of the abelian closure K that can be used to construct primitive roots of unity. The string s will be used during printing.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/abelian_closure/#set_variable!-Tuple{QQAbField, String}","page":"Abelian closure of the rationals","title":"set_variable!","text":"set_variable!(K::QQAbField, s::String)\n\nChange the printing of the primitive n-th root of the abelian closure of the rationals to s(n), where s is the supplied string.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/abelian_closure/#get_variable-Tuple{QQAbField}","page":"Abelian closure of the rationals","title":"get_variable","text":"get_variable(K::QQAbField)\n\nReturn the string used to print the primitive n-th root of the abelian closure of the rationals.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/abelian_closure/#Examples","page":"Abelian closure of the rationals","title":"Examples","text":"","category":"section"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"julia> K, z = abelian_closure(QQ);\n\njulia> z(4)\nz(4)\n\njulia> ζ = gen(K, \"ζ\")\nGenerator of abelian closure of Q\n\njulia> ζ(5) + ζ(3)\nζ(15)^5 + ζ(15)^3","category":"page"},{"location":"NumberTheory/abelian_closure/#Reduction-to-characteristic-p","page":"Abelian closure of the rationals","title":"Reduction to characteristic p","text":"","category":"section"},{"location":"NumberTheory/abelian_closure/","page":"Abelian closure of the rationals","title":"Abelian closure of the rationals","text":"reduce(val::QQAbElem, F::FinField)","category":"page"},{"location":"NumberTheory/abelian_closure/#reduce-Tuple{QQAbElem, FinField}","page":"Abelian closure of the rationals","title":"reduce","text":"reduce(val::QQAbElem, F::FinField)\n\nReturn the element of F that is the p-modular reduction of val, where p is the characteristic of F. An exception is thrown if val cannot be reduced modulo p or if the reduction does not lie in F.\n\nExamples\n\njulia> K, z = abelian_closure(QQ);\n\njulia> F = GF(2, 3);\n\njulia> reduce(z(7), F)\no\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#ToricMorphisms","page":"ToricMorphisms","title":"ToricMorphisms","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"A class of morphisms among toric varieties are described by certain lattice morphisms. Let N_1 and N_2 be lattices and Sigma_1, Sigma_2 fans in N_1 and N_2 respectively. A mathbbZ-linear map","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"overlinephi colon N_1 to N_2","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"is said to be compatible with the fans Sigma_1 and Sigma_2 if for every cone sigma_1 in Sigma_1, there exists a cone sigma_2 in Sigma_2 such that overlinephi_mathbbR(sigma_1) subseteq sigma_2.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"By theorem 3.3.4 David A. Cox, John B. Little, Henry K. Schenck (2011), such a map overlinephi induces a morphism phi colon X_Sigma_1 to X_Sigma_2 of the toric varieties, and those morphisms are exactly the toric morphisms.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#Constructors","page":"ToricMorphisms","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#Generic-constructors-without-specified-codomain","page":"ToricMorphisms","title":"Generic constructors without specified codomain","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Vector{Vector{T}}) where {T <: IntegerUnion}\ntoric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Matrix{T}) where {T <: IntegerUnion}\ntoric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::ZZMatrix)\ntoric_morphism(domain::AbstractNormalToricVariety, grid_morphism::GrpAbFinGenMap)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Array{Vector{T}, 1}}} where T<:Union{Integer, ZZRingElem}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Vector{Vector{T}}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = [[0, 1]]\n1-element Vector{Vector{Int64}}:\n [0, 1]\n\njulia> toric_morphism(domain, mapping_matrix)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Matrix{T}}} where T<:Union{Integer, ZZRingElem}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Matrix{T}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = [0 1]\n1×2 Matrix{Int64}:\n 0 1\n\njulia> toric_morphism(domain, mapping_matrix)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Tuple{Oscar.AbstractNormalToricVariety, ZZMatrix}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::ZZMatrix, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> codomain = hirzebruch_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = matrix(ZZ, [0 1])\n[0 1]\n\njulia> toric_morphism(domain, mapping_matrix, codomain)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Tuple{Oscar.AbstractNormalToricVariety, GrpAbFinGenMap}","page":"ToricMorphisms","title":"toric_morphism","text":"function toric_morphism(domain::AbstractNormalToricVariety, grid_morphism::GrpAbFinGenMap, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism from the domain to the codomain with map given by the grid_morphism. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> codomain = hirzebruch_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = matrix(ZZ, [[0, 1]])\n[0 1]\n\njulia> grid_morphism = hom(character_lattice(domain), character_lattice(codomain), mapping_matrix)\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z\nCodomain:\n=========\nAbelian group with structure: Z^2\n\njulia> toric_morphism(domain, grid_morphism, codomain)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#Generic-constructors-with-specified-codomain","page":"ToricMorphisms","title":"Generic constructors with specified codomain","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"toric_morphism(v1::AbstractNormalToricVariety, mapping_matrix::Vector{Vector{T}}, v2::AbstractNormalToricVariety) where {T <: IntegerUnion}\ntoric_morphism(v1::AbstractNormalToricVariety, mapping_matrix::Matrix{T}, v2::AbstractNormalToricVariety) where {T <: IntegerUnion}\ntoric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::ZZMatrix, codomain::AbstractNormalToricVariety)\ntoric_morphism(domain::AbstractNormalToricVariety, grid_morphism::GrpAbFinGenMap, codomain::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Array{Vector{T}, 1}, Oscar.AbstractNormalToricVariety}} where T<:Union{Integer, ZZRingElem}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Vector{Vector{T}}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = [[0, 1]]\n1-element Vector{Vector{Int64}}:\n [0, 1]\n\njulia> toric_morphism(domain, mapping_matrix)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Matrix{T}, Oscar.AbstractNormalToricVariety}} where T<:Union{Integer, ZZRingElem}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::Matrix{T}, codomain::T2=nothing) where {T <: IntegerUnion, T2 <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = [0 1]\n1×2 Matrix{Int64}:\n 0 1\n\njulia> toric_morphism(domain, mapping_matrix)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Tuple{Oscar.AbstractNormalToricVariety, ZZMatrix, Oscar.AbstractNormalToricVariety}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::AbstractNormalToricVariety, mapping_matrix::ZZMatrix, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> codomain = hirzebruch_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = matrix(ZZ, [0 1])\n[0 1]\n\njulia> toric_morphism(domain, mapping_matrix, codomain)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Tuple{Oscar.AbstractNormalToricVariety, GrpAbFinGenMap, Oscar.AbstractNormalToricVariety}","page":"ToricMorphisms","title":"toric_morphism","text":"function toric_morphism(domain::AbstractNormalToricVariety, grid_morphism::GrpAbFinGenMap, codomain::T=nothing) where {T <: Union{AbstractNormalToricVariety, Nothing}}\n\nConstruct the toric morphism from the domain to the codomain with map given by the grid_morphism. As optional argument, the codomain of the morphism can be specified.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal, non-affine, smooth, projective, gorenstein, fano, 1-dimensional toric variety without torusfactor\n\njulia> codomain = hirzebruch_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> mapping_matrix = matrix(ZZ, [[0, 1]])\n[0 1]\n\njulia> grid_morphism = hom(character_lattice(domain), character_lattice(codomain), mapping_matrix)\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z\nCodomain:\n=========\nAbelian group with structure: Z^2\n\njulia> toric_morphism(domain, grid_morphism, codomain)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#Special-constructors","page":"ToricMorphisms","title":"Special constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"toric_identity_morphism(variety::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_identity_morphism-Tuple{Oscar.AbstractNormalToricVariety}","page":"ToricMorphisms","title":"toric_identity_morphism","text":"toric_identity_morphism(variety::AbstractNormalToricVariety)\n\nConstruct the toric identity morphism from variety to variety.\n\nExamples\n\njulia> toric_identity_morphism(hirzebruch_surface(NormalToricVariety, 2))\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#Attributes-of-Toric-Morhpisms","page":"ToricMorphisms","title":"Attributes of Toric Morhpisms","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#General-attributes","page":"ToricMorphisms","title":"General attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"domain(tm::ToricMorphism)\nimage(tm::ToricMorphism)\ncodomain(tm::ToricMorphism)\ngrid_morphism(tm::ToricMorphism)\nmorphism_on_torusinvariant_weil_divisor_group(tm::ToricMorphism)\nmorphism_on_torusinvariant_cartier_divisor_group(tm::ToricMorphism)\nmorphism_on_class_group(tm::ToricMorphism)\nmorphism_on_picard_group(tm::ToricMorphism)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#domain-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"domain","text":"domain(tm::ToricMorphism)\n\nReturn the domain of the toric morphism tm.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> domain(toric_identity_morphism(F4))\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#image-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"image","text":"image(tm::ToricMorphism)\n\nReturn the image of the toric morphism tm.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> image(toric_identity_morphism(F4))\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#codomain-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"codomain","text":"codomain(tm::ToricMorphism)\n\nReturn the codomain of the toric morphism tm.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> codomain(toric_identity_morphism(F4))\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#grid_morphism-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"grid_morphism","text":"grid_morphism(tm::ToricMorphism)\n\nReturn the underlying grid morphism of the toric morphism tm.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> grid_morphism(toric_identity_morphism(F4))\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^2\nCodomain:\n=========\nAbelian group with structure: Z^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#morphism_on_torusinvariant_weil_divisor_group-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"morphism_on_torusinvariant_weil_divisor_group","text":"morphism_on_torusinvariant_weil_divisor_group(tm::ToricMorphism)\n\nFor a given toric morphism tm, this method computes the corresponding map of the torusinvariant Weil divisors.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> morphism_on_torusinvariant_weil_divisor_group(toric_identity_morphism(F4))\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^4\nCodomain:\n=========\nAbelian group with structure: Z^4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#morphism_on_torusinvariant_cartier_divisor_group-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"morphism_on_torusinvariant_cartier_divisor_group","text":"morphism_on_torusinvariant_cartier_divisor_group(tm::ToricMorphism)\n\nFor a given toric morphism tm, this method computes the corresponding map of the Cartier divisors.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> morphism_on_torusinvariant_cartier_divisor_group(toric_identity_morphism(F4))\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^4\nCodomain:\n=========\nAbelian group with structure: Z^4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#morphism_on_class_group-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"morphism_on_class_group","text":"morphism_on_class_group(tm::ToricMorphism)\n\nFor a given toric morphism tm, this method computes the corresponding map of the Class groups.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> morphism_on_class_group(toric_identity_morphism(F4))\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^2\nCodomain:\n=========\nAbelian group with structure: Z^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#morphism_on_picard_group-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"morphism_on_picard_group","text":"morphism_on_picard_group(tm::ToricMorphism)\n\nFor a given toric morphism tm, this method computes the corresponding map of the Picard groups.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> morphism_on_picard_group(toric_identity_morphism(F4))\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^2\nCodomain:\n=========\nAbelian group with structure: Z^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#Special-attributes-of-toric-varieties","page":"ToricMorphisms","title":"Special attributes of toric varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"To every toric variety v we can associate a special toric variety, the Cox variety. By definition, the Cox variety is such that the mapping matrix of the toric morphism from the Cox variety to the variety v is simply given by the ray generators of the variety v. Put differently, if there are exactly N ray generators for the fan of v, then the Cox variety of v has a fan for which the ray generators are the standard basis of mathbbR^N and the maximal cones are one to one to the maximal cones of the fan of v.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/","page":"ToricMorphisms","title":"ToricMorphisms","text":"morphism_from_cox_variety(variety::AbstractNormalToricVariety)\ncox_variety(variety::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#morphism_from_cox_variety-Tuple{Oscar.AbstractNormalToricVariety}","page":"ToricMorphisms","title":"morphism_from_cox_variety","text":"morphism_from_cox_variety(variety::AbstractNormalToricVariety)\n\nReturn the quotient morphism from the Cox variety to the toric variety in question.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> morphism_from_cox_variety(F4)\nA toric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#cox_variety-Tuple{Oscar.AbstractNormalToricVariety}","page":"ToricMorphisms","title":"cox_variety","text":"cox_variety(variety::AbstractNormalToricVariety)\n\nReturn the Cox variety of the toric variety in question.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> cox_variety(F4)\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/intro/#Content","page":"Introduction","title":"Content","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"The toric geometry part of OSCAR comprises algorithms addressing normal toric varieties and objects from commutative algebra and polyhedral geometry derived thereof. In particular, we provide support for the following:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"torus-invariant divisor (classes),\nline bundles,\nline bundle cohomology via cohomCalg (cf. Ralph Blumenhagen, Benjamin Jurke, Thorsten Rahn, Helmut Roschy (2010)),\nvanishing sets of line bundle cohomology (cf. Appendix B of Martin Bies (2018)),\ncohomology ring and cohomology classes,\nChow ring, algebraic cycles and intersection theory,\nelementary support for closed subvarieties.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/#Status","page":"Introduction","title":"Status","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"This project is work-in-progress.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/#Tutorial","page":"Introduction","title":"Tutorial","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"We provide a tutorial for toric geometry in OSCAR.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/#Long-term-goals","page":"Introduction","title":"Long term goals","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"We follow David A. Cox, John B. Little, Henry K. Schenck (2011). Our long term goals include the following:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"Ensure that one can perform all computations of Appendix B in David A. Cox, John B. Little, Henry K. Schenck (2011).\nProvide support for coherent sheaves and their sheaf cohomologies. In particular, the existing algorithms in ToricVarieties_project (based on Martin Bies (2018)) should eventually be available in OSCAR.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"Martin Bies,\nLars Kastner.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Genera-for-hermitian-lattices","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Local-genus-symbols","page":"Genera for hermitian lattices","title":"Local genus symbols","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Definition 8.3.1 ([Kir16]) Let L be a hermitian lattice over EK and let mathfrak p be a prime ideal of mathcal O_K. Let mathfrak P be the largest ideal of mathcal O_E over mathfrak p being invariant under the involution of E. We suppose that we are given a Jordan decomposition","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" L_mathfrak p = perp_i=1^tL_i","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"where the Jordan block L_i is mathfrak P^s_i-modular for 1 leq i leq t, for a strictly increasing sequence of integers s_1 ldots s_t. In particular, mathfrak s(L_i) = mathfrak P^s_i. Then, the local genus symbol g(L mathfrak p) of L_mathfrak p is defined to be:","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"if mathfrak p is good, i.e. non ramified and non dyadic,","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" g(L mathfrak p) = (s_1 r_1 d_1) ldots (s_t r_t d_t)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"where d_i = 1 if the determinant (resp. discriminant) of L_i is a norm in K_mathfrak p^times, and d_i = -1 otherwise, and r_i = textrank(L_i) for all i;","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"if mathfrak p is bad,","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" g(L mathfrak p) = (s_1 r_1 d_1 n_1) ldots (s_t r_t d_t n_t)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"where for all i, n_i = textord_mathfrak p(mathfrak n(L_i))","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Note that we define the scale and the norm of the lattice L_i (1 leq i leq n) defined over the extension of local fields E_mathfrak PK_mathfrak p similarly to the ones of L, by extending by continuity the sesquilinear form of the ambient space of L to the completion. Regarding the determinant (resp. discriminant), it is defined as the determinant of the Gram matrix associated to a basis of L_i relatively to the extension of the sesquilinear form (resp. (-1)^(m(m-1)2 times the determinant, where m is the rank of L_i).","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"We call any tuple in g = g(L mathfrak p) = g_1 ldots g_t a Jordan block of g since it corresponds to invariants of a Jordan block of the completion of the lattice L at mathfrak p. For any such block g_i, we call respectively s_i r_i d_i n_i the scale, the rank, the determinant class (resp. discriminant class) and the norm of g_i. Note that the norm is necessary only when the prime ideal is bad.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"We say that two hermitian lattices L and L over EK are in the same local genus at mathfrak p if g(L mathfrak p) = g(L mathfrak p).","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Creation-of-local-genus-symbols","page":"Genera for hermitian lattices","title":"Creation of local genus symbols","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"There are two ways of creating a local genus symbol for hermitian lattices:","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"either abstractly, by choosing the extension EK, the prime ideal mathfrak p of mathcal O_K, the Jordan blocks data and the type of the d_i's (either determinant class :det or discriminant class :disc);","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(HermLat, E::NumField, p::NfOrdIdl, data::Vector; type::Symbol = :det,\n check::Bool = false)\n -> HermLocalGenus","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"or by constructing the local genus symbol of the completion of a hermitian lattice L over EK at a prime ideal mathfrak p of mathcal O_K.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(L::HermLat, p::NfOrdIdl) -> HermLocalGenus","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Examples","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"We will construct two examples for the rest of this section. Note that the prime chosen here is bad.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det)\nD = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];\nL = hermitian_lattice(E, gens, gram = D);\ng2 = genus(L, p)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Attributes","page":"Genera for hermitian lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"length(::HermLocalGenus)\nbase_field(::HermLocalGenus)\nprime(::HermLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#length-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"length","text":"length(g::HermLocalGenus) -> Int\n\nGiven a local genus symbol g for hermitian lattices, return the number of Jordan blocks of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#base_field-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"base_field","text":"base_field(g::HermLocalGenus) -> NumField\n\nGiven a local genus symbol g for hermitian lattices over EK, return E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#prime-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"prime","text":"prime(g::HermLocalGenus) -> NfOrdIdl\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return mathfrak p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-2","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);\nlength(g1)\nbase_field(g1)\nprime(g1)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Invariants","page":"Genera for hermitian lattices","title":"Invariants","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"scale(::HermLocalGenus, ::Int)\nscale(::HermLocalGenus)\nscales(::HermLocalGenus)\nrank(::HermLocalGenus, ::Int)\nrank(::HermLocalGenus)\nranks(::HermLocalGenus)\ndet(::HermLocalGenus, ::Int)\ndet(::HermLocalGenus)\ndets(::HermLocalGenus)\ndiscriminant(::HermLocalGenus, ::Int)\ndiscriminant(::HermLocalGenus)\nnorm(::HermLocalGenus, ::Int)\nnorms(::HermLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#scale-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"scale","text":"scale(g::HermLocalGenus, i::Int) -> Int\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime mathfrak p of mathcal O_K, return the mathfrak P-valuation of the scale of the ith Jordan block of g, where mathfrak P is a prime ideal of mathcal O_E lying over mathfrak p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#scale-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"scale","text":"scale(g::HermLocalGenus) -> NfOrdFracIdl\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime mathfrak p of mathcal O_K, return the scale of the Jordan block of minimum mathfrak P-valuation, where mathfrakP is a prime ideal of mathcal O_E lying over mathfrak p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#scales-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"scales","text":"scales(g::HermLocalGenus) -> Vector{Int}\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime mathfrak p of mathcal O_K, return the mathfrak P-valuation of the scales of the Jordan blocks of g, where mathfrak P is a prime ideal of mathcal O_E lying over mathfrak p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#rank-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"rank","text":"rank(g::HermLocalGenus, i::Int) -> Int\n\nGiven a local genus symbol g for hermitian lattices, return the rank of the ith Jordan block of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#rank-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"rank","text":"rank(g::HermLocalGenus) -> Int\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return the rank of any hermitian lattice whose mathfrak p-adic completion has local genus symbol g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#ranks-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"ranks","text":"ranks(g::HermLocalGenus) -> Vector{Int}\n\nGiven a local genus symbol g for hermitian lattices, return the ranks of the Jordan blocks of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#det-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"det","text":"det(g::HermLocalGenus, i::Int) -> Int\n\nGiven a local genus symbol g for hermitian lattices over EK, return the determinant of the ith Jordan block of g.\n\nThe returned value is 1 or -1 depending on whether the determinant is a local norm in K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#det-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"det","text":"det(g::HermLocalGenus) -> Int\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return the determinant of a hermitian lattice whose mathfrak p-adic completion has local genus symbol g.\n\nThe returned value is 1 or -1 depending on whether the determinant is a local norm in K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#dets-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"dets","text":"dets(g::HermLocalGenus) -> Vector{Int}\n\nGiven a local genus symbol g for hermitian lattices over EK, return the determinants of the Jordan blocks of g.\n\nThe returned values are 1 or -1 depending on whether the respective determinants are are local norms in K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#discriminant-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"discriminant","text":"discriminant(g::HermLocalGenus, i::Int) -> Int\n\nGiven a local genus symbol g for hermitian lattices over EK, return the discriminant of the ith Jordan block of g.\n\nThe returned value is 1 or -1 depending on whether the discriminant is a local norm in K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#discriminant-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"discriminant","text":"discriminant(g::HermLocalGenus) -> Int\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return the discriminant of a hermitian lattice whose mathfrak p-adic completion has local genus symbol g.\n\nThe returned value is 1 or -1 depending on whether the discriminant is a local norm in K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#norm-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"norm","text":"norm(g::HermLocalGenus, i::Int) -> Int\n\nGiven a ramified dyadic local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return the mathfrak p-valuation of the norm of the ith Jordan block of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#norms-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"norms","text":"norms(g::HermLocalGenus) -> Vector{Int}\n\nGiven a ramified dyadic local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return the mathfrak p-valuations of the norms of the Jordan blocks of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-3","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\nD = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];\nL = hermitian_lattice(E, gens, gram = D);\ng2 = genus(L, p);\nscales(g2)\nranks(g2)\ndets(g2)\nnorms(g2)\nrank(g2), det(g2), discriminant(g2)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Predicates","page":"Genera for hermitian lattices","title":"Predicates","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"is_ramified(::HermLocalGenus)\nis_split(::HermLocalGenus)\nis_inert(::HermLocalGenus)\nis_dyadic(::HermLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#is_ramified-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"is_ramified","text":"is_ramified(g::HermLocalGenus) -> Bool\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return whether mathfrak p is ramified in mathcal O_E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#is_split-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"is_split","text":"is_split(g::HermLocalGenus) -> Bool\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return whether mathfrak p is split in mathcal O_E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#is_inert-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"is_inert","text":"is_inert(g::HermLocalGenus) -> Bool\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return whether mathfrak p is inert in mathcal O_E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#is_dyadic-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"is_dyadic","text":"is_dyadic(g::HermLocalGenus) -> Bool\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return whether mathfrak p is dyadic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-4","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);\nis_ramified(g1), is_split(g1), is_inert(g1), is_dyadic(g1)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Local-uniformizer","page":"Genera for hermitian lattices","title":"Local uniformizer","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"uniformizer(::HermLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#uniformizer-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"uniformizer","text":"uniformizer(g::HermLocalGenus) -> NumFieldElem\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return a generator for the largest ideal of mathcal O_E containing mathfrak p and invariant under the action of the non-trivial involution of E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Example","page":"Genera for hermitian lattices","title":"Example","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);\nuniformizer(g1)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Determinant-representatives","page":"Genera for hermitian lattices","title":"Determinant representatives","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Let g be a local genus symbol for hermitian lattices. Its determinant class, or the determinant class of its Jordan blocks, are given by pm 1, depending on whether the determinants are local norms or not. It is possible to get a representative of this determinant class in terms of powers of the uniformizer of g.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"det_representative(::HermLocalGenus, ::Int)\ndet_representative(::HermLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#det_representative-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"det_representative","text":"det_representative(g::HermLocalGenus, i::Int) -> NumFieldElem\n\nGiven a local genus symbol g for hermitian lattices over EK, return a representative of the norm class of the determinant of the ith Jordan block of g in K^times.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#det_representative-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"det_representative","text":"det_representative(g::HermLocalGenus) -> NumFieldElem\n\nGiven a local genus symbol g for hermitian lattices over EK, return a representative of the norm class of the determinant of g in K^times.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-5","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);\ndet_representative(g1)\ndet_representative(g1,2)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Gram-matrices","page":"Genera for hermitian lattices","title":"Gram matrices","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"gram_matrix(::HermLocalGenus, ::Int)\ngram_matrix(::HermLocalGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#gram_matrix-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"gram_matrix","text":"gram_matrix(g::HermLocalGenus, i::Int) -> MatElem\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return a Gram matrix M of the ith Jordan block of g, with coefficients in E. M is such that any hermitian lattice over EK with Gram matrix M satisfies that the local genus symbol of its completion at mathfrak p is equal to the ith Jordan block of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#gram_matrix-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"gram_matrix","text":"gram_matrix(g::HermLocalGenus) -> MatElem\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return a Gram matrix M of g, with coefficients in E.M is such that any hermitian lattice over EK with Gram matrix M satisfies that the local genus symbol of its completion at mathfrak p is g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-6","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\nD = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];\nL = hermitian_lattice(E, gens, gram = D);\ng2 = genus(L, p);\ngram_matrix(g2)\ngram_matrix(g2,1)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Global-genus-symbols","page":"Genera for hermitian lattices","title":"Global genus symbols","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Let L be a hermitian lattice over EK. Let P(L) be the set of all prime ideals of mathcal O_K which are bad (ramified or dyadic), which are dividing the scale of L or which are dividing the volume of L. Let S(EK) be the set of real infinite places of K which split into complex places in E. We define the global genus symbol G(L) of L to be the datum consisting of the local genus symbols of L at each prime of P(L) and the signatures (i.e. the negative index of inertia) of the Gram matrix of the rational span of L at each place in S(EK).","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Note that prime ideals in P(L) which don't ramify correspond to those for which the corresponding completions of L are not unimodular.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"We say that two lattice L and L over EK are in the same genus, if G(L) = G(L).","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Creation-of-global-genus-symbols","page":"Genera for hermitian lattices","title":"Creation of global genus symbols","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Similarly, there are two ways of constructing a global genus symbol for hermitian lattices:","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"either abstractly, by choosing the extension EK, the set of local genus symbols S and the signatures signatures at the places in S(EK). Note that this requires the given invariants to satisfy the product formula for Hilbert symbols.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(S::Vector{HermLocalGenus}, signatures) -> HermGenus","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Here signatures can be a dictionary with keys the infinite places and values the corresponding signatures, or a collection of tuples of the type (::InfPlc, ::Int);","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"or by constructing the global genus symbol of a given hermitian lattice L.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(L::HermLat) -> HermGenus","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Examples-7","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"As before, we will construct two different global genus symbols for hermitian lattices, which we will use for the rest of this section.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);\ninfp = infinite_places(E)\nSEK = unique([r.base_field_place for r in infp if isreal(r.base_field_place) && !isreal(r)]);\nlength(SEK)\nG1 = genus([g1], [(SEK[1], 1)])\nD = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];\nL = hermitian_lattice(E, gens, gram = D);\nG2 = genus(L)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Attributes-2","page":"Genera for hermitian lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"base_field(::HermGenus)\nprimes(::HermGenus)\nsignatures(::HermGenus)\nrank(::HermGenus)\nis_integral(::HermGenus)\nlocal_symbols(::HermGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#base_field-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"base_field","text":"base_field(G::HermGenus) -> NumField\n\nGiven a global genus symbol G for hermitian lattices over EK, return E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#primes-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"primes","text":"primes(G::HermGenus) -> Vector{NfOrdIdl}\n\nGiven a global genus symbol G for hermitian lattices over EK, return the list of prime ideals of mathcal O_K at which G has a local genus symbol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#signatures-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"signatures","text":"signatures(G::HermGenus) -> Dict{InfPlc, Int}\n\nGiven a global genus symbol G for hermitian lattices over EK, return the signatures at the infinite places of K. For each real place, it is given by the negative index of inertia of the Gram matrix of the rational span of a hermitian lattice whose global genus symbol is G.\n\nThe output is given as a dictionary with keys the infinite places of K and value the corresponding signatures.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#rank-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"rank","text":"rank(G::HermGenus) -> Int\n\nReturn the rank of any hermitian lattice with global genus symbol G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#is_integral-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"is_integral","text":"is_integral(G::HermGenus) -> Bool\n\nReturn whether G defines a genus of integral hermitian lattices.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#local_symbols-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"local_symbols","text":"local_symbols(G::HermGenus) -> Vector{HermLocalGenus}\n\nGiven a global genus symbol of hermitian lattices, return its associated local genus symbols.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-8","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\nD = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];\nL = hermitian_lattice(E, gens, gram = D);\nG2 = genus(L);\nbase_field(G2)\nprimes(G2)\nsignatures(G2)\nrank(G2)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Mass","page":"Genera for hermitian lattices","title":"Mass","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Definition 4.2.1 [Kir16] Let L be a hermitian lattice over EK, and suppose that L is definite. In particular, the automorphism group of L is finite. Let L_1 ldots L_n be a set of representatives of isometry classes in the genus of L. This means that if L is a lattice over EK in the genus of L (i.e. they are in the same genus), then L is isometric to one of the L_i's, and these representatives are pairwise non-isometric. Then we define the mass of the genus G(L) of L to be","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" textmass(G(L)) = sum_i=1^nfrac1textAut(L_i)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"Note that since L is definite, any lattice in the genus of L is also definite, and the definition makes sense.","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"mass(::HermLat)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#mass-Tuple{HermLat}","page":"Genera for hermitian lattices","title":"mass","text":"mass(L::HermLat) -> QQFieldElem\n\nGiven a definite hermitian lattice L, return the mass of its genus.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Example-2","page":"Genera for hermitian lattices","title":"Example","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = polynomial_ring(FlintQQ, \"x\");\nf = x^2 - 2;\nK, a = number_field(f, \"a\", cached = false);\nKt, t = polynomial_ring(K, \"t\");\ng = t^2 + 1;\nE, b = number_field(g, \"b\", cached = false);\nD = matrix(E, 3, 3, [1, 0, 0, 0, 1, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [(-3*a + 7)*b + 3*a, (5//2*a - 1)*b - 3//2*a + 4, 0]), map(E, [(3004*a - 4197)*b - 3088*a + 4348, (-1047//2*a + 765)*b + 5313//2*a - 3780, (-a - 1)*b + 3*a - 1]), map(E, [(728381*a - 998259)*b + 3345554*a - 4653462, (-1507194*a + 2168244)*b - 1507194*a + 2168244, (-5917//2*a - 915)*b - 4331//2*a - 488])];\nL = hermitian_lattice(E, gens, gram = D);\nmass(L)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Representatives-of-a-genus","page":"Genera for hermitian lattices","title":"Representatives of a genus","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"representative(::HermLocalGenus)\nBase.in(::HermLat, ::HermLocalGenus)\nrepresentative(::HermGenus)\nBase.in(::HermLat, ::HermGenus)\nrepresentatives(::HermGenus)\ngenus_representatives(::HermLat)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#representative-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"representative","text":"representative(g::HermLocalGenus) -> HermLat\n\nGiven a local genus symbol g for hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, return a hermitian lattice over EK whose completion at mathfrak p admits g as local genus symbol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#in-Tuple{HermLat, HermLocalGenus}","page":"Genera for hermitian lattices","title":"in","text":"in(L::HermLat, g::HermLocalGenus) -> Bool\n\nReturn whether g and the local genus symbol of the completion of the hermitian lattice L at prime(g) agree. Note that L being in g requires both L and g to be defined over the same extension EK.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#representative-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"representative","text":"representative(G::HermGenus) -> HermLat\n\nGiven a global genus symbol G for hermitian lattices over EK, return a hermitian lattice over EK which admits G as global genus symbol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#in-Tuple{HermLat, HermGenus}","page":"Genera for hermitian lattices","title":"in","text":"in(L::HermLat, G::HermGenus) -> Bool\n\nReturn whether G and the global genus symbol of the hermitian lattice L agree.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#representatives-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"representatives","text":"representatives(G::HermGenus) -> Vector{HermLat}\n\nGiven a global genus symbol G for hermitian lattices, return representatives for the isometry classes of hermitian lattices in G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#genus_representatives-Tuple{HermLat}","page":"Genera for hermitian lattices","title":"genus_representatives","text":"genus_representatives(L::HermLat; max = inf, use_auto = true,\n use_mass = false)\n -> Vector{HermLat}\n\nReturn representatives for the isometry classes in the genus of the hermitian lattice L. At most max representatives are returned.\n\nIf L is definite, the use of the automorphism group of L is enabled by default. It can be disabled by use_auto = false. In the case where L is indefinite, the entry use_auto has no effect. The computation of the mass can be enabled by use_mass = true.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-9","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);\nSEK = unique([restrict(r, K) for r in infinite_places(E) if isreal(restrict(r, K)) && !isreal(r)]);\nG1 = genus([g1], [(SEK[1], 1)]);\nL1 = representative(g1)\nL1 in g1\nL2 = representative(G1)\nL2 in G1, L2 in g1\nlength(genus_representatives(L1))\nlength(representatives(G1))","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Sum-of-genera","page":"Genera for hermitian lattices","title":"Sum of genera","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"direct_sum(::HermLocalGenus, ::HermLocalGenus)\ndirect_sum(::HermGenus, ::HermGenus)","category":"page"},{"location":"Hecke/quad_forms/genusherm/#direct_sum-Tuple{HermLocalGenus, HermLocalGenus}","page":"Genera for hermitian lattices","title":"direct_sum","text":"direct_sum(g1::HermLocalGenus, g2::HermLocalGenus) -> HermLocalGenus\n\nGiven two local genus symbols g1 and g2 for hermitian lattices over EK at the same prime ideal mathfrak p of mathcal O_K, return their direct sum. It corresponds to the local genus symbol of the mathfrak p-adic completion of the direct sum of respective representatives of g1 and g2.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#direct_sum-Tuple{HermGenus, HermGenus}","page":"Genera for hermitian lattices","title":"direct_sum","text":"direct_sum(G1::HermGenus, G2::HermGenus) -> HermGenus\n\nGiven two global genus symbols G1 and G2 for hermitian lattices over EK, return their direct sum. It corresponds to the global genus symbol of the direct sum of respective representatives of G1 and G2.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-10","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nQx, x = QQ[\"x\"];\nK, a = number_field(x^2 - 2, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a, \"b\");\nOK = maximal_order(K);\np = prime_decomposition(OK, 2)[1][1];\ng1 = genus(HermLat, E, p, [(0, 1, 1, 0), (2, 2, -1, 1)], type = :det);\nSEK = unique([restrict(r, K) for r in infinite_places(E) if isreal(restrict(r, K)) && !isreal(r)]);\nG1 = genus([g1], [(SEK[1], 1)]);\nD = matrix(E, 3, 3, [5//2*a - 4, 0, 0, 0, a, a, 0, a, -4*a + 8]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [1, 0, 0]), map(E, [a, 0, 0]), map(E, [b, 0, 0]), map(E, [a*b, 0, 0]), map(E, [0, 1, 0]), map(E, [0, a, 0]), map(E, [0, b, 0]), map(E, [0, a*b, 0]), map(E, [0, 0, 1]), map(E, [0, 0, a]), map(E, [0, 0, b]), map(E, [0, 0, a*b])];\nL = hermitian_lattice(E, gens, gram = D);\ng2 = genus(L, p);\nG2 = genus(L);\ndirect_sum(g1, g2)\ndirect_sum(G1, G2)","category":"page"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Enumeration-of-genera","page":"Genera for hermitian lattices","title":"Enumeration of genera","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"hermitian_local_genera(E, p, ::Int, ::Int, ::Int, ::Int)\nhermitian_genera(::Hecke.NfRel, ::Int, ::Dict{InfPlc, Int}, ::Union{Hecke.NfRelOrdIdl, Hecke.NfRelOrdFracIdl})","category":"page"},{"location":"Hecke/quad_forms/genusherm/#hermitian_local_genera-Tuple{Any, Any, Vararg{Int64, 4}}","page":"Genera for hermitian lattices","title":"hermitian_local_genera","text":"hermitian_local_genera(E::NumField, p::NfOrdIdl, rank::Int,\n det_val::Int, min_scale::Int, max_scale::Int)\n -> Vector{HermLocalGenus}\n\nReturn all local genus symbols for hermitian lattices over the algebra E, with base field K, at the prime idealp of mathcal O_K. Each of them has rank equal to rank, scale mathfrak P-valuations bounded between min_scale and max_scale and determinant p-valuations equal to det_val, where mathfrak P is a prime ideal of mathcal O_E lying above p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#hermitian_genera-Tuple{Hecke.NfRel, Int64, Dict{InfPlc, Int64}, Union{Hecke.NfRelOrdFracIdl, Hecke.NfRelOrdIdl}}","page":"Genera for hermitian lattices","title":"hermitian_genera","text":"hermitian_genera(E::NumField, rank::Int,\n signatures::Dict{InfPlc, Int},\n determinant::Union{Hecke.NfRelOrdIdl, Hecke.NfRelOrdFracIdl};\n min_scale::Union{Hecke.NfRelOrdIdl, Hecke.NfRelOrdFracIdl} = is_integral(determinant) ? inv(1*order(determinant)) : determinant,\n max_scale::Union{Hecke.NfRelOrdIdl, Hecke.NfRelOrdFracIdl} = is_integral(determinant) ? determinant : inv(1*order(determinant)))\n -> Vector{HermGenus}\n\nReturn all global genus symbols for hermitian lattices over the algebraE with rank rank, signatures given by signatures, scale bounded by max_scale and determinant class equal to determinant.\n\nIf max_scale == nothing, it is set to be equal to determinant.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#Examples-11","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(8, \"a\");\nKt, t = K[\"t\"];\nE, b = number_field(t^2 - a * t + 1);\np = prime_decomposition(maximal_order(K), 2)[1][1];\nhermitian_local_genera(E, p, 4, 2, 0, 4)\nSEK = unique([restrict(r, K) for r in infinite_places(E) if isreal(restrict(r, K)) && !isreal(r)]);\nhermitian_genera(E, 3, Dict(SEK[1] => 1, SEK[2] => 1), 30 * maximal_order(E))","category":"page"},{"location":"Hecke/quad_forms/genusherm/#Rescaling","page":"Genera for hermitian lattices","title":"Rescaling","text":"","category":"section"},{"location":"Hecke/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"rescale(g::HermLocalGenus, a::Union{FieldElem, RationalUnion})\nrescale(G::HermGenus, a::Union{FieldElem, RationalUnion})","category":"page"},{"location":"Hecke/quad_forms/genusherm/#rescale-Tuple{HermLocalGenus, Union{FieldElem, Integer, ZZRingElem, Rational}}","page":"Genera for hermitian lattices","title":"rescale","text":"rescale(g::HermLocalGenus, a::Union{FieldElem, RationalUnion})\n -> HermLocalGenus\n\nGiven a local genus symbol G of hermitian lattices and an element a lying in the base field E of g, return the local genus symbol at the prime ideal p associated to g of any representative of g rescaled by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/genusherm/#rescale-Tuple{HermGenus, Union{FieldElem, Integer, ZZRingElem, Rational}}","page":"Genera for hermitian lattices","title":"rescale","text":"rescale(G::HermGenus, a::Union{FieldElem, RationalUnion}) -> HermGenus\n\nGiven a global genus symbol G of hermitian lattices and an element a lying in the base field E of G, return the global genus symbol of any representative of G rescaled by a.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Toric-Line-Bundles","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Constructors","page":"Toric Line Bundles","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Generic-constructors","page":"Toric Line Bundles","title":"Generic constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"toric_line_bundle(v::AbstractNormalToricVariety, picard_class::GrpAbFinGenElem)\ntoric_line_bundle(v::AbstractNormalToricVariety, picard_class::Vector{T}) where {T <: IntegerUnion}\ntoric_line_bundle(v::AbstractNormalToricVariety, d::ToricDivisor)\ntoric_line_bundle(d::ToricDivisor)\ntoric_line_bundle(v::AbstractNormalToricVariety, dc::ToricDivisorClass)\ntoric_line_bundle(dc::ToricDivisorClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_line_bundle-Tuple{Oscar.AbstractNormalToricVariety, GrpAbFinGenElem}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::AbstractNormalToricVariety, picard_class::GrpAbFinGenElem)\n\nConstruct the line bundle on the abstract normal toric variety with given class in the Picard group of the toric variety in question.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(P2, picard_group(P2)([1]))\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_line_bundle-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::AbstractNormalToricVariety, picard_class::Vector{T}) where {T <: IntegerUnion}\n\nConstruct the line bundle on the abstract normal toric variety v with class c in the Picard group of v.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_line_bundle-Tuple{Oscar.AbstractNormalToricVariety, ToricDivisor}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::AbstractNormalToricVariety, d::ToricDivisor)\n\nConstruct the toric variety associated to a (Cartier) torus-invariant divisor d on the normal toric variety v.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, toric_divisor(v, [1, 2, 3]))\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_line_bundle-Tuple{ToricDivisor}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(d::ToricDivisor)\n\nConstruct the toric variety associated to a (Cartier) torus-invariant divisor d.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(v, [1, 2, 3]);\n\njulia> l = toric_line_bundle(d)\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_line_bundle-Tuple{Oscar.AbstractNormalToricVariety, ToricDivisorClass}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::AbstractNormalToricVariety, dc::ToricDivisorClass)\n\nConstruct the toric variety associated to a divisor class in the class group of a toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(v, [1, 2, 3])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> dc = toric_divisor_class(d)\nDivisor class on a normal toric variety\n\njulia> l = toric_line_bundle(v, dc)\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_line_bundle-Tuple{ToricDivisorClass}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(dc::ToricDivisorClass)\n\nConstruct the toric variety associated to a divisor class in the class group of a toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(v, [1, 2, 3])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> dc = toric_divisor_class(d)\nDivisor class on a normal toric variety\n\njulia> l = toric_line_bundle(dc)\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Tensor-products","page":"Toric Line Bundles","title":"Tensor products","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"Toric line bundles can be tensored via *. The n-th tensor power can be computed via ^n. In particular, ^(-1) computes the inverse of a line bundle. Alternatively, one can compute the inverse by invoking inv.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Special-line-bundles","page":"Toric Line Bundles","title":"Special line bundles","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"anticanonical_bundle(v::AbstractNormalToricVariety)\ncanonical_bundle(v::AbstractNormalToricVariety)\nstructure_sheaf(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#anticanonical_bundle-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Line Bundles","title":"anticanonical_bundle","text":"anticanonical_bundle(v::AbstractNormalToricVariety)\n\nConstruct the anticanonical bundle of a normal toric variety. For convenience, we also support anticanonical_bundle(variety).\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> anticanonical_bundle(v)\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#canonical_bundle-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Line Bundles","title":"canonical_bundle","text":"canonical_bundle(v::AbstractNormalToricVariety)\n\nConstruct the canonical bundle of a normal toric variety. For convenience, we also support canonical_bundle(variety).\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> canonical_bundle(v)\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#structure_sheaf-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Line Bundles","title":"structure_sheaf","text":"structure_sheaf(v::AbstractNormalToricVariety)\n\nConstruct the structure sheaf of a normal toric variety. For convenience, we also support structure_sheaf(variety).\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> structure_sheaf(v)\nToric line bundle on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Properties","page":"Toric Line Bundles","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"Equality of toric line bundles can be tested via ==.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"To check if a toric line bundle is trivial, one can invoke is_trivial. Beyond this, we support the following properties of toric line bundles:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"is_basepoint_free(l::ToricLineBundle)\nis_ample(l::ToricLineBundle)\nis_very_ample(l::ToricLineBundle)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#is_basepoint_free-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"is_basepoint_free","text":"is_basepoint_free(l::ToricLineBundle)\n\nReturn true if the toric line bundle l is basepoint free and false otherwise.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> is_basepoint_free(toric_line_bundle(F4, [1, 0]))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#is_ample-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"is_ample","text":"is_ample(l::ToricLineBundle)\n\nReturn true if the toric line bundle l is ample and false otherwise.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> is_ample(toric_line_bundle(F4, [1,0]))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#is_very_ample-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"is_very_ample","text":"is_very_ample(l::ToricLineBundle)\n\nReturn true if the toric line bundle l is very ample and false otherwise.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> is_very_ample(toric_line_bundle(F4, [1,0]))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Attributes","page":"Toric Line Bundles","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"degree(l::ToricLineBundle)\npicard_class(l::ToricLineBundle)\ntoric_divisor(l::ToricLineBundle)\ntoric_divisor_class(l::ToricLineBundle)\ntoric_variety(l::ToricLineBundle)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#degree-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"degree","text":"degree(l::ToricLineBundle)\n\nReturn the degree of the toric line bundle l.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> degree(l)\n2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#picard_class-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"picard_class","text":"picard_class(l::ToricLineBundle)\n\nReturn the class in the Picard group which defines the toric line bundle l.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> picard_class(l)\nElement of\nGrpAb: Z\nwith components [2]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_divisor-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"toric_divisor","text":"toric_divisor(l::ToricLineBundle)\n\nReturn a toric divisor corresponding to the toric line bundle l.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> toric_divisor(l)\nTorus-invariant, cartier, non-prime divisor on a normal toric variety\n\njulia> is_cartier(toric_divisor(l))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_divisor_class-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"toric_divisor_class","text":"toric_divisor_class(l::ToricLineBundle)\n\nReturn a divisor class in the Class group corresponding to the toric line bundle l.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> toric_divisor(l)\nTorus-invariant, cartier, non-prime divisor on a normal toric variety\n\njulia> is_cartier(toric_divisor(l))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_variety-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"toric_variety","text":"toric_variety(l::ToricLineBundle)\n\nReturn the toric variety over which the toric line bundle l is defined.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> toric_variety(l)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#Methods","page":"Toric Line Bundles","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/","page":"Toric Line Bundles","title":"Toric Line Bundles","text":"basis_of_global_sections_via_rational_functions(l::ToricLineBundle)\nbasis_of_global_sections_via_homogeneous_component(l::ToricLineBundle)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#basis_of_global_sections_via_rational_functions-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"basis_of_global_sections_via_rational_functions","text":"basis_of_global_sections_via_rational_functions(l::ToricLineBundle)\n\nReturn a basis of the global sections of the toric line bundle l in terms of rational functions.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> basis_of_global_sections_via_rational_functions(l)\n6-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x1_^2\n x2*x1_^2\n x2^2*x1_^2\n x1_\n x2*x1_\n 1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#basis_of_global_sections_via_homogeneous_component-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"basis_of_global_sections_via_homogeneous_component","text":"basis_of_global_sections_via_homogeneous_component(l::ToricLineBundle)\n\nReturn a basis of the global sections of the toric line bundle l in terms of a homogeneous component of the Cox ring of toric_variety(l). For convenience, this method can also be called via basis_of_global_sections(l::ToricLineBundle).\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> basis_of_global_sections_via_homogeneous_component(l)\n6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x3^2\n x2*x3\n x2^2\n x1*x3\n x1*x2\n x1^2\n\njulia> basis_of_global_sections(l)\n6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x3^2\n x2*x3\n x2^2\n x1*x3\n x1*x2\n x1^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Cohomology-Classes","page":"Cohomology Classes","title":"Cohomology Classes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Constructors","page":"Cohomology Classes","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#General-constructors","page":"Cohomology Classes","title":"General constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"cohomology_class(v::AbstractNormalToricVariety, p::MPolyQuoRingElem)\ncohomology_class(d::ToricDivisor)\ncohomology_class(c::ToricDivisorClass)\ncohomology_class(l::ToricLineBundle)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#cohomology_class-Tuple{Oscar.AbstractNormalToricVariety, MPolyQuoRingElem}","page":"Cohomology Classes","title":"cohomology_class","text":"cohomology_class(v::AbstractNormalToricVariety, p::MPolyQuoRingElem)\n\nConstruct the toric cohomology class on the toric variety v corresponding to the polynomial p. Note that p must reside in the cohomology ring of v.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> c = cohomology_class(P2, gens(cohomology_ring(P2))[1])\nCohomology class on a normal toric variety given by x1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#cohomology_class-Tuple{ToricDivisor}","page":"Cohomology Classes","title":"cohomology_class","text":"cohomology_class(d::ToricDivisor)\n\nConstruct the toric cohomology class corresponding to the toric divisor d.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(P2, [1, 2, 3])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> cohomology_class(d)\nCohomology class on a normal toric variety given by 6*x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#cohomology_class-Tuple{ToricDivisorClass}","page":"Cohomology Classes","title":"cohomology_class","text":"cohomology_class(c::ToricDivisorClass)\n\nConstruct the toric cohomology class corresponding to the toric divisor class c.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, [2])\nDivisor class on a normal toric variety\n\njulia> cohomology_class(tdc)\nCohomology class on a normal toric variety given by 2*x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#cohomology_class-Tuple{ToricLineBundle}","page":"Cohomology Classes","title":"cohomology_class","text":"cohomology_class(l::ToricLineBundle)\n\nConstruct the toric cohomology class corresponding to the toric line bundle l.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(P2, [2])\nToric line bundle on a normal toric variety\n\njulia> polynomial(cohomology_class(l))\n2*x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Addition,-subtraction-and-scalar-multiplication","page":"Cohomology Classes","title":"Addition, subtraction and scalar multiplication","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"Cohomology classes can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem or QQFieldElem.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Wedge-product","page":"Cohomology Classes","title":"Wedge product","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"The wedge product of cohomology classes is implemented via *, using internally the multiplication of the corresponding polynomial (equivalence classes) in the Cox ring.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"A cohomology class can be wedged n-times with itself via ^n, where n can be an integer or of type ZZRingElem.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Properties","page":"Cohomology Classes","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"One can check if a cohomology class is trivial via is_trivial.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"Equality of cohomology classes can be tested via ==.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Attributes","page":"Cohomology Classes","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"toric_variety(c::CohomologyClass)\ncoefficients(c::CohomologyClass)\nexponents(c::CohomologyClass)\npolynomial(c::CohomologyClass)\npolynomial(ring::MPolyQuoRing, c::CohomologyClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#toric_variety-Tuple{CohomologyClass}","page":"Cohomology Classes","title":"toric_variety","text":"toric_variety(c::CohomologyClass)\n\nReturn the normal toric variety of the cohomology class c.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> cc = cohomology_class(d)\nCohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2\n\njulia> toric_variety(cc)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#coefficients-Tuple{CohomologyClass}","page":"Cohomology Classes","title":"coefficients","text":"coefficients(c::CohomologyClass)\n\nReturn the coefficients of the cohomology class c.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> cc = cohomology_class(d)\nCohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2\n\njulia> coefficients(cc)\n3-element Vector{QQFieldElem}:\n 6\n 1\n 7\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#exponents-Tuple{CohomologyClass}","page":"Cohomology Classes","title":"exponents","text":"exponents(c::CohomologyClass)\n\nReturn the exponents of the cohomology class c.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> cc = cohomology_class(d)\nCohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2\n\njulia> exponents(cc)\n[0 0 1 0 0]\n[0 0 0 1 0]\n[0 0 0 0 1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#polynomial-Tuple{CohomologyClass}","page":"Cohomology Classes","title":"polynomial","text":"polynomial(c::CohomologyClass)\n\nReturn the polynomial in the cohomology ring of the normal toric variety toric_variety(c) which corresponds to c.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> cc = cohomology_class(d)\nCohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2\n\njulia> polynomial(cc)\n6*x3 + e1 + 7*e2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#polynomial-Tuple{MPolyQuoRing, CohomologyClass}","page":"Cohomology Classes","title":"polynomial","text":"polynomial(c::CohomologyClass, ring::MPolyQuoRing)\n\nReturn the polynomial in ring corresponding to the cohomology class c.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> cc = cohomology_class(d)\nCohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2\n\njulia> R, _ = polynomial_ring(QQ, 5)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x1, x2, x3, x4, x5])\n\njulia> (x1, x2, x3, x4, x5) = gens(R)\n5-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n x4\n x5\n\njulia> sr_and_linear_relation_ideal = ideal([x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5])\nideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)\n\njulia> R_quo = quo(R, sr_and_linear_relation_ideal)[1]\nQuotient\n of multivariate polynomial ring in 5 variables over QQ\n by ideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)\n\njulia> polynomial(R_quo, cc)\n6*x3 + x4 + 7*x5\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Methods","page":"Cohomology Classes","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"integrate(c::CohomologyClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#integrate-Tuple{CohomologyClass}","page":"Cohomology Classes","title":"integrate","text":"integrate(c::CohomologyClass)\n\nIntegrate the cohomolgy class c over the normal toric variety toric_variety(c).\n\nExamples\n\njulia> dP3 = del_pezzo_surface(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> (x1, x2, x3, e1, e2, e3) = gens(cohomology_ring(dP3))\n6-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n x1\n x2\n x3\n e1\n e2\n e3\n\njulia> c = cohomology_class(dP3, e3*e3 + e3)\nCohomology class on a normal toric variety given by e3^2 + e3\n\njulia> integrate(c)\n-1\n\njulia> F3 = hirzebruch_surface(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> (x1, x2, x3, x4) = gens(cohomology_ring(F3))\n4-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n t1\n x1\n t2\n x2\n\njulia> c = cohomology_class(F3, x1*x2 + x3*x4)\nCohomology class on a normal toric variety given by 2//3*x2^2\n\njulia> integrate(c)\n2\n\nThe following example constructs the Fano variety 2-36 (cf. https://www.fanography.info/2-36) and verifies that the triple self-intersection number of its anticanonical bundle is 62.\n\nExamples\n\njulia> e1 = [1,0,0];\n\njulia> e2 = [0,1,0];\n\njulia> e3 = [0,0,1];\n\njulia> m = 2;\n\njulia> ray_generators = [e1, -e1, e2, e3, - e2 - e3 - m * e1];\n\njulia> max_cones = [[1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5]];\n\njulia> X = normal_toric_variety(ray_generators, max_cones; non_redundant = true)\nNormal toric variety\n\njulia> cox_ring(X)\nMultivariate polynomial ring in 5 variables over QQ graded by\n x1 -> [1 0]\n x2 -> [1 2]\n x3 -> [0 -1]\n x4 -> [0 -1]\n x5 -> [0 -1]\n\njulia> cohomology_ring(X)\nQuotient\n of graded multivariate polynomial ring in 5 variables over QQ\n by ideal(x1 - x2 - 2*x5, x3 - x5, x4 - x5, x1*x2, x3*x4*x5)\n\njulia> integrate(cohomology_class(anticanonical_divisor(X))^3)\n62\n\njulia> integrate(cohomology_class(anticanonical_divisor_class(X))^3)\n62\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#Special-attributes-of-toric-varieties","page":"Cohomology Classes","title":"Special attributes of toric varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/","page":"Cohomology Classes","title":"Cohomology Classes","text":"cohomology_ring(v::AbstractNormalToricVariety)\nvolume_form(v::NormalToricVariety)\nintersection_form(v::NormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#cohomology_ring-Tuple{Oscar.AbstractNormalToricVariety}","page":"Cohomology Classes","title":"cohomology_ring","text":"cohomology_ring(v::AbstractNormalToricVariety)\n\nReturn the cohomology ring of the simplicial and complete toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> ngens(cohomology_ring(p2))\n3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#volume_form-Tuple{NormalToricVariety}","page":"Cohomology Classes","title":"volume_form","text":"volume_form(v::NormalToricVariety)\n\nConstruct the volume form of the normal toric toric variety v.\n\nExamples\n\njulia> polynomial(volume_form(projective_space(NormalToricVariety, 2)))\nx3^2\n\njulia> polynomial(volume_form(del_pezzo_surface(NormalToricVariety, 3)))\n-e3^2\n\njulia> polynomial(volume_form(hirzebruch_surface(NormalToricVariety, 5)))\n1//5*x2^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#intersection_form-Tuple{NormalToricVariety}","page":"Cohomology Classes","title":"intersection_form","text":"intersection_form(v::NormalToricVariety)\n\nComputes the intersection numbers among the cohomology classes associated to the torusinvariant prime divisors of the normal toric toric variety v.\n\nExamples\n\njulia> F3 = hirzebruch_surface(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> length(intersection_form(F3))\n10\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/submodule/#Submodules","page":"Submodules","title":"Submodules","text":"","category":"section"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"AbstractAlgebra allows the construction of submodules/subvector spaces of AbstractAlgebra modules over euclidean domains. These are given as the submodule generated by a finite list of elements in the original module.","category":"page"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"We define two submodules to be equal if they are (transitively) submodules of the same module M and their generators generate the same set of elements.","category":"page"},{"location":"AbstractAlgebra/submodule/#Generic-submodule-type","page":"Submodules","title":"Generic submodule type","text":"","category":"section"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"AbstractAlgebra implements a generic submodule type Generic.Submodule{T} where T is the element type of the base ring in src/generic/Submodule.jl. See src/generic/GenericTypes.jl for more details of the type definition.","category":"page"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"Elements of a generic submodule have type Generic.SubmoduleElem{T}.","category":"page"},{"location":"AbstractAlgebra/submodule/#Abstract-types","page":"Submodules","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"Submodule types belong to the abstract type FPModule{T} and their elements to FPModuleElem{T}.","category":"page"},{"location":"AbstractAlgebra/submodule/#Constructors","page":"Submodules","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"sub(::FPModule{T}, ::Vector{FPModuleElem{T}}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/submodule/#sub-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, Array{AbstractAlgebra.FPModuleElem{T}, 1}}} where T<:RingElement","page":"Submodules","title":"sub","text":"sub(m::AbstractAlgebra.FPModule{T}, gens::Vector{<:AbstractAlgebra.FPModuleElem{T}}) where T <: RingElement\n\nReturn the submodule of the module m generated by the given generators, given as elements of m.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"sub(::FPModule{T}, ::Vector{Generic.Submodule{T}}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/submodule/#sub-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, Array{AbstractAlgebra.Generic.Submodule{T}, 1}}} where T<:RingElement","page":"Submodules","title":"sub","text":"sub(m::Module{T}, subs::Vector{<:Generic.Submodule{T}}) where T <: RingElement\n\nReturn the submodule S of the module m generated by the union of the given submodules of m, and a map which is the canonical injection from S to m.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"Note that the preimage of the canonical injection can be obtained using the preimage function described in the section on module homomorphisms. As the canonical injection is injective, this is unique.","category":"page"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"julia> M = FreeModule(ZZ, 2)\nFree module of rank 2 over integers\n\njulia> m = M([ZZ(1), ZZ(2)])\n(1, 2)\n\njulia> n = M([ZZ(2), ZZ(-1)])\n(2, -1)\n\njulia> N, f = sub(M, [m, n])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 2 over integers)\n\njulia> v = N([ZZ(3), ZZ(4)])\n(3, 4)\n\njulia> v2 = f(v)\n(3, 26)\n\njulia> V = VectorSpace(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> m = V([QQ(1), QQ(2)])\n(1//1, 2//1)\n\njulia> n = V([QQ(2), QQ(-1)])\n(2//1, -1//1)\n\njulia> N, f = sub(V, [m, n])\n(Subspace over Rationals with 2 generators and no relations, Hom: Subspace over Rationals with 2 generators and no relations -> Vector space of dimension 2 over rationals)\n","category":"page"},{"location":"AbstractAlgebra/submodule/#Functionality-for-submodules","page":"Submodules","title":"Functionality for submodules","text":"","category":"section"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"In addition to the Module interface, AbstractAlgebra submodules implement the following functionality.","category":"page"},{"location":"AbstractAlgebra/submodule/#Basic-manipulation","page":"Submodules","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"supermodule(::Generic.Submodule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/submodule/#supermodule-Union{Tuple{AbstractAlgebra.Generic.Submodule{T}}, Tuple{T}} where T<:RingElement","page":"Submodules","title":"supermodule","text":"supermodule(M::Submodule{T}) where T <: RingElement\n\nReturn the module that this module is a submodule of.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"is_submodule(::FPModule{T}, ::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/submodule/#is_submodule-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}}} where T<:RingElement","page":"Submodules","title":"is_submodule","text":"is_submodule(M::AbstractAlgebra.FPModule{T}, N::AbstractAlgebra.FPModule{T}) where T <: RingElement\n\nReturn true if N was constructed as a submodule of M. The relation is taken transitively (i.e. subsubmodules are submodules for the purposes of this relation, etc). The module M is also considered a submodule of itself for this relation.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"is_compatible(::FPModule{T}, ::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/submodule/#is_compatible-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}}} where T<:RingElement","page":"Submodules","title":"is_compatible","text":"is_compatible(M::AbstractAlgebra.FPModule{T}, N::AbstractAlgebra.FPModule{T}) where T <: RingElement\n\nReturn true, P if the given modules are compatible, i.e. that they are (transitively) submodules of the same module, P. Otherwise return false, M.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"dim(N::Generic.Submodule{T}) where T <: FieldElement","category":"page"},{"location":"AbstractAlgebra/submodule/#dim-Union{Tuple{AbstractAlgebra.Generic.Submodule{T}}, Tuple{T}} where T<:FieldElement","page":"Submodules","title":"dim","text":"dim(N::Submodule{T}) where T <: FieldElement\n\nReturn the dimension of the given vector subspace.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"julia> M = FreeModule(ZZ, 2)\nFree module of rank 2 over integers\n\njulia> m = M([ZZ(2), ZZ(3)])\n(2, 3)\n\njulia> n = M([ZZ(1), ZZ(4)])\n(1, 4)\n\njulia> N1, = sub(M, [m, n])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 2 over integers)\n\njulia> N2, = sub(M, [m])\n(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)\n\njulia> supermodule(N1) == M\ntrue\n\njulia> is_compatible(N1, N2)\n(true, Free module of rank 2 over integers)\n\njulia> is_submodule(N1, M)\nfalse\n\n\njulia> V = VectorSpace(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> m = V([QQ(2), QQ(3)])\n(2//1, 3//1)\n\njulia> N, = sub(V, [m])\n(Subspace over Rationals with 1 generator and no relations, Hom: Subspace over Rationals with 1 generator and no relations -> Vector space of dimension 2 over rationals)\n\njulia> dim(V)\n2\n\njulia> dim(N)\n1\n","category":"page"},{"location":"AbstractAlgebra/submodule/#Intersection","page":"Submodules","title":"Intersection","text":"","category":"section"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"Base.intersect(M::FPModule{T}, N::FPModule{T}) where\nT <: RingElement","category":"page"},{"location":"AbstractAlgebra/submodule/#intersect-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}}} where T<:RingElement","page":"Submodules","title":"intersect","text":"Base.intersect(M::FPModule{T}, N::FPModule{T}) where T <: RingElement\n\nReturn the intersection of the modules M as a submodule of M. Note that M and N must be (constructed as) submodules (transitively) of some common module P.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/submodule/","page":"Submodules","title":"Submodules","text":"julia> M = FreeModule(ZZ, 2)\nFree module of rank 2 over integers\n\njulia> m = M([ZZ(2), ZZ(3)])\n(2, 3)\n\njulia> n = M([ZZ(1), ZZ(4)])\n(1, 4)\n\njulia> N1 = sub(M, [m, n])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 2 over integers)\n\njulia> N2 = sub(M, [m])\n(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)\n\njulia> I = intersect(N1, N2)\nAny[]","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"PolyhedralGeometry/linear_programs/#Linear-Programs","page":"Linear Programs","title":"Linear Programs","text":"","category":"section"},{"location":"PolyhedralGeometry/linear_programs/#Introduction","page":"Linear Programs","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"The purpose of a linear program is to optimize a linear function over a polyhedron.","category":"page"},{"location":"PolyhedralGeometry/linear_programs/#Constructions","page":"Linear Programs","title":"Constructions","text":"","category":"section"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"Linear programs are constructed from a polyhedron and a linear objective function which is described by a vector and (optionally) a translation. One can select whether the optimization problem is to maximize or to minimize the objective function.","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"linear_program","category":"page"},{"location":"PolyhedralGeometry/linear_programs/#linear_program","page":"Linear Programs","title":"linear_program","text":"linear_program(P, c; k = 0, convention = :max)\n\nThe linear program on the feasible set P (a Polyhedron) with respect to the function x ↦ dot(c,x)+k.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/linear_programs/#Solving-a-linear-program-an-example","page":"Linear Programs","title":"Solving a linear program - an example","text":"","category":"section"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"Let P=-11^3 be the 3-dimensional cube in mathbbR^3, and consider the linear function ell, given by ell(xyz) = 3x-2y+4z+2. Minimizing ell over P can be done by solving the corresponding linear program. Computationally, this means first defining a linear program:","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"julia> P = cube(3)\nPolyhedron in ambient dimension 3\n\njulia> LP = linear_program(P,[3,-2,4];k=2,convention = :min)\nLinear program\n min{c⋅x + k | x ∈ P}\nwhere P is a Polyhedron{QQFieldElem} and\n c=Polymake.LibPolymake.Rational[3 -2 4]\n k=2","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"The information about the linear program LP can be easily extracted.","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"julia> P = cube(3);\n\njulia> LP = linear_program(P,[3,-2,4];k=2,convention = :min);\n\njulia> c, k = objective_function(LP)\n(QQFieldElem[3, -2, 4], 2)\n\njulia> P == feasible_region(LP)\ntrue","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"To solve the optimization problem call solve_lp, which returns a pair m, v where the optimal value is m, and that value is attained at v.","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"julia> P = cube(3);\n\njulia> LP = linear_program(P,[3,-2,4];k=2,convention = :min);\n\njulia> m, v = solve_lp(LP)\n(-7, QQFieldElem[-1, 1, -1])\n\njulia> ℓ = objective_function(LP; as = :function);\n\njulia> ℓ(v) == convert(QQFieldElem, m)\ntrue","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"note: Infinite solutions\nNote that the optimal value may be pminfty which currently is well-defined by Polymake.jl, but not with the QQFieldElem number type. Hence manual conversion is necessary, until this issue has been resolved.","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"The optimal value and an optimal vertex may be obtained individually as well.","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"julia> P = cube(3);\n\njulia> LP = linear_program(P,[3,-2,4];k=2,convention = :min);\n\njulia> M = optimal_value(LP)\n-7\n\njulia> V = optimal_vertex(LP)\n3-element PointVector{QQFieldElem}:\n -1\n 1\n -1","category":"page"},{"location":"PolyhedralGeometry/linear_programs/#Functions","page":"Linear Programs","title":"Functions","text":"","category":"section"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"feasible_region(lp::LinearProgram)\nobjective_function(lp::LinearProgram{T}; as::Symbol = :pair) where T<:scalar_types\nsolve_lp(LP::LinearProgram)\noptimal_value(lp::LinearProgram{T}) where T<:scalar_types\noptimal_vertex(lp::LinearProgram{T}) where T<:scalar_types\nload_lp(file::String)\nsave_lp(target::Union{String,IO}, lp::Union{MixedIntegerLinearProgram{QQFieldElem},LinearProgram{QQFieldElem}})\nload_mps(file::String)\nsave_mps(target::Union{String,IO}, lp::Union{MixedIntegerLinearProgram{QQFieldElem},LinearProgram{QQFieldElem}})","category":"page"},{"location":"PolyhedralGeometry/linear_programs/#feasible_region-Tuple{LinearProgram}","page":"Linear Programs","title":"feasible_region","text":"feasible_region(lp::LinearProgram)\n\nReturn the feasible region of the linear program lp, which is a Polyhedron.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#objective_function-Union{Tuple{LinearProgram{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Linear Programs","title":"objective_function","text":"objective_function(LP::LinearProgram; as = :pair)\n\nReturn the objective function x ↦ dot(c,x)+k of the linear program LP. The allowed values for as are\n\npair: Return the pair (c,k)\nfunction: Return the objective function as a function.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#solve_lp-Tuple{LinearProgram}","page":"Linear Programs","title":"solve_lp","text":"solve_lp(LP::LinearProgram)\n\nReturn a pair (m,v) where the optimal value m of the objective function of LP is attained at v (if m exists). If the optimum is not attained, m may be inf or -inf in which case v is nothing.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#optimal_value-Union{Tuple{LinearProgram{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Linear Programs","title":"optimal_value","text":"optimal_value(LP::LinearProgram)\n\nReturn, if it exists, the optimal value of the objective function of LP over the feasible region of LP. Otherwise, return -inf or inf depending on convention.\n\nExamples\n\nThe following example constructs a linear program over the three dimensional cube, and obtains the minimal value of the function (x,y,z) ↦ x+2y-3z over that cube.\n\njulia> C=cube(3)\nPolyhedron in ambient dimension 3\n\njulia> LP=linear_program(C,[1,2,-3]; convention = :min)\nLinear program\n min{c⋅x + k | x ∈ P}\nwhere P is a Polyhedron{QQFieldElem} and\n c=Polymake.LibPolymake.Rational[1 2 -3]\n k=0\n\njulia> optimal_value(LP)\n-6\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#optimal_vertex-Union{Tuple{LinearProgram{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Linear Programs","title":"optimal_vertex","text":"optimal_vertex(LP::LinearProgram)\n\nReturn either a point of the feasible region of LP which optimizes the objective function of LP, or nothing if no such point exists.\n\nExamples\n\nThe following example constructs a linear program over the three dimensional cube, and obtains the vertex of the cube which maximizes the function (x,y,z) ↦ x+2y-3z.\n\njulia> C=cube(3)\nPolyhedron in ambient dimension 3\n\njulia> LP=linear_program(C,[1,2,-3])\nLinear program\n max{c⋅x + k | x ∈ P}\nwhere P is a Polyhedron{QQFieldElem} and\n c=Polymake.LibPolymake.Rational[1 2 -3]\n k=0\n\njulia> optimal_vertex(LP)\n3-element PointVector{QQFieldElem}:\n 1\n 1\n -1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#load_lp-Tuple{String}","page":"Linear Programs","title":"load_lp","text":"load_lp(file::String)\n\nLoad a (mixed integer) linear program from an .lp file using the LP file format.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#save_lp-Tuple{Union{IO, String}, Union{LinearProgram{QQFieldElem}, MixedIntegerLinearProgram{QQFieldElem}}}","page":"Linear Programs","title":"save_lp","text":"save_lp(target::Union{String, IO}, lp::Union{MixedIntegerLinearProgram,LinearProgram})\n\nSave a (mixed integer) linear program to an .lp file using the LP file format.\n\nExamples\n\nTake the square -1232^2 with objective 11 and one integer variable. Print the object in LP format to stdout:\n\njulia> c = cube(2, -1//2, 3//2)\nPolyhedron in ambient dimension 2\n\njulia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])\nMixed integer linear program\n\njulia> save_lp(stdout, milp)\nMAXIMIZE\n obj: +1 x1 +1 x2\nSubject To\n ie0: +2 x1 >= -1\n ie1: -2 x1 >= -3\n ie2: +2 x2 >= -1\n ie3: -2 x2 >= -3\nBOUNDS\n x1 free\n x2 free\nGENERAL\n x1\nEND\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#load_mps-Tuple{String}","page":"Linear Programs","title":"load_mps","text":"load_mps(file::String)\n\nLoad a (mixed integer) linear program from an .mps file using the MPS file format.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/linear_programs/#save_mps-Tuple{Union{IO, String}, Union{LinearProgram{QQFieldElem}, MixedIntegerLinearProgram{QQFieldElem}}}","page":"Linear Programs","title":"save_mps","text":"save_mps(target::String, lp::Union{MixedIntegerLinearProgram,LinearProgram})\n\nSave a (mixed integer) linear program to an .mps file using the MPS file format.\n\nExamples\n\nCreate the square -1232^2 with objective 11 and one integer variable. Print the object in MPS format to stdout:\n\njulia> c = cube(2, -1//2, 3//2)\nPolyhedron in ambient dimension 2\n\njulia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])\nMixed integer linear program\n\njulia> save_mps(stdout, milp)\n* Class:\tMIP\n* Rows:\t\t5\n* Columns:\t2\n* Format:\tMPS\n*\nNAME unnamed#0\nROWS\n N C0000000\n G R0000000\n G R0000001\n G R0000002\n G R0000003\nCOLUMNS\n M0000000 'MARKER' 'INTORG'\n x1 C0000000 1 R0000000 1\n x1 R0000001 -1 \n M0000000 'MARKER' 'INTEND'\n x2 C0000000 1 R0000002 1\n x2 R0000003 -1 \nRHS\n B R0000000 -0.5 R0000001 -1.5\n B R0000002 -0.5 R0000003 -1.5\nBOUNDS\n FR BND x1 \n FR BND x2 \nENDATA\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"The algebraic geometry part of OSCAR provides functionality for dealing with","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"affine algebraic sets and varieties\nprojective algebraic sets and varieties\nschemes\ntoric varieties,\ntoric schemes,\ntropical geometry.","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"Computations in affine and projective algebraic geometry rely on Commutative Algebra.","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"Similarly, most algorithms for toric varieties and schemes are are based on Polyhedral Geometry.","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on the theory of varieties and schemes include:","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"Robin Hartshorne (1977)\nThe Stacks Project","category":"page"},{"location":"AlgebraicGeometry/intro/#Conventions","page":"Introduction","title":"Conventions","text":"","category":"section"},{"location":"AlgebraicGeometry/intro/#Projectivization","page":"Introduction","title":"Projectivization","text":"","category":"section"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"There are two opposite conventions in common use when defining the projectivization. For details, see https://stacks.math.columbia.edu/tag/01OA (search for \"Warning\").","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"For an example, look at proposition 3 in https://arxiv.org/abs/1501.04049. This proposition states that any elliptically fibred K3-surface can be described as hypersurface in the space mathbbP(mathcalO_mathbbP^1(0) oplus mathcalO_mathbbP^1(-4) oplus mathcalO_mathbbP^1(-6)). Authors, that apply the opposite convention, would say that any elliptically fibred K3-surface is a hypersurface in mathbbP(mathcalO_mathbbP^1(0) oplus mathcalO_mathbbP^1(4) oplus mathcalO_mathbbP^1(6)). Note the opposite signs.","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"Irrespective of the signs used to denote the ambient space, there is always agreement on the hypersurface equation and the transformation behavior of the local coordinates. In the above example, the hypersurface equation is","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"z y^2 = x^3 + alpha(st) x z^2 + beta(st) z^3 ","category":"page"},{"location":"AlgebraicGeometry/intro/","page":"Introduction","title":"Introduction","text":"where (st) are coordinates on mathbbP^1 and alpha(st), beta(st) are homogeneous polynomials in s, t of degrees 8 and 12, respectively. The projective coordinates x y z of the ambient space transform as sections of the bundles mathcalO_mathbbP^1(4), mathcalO_mathbbP^1(6) and mathcalO_mathbbP^1(0), respectively.","category":"page"},{"location":"Hecke/orders/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"This chapter deals with number fields and orders there of. We follow the common terminology and conventions as e.g. used in Henri Cohen (1993), Henri Cohen (2000), M. Pohst, H. Zassenhaus (1997) or Daniel A. Marcus (2018).","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"If K is a number field, then an order mathcal O of K is a subring of the ring of integers mathcal O_K of K, which is free of rank K mathbf Q as a mathbf Z-module. Depending on whether K is an absolute field or relative field, orders are treated differently. As far as possible, the interaction and the interface for orders of absolute number fields and of relative number fields is the same.","category":"page"},{"location":"Hecke/orders/introduction/#Orders-of-absolute-number-fields","page":"Introduction","title":"Orders of absolute number fields","text":"","category":"section"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"Assume that K is defined as an absolute field. An order mathcal O of such a field are constructed (implicitly) by specifying a mathbf Z-basis, which is referred to as the basis of mathcal O. If (omega_1dotscomega_d) is the basis of mathcal O and (alpha_1dotscalpha_d) the basis of K, then the matrix B in operatornameMat_d times d(mathbf Q) with","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"beginpmatrix omega_1 vdots omega_d endpmatrix = B beginpmatrix alpha_1 vdots alpha_d endpmatrix","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"is the basis matrix of K. If K = mathbfQ(alpha) = mathbfQx(f) is simple with f in mathbfZx, then natural order mathbf Zalpha = mathbfZx(f) is called the equation order of K.","category":"page"},{"location":"Hecke/orders/introduction/#Orders-of-relative-number-fields","page":"Introduction","title":"Orders of relative number fields","text":"","category":"section"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"Orders in non-absolute number fields, that is, relative extensions, are represented differently. Let LK be a finite extension of number fields, then currently we require any order in L to contain mathcal O_K, the ring of integers of K. In this case, an order mathcal O in L is a finitly generated torsion-free module over the Dedekind domain mathcal O_K. As a ring, the order mathcal O is unitary and has L as a fraction field. Due to mathcal O_K in general not being a principal ideal domain, the module structure is more complicated and requires so called pseudo-matrices. See here for details on pseudo-matrices, or Henri Cohen (2000), Chapter 1 for an introduction.","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"In short, mathcal O is represented as sum mathfrak a_i omega_i with fractional mathcal O_K ideals mathfrak a_isubset K and K-linear independent elements omega_iin L. In general it is impossible to have both mathfrak a_i integral and omega_i in mathcal O, thus coefficients will not be integral and/or generators not in the structure.","category":"page"},{"location":"Hecke/orders/introduction/#Examples","page":"Introduction","title":"Examples","text":"","category":"section"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"Usually, to create an order, one starts with a field (or a polynomial):","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"using Hecke; # hide\nQx, x = polynomial_ring(QQ, \"x\");\nK, a = number_field(x^2 - 10, \"a\");\nE = EquationOrder(K)\nZ_K = MaximalOrder(K)\nconductor(E)\nE == Z_K","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"Once orders are created, we can play with elements and ideals:","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"lp = prime_decomposition(Z_K, 2)\np = lp[1][1]\nis_principal(p)\nfl, alpha = is_principal(p^2)\nnorm(alpha)","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"It is possible to work with residue fields as well:","category":"page"},{"location":"Hecke/orders/introduction/","page":"Introduction","title":"Introduction","text":"Fp, mFp = residue_field(Z_K, p)\n[ mFp(x) for x = basis(Z_K)]","category":"page"},{"location":"PolyhedralGeometry/cones/","page":"Cones","title":"Cones","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"PolyhedralGeometry/cones/#Cones","page":"Cones","title":"Cones","text":"","category":"section"},{"location":"PolyhedralGeometry/cones/#Introduction","page":"Cones","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/cones/","page":"Cones","title":"Cones","text":"Let mathbbF be an ordered field; the default is that mathbbF=mathbbQ is the field of rational numbers.","category":"page"},{"location":"PolyhedralGeometry/cones/","page":"Cones","title":"Cones","text":"A set C subseteq mathbbF^n is called a (polyhedral) cone if it can be written as the set of nonnegative linear combinations of finitely many vectors in mathbbF^n. Equivalently, cones can be written as the intersection of finitely many homogeneous linear inequalities.","category":"page"},{"location":"PolyhedralGeometry/cones/","page":"Cones","title":"Cones","text":"Any cone is a special case of a polyhedron. Conversely, intersecting a cone with a suitable affine hyperplane yields a polyhedron whose faces are in bijection with the faces of the cone. Going back and forth between polyhedra and their homogenizations, the cones, is a frequent operation. This is one reason for keeping cones as a distinct type.","category":"page"},{"location":"PolyhedralGeometry/cones/#Construction","page":"Cones","title":"Construction","text":"","category":"section"},{"location":"PolyhedralGeometry/cones/","page":"Cones","title":"Cones","text":"positive_hull(::Type{T}, ::Union{Oscar.MatElem, AbstractMatrix}) where T<:scalar_types\ncone_from_inequalities\ncone_from_equations\nsecondary_cone(SOP::SubdivisionOfPoints{T}) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/cones/#positive_hull-Union{Tuple{T}, Tuple{Type{T}, Union{MatElem, AbstractMatrix}}} where T<:Union{Float64, FieldElem}","page":"Cones","title":"positive_hull","text":"positive_hull([::Union{Type{T}, Field} = QQFieldElem,] R::AbstractCollection[RayVector] [, L::AbstractCollection[RayVector]]; non_redundant::Bool = false) where T<:scalar_types\n\nA polyhedral cone, not necessarily pointed, defined by the positive hull of the rays R, with lineality given by L. The first argument either specifies the Type of its coefficients or their parent Field.\n\nR is given row-wise as representative vectors, with lineality generated by the rows of L, i.e. the cone consists of all positive linear combinations of the rows of R plus all linear combinations of the rows of L.\n\nThis is an interior description, analogous to the V-representation of a polytope.\n\nRedundant rays are allowed.\n\nExamples\n\nTo construct the positive orthant as a Cone, you can write:\n\njulia> R = [1 0; 0 1];\n\njulia> PO = positive_hull(R)\nPolyhedral cone in ambient dimension 2\n\nTo obtain the upper half-space of the plane:\n\njulia> R = [0 1];\n\njulia> L = [1 0];\n\njulia> HS = positive_hull(R, L)\nPolyhedral cone in ambient dimension 2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#cone_from_inequalities","page":"Cones","title":"cone_from_inequalities","text":"cone_from_inequalities([::Union{Type{T}, Field} = QQFieldElem,] I::AbstractCollection[LinearHalfspace] [, E::AbstractCollection[LinearHyperplane]]; non_redundant::Bool = false)\n\nThe (convex) cone defined by\n\n x Ix 0 Ex = 0 \n\nUse non_redundant = true if the given description contains no redundant rows to avoid unnecessary redundancy checks. The first argument either specifies the Type of its coefficients or their parent Field.\n\nExamples\n\njulia> C = cone_from_inequalities([0 -1; -1 1])\nPolyhedral cone in ambient dimension 2\n\njulia> rays(C)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [1, 1]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/cones/#cone_from_equations","page":"Cones","title":"cone_from_equations","text":"cone_from_equations([::Union{Type{T}, Field} = QQFieldElem,] E::AbstractCollection[LinearHyperplane]; non_redundant::Bool = false)\n\nThe (convex) cone defined by\n\n x Ex = 0 \n\nUse non_redundant = true if the given description contains no redundant rows to avoid unnecessary redundancy checks. The first argument either specifies the Type of its coefficients or their parent Field.\n\nExamples\n\njulia> C = cone_from_equations([1 0 0; 0 -1 1])\nPolyhedral cone in ambient dimension 3\n\njulia> lineality_space(C)\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [0, 1, 1]\n\njulia> dim(C)\n1\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/cones/#secondary_cone-Union{Tuple{SubdivisionOfPoints{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Cones","title":"secondary_cone","text":"secondary_cone(SOP::SubdivisionOfPoints)\n\nReturn the secondary cone of a subdivision of points, the closure of all the weight vectors inducing the given subdivision of points.\n\nExamples\n\nFor a non-regular subdivision, the secondary cone can still contain non-trivial weights, but it will not be full-dimensional.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);\n\njulia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0)\nSubdivision of points in ambient dimension 3\n\njulia> C = secondary_cone(MOAE)\nPolyhedral cone in ambient dimension 6\n\njulia> dim(C)\n4\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#Auxiliary-functions","page":"Cones","title":"Auxiliary functions","text":"","category":"section"},{"location":"PolyhedralGeometry/cones/","page":"Cones","title":"Cones","text":"ambient_dim(C::Cone)\nBase.in(v::AbstractVector, C::Cone)\nBase.issubset(C0::Cone{T}, C1::Cone{T}) where T<:scalar_types\nf_vector(C::Cone)\nhilbert_basis(C::Cone{QQFieldElem})\ncodim(C::Cone)\ndim(C::Cone)\npolarize(C::Cone{T}) where T<:scalar_types\nintersect(C::Cone...)\nis_pointed(C::Cone)\nis_fulldimensional(C::Cone)\nlineality_dim(C::Cone)\nlineality_space(C::Cone{T}) where T<:scalar_types\nnfacets(C::Cone)\nnrays(C::Cone)\nrays(C::Cone{T}) where T<:scalar_types\nrays_modulo_lineality(C::Cone{T}) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/cones/#ambient_dim-Tuple{Cone}","page":"Cones","title":"ambient_dim","text":"ambient_dim(C::Cone)\n\nReturn the ambient dimension of C.\n\nExamples\n\nThe cone C in this example is 2-dimensional within a 3-dimensional ambient space.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);\n\njulia> ambient_dim(C)\n3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#in-Tuple{AbstractVector, Cone}","page":"Cones","title":"in","text":"in(v::AbstractVector, C::Cone)\n\nCheck whether the vector v is contained in the cone C.\n\nExamples\n\nThe positive orthant only contains vectors with non-negative entries:\n\njulia> C = positive_hull([1 0; 0 1]);\n\njulia> [1, 2] in C\ntrue\n\njulia> [1, -2] in C\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#issubset-Union{Tuple{T}, Tuple{Cone{T}, Cone{T}}} where T<:Union{Float64, FieldElem}","page":"Cones","title":"issubset","text":"issubset(C0::Cone, C1::Cone)\n\nCheck whether C0 is a subset of the cone C1.\n\nExamples\n\njulia> C0 = positive_hull([1 1])\nPolyhedral cone in ambient dimension 2\n\njulia> C1 = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> issubset(C0, C1)\ntrue\n\njulia> issubset(C1, C0)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#f_vector-Tuple{Cone}","page":"Cones","title":"f_vector","text":"f_vector(C::Cone)\n\nCompute the vector (f₁f₂f_(dim(C)-1))` where f_i is the number of faces of C of dimension i.\n\nExamples\n\nTake the cone over a square, then the f-vector of the cone is the same as of the square.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 1 1 1; 1 0 1])\nPolyhedral cone in ambient dimension 3\n\njulia> f_vector(C)\n2-element Vector{ZZRingElem}:\n 4\n 4\n\njulia> square = cube(2)\nPolyhedron in ambient dimension 2\n\njulia> f_vector(square)\n2-element Vector{ZZRingElem}:\n 4\n 4\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#hilbert_basis-Tuple{Cone{QQFieldElem}}","page":"Cones","title":"hilbert_basis","text":"hilbert_basis(C::Cone{QQFieldElem})\n\nReturn the Hilbert basis of a pointed cone C as the rows of a matrix.\n\nExamples\n\nThis (non-smooth) cone in the plane has a hilbert basis with three elements.\n\njulia> C = positive_hull([1 0; 1 2])\nA polyhedral cone in ambient dimension 2\n\njulia> matrix(ZZ, hilbert_basis(C))\n[1 0]\n[1 2]\n[1 1]\n\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#codim-Tuple{Cone}","page":"Cones","title":"codim","text":"codim(C::Cone)\n\nReturn the codimension of C.\n\nExamples\n\nThe cone C in this example is 2-dimensional within a 3-dimensional ambient space.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);\n\njulia> codim(C)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#dim-Tuple{Cone}","page":"Cones","title":"dim","text":"dim(C::Cone)\n\nReturn the dimension of C.\n\nExamples\n\nThe cone C in this example is 2-dimensional within a 3-dimensional ambient space.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);\n\njulia> dim(C)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#polarize-Union{Tuple{Cone{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Cones","title":"polarize","text":"polarize(C::Cone)\n\nReturn the polar dual of C, the cone consisting of all those linear functions that evaluate positively on all of C.\n\nExamples\n\njulia> C = positive_hull([1 0; -1 2])\nPolyhedral cone in ambient dimension 2\n\njulia> Cv = polarize(C)\nPolyhedral cone in ambient dimension 2\n\njulia> rays(Cv)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 1//2]\n [0, 1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#intersect-Tuple{Vararg{Cone}}","page":"Cones","title":"intersect","text":"intersect(C::Cone...)\n\nReturn the intersection bigcaplimits_c in C c.\n\nExamples\n\njulia> C0 = positive_hull([1 0])\nPolyhedral cone in ambient dimension 2\n\njulia> C1 = positive_hull([0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> C01 = intersect(C0, C1)\nPolyhedral cone in ambient dimension 2\n\njulia> rays(C01)\n0-element SubObjectIterator{RayVector{QQFieldElem}}\n\njulia> dim(C01)\n0\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#is_pointed-Tuple{Cone}","page":"Cones","title":"is_pointed","text":"is_pointed(C::Cone)\n\nDetermine whether C is pointed, i.e. whether the origin is a face of C.\n\nExamples\n\nA cone with lineality is not pointed, but a cone only consisting of a single ray is.\n\njulia> C = positive_hull([1 0], [0 1]);\n\njulia> is_pointed(C)\nfalse\n\njulia> C = positive_hull([1 0]);\n\njulia> is_pointed(C)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#is_fulldimensional-Tuple{Cone}","page":"Cones","title":"is_fulldimensional","text":"is_fulldimensional(C::Cone)\n\nDetermine whether C is full-dimensional.\n\nExamples\n\nThe cone C in this example is 2-dimensional within a 3-dimensional ambient space.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 0 1 0]);\n\njulia> is_fulldimensional(C)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#lineality_dim-Tuple{Cone}","page":"Cones","title":"lineality_dim","text":"lineality_dim(C::Cone)\n\nCompute the dimension of the lineality space of C, i.e. the largest linear subspace contained in C.\n\nExamples\n\nA cone is pointed if and only if the dimension of its lineality space is zero.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 1 1 1; 1 0 1])\nPolyhedral cone in ambient dimension 3\n\njulia> is_pointed(C)\ntrue\n\njulia> lineality_dim(C)\n0\n\njulia> C1 = positive_hull([1 0],[0 1; 0 -1])\nPolyhedral cone in ambient dimension 2\n\njulia> is_pointed(C1)\nfalse\n\njulia> lineality_dim(C1)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#lineality_space-Union{Tuple{Cone{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Cones","title":"lineality_space","text":"lineality_space(C::Cone)\n\nReturn a basis of the lineality space of C.\n\nExamples\n\nThree rays are used here to construct the upper half-plane. Actually, two of these rays point in opposite directions. This gives us a 1-dimensional lineality.\n\njulia> UH = positive_hull([1 0; 0 1; -1 0]);\n\njulia> lineality_space(UH)\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#nfacets-Tuple{Cone}","page":"Cones","title":"nfacets","text":"nfacets(C::Cone)\n\nReturn the number of facets of a cone C.\n\nExamples\n\nThe cone over a square at height one has four facets.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 1 1 1; 1 0 1])\nPolyhedral cone in ambient dimension 3\n\njulia> nfacets(C)\n4\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#nrays-Tuple{Cone}","page":"Cones","title":"nrays","text":"nrays(C::Cone)\n\nReturn the number of rays of C.\n\nExamples\n\nHere a cone is constructed from three rays. Calling nrays reveals that one of these was redundant:\n\njulia> R = [1 0; 0 1; 0 2];\n\njulia> PO = positive_hull(R);\n\njulia> nrays(PO)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#rays-Union{Tuple{Cone{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Cones","title":"rays","text":"rays(C::Cone)\n\nReturn the rays of C.\n\nExamples\n\nHere a cone is constructed from three rays. Calling rays reveals that one of these was redundant:\n\njulia> R = [1 0; 0 1; 0 2];\n\njulia> PO = positive_hull(R);\n\njulia> rays(PO)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [0, 1]\n\nThe rays can also be converted to a matrix using the matrix(ring, ...) function. If ring=ZZ the primitive generators of the rays are returned.\n\njulia> R = [1 0; 2 3];\n\njulia> P = positive_hull(R);\n\njulia> rays(P)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [1, 3//2]\n\njulia> matrix(QQ, rays(P))\n[1 0]\n[1 3//2]\n\njulia> matrix(ZZ, rays(P))\n[1 0]\n[2 3]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#rays_modulo_lineality-Union{Tuple{Cone{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Cones","title":"rays_modulo_lineality","text":"rays_modulo_lineality(as, C::Cone)\n\nReturn the rays of the cone of C up to lineality as a NamedTuple with two iterators. If C has lineality L, then the iterator rays_modulo_lineality iterates over representatives of the rays of C/L. The iterator lineality_basis gives a basis of the lineality space L.\n\nExamples\n\nFor a pointed cone, with two generators, we get the usual rays:\n\njulia> C = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> rays(C)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [0, 1]\n\njulia> RML = rays_modulo_lineality(C)\n(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0], [0, 1]], lineality_basis = RayVector{QQFieldElem}[])\n\njulia> RML.rays_modulo_lineality\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [0, 1]\n\njulia> RML.lineality_basis\n0-element SubObjectIterator{RayVector{QQFieldElem}}\n\nIf the cone has lineality, the second iterator iterates over a basis for the space of lineality. The following example has one generator for the positive hull plus one generator for the lineality space: \n\njulia> C = positive_hull([1 0],[0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> lineality_dim(C)\n1\n\njulia> rays(C)\n0-element SubObjectIterator{RayVector{QQFieldElem}}\n\njulia> RML = rays_modulo_lineality(C)\n(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])\n\njulia> RML.lineality_basis\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [0, 1]\n\n\n\n\n\n","category":"method"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"CurrentModule = Nemo\nDocTestFilters = r\"[0-9\\.]+ seconds \\(.*\\)\"\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/#Getting-Started","page":"Getting Started","title":"Getting Started","text":"","category":"section"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Nemo is a computer algebra package for the Julia programming language, maintained by William Hart, Tommy Hofmann, Claus Fieker, Fredrik Johansson with additional code by Oleksandr Motsak, Marek Kaluba and other contributors.","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"https://github.com/Nemocas/Nemo.jl (Source code)\nhttps://nemocas.github.io/Nemo.jl/stable/ (Online documentation)","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"The features of Nemo so far include:","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Multiprecision integers and rationals\nIntegers modulo n\np-adic numbers\nFinite fields (prime and non-prime order)\nNumber field arithmetic\nAlgebraic numbers\nExact real and complex numbers\nArbitrary precision real and complex balls\nUnivariate and multivariate polynomials and matrices over the above","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Nemo depends on AbstractAlgebra.jl which provides Nemo with generic routines for:","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Univariate and multivariate polynomials\nAbsolute and relative power series\nLaurent series\nFraction fields\nResidue rings\nMatrices and linear algebra\nYoung Tableaux\nPermutation groups\nCharacters","category":"page"},{"location":"Nemo/#Installation","page":"Getting Started","title":"Installation","text":"","category":"section"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"To use Nemo we require Julia 1.6 or higher. Please see https://julialang.org/downloads/ for instructions on how to obtain julia for your system.","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"At the Julia prompt simply type","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"julia> using Pkg; Pkg.add(\"Nemo\")","category":"page"},{"location":"Nemo/#Quick-start","page":"Getting Started","title":"Quick start","text":"","category":"section"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Here are some examples of using Nemo.","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"This example computes recursive univariate polynomials.","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"julia> using Nemo\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over ZZ, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> T, z = polynomial_ring(S, \"z\")\n(Univariate polynomial ring in z over univariate polynomial ring, z)\n\njulia> f = x + y + z + 1\nz + y + x + 1\n\njulia> p = f^30; # semicolon suppresses output\n\njulia> @time q = p*(p+1);\n 0.161733 seconds (79.42 k allocations: 2.409 MiB)","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Here is an example using generic recursive ring constructions.","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"julia> using Nemo\n\njulia> R, x = FiniteField(7, 11, \"x\")\n(Finite field of degree 11 over GF(7), x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over GF(7^11), y)\n\njulia> T = residue_ring(S, y^3 + 3x*y + 1)\nResidue ring of univariate polynomial ring modulo y^3 + 3*x*y + 1\n\njulia> U, z = polynomial_ring(T, \"z\")\n(Univariate polynomial ring in z over residue ring, z)\n\njulia> f = (3y^2 + y + x)*z^2 + ((x + 2)*y^2 + x + 1)*z + 4x*y + 3;\n\njulia> g = (7y^2 - y + 2x + 7)*z^2 + (3y^2 + 4x + 1)*z + (2x + 1)*y + 1;\n\njulia> s = f^12;\n\njulia> t = (s + g)^12;\n\njulia> @time resultant(s, t)\n 0.059095 seconds (391.89 k allocations: 54.851 MiB, 5.22% gc time)\n(x^10 + 4*x^8 + 6*x^7 + 3*x^6 + 4*x^5 + x^4 + 6*x^3 + 5*x^2 + x)*y^2 + (5*x^10 + x^8 + 4*x^7 + 3*x^5 + 5*x^4 + 3*x^3 + x^2 + x + 6)*y + 2*x^10 + 6*x^9 + 5*x^8 + 5*x^7 + x^6 + 6*x^5 + 5*x^4 + 4*x^3 + x + 3","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Here is an example using matrices.","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"julia> using Nemo\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over ZZ, x)\n\njulia> S = matrix_space(R, 40, 40)\nMatrix space of 40 rows and 40 columns\n over univariate polynomial ring in x over ZZ\n\njulia> M = rand(S, 2:2, -20:20);\n\njulia> @time det(M);\n 0.080976 seconds (132.28 k allocations: 23.341 MiB, 4.11% gc time)","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"And here is an example with power series.","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"julia> using Nemo\n\njulia> R, x = QQ[\"x\"]\n(Univariate polynomial ring in x over QQ, x)\n\njulia> S, t = power_series_ring(R, 100, \"t\")\n(Univariate power series ring over univariate polynomial ring, t + O(t^101))\n\njulia> u = t + O(t^100)\nt + O(t^100)\n\njulia> @time divexact((u*exp(x*u)), (exp(u)-1));\n 0.412813 seconds (667.49 k allocations: 33.966 MiB, 90.26% compilation time)","category":"page"},{"location":"Nemo/#Building-dependencies-from-source","page":"Getting Started","title":"Building dependencies from source","text":"","category":"section"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Nemo depends on various C libraries which are installed using binaries by default. With julia version >= 1.3, the use of these binaries can be overridden by putting the following into the file ~/.julia/artifacts/Overrides.toml:","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"[e134572f-a0d5-539d-bddf-3cad8db41a82]\nFLINT = \"/prefix/for/libflint\"\n\n[d9960996-1013-53c9-9ba4-74a4155039c3]\nArb = \"/prefix/for/libarb\"\n\n[e21ec000-9f72-519e-ba6d-10061e575a27]\nAntic = \"/prefix/for/libantic\"","category":"page"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"(If only a specific library should be overridden, only the specific entry should be added.)","category":"page"},{"location":"Nemo/#Experimental-threading-support-for-flint","page":"Getting Started","title":"Experimental threading support for flint","text":"","category":"section"},{"location":"Nemo/","page":"Getting Started","title":"Getting Started","text":"Enabling a threaded version of flint can be done by setting the environment variable NEMO_THREADED=1. To set the actual number of threads, use Nemo.flint_set_num_threads($numberofthreads).","category":"page"},{"location":"Hecke/orders/elements/#Elements","page":"Elements","title":"Elements","text":"","category":"section"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"Elements in orders have two representations: they can be viewed as elements in the mathbf Z^n giving the coefficients wrt to the order basis where they are elements in. On the other hand, as every order is in a field, they also have a representation as number field elements. Since, asymptotically, operations are more efficient in the field (due to fast polynomial arithmetic) than in the order, the primary representation is that as a field element.","category":"page"},{"location":"Hecke/orders/elements/#Creation","page":"Elements","title":"Creation","text":"","category":"section"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"Elements are constructed either as linear combinations of basis elements or via explicit coercion. Elements will be of type NfAbsOrdElem, the type if actually parametrized by the type of the surrounding field and the type of the field elements. E.g. the type of any element in any order of an absolute simple field will be NfAbsOrdElem{AnticNumberField,nf_elem}","category":"page"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"NfAbsOrd","category":"page"},{"location":"Hecke/orders/elements/#NfAbsOrd","page":"Elements","title":"NfAbsOrd","text":" (O::NumFieldOrd)(a::NumFieldElem, check::Bool = true) -> NumFieldOrdElem\n\nGiven an element a of the ambient number field of mathcal O, this function coerces the element into mathcal O. It will be checked that a is contained in mathcal O if and only if check is true.\n\n\n\n\n\n (O::NumFieldOrd)(a::NumFieldOrdElem, check::Bool = true) -> NumFieldOrdElem\n\nGiven an element a of some order in the ambient number field of mathcal O, this function coerces the element into mathcal O. It will be checked that a is contained in mathcal O if and only if check is true.\n\n\n\n\n\n (O::NumFieldOrd)(a::IntegerUnion) -> NumFieldOrdElem\n\nGiven an element a of type ZZRingElem or Integer, this function coerces the element into mathcal O.\n\n\n\n\n\n (O::NfAbsOrd)(arr::Vector{ZZRingElem})\n\nReturns the element of mathcal O with coefficient vector arr.\n\n\n\n\n\n (O::NfAbsOrd)(arr::Vector{Integer})\n\nReturns the element of mathcal O with coefficient vector arr.\n\n\n\n\n\n","category":"type"},{"location":"Hecke/orders/elements/#Basic-properties","page":"Elements","title":"Basic properties","text":"","category":"section"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"parent(::NfOrdElem)\nelem_in_nf(::NfOrdElem)\ncoordinates(::NfOrdElem)\ndiscriminant(::Vector{NfOrdElem})\n==(::NfOrdElem, ::NfOrdElem)","category":"page"},{"location":"Hecke/orders/elements/#parent-Tuple{NfOrdElem}","page":"Elements","title":"parent","text":"parent(a::AbstractAlgebra.MatElem{T}) where T <: NCRingElement\n\nReturn the parent object of the given matrix.\n\n\n\n\n\nparent(a::MatAlgElem{T}) where T <: NCRingElement\n\nReturn the parent object of the given matrix.\n\n\n\n\n\nparent(a::NumFieldOrdElem) -> NumFieldOrd\n\nReturns the order of which a is an element.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#elem_in_nf-Tuple{NfOrdElem}","page":"Elements","title":"elem_in_nf","text":"elem_in_nf(a::NumFieldOrdElem) -> NumFieldElem\n\nReturns the element a considered as an element of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#coordinates-Tuple{NfOrdElem}","page":"Elements","title":"coordinates","text":"coordinates(a::NfAbsOrdElem) -> Vector{ZZRingElem}\n\nReturns the coefficient vector of a with respect to the basis of the order.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#discriminant-Tuple{Vector{NfOrdElem}}","page":"Elements","title":"discriminant","text":"discriminant(g::Vector)\n\nCompute the product of all differences of distinct elements in the array. \n\n\n\n\n\ndiscriminant(B::Vector{NumFieldOrdElem})\n\nReturns the discriminant of the family B of algebraic numbers, i.e. det((tr(Bi*Bj))_i j)^2.\n\n\n\n\n\ndiscriminant(E::EllCrv) -> FieldElem\n\nReturn the discriminant of E.\n\n\n\n\n\ndiscriminant(C::HypellCrv{T}) -> T\n\nCompute the discriminant of C.\n\n\n\n\n\ndiscriminant(O::AlgssRelOrd)\n\nReturns the discriminant of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#==-Tuple{NfOrdElem, NfOrdElem}","page":"Elements","title":"==","text":"==(x::NumFieldOrdElem, y::NumFieldOrdElem) -> Bool\n\nReturns whether x and y are equal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#Arithmetic","page":"Elements","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"All the usual arithmetic operatinos are defined:","category":"page"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"-(::NUmFieldOrdElem)\n+(::NumFieldOrdElem, ::NumFieldOrdElem)\n-(::NumFieldOrdElem, ::NumFieldOrdElem)\n*(::NumFieldOrdElem, ::NumFieldOrdElem)\n^(::NumFieldOrdElem, ::Int)\nmod(::NfAbsOrdElem, ::Int)\nmod_sym(::NumFieldOrdElem, ::ZZRingElem)\npowermod(::NfAbsOrdElem, ::ZZRingElem, ::Int)","category":"page"},{"location":"Hecke/orders/elements/#Miscellaneous","page":"Elements","title":"Miscellaneous","text":"","category":"section"},{"location":"Hecke/orders/elements/","page":"Elements","title":"Elements","text":"representation_matrix(::NfAbsOrdElem)\nrepresentation_matrix(::NfOrdElem, ::AnticNumberField)\ntr(::NumFieldOrdElem)\nnorm(::NumFieldOrdElem)\nabsolute_norm(::NfAbsOrdElem)\nabsolute_tr(::NfAbsOrdElem)\nrand(::NfOrd, ::Int)\nminkowski_map(::NfOrdElem, ::Int)\nconjugates_arb(::NfOrdElem, ::Int)\nconjugates_arb_log(::NfOrdElem, ::Int)\nt2(::NfOrdElem, ::Int)\nminpoly(::NfOrdElem)\ncharpoly(::NfOrdElem)\nfactor(::NfOrdElem)\ndenominator(a::NumFieldElem, O::NfRelOrd)\ndiscriminant(::Vector{NfAbsOrdElem})","category":"page"},{"location":"Hecke/orders/elements/#representation_matrix-Tuple{NfAbsOrdElem}","page":"Elements","title":"representation_matrix","text":"representation_matrix(a::NfAbsOrdElem) -> ZZMatrix\n\nReturns the representation matrix of the element a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#representation_matrix-Tuple{NfOrdElem, AnticNumberField}","page":"Elements","title":"representation_matrix","text":"representation_matrix(a::NfAbsOrdElem, K::AnticNumberField) -> FakeFmpqMat\n\nReturns the representation matrix of the element a considered as an element of the ambient number field K. It is assumed that K is the ambient number field of the order of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#tr-Tuple{NumFieldOrdElem}","page":"Elements","title":"tr","text":"tr(a::NumFieldOrdElem)\n\nReturns the trace of a as an element of the base ring.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#norm-Tuple{NumFieldOrdElem}","page":"Elements","title":"norm","text":"norm(a::NumFieldOrdElem)\n\nReturns the norm of a as an element in the base ring.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#absolute_norm-Tuple{NfAbsOrdElem}","page":"Elements","title":"absolute_norm","text":"absolute_norm(a::NumFieldOrdElem) -> ZZRingElem\n\nReturn the absolute norm as an integer.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#absolute_tr-Tuple{NfAbsOrdElem}","page":"Elements","title":"absolute_tr","text":"absolute_tr(a::NumFieldOrdElem) -> ZZRingElem\n\nReturn the absolute trace as an integer.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#rand-Tuple{NfOrd, Int64}","page":"Elements","title":"rand","text":"rand(O::NfOrd, n::IntegerUnion) -> NfAbsOrdElem\n\nComputes a coefficient vector with entries uniformly distributed in -ndotsc-101dotscn and returns the corresponding element of the order mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#minkowski_map-Tuple{NfOrdElem, Int64}","page":"Elements","title":"minkowski_map","text":"minkowski_map(a::NumFieldOrdElem, abs_tol::Int) -> Vector{arb}\n\nReturns the image of a under the Minkowski embedding. Every entry of the array returned is of type arb with radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#conjugates_arb-Tuple{NfOrdElem, Int64}","page":"Elements","title":"conjugates_arb","text":"conjugates_arb(x::NumFieldOrdElem, abs_tol::Int) -> Vector{acb}\n\nCompute the conjugates of x as elements of type acb. Recall that we order the complex conjugates sigma_r+1(x)sigma_r+2s(x) such that sigma_i(x) = overlinesigma_i + s(x) for r + 2 leq i leq r + s.\n\nEvery entry y of the array returned satisfies radius(real(y)) < 2^-abs_tol, radius(imag(y)) < 2^-abs_tol respectively.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#conjugates_arb_log-Tuple{NfOrdElem, Int64}","page":"Elements","title":"conjugates_arb_log","text":"conjugates_arb_log(x::NumFieldOrdElem, abs_tol::Int) -> Vector{arb}\n\nReturns the elements (log(lvert sigma_1(x) rvert)dotsclog(lvertsigma_r(x) rvert) dotsc2log(lvert sigma_r+1(x) rvert)dotsc 2log(lvert sigma_r+s(x)rvert)) as elements of type arb radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#t2-Tuple{NfOrdElem, Int64}","page":"Elements","title":"t2","text":"t2(x::NumFieldOrdElem, abs_tol::Int = 32) -> arb\n\nReturn the T_2-norm of x. The radius of the result will be less than 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#minpoly-Tuple{NfOrdElem}","page":"Elements","title":"minpoly","text":"minpoly(S::Ring, M::MatAlgElem{T}, charpoly_only::Bool = false) where {T <: RingElement}\n\nReturn the minimal polynomial p of the matrix M. The polynomial ring S of the resulting polynomial must be supplied and the matrix must be square.\n\n\n\n\n\nminpoly(a::NfAbsOrdElem) -> ZZPolyRingElem\n\nThe minimal polynomial of a.\n\n\n\n\n\nminpoly(S::Ring, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}\n\nReturn the minimal polynomial p of the matrix M. The polynomial ring S of the resulting polynomial must be supplied and the matrix must be square.\n\nExamples\n\njulia> R = GF(13)\nFinite field F_13\n\njulia> T, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over finite field F_13, y)\n\njulia> M = R[7 6 1;\n 7 7 5;\n 8 12 5]\n[7 6 1]\n[7 7 5]\n[8 12 5]\n\njulia> A = minpoly(T, M)\ny^2 + 10*y\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#charpoly-Tuple{NfOrdElem}","page":"Elements","title":"charpoly","text":"charpoly(a::NfAbsOrdElem) -> ZZPolyRingElem\ncharpoly(a::NfAbsOrdElem, FlintZZ) -> ZZPolyRingElem\n\nThe characteristic polynomial of a.\n\n\n\n\n\ncharpoly(V::Ring, Y::MatrixElem{T}) where {T <: RingElement}\n\nReturn the characteristic polynomial p of the matrix M. The polynomial ring R of the resulting polynomial must be supplied and the matrix is assumed to be square.\n\nExamples\n\njulia> R = residue_ring(ZZ, 7)\nResidue ring of integers modulo 7\n\njulia> S = matrix_space(R, 4, 4)\nMatrix space of 4 rows and 4 columns\n over residue ring of integers modulo 7\n\njulia> T, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over residue ring, x)\n\njulia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);\n R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])\n[1 2 4 3]\n[2 5 1 0]\n[6 1 3 2]\n[1 1 3 5]\n\njulia> A = charpoly(T, M)\nx^4 + 2*x^2 + 6*x + 2\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#factor-Tuple{NfOrdElem}","page":"Elements","title":"factor","text":"factor(a::NfOrdElem) -> Fac{NfOrdElem}\n\nComputes a factorization of a into irreducible elements. The return value is a factorization fac, which satisfies a = unit(fac) * prod(p^e for (p, e) in fac).\n\nThe function requires that a is non-zero and that all prime ideals containing a are principal, which is for example satisfied if class group of the order of a is trivial.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#denominator-Tuple{NumFieldElem, Hecke.NfRelOrd}","page":"Elements","title":"denominator","text":"denominator(a::NumFieldElem, O::NfOrd) -> ZZRingElem\n\nReturns the smallest positive integer k such that k cdot a is contained in mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/elements/#discriminant-Tuple{Vector{NfAbsOrdElem}}","page":"Elements","title":"discriminant","text":"discriminant(g::Vector)\n\nCompute the product of all differences of distinct elements in the array. \n\n\n\n\n\ndiscriminant(B::Vector{NumFieldOrdElem})\n\nReturns the discriminant of the family B of algebraic numbers, i.e. det((tr(Bi*Bj))_i j)^2.\n\n\n\n\n\ndiscriminant(E::EllCrv) -> FieldElem\n\nReturn the discriminant of E.\n\n\n\n\n\ndiscriminant(C::HypellCrv{T}) -> T\n\nCompute the discriminant of C.\n\n\n\n\n\ndiscriminant(O::AlgssRelOrd)\n\nReturns the discriminant of O.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/integer/#Integer-ring","page":"Integer ring","title":"Integer ring","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"AbstractAlgebra.jl provides a module, implemented in src/julia/Integer.jl for making Julia BigInts conform to the AbstractAlgebra.jl Ring interface.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"In addition to providing a parent object ZZ for Julia BigInts, we implement any additional functionality required by AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Because BigInt cannot be directly included in the AbstractAlgebra.jl abstract type hierarchy, we achieve integration of Julia BigInts by introducing a type union, called RingElement, which is a union of RingElem and a number of Julia types, including BigInt. Everywhere that RingElem is notionally used in AbstractAlgebra.jl, we are in fact using RingElement, with additional care being taken to avoid ambiguities.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"The details of how this is done are technical, and we refer the reader to the implementation for details. For most intents and purposes, one can think of the Julia BigInt type as belonging to RingElem.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"One other technicality is that Julia defines certain functions for BigInt, such as sqrt and exp differently to what AbstractAlgebra.jl requires. To get around this, we redefine these functions internally to AbstractAlgebra.jl, without redefining them for users of AbstractAlgebra.jl. This allows the internals of AbstractAlgebra.jl to function correctly, without broadcasting pirate definitions of already defined Julia functions to the world.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"To access the internal definitions, one can use AbstractAlgebra.sqrt and AbstractAlgebra.exp, etc.","category":"page"},{"location":"AbstractAlgebra/integer/#Types-and-parent-objects","page":"Integer ring","title":"Types and parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Integers have type BigInt, as in Julia itself. We simply supplement the functionality for this type as required for computer algebra.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"The parent objects of such integers has type Integers{BigInt}.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"For convenience, we also make Int a part of the AbstractAlgebra.jl type hierarchy and its parent object (accessible as zz) has type Integers{Int}. But we caution that this type is not particularly useful as a model of the integers and may not function as expected within AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/integer/#Integer-constructors","page":"Integer ring","title":"Integer constructors","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"In order to construct integers in AbstractAlgebra.jl, one can first construct the integer ring itself. This is accomplished using the following constructor.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Integers{BigInt}()","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"This gives the unique object of type Integers{BigInt} representing the ring of integers in AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"In practice, one simply uses ZZ which is assigned to be the return value of the above constructor. There is no need to call the constructor in practice.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Here are some examples of creating the integer ring and making use of the resulting parent object to coerce various elements into the ring.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"julia> f = ZZ()\n0\n\njulia> g = ZZ(123)\n123\n\njulia> h = ZZ(BigInt(1234))\n1234\n","category":"page"},{"location":"AbstractAlgebra/integer/#Basic-ring-functionality","page":"Integer ring","title":"Basic ring functionality","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"The integer ring in AbstractAlgebra.jl implements the full Ring interface and the Euclidean Ring interface.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"We give some examples of such functionality.","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"julia> f = ZZ(12)\n12\n\njulia> h = zero(ZZ)\n0\n\njulia> k = one(ZZ)\n1\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> T = parent(f)\nIntegers\n\njulia> f == deepcopy(f)\ntrue\n\njulia> g = f + 12\n24\n\njulia> h = powermod(f, 12, ZZ(17))\n4\n\njulia> flag, q = divides(f, ZZ(3))\n(true, 4)\n","category":"page"},{"location":"AbstractAlgebra/integer/#Integer-functionality-provided-by-AbstractAlgebra.jl","page":"Integer ring","title":"Integer functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"The functionality below supplements that provided by Julia itself for its BigInt type.","category":"page"},{"location":"AbstractAlgebra/integer/#Basic-functionality","page":"Integer ring","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"julia> r = ZZ(-1)\n-1\n\njulia> is_unit(r)\ntrue\n","category":"page"},{"location":"AbstractAlgebra/integer/#Divisibility-testing","page":"Integer ring","title":"Divisibility testing","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"is_divisible_by(a::BigInt, b::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#is_divisible_by-Tuple{BigInt, BigInt}","page":"Integer ring","title":"is_divisible_by","text":"is_divisible_by(a::Integer, b::Integer)\n\nReturn true if a is divisible by b, i.e. if there exists c such that a = bc.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"** Examples **","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"julia> r = ZZ(6)\n6\n\njulia> s = ZZ(3)\n3\n\njulia> is_divisible_by(r, s)\ntrue","category":"page"},{"location":"AbstractAlgebra/integer/#Square-root","page":"Integer ring","title":"Square root","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"AbstractAlgebra.sqrt(a::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#sqrt-Tuple{BigInt}","page":"Integer ring","title":"sqrt","text":"sqrt(a::T; check::Bool=true) where T <: Integer\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"is_square(a::BigInt)\nis_square_with_sqrt(a::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#is_square-Tuple{BigInt}","page":"Integer ring","title":"is_square","text":"is_square(f::PolyRingElem{T}) where T <: RingElement\n\nReturn true if f is a perfect square.\n\n\n\n\n\nis_square(a::ResFieldElem{T}) where T <: Integer\n\nReturn true if a is a square.\n\n\n\n\n\nis_square(a::T) where T <: Integer\n\nReturn true if a is a square.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/#is_square_with_sqrt-Tuple{BigInt}","page":"Integer ring","title":"is_square_with_sqrt","text":"is_square_with_sqrt(a::T) where T <: Integer\n\nReturn (true, s) if a is a perfect square, where s^2 = a. Otherwise return (false, 0).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"root(a::BigInt)\niroot(a::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#root-Tuple{BigInt}","page":"Integer ring","title":"root","text":"root(a::T, n::Int; check::Bool=true) where T <: Integer\n\nReturn the n-th root of a. If check=true the function will test if the input was a perfect n-th power, otherwise an exception will be raised. We require n 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/#iroot-Tuple{BigInt}","page":"Integer ring","title":"iroot","text":"iroot(a::T, n::Int) where T <: Integer\n\nReturn the truncated integer part of the n-th root of a (round towards zero). We require n 0 and also a geq 0 if n is even.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"is_power(a::BigInt)\nis_power_with_root(a::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#is_power-Tuple{BigInt}","page":"Integer ring","title":"is_power","text":"is_power(a::T, n::Int) where T <: Integer\n\nReturn true if a is a perfect n-th power, i.e. if there is a b such that a = b^n. We require n 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/#is_power_with_root-Tuple{BigInt}","page":"Integer ring","title":"is_power_with_root","text":"is_power_with_root(a::T, n::Int) where T <: Integer\n\nReturn true, q if a is a perfect n-th power with a = q^n. Otherwise return false, 0. We require n 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"AbstractAlgebra.exp(a::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#exp-Tuple{BigInt}","page":"Integer ring","title":"exp","text":"exp(a::T) where T <: Integer\n\nReturn 1 if a = 0, otherwise throw an exception. This function is not generally of use to the user, but is used internally in AbstractAlgebra.jl.\n\n\n\n\n\nexp(a::Rational{T}) where T <: Integer\n\nReturn 1 if a = 0, otherwise throw an exception.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"julia> d = AbstractAlgebra.sqrt(ZZ(36))\n6\n\njulia> is_square(ZZ(9))\ntrue\n\njulia> m = AbstractAlgebra.exp(ZZ(0))\n1","category":"page"},{"location":"AbstractAlgebra/integer/#Coprime-bases","page":"Integer ring","title":"Coprime bases","text":"","category":"section"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"ppio(a::BigInt, b::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#ppio-Tuple{BigInt, BigInt}","page":"Integer ring","title":"ppio","text":"ppio(a::T, b::T)\n\nSplit a into c*d where c = gcd(a b^infty).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"Examples","category":"page"},{"location":"AbstractAlgebra/integer/","page":"Integer ring","title":"Integer ring","text":"julia> c, n = ppio(ZZ(12), ZZ(26))\n(4, 3)\n","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"CurrentModule = Oscar","category":"page"},{"location":"InvariantTheory/reductive_groups/#Invariants-of-Linearly-Reductive-Groups","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"In this section, with notation as in the introduction to this chapter, G will be a linearly algebraic group over an algebraically closed field K, and rho G to textGL(V)cong textGL_n(K) will be a rational representation of G. As in the previous sections, G will act on KVcong Kx_1 dots x_n by linear substitution:","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"(f pi) (x_1 dots x_n) = f((x_1 dots x_n) cdot rho(pi)) text for all piin G","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"note: Note\nThe definition of linear reductivity guarantees the existence of a Reynolds operator mathcal R KV to KV. \nBy Hilbert's celebrated finiteness theorem, KV^G is finitely generated as a K-algebra.\nBy a result of Hochster and Roberts, KV^G is Cohen-Macaulay. ","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"In cases where the Reynold's operator can be explicitly handled, generators of invariant rings of linearly reductive groups can be found in two steps using Derksen's algorithm, see Harm Derksen (1999) :","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"First, compute generators of Hilbert's null-cone ideal.\nThen, apply the Reynold's operator to these generators.","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"See also Harm Derksen, Gregor Kemper (2015) and Wolfram Decker, Theo de Jong (1998).","category":"page"},{"location":"InvariantTheory/reductive_groups/#Creating-Invariant-Rings","page":"Invariants of Linearly Reductive Groups","title":"Creating Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"There are no exact means to handle algebraically closed fields on the computer. For the computation of invariant rings in the above setting, on the other hand, there is no need to deal with explicit elements of G or with its group structure. The implementation of Derksen's algorithm in OSCAR can handle situations where both G and the representation rho are defined over an exact subfield k of K which is supported by OSCAR: ","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"G is specified as an affine algebraic variety by polynomials with coefficients in k;\nrho G to textGL(V) cong textGL_n(K) is specified by an ntimes n matrix whose entries are polynomials in the same variables as those specifying G, with coefficients in k.","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"All computations are then performed over k.","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"warning: Warning\nOSCAR does neither check whether the affine variety defined by the given equations carries a group structure which makes it a linearly reductive group nor does it check whether the given ntimes n matrix really defines a representation.","category":"page"},{"location":"InvariantTheory/reductive_groups/#Basic-Data-Associated-to-Invariant-Rings","page":"Invariants of Linearly Reductive Groups","title":"Basic Data Associated to Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/#The-Reynolds-Operator","page":"Invariants of Linearly Reductive Groups","title":"The Reynolds Operator","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"Omega-process","category":"page"},{"location":"InvariantTheory/reductive_groups/#Generators-of-Hilbert's-Null-Cone-Ideal","page":"Invariants of Linearly Reductive Groups","title":"Generators of Hilbert's Null-Cone Ideal","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/#Generators-of-the-Invariant-Ring","page":"Invariants of Linearly Reductive Groups","title":"Generators of the Invariant Ring","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/#Fundamental-Systems-of-Invariants","page":"Invariants of Linearly Reductive Groups","title":"Fundamental Systems of Invariants","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/#Invariant-Rings-as-Affine-Algebras","page":"Invariants of Linearly Reductive Groups","title":"Invariant Rings as Affine Algebras","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"","category":"page"},{"location":"references/","page":"References","title":"References","text":"","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/#Localizations-of-modules-over-computable-rings","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"","category":"section"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"For localizations of modules, there exists a generic implementation of the common methods such as membership tests, kernel computations, etc. based on the work of Barakat, Posur, et. al; see Sebastian Posur (2018).","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"Let R be a ring of type <:Ring, U subset R a multiplicative set of type <:AbsMultSet and S = RU^-1 the localization of R at U. Recall that R is computable if one can compute syzygies and lifts over R. The results from Sebastian Posur (2018), Theorem 3.9, assert that then also the localization S is computable, provided that there exists a solution to the localization problem (Definition 3.8, Sebastian Posur (2018) and below). ","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"The user who wishes to use the generic code for localizations therefore has to make sure the following two requirements are met: ","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"The code for finitely generated modules and ideals must be functional over R, including the computation of coordinates and kernel. \nThe user has to solve the localization problem by implementing has_nonempty_intersection(U::MultSetType, I::IdealType) for the type MultSetType of multiplicative sets and the type IdealType of ideals in R that they would like to consider.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":" has_nonempty_intersection(U::AbsMultSet, I::Ideal)","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/#has_nonempty_intersection-Tuple{AbsMultSet, Ideal}","page":"Localizations of modules over computable rings","title":"has_nonempty_intersection","text":"has_nonempty_intersection(U::AbsMultSet, I::Ideal)\n\nFor a finitely generated ideal I R and a multiplicative set U R, this checks whether the intersection U I is nonempty and returns a triple \n\n(success, f, a).\n\nIn the affirmative case, success is true, f U I is some element in the intersection and a R¹ˣᵏ is a Vector{elem_type(R)} such that f = ᵢ aᵢgᵢ where gᵢ are the elements in gens(I).\n\nWhen the intersection is empty, this returns (false, f, a) with meaningless values for f and a.\n\nNote: When implementing methods of this function, it is recommended to choose f to be the 'least complex' in an appropriate sense for R.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"Note: In order to clear denominators of row vectors, the generic code uses the method lcm(v::Vector{T}) where T = elem_type(R). If no such method already exists, this has to also be provided; in the worst case by simply returning the product of the denominators. ","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"As soon as the above requirements are met, the methods ","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":" represents_element(u::FreeModElem{T}, M::SubquoModule{T}) where {T<:AbsLocalizedRingElem}\n coordinates(u::FreeModElem{T}, M::SubquoModule{T}) where {T<:AbsLocalizedRingElem}\n kernel(f::FreeModuleHom{DomType, CodType, Nothing}) where {T, DomType<:FreeMod{T}, CodType<:SubquoModule{T}}\n kernel(f::SubQuoHom{DomType, CodType, Nothing}) where {T, DomType<:FreeMod{T}, CodType<:SubquoModule{T}}\n iszero(a::SubquoModuleElem{T}) where {T<:AbsLocalizedRingElem}","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"will be available for modules over S, i.e. for T = elem_type(S). As can easily be seen, having the first three of these methods is already equivalent to S = RU^-1 being computable; hence all higher methods can be derived from these basic ones. ","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"The generic code makes use of a simple caching mechanism for the SubquoModules as follows. For a module M = (G + N)N with submodules G N subset R^n of some free module, the localization MU^-1 over S = RU^-1 has an associated saturated module over R:","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":" M = (G + N)N quad\n G = a in R^n exists u in U u cdot a in G + Nquad\n N = b in R^n exists u in U u cdot b in N","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"While it might be difficult to compute such saturations, we have a generic algorithm to check membership for elements in M (via represents_element for MU^-1). It is assumed that such membership tests are cheaper for modules over R compared to modules over S. For instance in the case where R is a multivariate polynomial ring, once a (relative) groebner basis has been computed for M, membership test for M is merely a reduction while for the localization MU^-1 it triggers another groebner basis computation a priori. ","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"But for every element a in R^n that has already been shown to represent an element in the saturation M, we can cache the results of the computation in an intermediate pre-saturated module M subset tilde M subset M by adding the necessary generators to G and N for a representation of a. Then, checking membership for a a second time will fall back to a membership test in tilde M. For the latter, we assume some caching to already be implemented as, for instance, for the use of groebner bases in the polynomial case.","category":"page"},{"location":"CommutativeAlgebra/FrameWorks/module_localizations/","page":"Localizations of modules over computable rings","title":"Localizations of modules over computable rings","text":"A sample implementation for various localizations of multivariate polynomial rings can be found in src/Modules/mpoly-localizations.jl. A modified version for localizations of affine algebras which also overwrites some of the generic methods, is in src/Modules/mpolyquo-localizations.jl.","category":"page"},{"location":"Hecke/number_fields/fields/#Number-field-operations","page":"Number field operations","title":"Number field operations","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/number_fields/fields/#Creation-of-number-fields","page":"Number field operations","title":"Creation of number fields","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"General number fields can be created using the function number_field. To create a simple number field given by a defining polynomial or a non-simple number field given by defining polynomials, the following functions can be used.","category":"page"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"number_field(::DocuDummy)\nnumber_field(::DocuDummy2)","category":"page"},{"location":"Hecke/number_fields/fields/#number_field-Tuple{Hecke.DocuDummy}","page":"Number field operations","title":"number_field","text":"number_field(f::Poly{NumFieldElem}, s::String;\n cached::Bool = false, check::Bool = false) -> NumField, NumFieldElem\n\nGiven an irreducible polynomial f in Kx over some number field K, this function creates the simple number field L = Kx(f) and returns (L b), where b is the class of x in L. The string s is used only for printing the primitive element b.\n\ncheck: Controls whether irreducibility of f is checked.\ncached: Controls whether the result is cached.\n\nExamples\n\njulia> K, a = quadratic_field(5);\n\njulia> Kt, t = K[\"t\"];\n\njulia> L, b = number_field(t^3 - 3, \"b\");\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#number_field-Tuple{Hecke.DocuDummy2}","page":"Number field operations","title":"number_field","text":"number_field(f::Vector{PolyElem{<:NumFieldElem}}, s::String=\"_\\$\", check = true)\n -> NumField, Vector{NumFieldElem}\n\nGiven a list f_1 ldots f_n of univariate polynomials in Kx over some number field K, constructs the extension Kx_1 ldots x_n(f_1(x_1) ldots f_n(x_n)).\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> K, a = number_field([x^2 - 2, x^2 - 3], \"a\")\n(Non-simple number field of degree 4 over QQ, NfAbsNSElem[a1, a2])\n\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"tip: Tip\nMany of the constructors have arguments of type Symbol or AbstractString. If used, they define the appearance in printing, and printing only. The named parameter check can be true or false, the default being true. This parameter controls whether the polynomials defining the number field are tested for irreducibility or not. Given that this can be potentially very time consuming if the degree if large, one can disable this test. Note however, that the behaviour of Hecke is undefined if a reducible polynomial is used to define a field.The named boolean parameter cached can be used to disable caching. Two number fields defined using the same polynomial from the identical polynomial ring and the same (identical) symbol/string will be identical if cached == true and different if cached == false.","category":"page"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"For frequently used number fields like quadratic fields, cyclotomic fields or radical extensions, the following functions are provided:","category":"page"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"cyclotomic_field(n::Int)\nquadratic_field(d::ZZRingElem)\nwildanger_field(n::Int, B::ZZRingElem)\nradical_extension(n::Int, a::NumFieldElem)\nrationals_as_number_field()","category":"page"},{"location":"Hecke/number_fields/fields/#cyclotomic_field-Tuple{Int64}","page":"Number field operations","title":"cyclotomic_field","text":"cyclotomic_field(n::Int, s::VarName = \"z_$n\", t = \"_\\$\"; cached = true)\n\nReturn a tuple R x consisting of the parent object R and generator x of the n-th cyclotomic field, mathbbQ(zeta_n). The supplied string s specifies how the generator of the number field should be printed. If provided, the string t specifies how the generator of the polynomial ring from which the number field is constructed, should be printed. If it is not supplied, a default dollar sign will be used to represent the variable.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#quadratic_field-Tuple{ZZRingElem}","page":"Number field operations","title":"quadratic_field","text":"quadratic_field(d::IntegerUnion) -> AnticNumberField, nf_elem\n\nReturns the field with defining polynomial x^2 - d.\n\nExamples\n\njulia> quadratic_field(5)\n(Real quadratic field defined by x^2 - 5, sqrt(5))\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#wildanger_field-Tuple{Int64, ZZRingElem}","page":"Number field operations","title":"wildanger_field","text":"wildanger_field(n::Int, B::ZZRingElem) -> AnticNumberField, nf_elem\n\nReturns the field with defining polynomial x^n + sum_i=0^n-1 (-1)^n-iBx^i. These fields tend to have non-trivial class groups.\n\nExamples\n\njulia> wildanger_field(3, ZZ(10), \"a\")\n(Number field of degree 3 over QQ, a)\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#radical_extension-Tuple{Int64, NumFieldElem}","page":"Number field operations","title":"radical_extension","text":"radical_extension(n::Int, a::NumFieldElem, s = \"_$\";\n check = true, cached = true) -> NumField, NumFieldElem\n\nGiven an element a of a number field K and an integer n, create the simple extension of K with the defining polynomial x^n - a.\n\nExamples\n\njulia> radical_extension(5, QQ(2), \"a\")\n(Number field of degree 5 over QQ, a)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#rationals_as_number_field-Tuple{}","page":"Number field operations","title":"rationals_as_number_field","text":"rationals_as_number_field() -> AnticNumberField, nf_elem\n\nReturns the rational numbers as the number field defined by x - 1.\n\nExamples\n\njulia> rationals_as_number_field()\n(Number field of degree 1 over QQ, 1)\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Basic-properties","page":"Number field operations","title":"Basic properties","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"basis(::SimpleNumField)\nbasis(::NonSimpleNumField)\nabsolute_basis(::NumField)\ndefining_polynomial(::SimpleNumField)\ndefining_polynomials(::NonSimpleNumField)\nabsolute_primitive_element(::NumField)\ncomponent(::NonSimpleNumField, ::Int)\nbase_field(::NumField)","category":"page"},{"location":"Hecke/number_fields/fields/#basis-Tuple{SimpleNumField}","page":"Number field operations","title":"basis","text":"basis(L::SimpleNumField) -> Vector{NumFieldElem}\n\nReturn the canonical basis of a simple extension LK, that is, the elements 1adotsca^d - 1, where d is the degree of K and a the primitive element.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> K, a = number_field(x^2 - 2, \"a\");\n\njulia> basis(K)\n2-element Vector{nf_elem}:\n 1\n a\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#basis-Tuple{NonSimpleNumField}","page":"Number field operations","title":"basis","text":"basis(L::NonSimpleNumField) -> Vector{NumFieldElem}\n\nReturns the canonical basis of a non-simple extension LK. If L = K(a_1dotsca_n) where each a_i has degree d_i, then the basis will be a_1^i_1dotsm a_d^i_d with 0 leq i_j leq d_j - 1 for 1 leq j leq n.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> K, (a1, a2) = number_field([x^2 - 2, x^2 - 3], \"a\");\n\njulia> basis(K)\n4-element Vector{NfAbsNSElem}:\n 1\n a1\n a2\n a1*a2\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#absolute_basis-Tuple{NumField}","page":"Number field operations","title":"absolute_basis","text":"absolute_basis(K::NumField) -> Vector{NumFieldElem}\n\nReturns an array of elements that form a basis of K (as a vector space) over the rationals.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#defining_polynomial-Tuple{SimpleNumField}","page":"Number field operations","title":"defining_polynomial","text":"defining_polynomial(L::SimpleNumField) -> PolyElem\n\nGiven a simple number field LK, constructed as L = Kx(f), this function returns f.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#defining_polynomials-Tuple{NonSimpleNumField}","page":"Number field operations","title":"defining_polynomials","text":"defining_polynomials(L::NonSimpleNumField) -> Vector{PolyElem}\n\nGiven a non-simple number field LK, constructed as L = Kx(f_1dotscf_r), return the vector containing the f_i's.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#absolute_primitive_element-Tuple{NumField}","page":"Number field operations","title":"absolute_primitive_element","text":"absolute_primitive_element(K::NumField) -> NumFieldElem\n\nGiven a number field K, this function returns an element gamma in K such that K = mathbfQ(gamma).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#component-Tuple{NonSimpleNumField, Int64}","page":"Number field operations","title":"component","text":"component(L::NonSimpleNumField, i::Int) -> SimpleNumField, Map\n\nGiven a non-simple extension LK, this function returns the simple number field corresponding to the i-th component of L together with its embedding.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#base_field-Tuple{NumField}","page":"Number field operations","title":"base_field","text":"base_field(L::NumField) -> NumField\n\nGiven a number field LK this function returns the base field K. For absolute extensions this returns mathbfQ.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Invariants","page":"Number field operations","title":"Invariants","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"degree(::NumField)\nabsolute_degree(::NumField)\nsignature(::NumField)\nunit_group_rank(::NumField)\nclass_number(::AnticNumberField)\nrelative_class_number(::AnticNumberField)\nregulator(::AnticNumberField)\ndiscriminant(::SimpleNumField)\nabsolute_discriminant(::SimpleNumField)","category":"page"},{"location":"Hecke/number_fields/fields/#degree-Tuple{NumField}","page":"Number field operations","title":"degree","text":"degree(L::NumField) -> Int\n\nGiven a number field LK, this function returns the degree of L over K.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> K, a = number_field(x^2 - 2, \"a\");\n\njulia> degree(K)\n2\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#absolute_degree-Tuple{NumField}","page":"Number field operations","title":"absolute_degree","text":"absolute_degree(L::NumField) -> Int\n\nGiven a number field LK, this function returns the degree of L over mathbf Q.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#signature-Tuple{NumField}","page":"Number field operations","title":"signature","text":"signature(K::NumField)\n\nReturn the signature of the number field of K.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> K, a = number_field(x^2 - 2, \"a\");\n\njulia> signature(K)\n(2, 0)\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#unit_group_rank-Tuple{NumField}","page":"Number field operations","title":"unit_group_rank","text":"unit_group_rank(K::NumField) -> Int\n\nReturn the rank of the unit group of any order of K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#class_number-Tuple{AnticNumberField}","page":"Number field operations","title":"class_number","text":"class_number(K::AnticNumberField) -> ZZRingElem\n\nReturns the class number of K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#relative_class_number-Tuple{AnticNumberField}","page":"Number field operations","title":"relative_class_number","text":"relative_class_number(K::AnticNumberField) -> ZZRingElem\n\nReturns the relative class number of K. The field must be a CM-field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#regulator-Tuple{AnticNumberField}","page":"Number field operations","title":"regulator","text":"regulator(K::AnticNumberField)\n\nComputes the regulator of K, i.e. the discriminant of the unit lattice for the maximal order of K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#discriminant-Tuple{SimpleNumField}","page":"Number field operations","title":"discriminant","text":"discriminant(L::SimpleNumField) -> NumFieldElem\n\nThe discriminant of the defining polynomial of L, not the discriminant of the maximal order of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#absolute_discriminant-Tuple{SimpleNumField}","page":"Number field operations","title":"absolute_discriminant","text":"absolute_discriminant(L::SimpleNumField, QQ) -> QQFieldElem\n\nThe absolute discriminant of the defining polynomial of L, not the discriminant of the maximal order of L. This is the norm of the discriminant times the d-th power of the discriminant of the base field, where d is the degree of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Predicates","page":"Number field operations","title":"Predicates","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"is_simple(::NumField)\nis_absolute(::NumField)\nis_totally_real(::NumField)\nis_totally_complex(::NumField)\nis_cm_field(::NumField)\nis_kummer_extension(::SimpleNumField)\nis_radical_extension(::SimpleNumField)\nis_linearly_disjoint(::SimpleNumField, ::SimpleNumField)\nis_weakly_ramified(::AnticNumberField, ::NfOrdIdl)\nis_tamely_ramified(::AnticNumberField)\nis_tamely_ramified(::AnticNumberField, p::Int)\nis_abelian(::NumField)","category":"page"},{"location":"Hecke/number_fields/fields/#is_simple-Tuple{NumField}","page":"Number field operations","title":"is_simple","text":"is_simple(L::NumField) -> Bool\n\nGiven a number field LK this function returns whether L is simple, that is, whether LK is defined by a univariate polynomial.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_absolute-Tuple{NumField}","page":"Number field operations","title":"is_absolute","text":"is_absolute(L::NumField) -> Bool\n\nReturns whether L is an absolute extension, that is, whether the base field of L is mathbfQ.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_totally_real-Tuple{NumField}","page":"Number field operations","title":"is_totally_real","text":"is_totally_real(K::number_field) -> Bool\n\nReturns true if and only if K is totally real, that is, if all roots of the defining polynomial are real.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_totally_complex-Tuple{NumField}","page":"Number field operations","title":"is_totally_complex","text":"is_totally_complex(K::AnticNumberField) -> Bool\n\nReturns true if and only if K is totally complex, that is, if all roots of the defining polynomial are not real.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_cm_field-Tuple{NumField}","page":"Number field operations","title":"is_cm_field","text":"is_cm_field(K::AnticNumberField) -> Bool, NfToNfMor\n\nGiven a number field K, this function returns true and the complex conjugation if the field is CM, false and the identity otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_kummer_extension-Tuple{SimpleNumField}","page":"Number field operations","title":"is_kummer_extension","text":"is_kummer_extension(L::SimpleNumField) -> Bool\n\nTests if LK is a Kummer extension, that is, if the defining polynomial is of the form x^n - b for some b in K and if K contains the n-th roots of unity.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_radical_extension-Tuple{SimpleNumField}","page":"Number field operations","title":"is_radical_extension","text":"is_radical_extension(L::SimpleNumField) -> Bool\n\nTests if LK is pure, that is, if the defining polynomial is of the form x^n - b for some b in K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_linearly_disjoint-Tuple{SimpleNumField, SimpleNumField}","page":"Number field operations","title":"is_linearly_disjoint","text":"is_linearly_disjoint(K::SimpleNumField, L::SimpleNumField) -> Bool\n\nGiven two number fields K and L with the same base field k, this function returns whether K and L are linear disjoint over k.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_weakly_ramified-Tuple{AnticNumberField, NfOrdIdl}","page":"Number field operations","title":"is_weakly_ramified","text":"is_weakly_ramified(K::AnticNumberField, P::NfOrdIdl) -> Bool\n\nGiven a prime ideal P of a number field K, return whether P is weakly ramified, that is, whether the second ramification group is trivial.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_tamely_ramified-Tuple{AnticNumberField}","page":"Number field operations","title":"is_tamely_ramified","text":"is_tamely_ramified(K::AnticNumberField) -> Bool\n\nReturns whether the number field K is tamely ramified.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_tamely_ramified-Tuple{AnticNumberField, Int64}","page":"Number field operations","title":"is_tamely_ramified","text":"is_tamely_ramified(O::NfOrd, p::Union{Int, ZZRingElem}) -> Bool\n\nReturns whether the integer p is tamely ramified in mathcal O. It is assumed that p is prime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_abelian-Tuple{NumField}","page":"Number field operations","title":"is_abelian","text":"is_abelian(L::NumField) -> Bool\n\nCheck if the number field LK is abelian over K. The function is probabilistic and assumes GRH.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Subfields","page":"Number field operations","title":"Subfields","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"is_subfield(::SimpleNumField, ::SimpleNumField)\nsubfields(::SimpleNumField)\nprincipal_subfields(::SimpleNumField)\ncompositum(::AnticNumberField, ::AnticNumberField)\nembedding(::NumField, ::NumField)\nnormal_closure(::AnticNumberField)\nrelative_simple_extension(::NumField, ::NumField)\nis_subfield_normal(::AnticNumberField, ::AnticNumberField)","category":"page"},{"location":"Hecke/number_fields/fields/#is_subfield-Tuple{SimpleNumField, SimpleNumField}","page":"Number field operations","title":"is_subfield","text":"is_subfield(K::SimpleNumField, L::SimpleNumField) -> Bool, Map\n\nReturn true and an injection from K to L if K is a subfield of L. Otherwise the function returns false and a morphism mapping everything to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#subfields-Tuple{SimpleNumField}","page":"Number field operations","title":"subfields","text":"subfields(L::SimpleNumField) -> Vector{Tuple{NumField, Map}}\n\nGiven a simple extension LK, returns all subfields of L containing K as tuples (k iota) consisting of a simple extension k and an embedding iota k to K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#principal_subfields-Tuple{SimpleNumField}","page":"Number field operations","title":"principal_subfields","text":"principal_subfields(L::SimpleNumField) -> Vector{Tuple{NumField, Map}}\n\nReturn the principal subfields of L as pairs consisting of a subfield k and an embedding k to L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#compositum-Tuple{AnticNumberField, AnticNumberField}","page":"Number field operations","title":"compositum","text":"compositum(K::AnticNumberField, L::AnticNumberField) -> AnticNumberField, Map, Map\n\nAssuming L is normal (which is not checked), compute the compositum C of the 2 fields together with the embedding of K to C and L to C.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#embedding-Tuple{NumField, NumField}","page":"Number field operations","title":"embedding","text":"embedding(k::NumField, K::NumField) -> Map\n\nAssuming k is known to be a subfield of K, return the embedding map.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#normal_closure-Tuple{AnticNumberField}","page":"Number field operations","title":"normal_closure","text":"normal_closure(K::AnticNumberField) -> AnticNumberField, NfToNfMor\n\nThe normal closure of K together with the embedding map.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#relative_simple_extension-Tuple{NumField, NumField}","page":"Number field operations","title":"relative_simple_extension","text":"relative_simple_extension(K::NumField, k::NumField) -> NfRel\n\nGiven two fields Ksupset k, it returns K as a simple relative extension L of k and an isomorphism L to K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_subfield_normal-Tuple{AnticNumberField, AnticNumberField}","page":"Number field operations","title":"is_subfield_normal","text":" is_subfield_normal(K::AnticNumberField, L::AnticNumberField) -> Bool, NfToNfMor\n\nReturns true and an injection from K to L if K is a subfield of L. Otherwise the function returns \"false\" and a morphism mapping everything to 0.\n\nThis function assumes that K is normal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Conversion","page":"Number field operations","title":"Conversion","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"simplify(::AnticNumberField)\nabsolute_simple_field(K::NumField)\nsimple_extension(::NonSimpleNumField)\nsimplified_simple_extension(::NonSimpleNumField)","category":"page"},{"location":"Hecke/number_fields/fields/#simplify-Tuple{AnticNumberField}","page":"Number field operations","title":"simplify","text":"simplify(K::AnticNumberField; canonical::Bool = false) -> AnticNumberField, NfToNfMor\n\nTries to find an isomorphic field L given by a \"simpler\" defining polynomial. By default, \"simple\" is defined to be of smaller index, testing is done only using a LLL-basis of the maximal order.\n\nIf canonical is set to true, then a canonical defining polynomial is found, where canonical is using the definition of PARI's polredabs, which is described in http://beta.lmfdb.org/knowledge/show/nf.polredabs.\n\nBoth versions require a LLL reduced basis for the maximal order.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#absolute_simple_field-Tuple{NumField}","page":"Number field operations","title":"absolute_simple_field","text":"absolute_simple_field(K::NumField) -> NumField, Map\n\nGiven a number field K, this function returns an absolute simple number field MmathbfQ together with a mathbfQ-linear isomorphism M to K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#simple_extension-Tuple{NonSimpleNumField}","page":"Number field operations","title":"simple_extension","text":"simple_extension(L::NonSimpleNumField) -> SimpleNumField, Map\n\nGiven a non-simple extension LK, this function computes a simple extension MK and a K-linear isomorphism M to L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#simplified_simple_extension-Tuple{NonSimpleNumField}","page":"Number field operations","title":"simplified_simple_extension","text":"simplified_simple_extension(L::NonSimpleNumField) -> SimpleNumField, Map\n\nGiven a non-simple extension LK, this function returns an isomorphic simple number field with a \"small\" defining equation together with the isomorphism.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Morphisms","page":"Number field operations","title":"Morphisms","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"is_isomorphic(::SimpleNumField, ::SimpleNumField)\nis_isomorphic_with_map(::SimpleNumField, ::SimpleNumField)\nis_involution(::NfToNfMor)\nfixed_field(::NumFieldMor)\nautomorphism_list(::NumField)\nautomorphism_group(::AnticNumberField)\ncomplex_conjugation(::AnticNumberField)","category":"page"},{"location":"Hecke/number_fields/fields/#is_isomorphic-Tuple{SimpleNumField, SimpleNumField}","page":"Number field operations","title":"is_isomorphic","text":"is_isomorphic(K::SimpleNumField, L::SimpleNumField) -> Bool\n\nReturn true if K and L are isomorphic, otherwise false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_isomorphic_with_map-Tuple{SimpleNumField, SimpleNumField}","page":"Number field operations","title":"is_isomorphic_with_map","text":"is_isomorphic_with_map(K::SimpleNumField, L::SimpleNumField) -> Bool, Map\n\nReturn true and an isomorphism from K to L if K and L are isomorphic. Otherwise the function returns false and a morphism mapping everything to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_involution-Tuple{NfToNfMor}","page":"Number field operations","title":"is_involution","text":"is_involution(f::NfToNfMor) -> Bool\n\nReturns true if f is an involution, i.e. if f^2 is the identity, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#fixed_field-Tuple{Hecke.NumFieldMor}","page":"Number field operations","title":"fixed_field","text":"fixed_field(K::SimpleNumField,\n sigma::Map;\n simplify::Bool = true) -> number_field, NfToNfMor\n\nGiven a number field K and an automorphism sigma of K, this function returns the fixed field of sigma as a pair (L i) consisting of a number field L and an embedding of L into K.\n\nBy default, the function tries to find a small defining polynomial of L. This can be disabled by setting simplify = false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#automorphism_list-Tuple{NumField}","page":"Number field operations","title":"automorphism_list","text":"automorphism_list(L::NumField) -> Vector{NumFieldMor}\n\nGiven a number field LK, return a list of all K-automorphisms of L.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#automorphism_group-Tuple{AnticNumberField}","page":"Number field operations","title":"automorphism_group","text":"automorphism_group(K::NumField) -> GenGrp, GrpGenToNfMorSet\n\nGiven a number field K, this function returns a group G and a map from G to the automorphisms of K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#complex_conjugation-Tuple{AnticNumberField}","page":"Number field operations","title":"complex_conjugation","text":"complex_conjugation(K::AnticNumberField)\n\nGiven a totally complex normal number field, this function returns an automorphism which is the restriction of complex conjugation at one embedding.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Galois-theory","page":"Number field operations","title":"Galois theory","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"normal_basis(::NumField)\ndecomposition_group(::AnticNumberField, ::NfOrdIdl, ::Map)\nramification_group(::AnticNumberField, ::NfOrdIdl, ::Int, ::Map)\ninertia_subgroup(::AnticNumberField, ::NfOrdIdl, ::Map)","category":"page"},{"location":"Hecke/number_fields/fields/#normal_basis-Tuple{NumField}","page":"Number field operations","title":"normal_basis","text":"normal_basis(L::NumField) -> NumFieldElem\n\nGiven a normal number field LK, this function returns an element a of L, such that the orbit of a under the Galois group of LK is an K-basis of L.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#decomposition_group-Tuple{AnticNumberField, NfOrdIdl, Map}","page":"Number field operations","title":"decomposition_group","text":"decomposition_group(K::AnticNumberField, P::NfOrdIdl, m::Map)\n -> Grp, GrpToGrp\n\nGiven a prime ideal P of a number field K and a map m return from automorphism_group(K), return the decomposition group of P as a subgroup of the domain of m.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#ramification_group-Tuple{AnticNumberField, NfOrdIdl, Int64, Map}","page":"Number field operations","title":"ramification_group","text":"ramification_group(K::AnticNumberField, P::NfOrdIdl, m::Map) -> Grp, GrpToGrp\n\nGiven a prime ideal P of a number field K and a map m return from automorphism_group(K), return the ramification group of P as a subgroup of the domain of m.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#inertia_subgroup-Tuple{AnticNumberField, NfOrdIdl, Map}","page":"Number field operations","title":"inertia_subgroup","text":"inertia_subgroup(K::AnticNumberField, P::NfOrdIdl, m::Map) -> Grp, GrpToGrp\n\nGiven a prime ideal P of a number field K and a map m return from automorphism_group(K), return the inertia subgroup of P as a subgroup of the domain of m.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Infinite-places","page":"Number field operations","title":"Infinite places","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"infinite_places(K::NumField)\nreal_places(K::AnticNumberField)\ncomplex_places(K::AnticNumberField)\nisreal(::Plc)\nis_complex(::Plc)","category":"page"},{"location":"Hecke/number_fields/fields/#infinite_places-Tuple{NumField}","page":"Number field operations","title":"infinite_places","text":"infinite_places(K::NumField) -> Vector{InfPlc}\n\nReturn all infinite places of the number field.\n\nExamples\n\njulia> K, = quadratic_field(5);\n\njulia> infinite_places(K)\n2-element Vector{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}}:\n Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field defined by x^2 - 5)\n Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field defined by x^2 - 5)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#real_places-Tuple{AnticNumberField}","page":"Number field operations","title":"real_places","text":"real_places(K::NumField) -> Vector{InfPlc}\n\nReturn all infinite real places of the number field.\n\nExamples\n\njulia> K, = quadratic_field(5);\n\njulia> infinite_places(K)\n2-element Vector{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}}:\n Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field defined by x^2 - 5)\n Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field defined by x^2 - 5)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#complex_places-Tuple{AnticNumberField}","page":"Number field operations","title":"complex_places","text":"complex_places(K::NumField) -> Vector{InfPlc}\n\nReturn all infinite complex places of K.\n\nExamples\n\njulia> K, = quadratic_field(-5);\n\njulia> complex_places(K)\n1-element Vector{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}}:\n Infinite place corresponding to (Complex embedding corresponding to 0.00 + 2.24 * i of imaginary quadratic field defined by x^2 + 5)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#isreal-Tuple{Plc}","page":"Number field operations","title":"isreal","text":"isreal(P::Plc)\n\nReturn whether the embedding into mathbfC defined by P is real or not.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_complex-Tuple{Plc}","page":"Number field operations","title":"is_complex","text":"is_complex(P::Plc) -> Bool\n\nReturn whether the embedding into mathbfC defined by P is complex or not.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#Miscellaneous","page":"Number field operations","title":"Miscellaneous","text":"","category":"section"},{"location":"Hecke/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"norm_equation(::AnticNumberField, ::Any)\nlorenz_module(::AnticNumberField, ::Int)\nkummer_failure(::nf_elem, ::Int, ::Int)\nis_defining_polynomial_nice(::AnticNumberField)","category":"page"},{"location":"Hecke/number_fields/fields/#norm_equation-Tuple{AnticNumberField, Any}","page":"Number field operations","title":"norm_equation","text":"norm_equation(K::AnticNumerField, a) -> nf_elem\n\nFor a an integer or rational, try to find T in K s.th. N(T) = a. Raises an error if unsuccessful.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#lorenz_module-Tuple{AnticNumberField, Int64}","page":"Number field operations","title":"lorenz_module","text":"lorenz_module(k::AnticNumberField, n::Int) -> NfOrdIdl\n\nFinds an ideal A s.th. for all positive units e = 1 bmod A we have that e is an n-th power. Uses Lorenz, number theory, 9.3.1. If containing is set, it has to be an integral ideal. The resulting ideal will be a multiple of this.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#kummer_failure-Tuple{nf_elem, Int64, Int64}","page":"Number field operations","title":"kummer_failure","text":"kummer_failure(x::nf_elem, M::Int, N::Int) -> Int\n\nComputes the quotient of N and K(zeta_M sqrtN(x))colon K(zeta_M), where K is the field containing x and N divides M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/fields/#is_defining_polynomial_nice-Tuple{AnticNumberField}","page":"Number field operations","title":"is_defining_polynomial_nice","text":"is_defining_polynomial_nice(K::AnticNumberField)\n\nTests if the defining polynomial of K is integral and monic.\n\n\n\n\n\n","category":"method"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"General/faq/#Frequently-Asked-Questions","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"section"},{"location":"General/faq/#General-questions","page":"Frequently Asked Questions","title":"General questions","text":"","category":"section"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: How do I install OSCAR?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can find our installation instructions here.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: Can I find all methods that apply to a given object?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Yes, Julia provides the function methodswith for this very purpose.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For your convenience, let us give an example here. To this end, we first create a projective space in OSCAR:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> v = projective_space(NormalToricVariety,2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> typeof(v)\nNormalToricVariety","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Suppose that we now want to find all methods that accept a NormalToricVariety as one of their arguments. This can be achieved as follows:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> methodswith(typeof(v))\n[1] intersection_form(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/CohomologyClasses/special_attributes.jl:101\n[2] mori_cone(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/attributes.jl:976\n[3] nef_cone(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/attributes.jl:953\n[4] toric_ideal(ntv::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/attributes.jl:510\n[5] volume_form(v::NormalToricVariety) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/CohomologyClasses/special_attributes.jl:50","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Often it can be beneficial to also include supertypes in the search:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> methodswith(typeof(v), supertypes = true)","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As of December 2022, this results in a list of 101 functions.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Note that we can also find the constructors, i.e. functions that return an object of type NormalToricVariety. This is possible with the Julia function methods:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> methods(typeof(v))\n# 5 methods for type constructor:\n[1] NormalToricVariety(P::Polyhedron) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:183\n[2] NormalToricVariety(PF::PolyhedralFan) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:155\n[3] NormalToricVariety(rays::Vector{Vector{Int64}}, max_cones::Vector{Vector{Int64}}; non_redundant) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:131\n[4] NormalToricVariety(C::Cone) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:79\n[5] NormalToricVariety(polymakeNTV::Polymake.BigObject) in Oscar at /datadisk/Computer/Mathematics_software/PackagesForJulia/Oscar.jl/src/ToricVarieties/NormalToricVarieties/constructors.jl:8","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: Why do you have your own matrix types, and why do they not support the exact same commands as Julia matrices?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Unfortunately, Julia's matrices and linear algebra cannot be made to work in our context due to two independent problems:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In empty matrices (0 rows or columns) all that is known is the type of the matrix entries, however for the complex types used in OSCAR, this information is not sufficient to create elements, hence zero(T) or friends cannot work.\nMany functions (e.g. det) assume that all types used embed into the real or complex numbers, in Julia det(ones(Int, (1,1))) == 1.0, so the fact that this is exactly the integer 1 is lost. Furthermore, more general rings cannot be embedded into the reals at all.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: Why can zero(T) for a type T not work?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"At least two reasons:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The type depends on data that is not a bit-type.\nEven if it could, it is not desirable. Typical example: computations in ZnZ, so modular arithmetic. If n is small, then it is tempting to define a type T depending on n. We actually did this, and tried to use this. It did not work well, for various reasons. E.g.:\nA generic algorithmic pattern for problems over the integers is to solve them by solving them modulo n for many n, e.g. chosen as prime numbers, and then to combine them. If the type depends on n, then for every prime the code gets compiled, thus negating any advantages from the use of modular techniqes.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Of course, one could make the n an additional parameter to all functions needing it, but then e.g. addition of matrices would have to be implemented specifically for this case, negating the advantages of generic implementations.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In OSCAR, the role of the type is split between the actual Julia type and the parent.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: What is a parent?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Almost all element-like objects in OSCAR have a parent, i.e., they belong to some larger structure. For example algebraic numbers belong to a number field, modular integers belong to a ring ZnZ, permutations are elements of permutation groups and so on. The data common to all such elements is out-sourced to the parent. For a number field for example, the parent contains the polynomial used to define the field (plus other information).","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Given that a type alone is not large enough to contain the data, the parent is used. Roughly, outside a function signature, a parent replaces the role of the type. For example, for a ring element elm in OSCAR zero(parent(elm)) works, even if zero(typeof(elm)) may not.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: How can I install or access custom GAP packages (e.g. unpublished ones)?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"TODO","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: Why does my program not terminate?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Many of the algorithms implemented in OSCAR have a very high complexity. Even if not calling one of these algorithms directly, you may be using it in the background. Please read our page on [Complex Algorithms in OSCAR].","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/#Windows-specific","page":"Frequently Asked Questions","title":"Windows specific","text":"","category":"section"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: How can I install OSCAR on Windows?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Please follow the install instructions on our website.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: Why does OSCAR require WSL on Windows?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Several of the OSCAR corner stones originate from Unix-like operating systems and have no or only limited native support for Windows.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: How can I access Linux files from the Explorer?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Type \\\\wsl$ into the Explorer address bar, then press the Enter key.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/#Linux-specific","page":"Frequently Asked Questions","title":"Linux specific","text":"","category":"section"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: Why can't I install OSCAR using the Julia version installed by my package manager?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Some Linux distributions unfortunately ship crippled versions of Julia by default, which prevent OSCAR from working. For example the Debian and Ubuntu Julia packages are missing some files required by OSCAR. In this case, this can be resolved by also installing the libjulia-dev package.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For this reason, we recommend always using the official Julia binaries available form the Julia website.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: What to do if I get an error similar to libstdc++.so.6: version `GLIBCXX_3.4.26'?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Sometimes installing or updating OSCAR gives the error libstdc++.so.6: version `GLIBCXX_3.4.26' or a similar one.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This typically happens when manually installing Julia using the official Julia binaries from their website. These bundle their own copy of the C++ standard library, which can lead to trouble if its version differs from the system's C++ library.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As a workaround, you can rename the copy of the C++ library bundled with Julia, so that the system copy is used. This can be achieved by executing the following Julia code:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":" path = Libdl.dlpath(\"libstdc++\")\n mv(path,\"$path.bak\")","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If for some reason you need to restore the C++ library bundled with Julia, you can simply rename it back.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: Why does OSCAR fail to precompile when using it with GNU parallel?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You get errors like the following when trying to run some script using OSCAR with GNU parallel:","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":" ERROR: LoadError: InitError: ArgumentError: '.../deps/_jll' exists. `force=true` is required to remove '...' before copying.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"There was a bug in julia versions before 1.8 that ignored the parent argument for the tempname function when the TMPDIR environment variable is set and GNU parallel by default sets TMPDIR to /tmp.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Either upgrade to Julia 1.8 or later, or add delete!(ENV, \"TMPDIR\"); to the beginning of your julia code (before importing / using Oscar).","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/#AbstractCollection","page":"AbstractCollection","title":"AbstractCollection","text":"","category":"section"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"Allowing the user to pass input using several formats usually is handled within julia by defining specialized methods for each function and argument type(s). This can prove to be inefficient when the amount possible combinations of these increases. AbstractCollection is a Dict meant to enable the user to profit from a fixed interpretation describing different collections of mathematical objects, while also simplifying the life of the developer, also resulting in less code duplication.","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/#Idea","page":"AbstractCollection","title":"Idea","text":"","category":"section"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"Commonly the same kind of information, e.g. an amount of PointVectors, is accepted as argument for many different functions. The user can chose from different types (coming with an interpretation of their content) to use when calling one of these functions to describe the data. This data is then converted to a type and format Polymake.jl (and thus indirectly the polymake kernel) supports.","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/#Example","page":"AbstractCollection","title":"Example","text":"","category":"section"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"Usually in polymake, a collection of points is displayed as a matrix of row-vectors. Such a matrix is always created from the input information. When writing a new function accepting an object x of type AbstractCollection[PointVector] (note that, with AbstractCollection being a Dict, its entries are accessed using square brackets; the keys are the Oscar types of the elements of the collection), the necessary conversion can (and should) be called at the beginning. These conversion functions already exist and support all of the types stated in Type compatibility. In this case the function is homogenized_matrix(x, 1).","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"RayVectors and their collections work about the same; the main difference for the programmer is that homogenized_matrix(x, 0) is called.","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"When looking at the beginning of the convex_hull method, the corresponding conversions of the three arguments V, R and L can be seen:","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"function convex_hull(::Type{T}, V::AbstractCollection[PointVector], R::Union{AbstractCollection[RayVector], Nothing} = nothing, L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) where T<:scalar_types\n # Rays and Points are homogenized and combined and\n # Lineality is homogenized\n points = stack(homogenized_matrix(V, 1), homogenized_matrix(R, 0))\n lineality = isnothing(L) || isempty(L) ? zero_matrix(QQ, 0, size(points,2)) : homogenized_matrix(L, 0)\n\n ...\nend","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/#Conversion-functions","page":"AbstractCollection","title":"Conversion functions","text":"","category":"section"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"So effectively supporting AbstractCollections only requires to know when to apply which conversion function. The following table explains this for AbstractCollection[T]:","category":"page"},{"location":"DeveloperDocumentation/AbstractCollection/","page":"AbstractCollection","title":"AbstractCollection","text":"T Target format Conversion function\nPointVector matrix of row-vectors homogenized_matrix(*, 1)\nRayVector matrix of row-vectors (linear setting) unhomogenized_matrix(*)\nRayVector matrix of row-vectors (affine setting) homogenized_matrix(*, 0)\nLinearHalfspace/LinearHyperplane inequality/equation matrix (linear setting) linear_matrix_for_polymake(*)\nAffineHalfspace/AffineHyperplane inequality/equation matrix (affine setting) affine_matrix_for_polymake(*)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/","page":"Subvarieties","title":"Subvarieties","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#Subvarieties","page":"Subvarieties","title":"Subvarieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#Introduction","page":"Subvarieties","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/","page":"Subvarieties","title":"Subvarieties","text":"We focus on simplicial toric varieties. Then, any closed subvariety is given as the vanishing set of a homogeneous ideal in the Cox ring of the toric variety in question (cf. proposition 5.2.4 in David A. Cox, John B. Little, Henry K. Schenck (2011)). As of now, we provide elementary support for closed subvarieties of simplicial toric varieties.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#Constructors","page":"Subvarieties","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#General-constructors","page":"Subvarieties","title":"General constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/","page":"Subvarieties","title":"Subvarieties","text":"closed_subvariety_of_toric_variety(toric_variety::AbstractNormalToricVariety, defining_polynomials::Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}})\nclosed_subvariety_of_toric_variety(toric_variety::AbstractNormalToricVariety, defining_ideal::MPolyIdeal)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#closed_subvariety_of_toric_variety-Tuple{Oscar.AbstractNormalToricVariety, Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}","page":"Subvarieties","title":"closed_subvariety_of_toric_variety","text":"closed_subvariety_of_toric_variety(toric_variety::AbstractNormalToricVariety, defining_polynomials::Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}})\n\nConstruct the closed subvariety of a simplicial normal toric variety. The defining data for the closed subvariety is a list of homogeneous polynomials, all of which must be elements of the Cox ring of the toric variety in question. The common vanishing locus of these polynomials defines the closed subvariety in question. By proposition 5.2.4 in David A. Cox, John B. Little, Henry K. Schenck (2011) every closed subvariety of a simplicial toric variety arises in this way.\n\nExamples\n\njulia> f2 = hirzebruch_surface(NormalToricVariety, 2);\n\njulia> (t1, x1, t2, x2) = gens(cox_ring(f2));\n\njulia> closed_subvariety_of_toric_variety(f2, [t1])\nClosed subvariety of a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#closed_subvariety_of_toric_variety-Tuple{Oscar.AbstractNormalToricVariety, MPolyIdeal}","page":"Subvarieties","title":"closed_subvariety_of_toric_variety","text":"closed_subvariety_of_toric_variety(toric_variety::AbstractNormalToricVariety, defining_ideal::MPolyIdeal)\n\nConstruct the closed subvariety of a simplicial normal toric variety. The defining data for the closed subvariety is an ideal of the Cox ring of the toric variety in question. By proposition 5.2.4 in David A. Cox, John B. Little, Henry K. Schenck (2011) every closed subvariety of a simplicial toric variety arises in this way.\n\nExamples\n\njulia> f2 = hirzebruch_surface(NormalToricVariety, 2);\n\njulia> (t1, x1, t2, x2) = gens(cox_ring(f2));\n\njulia> closed_subvariety_of_toric_variety(f2, ideal([t1]))\nClosed subvariety of a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#Properties","page":"Subvarieties","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/","page":"Subvarieties","title":"Subvarieties","text":"is_empty(c::ClosedSubvarietyOfToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#is_empty-Tuple{ClosedSubvarietyOfToricVariety}","page":"Subvarieties","title":"is_empty","text":"is_empty(c::ClosedSubvarietyOfToricVariety)\n\nChecks if a closed subvariety of a toric variety is empty. This check uses proposition 5.2.6 in David A. Cox, John B. Little, Henry K. Schenck (2011).\n\nExamples\n\njulia> f2 = hirzebruch_surface(NormalToricVariety, 2);\n\njulia> (t1, x1, t2, x2) = gens(cox_ring(f2));\n\njulia> c = closed_subvariety_of_toric_variety(f2, [t1])\nClosed subvariety of a normal toric variety\n\njulia> is_empty(c)\nfalse\n\njulia> c2 = closed_subvariety_of_toric_variety(f2, [x1,x2])\nClosed subvariety of a normal toric variety\n\njulia> is_empty(c2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#Attributes","page":"Subvarieties","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/","page":"Subvarieties","title":"Subvarieties","text":"toric_variety(c::ClosedSubvarietyOfToricVariety)\ndefining_ideal(c::ClosedSubvarietyOfToricVariety)\nradical(c::ClosedSubvarietyOfToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#toric_variety-Tuple{ClosedSubvarietyOfToricVariety}","page":"Subvarieties","title":"toric_variety","text":"toric_variety(c::ClosedSubvarietyOfToricVariety)\n\nWhen constructing a closed subvariety, a toric variety must be provided in which the closed subvariety is contained. This method returns this initially provided toric supervariety.\n\nNote however that perse, a closed subvariety can be contained in different non-isomorphic toric varieties.\n\nExamples\n\njulia> f2 = hirzebruch_surface(NormalToricVariety, 2);\n\njulia> (t1, x1, t2, x2) = gens(cox_ring(f2));\n\njulia> c = closed_subvariety_of_toric_variety(f2, [t1])\nClosed subvariety of a normal toric variety\n\njulia> toric_variety(c) == f2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#defining_ideal-Tuple{ClosedSubvarietyOfToricVariety}","page":"Subvarieties","title":"defining_ideal","text":"defining_ideal(c::ClosedSubvarietyOfToricVariety)\n\nWhen constructing a closed subvariety, an ideal in the Cox ring of a normal toric variety must be provided. This method returns this initially provided ideal.\n\nExamples\n\njulia> f2 = hirzebruch_surface(NormalToricVariety, 2);\n\njulia> (t1, x1, t2, x2) = gens(cox_ring(f2));\n\njulia> c = closed_subvariety_of_toric_variety(f2, [t1])\nClosed subvariety of a normal toric variety\n\njulia> defining_ideal(c) == ideal([t1])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#radical-Tuple{ClosedSubvarietyOfToricVariety}","page":"Subvarieties","title":"radical","text":"radical(c::ClosedSubvarietyOfToricVariety)\n\nWhen constructing a closed subvariety, an ideal in the Cox ring of a normal toric variety must be provided. This method returns the radical of this initially provided ideal.\n\nExamples\n\njulia> f2 = hirzebruch_surface(NormalToricVariety, 2);\n\njulia> (t1, x1, t2, x2) = gens(cox_ring(f2));\n\njulia> c = closed_subvariety_of_toric_variety(f2, [t1])\nClosed subvariety of a normal toric variety\n\njulia> radical(c) == ideal([t1])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/gap_integration/#GAP-Integration","page":"GAP Integration","title":"GAP Integration","text":"","category":"section"},{"location":"DeveloperDocumentation/gap_integration/","page":"GAP Integration","title":"GAP Integration","text":"This section explains how Oscar interacts with GAP.","category":"page"},{"location":"DeveloperDocumentation/gap_integration/#The-Julia-package-[GAP.jl](https://github.com/oscar-system/GAP.jl)","page":"GAP Integration","title":"The Julia package GAP.jl","text":"","category":"section"},{"location":"DeveloperDocumentation/gap_integration/","page":"GAP Integration","title":"GAP Integration","text":"This package provides a bidirectional interface between GAP and Julia. Its documentation describes how to call GAP functions in Julia code and vice versa, and how low level Julia objects can be converted to GAP objects and vice versa.","category":"page"},{"location":"DeveloperDocumentation/gap_integration/","page":"GAP Integration","title":"GAP Integration","text":"When one works interactively in an Oscar session, calling GAP.prompt() opens a GAP session which has access to the variables in the Julia session, in particular to all Oscar functions and objects; one can return to the Julia prompt by entering quit; in the GAP session.","category":"page"},{"location":"DeveloperDocumentation/gap_integration/#Interface-functionalities-beyond-GAP.jl","page":"GAP Integration","title":"Interface functionalities beyond GAP.jl","text":"","category":"section"},{"location":"DeveloperDocumentation/gap_integration/","page":"GAP Integration","title":"GAP Integration","text":"For code involving Julia types that are defined in Oscar, GAP.jl cannot provide utility functions such as conversions to and from GAP.","category":"page"},{"location":"DeveloperDocumentation/gap_integration/","page":"GAP Integration","title":"GAP Integration","text":"The GAP package OscarInterface (at gap/OscarInterface) is intended to contain the GAP code in question, for example the declarations of new filters and the installation of new methods.\nNote that such code must be loaded at runtime into the GAP session that is started by Julia, and the OscarInterface package gets loaded in Oscar's __init__ function.\nThe files in the directory src/GAP are intended to contain the Julia code in question, for example conversions from GAP to ZZRingElem, QQFieldElem, FinFieldElem, etc., and the construction of isomorphisms between algebraic structures such as rings and fields in GAP and Oscar, via Oscar.iso_oscar_gap and Oscar.iso_gap_oscar.\nIn Oscar code, global GAP variables can be accessed as members of GAP.Globals, but for the case of GAP functions, it is more efficient to use Oscar.GAPWrap instead.\nFor example, if one wants to call GAP's IsFinite then it is recommended to replace the call GAP.Globals.IsFinite(x)::Bool, for some GAP object x (a group or a ring or a list, etc.), by Oscar.GAPWrap.IsFinite(x). This works only if the method in question gets defined in src/GAP/wrappers.jl, thus methods with the required signatures should be added to this file when they turn out to be needed.\n(The reason why we collect the GAP.@wrap lines in an Oscar file and not inside GAP.jl is that we can extend the list without waiting for releases of GAP.jl.)\nIn GAP code, global Julia variables can be accessed as members of Julia, relative to its Main module. For example, one can call Julia.sqrt and Julia.typeof (or Julia.Base.sqrt and Julia.Core.typeof) in GAP code.\nIn order to access variables from the Oscar module, it is not safe to use Julia.Oscar because the module Oscar is not always defined in Main. Instead, there is the global GAP variable Oscar.","category":"page"},{"location":"DeveloperDocumentation/gap_integration/","page":"GAP Integration","title":"GAP Integration","text":"Oscar.iso_oscar_gap\nOscar.iso_gap_oscar","category":"page"},{"location":"DeveloperDocumentation/gap_integration/#iso_oscar_gap","page":"GAP Integration","title":"iso_oscar_gap","text":"Oscar.iso_oscar_gap(R) -> Map{T, GAP.GapObj}\n\nReturn an isomorphism f with domain R and codomain a GAP object S.\n\nElements x of R are mapped to S via f(x), and elements y of S are mapped to R via preimage(f, y).\n\nMatrices m over R are mapped to matrices over S via map_entries(f, m), and matrices n over S are mapped to matrices over R via Oscar.preimage_matrix(f, n).\n\nAdmissible values of R and the corresponding S are currently as follows.\n\nR S (in GAP.Globals)\nZZ Integers\nQQ Rationals\nresidue_ring(ZZ, n) mod(Integers, n)\nFiniteField(p, d)[1] GF(p, d)\ncyclotomic_field(n)[1] CF(n)\nnumber_field(f::QQPolyRingElem)[1] AlgebraicExtension(Rationals, g)\nabelian_closure(QQ)[1] Cyclotomics\npolynomial_ring(F)[1] PolynomialRing(G)\npolynomial_ring(F, n)[1] PolynomialRing(G, n)\n\n(Here g is the polynomial over GAP.Globals.Rationals that corresponds to f, and G is equal to Oscar.iso_oscar_gap(F).)\n\nExamples\n\njulia> f = Oscar.iso_oscar_gap(ZZ);\n\njulia> x = ZZ(2)^100; y = f(x)\nGAP: 1267650600228229401496703205376\n\njulia> preimage(f, y) == x\ntrue\n\njulia> m = matrix(ZZ, 2, 3, [1, 2, 3, 4, 5, 6]);\n\njulia> n = map_entries(f, m)\nGAP: [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]\n\njulia> Oscar.preimage_matrix(f, n) == m\ntrue\n\njulia> R, x = polynomial_ring(QQ);\n\njulia> f = Oscar.iso_oscar_gap(R);\n\njulia> pol = x^2 + x - 1;\n\njulia> y = f(pol)\nGAP: x_1^2+x_1-1\n\njulia> preimage(f, y) == pol\ntrue\n\nwarning: Warning\nThe functions Oscar.iso_oscar_gap and Oscar.iso_gap_oscar are not injective. Due to caching, it may happen that S stores an attribute value of Oscar.iso_gap_oscar(S), but that the codomain of this map is not identical with or even not equal to the given R.\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/gap_integration/#iso_gap_oscar","page":"GAP Integration","title":"iso_gap_oscar","text":"Oscar.iso_gap_oscar(R) -> Map{GAP.GapObj, T}\n\nReturn an isomorphism f with domain the GAP object R and codomain an Oscar object S.\n\nElements x of R are mapped to S via f(x), and elements y of S are mapped to R via preimage(f, y).\n\nMatrices m over R are mapped to matrices over S via map_entries(f, m), and matrices n over S are mapped to matrices over R via Oscar.preimage_matrix(f, n).\n\nAdmissible values of R and the corresponding S are currently as follows.\n\nS (in GAP.Globals) R\nIntegers ZZ\nRationals QQ\nmod(Integers, n) residue_ring(ZZ, n)\nGF(p, d) FiniteField(p, d)[1]\nCF(n) cyclotomic_field(n)[1]\nAlgebraicExtension(Rationals, f) number_field(g)[1]\nCyclotomics abelian_closure(QQ)[1]\nPolynomialRing(F) polynomial_ring(G)[1]\nPolynomialRing(F, n) polynomial_ring(G, n)[1]\n\n(Here g is the polynomial over QQ that corresponds to the polynomial f, and G is equal to Oscar.iso_gap_oscar(F).)\n\nExamples\n\njulia> f = Oscar.iso_gap_oscar(GAP.Globals.Integers);\n\njulia> x = ZZ(2)^100; y = preimage(f, x)\nGAP: 1267650600228229401496703205376\n\njulia> f(y) == x\ntrue\n\njulia> m = matrix(ZZ, 2, 3, [1, 2, 3, 4, 5, 6]);\n\njulia> n = Oscar.preimage_matrix(f, m)\nGAP: [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]\n\njulia> map_entries(f, n) == m\ntrue\n\njulia> R = GAP.Globals.PolynomialRing(GAP.Globals.Rationals);\n\njulia> f = Oscar.iso_gap_oscar(R);\n\njulia> x = gen(codomain(f));\n\njulia> pol = x^2 + x + 1;\n\njulia> y = preimage(f, pol)\nGAP: x_1^2+x_1+1\n\njulia> f(y) == pol\ntrue\n\nwarning: Warning\nThe functions Oscar.iso_gap_oscar and Oscar.iso_oscar_gap are not injective. Due to caching, it may happen that S stores an attribute value of Oscar.iso_oscar_gap(S), but that the codomain of this map is not identical with or even not equal to the given R.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/function_fields/intro/#Function-Fields","page":"Function Fields","title":"Function Fields","text":"","category":"section"},{"location":"Hecke/function_fields/intro/","page":"Function Fields","title":"Function Fields","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/function_fields/intro/#FunctionFieldsLink","page":"Function Fields","title":"Introduction","text":"","category":"section"},{"location":"Hecke/function_fields/intro/","page":"Function Fields","title":"Function Fields","text":"By definition, a (univariate) function field can be written as a finite extension of a rational function field k(x) for a field k (commonly k = mathbbQ or k = mathbbF_p). In Hecke, a function field L is currently defined as being a (univariate) rational function field k(x) or a finite extension thereof. In other words, the extension is defined in the the following way:","category":"page"},{"location":"Hecke/function_fields/intro/","page":"Function Fields","title":"Function Fields","text":"We have L = k(x)(f), where f in k(x)y is an irreducible polynomial (simple extension)","category":"page"},{"location":"Hecke/function_fields/intro/","page":"Function Fields","title":"Function Fields","text":"We refer to k(x) as the base field of the function field L. We call L an absolute function field if the base field is equal to the rational function field k(x).","category":"page"},{"location":"Hecke/quad_forms/basics/#Spaces","page":"Spaces","title":"Spaces","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/quad_forms/basics/#Creation-of-spaces","page":"Spaces","title":"Creation of spaces","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"quadratic_space(::NumField, ::Int)\nhermitian_space(::NumField, ::Int)\nquadratic_space(::NumField, ::MatElem)\nhermitian_space(::NumField, ::MatElem)","category":"page"},{"location":"Hecke/quad_forms/basics/#quadratic_space-Tuple{NumField, Int64}","page":"Spaces","title":"quadratic_space","text":"quadratic_space(K::NumField, n::Int; cached::Bool = true) -> QuadSpace\n\nCreate the quadratic space over K with dimension n and Gram matrix equals to the identity matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#hermitian_space-Tuple{NumField, Int64}","page":"Spaces","title":"hermitian_space","text":"hermitian_space(E::NumField, n::Int; cached::Bool = true) -> HermSpace\n\nCreate the hermitian space over E with dimension n and Gram matrix equals to the identity matrix. The number field E must be a quadratic extension, that is, degree(E) == 2 must hold.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#quadratic_space-Tuple{NumField, MatElem}","page":"Spaces","title":"quadratic_space","text":"quadratic_space(K::NumField, G::MatElem; cached::Bool = true) -> QuadSpace\n\nCreate the quadratic space over K with Gram matrix G. The matrix G must be square and symmetric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#hermitian_space-Tuple{NumField, MatElem}","page":"Spaces","title":"hermitian_space","text":"hermitian_space(E::NumField, gram::MatElem; cached::Bool = true) -> HermSpace\n\nCreate the hermitian space over E with Gram matrix equals to gram. The matrix gram must be square and hermitian with respect to the non-trivial automorphism of E. The number field E must be a quadratic extension, that is, degree(E) == 2 must hold.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Examples","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Here are easy examples to see how these constructors work. We will keep the two following spaces for the rest of this section:","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nE, b = number_field(t^2-a*t+1, \"b\");\nQ = quadratic_space(K, K[0 1; 1 0])\nH = hermitian_space(E, 3)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Attributes","page":"Spaces","title":"Attributes","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Let (V Phi) be a space over EK. We define its dimension to be its dimension as a vector space over its base ring E and its rank to be the rank of its Gram matrix. If these two invariants agree, the space is said to be regular.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"While dealing with lattices, one always works with regular ambient spaces.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"The determinant textdet(V Phi) of (V Phi) is defined to be the class of the determinant of its Gram matrix in K^timesN(E^times) (which is similar to K^times(K^times)^2 in the quadratic case). The discriminant textdisc(V Phi) of (V Phi) is defined to be (-1)^(m(m-1)2)textdet(V Phi), where m is the rank of (V Phi).","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"rank(::AbstractSpace)\ndim(::AbstractSpace)\ngram_matrix(::AbstractSpace)\ninvolution(::AbstractSpace)\nbase_ring(::AbstractSpace)\nfixed_field(::AbstractSpace)\ndet(::AbstractSpace)\ndiscriminant(::AbstractSpace)","category":"page"},{"location":"Hecke/quad_forms/basics/#rank-Tuple{AbstractSpace}","page":"Spaces","title":"rank","text":"rank(V::AbstractSpace) -> Int\n\nReturn the rank of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#dim-Tuple{AbstractSpace}","page":"Spaces","title":"dim","text":"dim(V::AbstractSpace) -> Int\n\nReturn the dimension of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#gram_matrix-Tuple{AbstractSpace}","page":"Spaces","title":"gram_matrix","text":"gram_matrix(V::AbstractSpace) -> MatElem\n\nReturn the Gram matrix of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#involution-Tuple{AbstractSpace}","page":"Spaces","title":"involution","text":"involution(V::AbstractSpace) -> NumFieldMor\n\nReturn the involution of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#base_ring-Tuple{AbstractSpace}","page":"Spaces","title":"base_ring","text":"base_ring(V::AbstractSpace) -> NumField\n\nReturn the algebra over which the space V is defined.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#fixed_field-Tuple{AbstractSpace}","page":"Spaces","title":"fixed_field","text":"fixed_field(V::AbstractSpace) -> NumField\n\nReturn the fixed field of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#det-Tuple{AbstractSpace}","page":"Spaces","title":"det","text":"det(V::AbstractSpace) -> FieldElem\n\nReturn the determinant of the space V as an element of its fixed field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#discriminant-Tuple{AbstractSpace}","page":"Spaces","title":"discriminant","text":"discriminant(V::AbstractSpace) -> FieldElem\n\nReturn the discriminant of the space V as an element of its fixed field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Examples-2","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"So for instance, one could get the following information about the hermitian space H:","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nE, b = number_field(t^2-a*t+1, \"b\");\nH = hermitian_space(E, 3);\nrank(H), dim(H)\ngram_matrix(H)\ninvolution(H)\nbase_ring(H)\nfixed_field(H)\ndet(H), discriminant(H)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Predicates","page":"Spaces","title":"Predicates","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Let (V Phi) be a hermitian space over EK (resp. quadratic space K). We say that (V Phi) is definite if EK is CM (resp. K is totally real) and if there exists an orthogonal basis of V for which the diagonal elements of the associated Gram matrix of (V Phi) are either all totally positive or all totally negative. In the former case, V is said to be positive definite, while in the latter case it is negative definite. In all the other cases, we say that V is indefinite.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_regular(::AbstractSpace)\nis_quadratic(::AbstractSpace)\nishermitian(::AbstractSpace)\nis_positive_definite(::AbstractSpace)\nis_negative_definite(::AbstractSpace)\nis_definite(::AbstractSpace)","category":"page"},{"location":"Hecke/quad_forms/basics/#is_regular-Tuple{AbstractSpace}","page":"Spaces","title":"is_regular","text":"is_regular(V::AbstractSpace) -> Bool\n\nReturn whether the space V is regular, that is, if the Gram matrix has full rank.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#is_quadratic-Tuple{AbstractSpace}","page":"Spaces","title":"is_quadratic","text":"is_quadratic(V::AbstractSpace) -> Bool\n\nReturn whether the space V is quadratic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#ishermitian-Tuple{AbstractSpace}","page":"Spaces","title":"ishermitian","text":"is_hermitian(V::AbstractSpace) -> Bool\n\nReturn whether the space V is hermitian.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#is_positive_definite-Tuple{AbstractSpace}","page":"Spaces","title":"is_positive_definite","text":"is_positive_definite(V::AbstractSpace) -> Bool\n\nReturn whether the space V is positive definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#is_negative_definite-Tuple{AbstractSpace}","page":"Spaces","title":"is_negative_definite","text":"is_negative_definite(V::AbstractSpace) -> Bool\n\nReturn whether the space V is negative definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#is_definite-Tuple{AbstractSpace}","page":"Spaces","title":"is_definite","text":"is_definite(V::AbstractSpace) -> Bool\n\nReturn whether the space V is definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Note that the is_hermitian function tests whether the space is non-quadratic.","category":"page"},{"location":"Hecke/quad_forms/basics/#Examples-3","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nE, b = number_field(t^2-a*t+1, \"b\");\nQ = quadratic_space(K, K[0 1; 1 0]);\nH = hermitian_space(E, 3);\nis_regular(Q), is_regular(H)\nis_quadratic(Q), ishermitian(H)\nis_definite(Q), is_positive_definite(H)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Inner-products-and-diagonalization","page":"Spaces","title":"Inner products and diagonalization","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"gram_matrix(::AbstractSpace{T}, ::MatElem{S}) where {S, T}\ngram_matrix(::AbstractSpace{T}, ::Vector{Vector{U}}) where {T, U}\ninner_product(::AbstractSpace, ::Vector, ::Vector)\northogonal_basis(::AbstractSpace)\ndiagonal(::AbstractSpace)\nrestrict_scalars(::AbstractSpace, ::QQField, ::FieldElem)","category":"page"},{"location":"Hecke/quad_forms/basics/#gram_matrix-Union{Tuple{T}, Tuple{S}, Tuple{AbstractSpace{T}, MatElem{S}}} where {S, T}","page":"Spaces","title":"gram_matrix","text":"gram_matrix(V::AbstractSpace, M::MatElem) -> MatElem\n\nReturn the Gram matrix of the rows of M with respect to the Gram matrix of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#gram_matrix-Union{Tuple{U}, Tuple{T}, Tuple{AbstractSpace{T}, Array{Vector{U}, 1}}} where {T, U}","page":"Spaces","title":"gram_matrix","text":"gram_matrix(V::AbstractSpace, S::Vector{Vector}) -> MatElem\n\nReturn the Gram matrix of the sequence S with respect to the Gram matrix of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#inner_product-Tuple{AbstractSpace, Vector, Vector}","page":"Spaces","title":"inner_product","text":"inner_product(V::AbstractSpace, v::Vector, w::Vector) -> FieldElem\n\nReturn the inner product of v and w with respect to the bilinear form of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#orthogonal_basis-Tuple{AbstractSpace}","page":"Spaces","title":"orthogonal_basis","text":"orthogonal_basis(V::AbstractSpace) -> MatElem\n\nReturn a matrix M, such that the rows of M form an orthogonal basis of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#diagonal-Tuple{AbstractSpace}","page":"Spaces","title":"diagonal","text":"diagonal(V::AbstractSpace) -> Vector{FieldElem}\n\nReturn a vector of elements a_1dotsca_n such that the space V is isometric to the diagonal space langle a_1dotsca_n rangle.\n\nThe elements are contained in the fixed field of V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#restrict_scalars-Tuple{AbstractSpace, QQField, FieldElem}","page":"Spaces","title":"restrict_scalars","text":"restrict_scalars(V::AbstractSpace, K::QQField,\n alpha::FieldElem = one(base_ring(V)))\n -> QuadSpace, AbstractSpaceRes\n\nGiven a space (V Phi) and a subfield K of the base algebra E of V, return the quadratic space W obtained by restricting the scalars of (V alphaPhi) to K, together with the map f for extending the scalars back. The form on the restriction is given by Tr circ Phi where Tr E to K is the trace form. The rescaling factor alpha is set to 1 by default.\n\nNote that for now one can only restrict scalars to mathbb Q.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Examples-4","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nE, b = number_field(t^2-a*t+1, \"b\");\nQ = quadratic_space(K, K[0 1; 1 0]);\nH = hermitian_space(E, 3);\ngram_matrix(Q, K[1 1; 2 0])\ngram_matrix(H, E[1 0 0; 0 1 0; 0 0 1])\ninner_product(Q, K[1 1], K[0 2])\northogonal_basis(H)\ndiagonal(Q), diagonal(H)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Equivalence","page":"Spaces","title":"Equivalence","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Let (V Phi) and (V Phi) be spaces over the same extension EK. A homomorphism of spaces from V to V is a E-linear mapping f colon V to V such that for all xy in V, one has","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":" Phi(f(x) f(y)) = Phi(xy)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"An automorphism of spaces is called an isometry and a monomorphism is called an embedding.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"hasse_invariant(::QuadSpace, p)\nwitt_invariant(::QuadSpace, p)\nis_isometric(::AbstractSpace, ::AbstractSpace)\nis_isometric(::AbstractSpace, ::AbstractSpace, p)\ninvariants(::QuadSpace)","category":"page"},{"location":"Hecke/quad_forms/basics/#hasse_invariant-Tuple{Hecke.QuadSpace, Any}","page":"Spaces","title":"hasse_invariant","text":"hasse_invariant(V::QuadSpace, p::Union{InfPlc, NfOrdIdl}) -> Int\n\nReturns the Hasse invariant of the quadratic space V at p. This is equal to the product of local Hilbert symbols (a_i a_j)_p, i j, where V is isometric to langle a_1 dotsc a_nrangle. If V is degenerate return the hasse invariant of V/radical(V).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#witt_invariant-Tuple{Hecke.QuadSpace, Any}","page":"Spaces","title":"witt_invariant","text":"witt_invariant(V::QuadSpace, p::Union{InfPlc, NfOrdIdl}) -> Int\n\nReturns the Witt invariant of the quadratic space V at p.\n\nSee [Definition 3.2.1, Kir16].\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#is_isometric-Tuple{AbstractSpace, AbstractSpace}","page":"Spaces","title":"is_isometric","text":"is_isometric(L::AbstractSpace, M::AbstractSpace) -> Bool\n\nReturn whether the spaces L and M are isometric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#is_isometric-Tuple{AbstractSpace, AbstractSpace, Any}","page":"Spaces","title":"is_isometric","text":"is_isometric(L::AbstractSpace, M::AbstractSpace, p::Union{InfPlc, NfOrdIdl}) -> Bool\n\nReturn whether the spaces L and M are isometric over the completion at p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#invariants-Tuple{Hecke.QuadSpace}","page":"Spaces","title":"invariants","text":"invariants(M::QuadSpace)\n -> FieldElem, Dict{NfOrdIdl, Int}, Vector{Tuple{InfPlc, Int}}\n\nReturns a tuple (n, k, d, H, I) of invariants of M, which determine the isometry class completely. Here n is the dimension. The dimension of the kernel is k. The element d is the determinant of a Gram matrix of the non-degenerate part, H contains the non-trivial Hasse invariants and I contains for each real place the negative index of inertia.\n\nNote that d is determined only modulo squares.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Examples-5","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"For instance, for the case of Q and the totally ramified prime mathfrak p of O_K above 7, one can get:","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nQ = quadratic_space(K, K[0 1; 1 0]);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\nhasse_invariant(Q, p), witt_invariant(Q, p)\nQ2 = quadratic_space(K, K[-1 0; 0 1]);\nis_isometric(Q, Q2, p)\nis_isometric(Q, Q2)\ninvariants(Q2)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Embeddings","page":"Spaces","title":"Embeddings","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Let (V Phi) and (V Phi) be two spaces over the same extension EK, and let sigma colon V to V be an E-linear morphism. sigma is called a representation of V into V if for all x in V","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":" Phi(sigma(x) sigma(x)) = Phi(xx)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"In such a case, V is said to be represented by V and sigma can be seen as an embedding of V into V. This representation property can be also tested locally with respect to the completions at some finite places. Note that in both quadratic and hermitian cases, completions are taken at finite places of the fixed field K.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_locally_represented_by(::AbstractSpace, ::AbstractSpace, p)\nis_represented_by(::AbstractSpace, ::AbstractSpace)","category":"page"},{"location":"Hecke/quad_forms/basics/#is_locally_represented_by-Tuple{AbstractSpace, AbstractSpace, Any}","page":"Spaces","title":"is_locally_represented_by","text":"is_locally_represented_by(U::T, V::T, p::NfOrdIdl) where T <: AbstractSpace -> Bool\n\nGiven two spaces U and V over the same algebra E, and a prime ideal p in the maximal order mathcal O_K of their fixed field K, return whether U is represented by V locally at p, i.e. whether U_p embeds in V_p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#is_represented_by-Tuple{AbstractSpace, AbstractSpace}","page":"Spaces","title":"is_represented_by","text":"is_represented_by(U::T, V::T) where T <: AbstractSpace -> Bool\n\nGiven two spaces U and V over the same algebra E, return whether U is represented by V, i.e. whether U embeds in V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Examples-6","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Still using the spaces Q and H, we can decide whether some other spaces embed respectively locally or globally into Q or H:","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nE, b = number_field(t^2-a*t+1, \"b\");\nQ = quadratic_space(K, K[0 1; 1 0]);\nH = hermitian_space(E, 3);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\nQ2 = quadratic_space(K, K[-1 0; 0 1]);\nH2 = hermitian_space(E, E[-1 0 0; 0 1 0; 0 0 -1]);\nis_locally_represented_by(Q2, Q, p)\nis_represented_by(Q2, Q)\nis_locally_represented_by(H2, H, p)\nis_represented_by(H2, H)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Categorical-constructions","page":"Spaces","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"One can construct direct sums of spaces of the same kind. Since those are also direct products, they are called biproducts in this context. Depending on the user usage, one of the following three methods can be called to obtain the direct sum of a finite collection of spaces. Note that the corresponding copies of the original spaces in the direct sum are pairwise orthogonal.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"direct_sum(::Vector{AbstractSpace})\ndirect_product(::Vector{AbstractSpace})\nbiproduct(::Vector{AbstractSpace})","category":"page"},{"location":"Hecke/quad_forms/basics/#direct_sum-Tuple{Vector{AbstractSpace}}","page":"Spaces","title":"direct_sum","text":"direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T\n\nGiven modules M_1dots M_n, say, return the direct sum bigoplus_i=1^n M_i. \n\nAdditionally, return \n\na vector containing the canonical injections M_itobigoplus_i=1^n M_i if task = :sum (default),\na vector containing the canonical projections bigoplus_i=1^n M_ito M_i if task = :prod,\ntwo vectors containing the canonical injections and projections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_sum(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}\ndirect_sum(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian spaces V_1 ldots V_n, return their direct sum V = V_1 oplus ldots oplus V_n, together with the injections V_i to V.\n\nFor objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct product with the projections V to V_i, one should call direct_product(x). If one wants to obtain V as a biproduct with the injections V_i to V and the projections V to V_i, one should call biproduct(x).\n\n\n\n\n\ndirect_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls\n\nReturn the isometry class of the direct sum of two representatives.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#direct_product-Tuple{Vector{AbstractSpace}}","page":"Spaces","title":"direct_product","text":"direct_product(F::FreeMod{T}...; task::Symbol = :prod) where T\n\nGiven free modules F_1dots F_n, say, return the direct product prod_i=1^n F_i.\n\nAdditionally, return\n\na vector containing the canonical projections prod_i=1^n F_ito F_i if task = :prod (default),\na vector containing the canonical injections F_itoprod_i=1^n F_i if task = :sum,\ntwo vectors containing the canonical projections and injections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_product(M::ModuleFP{T}...; task::Symbol = :prod) where T\n\nGiven modules M_1dots M_n, say, return the direct product prod_i=1^n M_i.\n\nAdditionally, return\n\na vector containing the canonical projections prod_i=1^n M_ito M_i if task = :prod (default),\na vector containing the canonical injections M_itoprod_i=1^n M_i if task = :sum,\ntwo vectors containing the canonical projections and injections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_product(algebras::AlgAss...; task::Symbol = :sum)\n -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\ndirect_product(algebras::Vector{AlgAss}; task::Symbol = :sum)\n -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\n\nReturns the algebra A = A_1 times cdots times A_k. task can be \":sum\", \":prod\", \":both\" or \":none\" and determines which canonical maps are computed as well: \":sum\" for the injections, \":prod\" for the projections.\n\n\n\n\n\ndirect_product(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}\ndirect_product(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian spaces V_1 ldots V_n, return their direct product V = V_1 times ldots times V_n, together with the projections V to V_i.\n\nFor objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct sum with the injections V_i to V, one should call direct_sum(x). If one wants to obtain V as a biproduct with the injections V_i to V and the projections V to V_i, one should call biproduct(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#biproduct-Tuple{Vector{AbstractSpace}}","page":"Spaces","title":"biproduct","text":"biproduct(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\nbiproduct(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian spaces V_1 ldots V_n, return their biproduct V = V_1 oplus ldots oplus V_n, together with the injections V_i to V and the projections V to V_i.\n\nFor objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct sum with the injections V_i to V, one should call direct_sum(x). If one wants to obtain V as a direct product with the projections V to V_i, one should call direct_product(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Example","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nE, b = cyclotomix_field_as_cm_extensions(7);\nH = hermitian_space(E, 3);\nH2 = hermitian_space(E, E[-1 0 0; 0 1 0; 0 0 -1]);\nH3, inj, proj = biproduct(H, H2)\nis_one(matrix(compose(inj[1], proj[1])))\nis_zero(matrix(compose(inj[1], proj[2])))","category":"page"},{"location":"Hecke/quad_forms/basics/#Orthogonality-operations","page":"Spaces","title":"Orthogonality operations","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"orthogonal_complement(::AbstractSpace, ::MatElem)\northogonal_projection(::AbstractSpace, ::MatElem)","category":"page"},{"location":"Hecke/quad_forms/basics/#orthogonal_complement-Tuple{AbstractSpace, MatElem}","page":"Spaces","title":"orthogonal_complement","text":"orthogonal_complement(V::AbstractSpace, M::T) where T <: MatElem -> T\n\nGiven a space V and a subspace W with basis matrix M, return a basis matrix of the orthogonal complement of W inside V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#orthogonal_projection-Tuple{AbstractSpace, MatElem}","page":"Spaces","title":"orthogonal_projection","text":"orthogonal_projection(V::AbstractSpace, M::T) where T <: MatElem -> AbstractSpaceMor\n\nGiven a space V and a non-degenerate subspace W with basis matrix M, return the endomorphism of V corresponding to the projection onto the complement of W in V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Example-2","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nQ = quadratic_space(K, K[0 1; 1 0]);\northogonal_complement(Q, matrix(K, 1, 2, [1 0]))","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Isotropic-spaces","page":"Spaces","title":"Isotropic spaces","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Let (V Phi) be a space over EK and let mathfrak p be a place in K. V is said to be isotropic locally at mathfrak p if there exists an element x in V_mathfrak p such that Phi_mathfrak p(xx) = 0, where Phi_mathfrak p is the continuous extension of Phi to V_mathfrak p times V_mathfrak p.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_isotropic(::AbstractSpace, p)","category":"page"},{"location":"Hecke/quad_forms/basics/#is_isotropic-Tuple{AbstractSpace, Any}","page":"Spaces","title":"is_isotropic","text":"is_isotropic(V::AbstractSpace, p::Union{NfOrdIdl, InfPlc}) -> Bool\n\nGiven a space V and a place p in the fixed field K of V, return whether the completion of V at p is isotropic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Example-3","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nE, b = number_field(t^2-a*t+1, \"b\");\nH = hermitian_space(E, 3);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\nis_isotropic(H, p)","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/quad_forms/basics/#Hyperbolic-spaces","page":"Spaces","title":"Hyperbolic spaces","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"Let (V Phi) be a space over EK and let mathfrak p be a prime ideal of mathcal O_K. V is said to be hyperbolic locally at mathfrak p if the completion V_mathfrak p of V can be decomposed as an orthogonal sum of hyperbolic planes. The hyperbolic plane is the space (H Psi) of rank 2 over EK such that there exists a basis e_1 e_2 of H such that Psi(e_1 e_1) = Psi(e_2 e_2) = 0 and Psi(e_1 e_2) = 1.","category":"page"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_locally_hyperbolic(::HermSpace, ::NfOrdIdl)","category":"page"},{"location":"Hecke/quad_forms/basics/#is_locally_hyperbolic-Tuple{Hecke.HermSpace, NfOrdIdl}","page":"Spaces","title":"is_locally_hyperbolic","text":"is_locally_hyperbolic(V::Hermspace, p::NfOrdIdl) -> Bool\n\nReturn whether the completion of the hermitian space V over EK at the prime ideal p of mathcal O_K is hyperbolic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/basics/#Example-4","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = CyclotomicRealSubfield(7);\nKt, t = K[\"t\"];\nE, b = number_field(t^2-a*t+1, \"b\");\nH = hermitian_space(E, 3);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\nis_locally_hyperbolic(H, p)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#Affine-Varieties","page":"Affine Varieties","title":"Affine Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"An affine variety is an algebraic set such that X(K) is irreducible for k subseteq K an algebraic closure. See Affine Algebraic Sets.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"In Oscar varieties are implemented as special instances of Affine schemes and more formally defined as follows.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"AbsAffineVariety","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#AbsAffineVariety","page":"Affine Varieties","title":"AbsAffineVariety","text":"AbsAffineVariety <: AbsAffineAlgebraicSet\n\nAn affine, geometrically integral subscheme of an affine space over a field.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"Functionality which is not (yet) provided by a variety-specific implementation, falls back to the appropriate functionality of schemes.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#Constructors","page":"Affine Varieties","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"variety(I::MPolyIdeal; check=true)\nvariety(X::AbsSpec{<:Field}; is_reduced=false, check::Bool=true)\nvariety(R::MPolyAnyRing; check=true)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#variety-Tuple{MPolyIdeal}","page":"Affine Varieties","title":"variety","text":"variety(I::MPolyIdeal; check=true) -> AffineVariety\n\nReturn the affine variety defined by the ideal I.\n\nBy our convention, varieties are absolutely irreducible. Hence we check that the radical of I is prime and stays prime when viewed over the algebraic closure. This is an expensive check that can be disabled.\n\njulia> R, (x,y) = QQ[:x,:y]\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> variety(ideal([x,y]))\nAffine variety\n in affine 2-space over QQ with coordinates [x, y]\ndefined by defined by ideal(x, y)\n\n\nOver fields different from QQ, currently, we cannot check for irreducibility over the algebraic closure. But if you know that the ideal in question defines a variety, you can construct it by disabling the check.\n\njulia> R, (x,y) = GF(2)[:x,:y];\n\njulia> variety(x^3+y+1, check=false)\nAffine variety\n in affine 2-space over GF(2) with coordinates [x, y]\ndefined by defined by ideal(x^3 + y + 1)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#variety-Tuple{AbsSpec{<:Field}}","page":"Affine Varieties","title":"variety","text":"variety(X::AbsSpec; is_reduced::false, check::Bool=true) -> AffineVariety\n\nConvert X to an affine variety.\n\nIf is_reduced is set, assume that X is already reduced.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#variety-Tuple{Union{MPolyRing, MPolyLocRing, MPolyQuoLocRing, MPolyQuoRing}}","page":"Affine Varieties","title":"variety","text":"variety(R::Ring; check=true)\n\nReturn the affine variety with coordinate ring R.\n\nWe require that R is a finitely generated algebra over a field k and moreover that the base change of R to the algebraic closure bar k is an integral domain.\n\njulia> R, (x,y) = QQ[:x,:y];\n\njulia> Q,_ = quo(R,ideal([x,y]));\n\njulia> variety(Q)\nAffine variety\n in affine 2-space over QQ with coordinates [x, y]\ndefined by defined by ideal(x, y)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#Attributes","page":"Affine Varieties","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"So far all are inherited from Affine Algebraic Sets and Affine schemes.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#Properties","page":"Affine Varieties","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"So far all are inherited from Affine Algebraic Sets and Affine schemes.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#Methods","page":"Affine Varieties","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/","page":"Affine Varieties","title":"Affine Varieties","text":"So far all are inherited from Affine Algebraic Sets and Affine schemes.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#Quadratic-space-with-isometry","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"We call quadratic space with isometry any pair (V f) consisting of a non-degenerate quadratic space V together with an isometry fin O(V). We refer to the section about quadratic spaces of the documentation for new users.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"Note that currently, we support only rational quadratic forms, i.e. quadratic spaces defined over the rational.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"In Oscar, such a pair is encoded by the type called QuadSpaceWithIsom:","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"QuadSpaceWithIsom","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#QuadSpaceWithIsom","page":"Quadratic space with isometry","title":"QuadSpaceWithIsom","text":"QuadSpaceWithIsom\n\nA container type for pairs (V, f) consisting on an rational quadratic space V of type QuadSpace and an isometry f given as a QQMatrix representing the action on the standard basis of V.\n\nWe store the order of f too, which can finite or of infinite order.\n\nTo construct an object of type QuadSpaceWithIsom, see the set of functions called quadratic_space_with_isometry\n\nExamples\n\njulia> V = quadratic_space(QQ, 4);\n\njulia> quadratic_space_with_isometry(V, neg=true)\nQuadratic space of dimension 4\n with isometry of finite order 2\n given by\n [-1 0 0 0]\n [ 0 -1 0 0]\n [ 0 0 -1 0]\n [ 0 0 0 -1]\n\njulia> L = root_lattice(:E, 6);\n\njulia> V = ambient_space(L);\n\njulia> f = matrix(QQ, 6, 6, [ 1 2 3 2 1 1;\n -1 -2 -2 -2 -1 -1;\n 0 1 0 0 0 0;\n 1 0 0 0 0 0;\n -1 -1 -1 0 0 -1;\n 0 0 1 1 0 1]);\n\njulia> Vf = quadratic_space_with_isometry(V, f)\nQuadratic space of dimension 6\n with isometry of finite order 8\n given by\n [ 1 2 3 2 1 1]\n [-1 -2 -2 -2 -1 -1]\n [ 0 1 0 0 0 0]\n [ 1 0 0 0 0 0]\n [-1 -1 -1 0 0 -1]\n [ 0 0 1 1 0 1]\n\n\n\n\n\n","category":"type"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"and it is seen as a triple (V f n) where n is the order of f. We actually support isometries of finite and infinite order. In the case where f is of infinite order, then n = PosInf. If V has rank 0, then any isometry f of V is trivial and we set by default n = -1.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"Given a quadratic space with isometry (V f), we provide the following accessors to the elements of the previously described triple:","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"isometry(::QuadSpaceWithIsom)\norder_of_isometry(::QuadSpaceWithIsom)\nspace(::QuadSpaceWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#isometry-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"isometry","text":"isometry(Vf::QuadSpaceWithIsom) -> QQMatrix\n\nGiven a quadratic space with isometry (V f), return the underlying isometry f.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> isometry(Vf)\n[-1 0]\n[ 0 -1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#order_of_isometry-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"order_of_isometry","text":"order_of_isometry(Vf::QuadSpaceWithIsom) -> IntExt\n\nGiven a quadratic space with isometry (V f), return the order of the underlying isometry f.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> order_of_isometry(Vf) == 2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#space-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"space","text":"space(Vf::QuadSpaceWithIsom) -> QuadSpace\n\nGiven a quadratic space with isometry (V f), return the underlying space V.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> space(Vf) === V\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"The main purpose of the definition of such objects is to define a contextual ambient space for quadratic lattices endowed with an isometry. Indeed, as we will see in the next section, lattices with isometry are attached to an ambient quadratic space with an isometry inducing the one on the lattice.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#Constructors","page":"Quadratic space with isometry","title":"Constructors","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"For simplicity, we have gathered the main constructors for objects of type QuadSpaceWithIsom under the same name quadratic_space_with_isometry. The user has then the choice on the parameters depending on what they intend to do:","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"quadratic_space_with_isometry(::Hecke.QuadSpace, ::QQMatrix)\nquadratic_space_with_isometry(::Hecke.QuadSpace)","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#quadratic_space_with_isometry-Tuple{Hecke.QuadSpace, QQMatrix}","page":"Quadratic space with isometry","title":"quadratic_space_with_isometry","text":"quadratic_space_with_isometry(V:QuadSpace, f::QQMatrix; check::Bool = false)\n -> QuadSpaceWithIsom\n\nGiven a quadratic space V and a matrix f, if f defines an isometry of V of order n (possibly infinite), return the corresponding quadratic space with isometry pair (V f).\n\nExamples\n\njulia> V = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> f = matrix(QQ, 2, 2, [1 1;\n 0 -1])\n[1 1]\n[0 -1]\n\njulia> Vf = quadratic_space_with_isometry(V, f)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#quadratic_space_with_isometry-Tuple{Hecke.QuadSpace}","page":"Quadratic space with isometry","title":"quadratic_space_with_isometry","text":"quadratic_space_with_isometry(V::QuadSpace; neg::Bool = false) -> QuadSpaceWithIsom\n\nGiven a quadratic space V, return the quadratic space with isometry pair (V f) where f is represented by the identity matrix.\n\nIf neg is set to true, then the isometry f is negative the identity on V.\n\nExamples\n\njulia> V = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> Vf = quadratic_space_with_isometry(V)\nQuadratic space of dimension 2\n with isometry of finite order 1\n given by\n [1 0]\n [0 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"By default, the first constructor always checks whether the matrix defines an isometry of the quadratic space. We recommend not to disable this parameter to avoid any complications. Note however that in the rank 0 case, the checks are avoided since all isometries are necessarily trivial.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#Attributes-and-first-operations","page":"Quadratic space with isometry","title":"Attributes and first operations","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"Given a quadratic space with isometry Vf = (V f), one has access to most of the attributes of V and f by calling the similar functions on the pair (V f) itself. For instance, in order to know the rank of V, one can simply call rank(Vf). Here is a list of what are the current accessible attributes:","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"characteristic_polynomial(::QuadSpaceWithIsom)\ndet(::QuadSpaceWithIsom)\ndiagonal(::QuadSpaceWithIsom)\ndim(::QuadSpaceWithIsom)\ndiscriminant(::QuadSpaceWithIsom)\ngram_matrix(::QuadSpaceWithIsom)\nis_definite(::QuadSpaceWithIsom)\nis_positive_definite(::QuadSpaceWithIsom)\nis_negative_definite(::QuadSpaceWithIsom)\nminimal_polynomial(::QuadSpaceWithIsom)\nrank(::QuadSpaceWithIsom)\nsignature_tuple(::QuadSpaceWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#characteristic_polynomial-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"characteristic_polynomial","text":"characteristic_polynomial(Vf::QuadSpaceWithIsom) -> QQPolyRingElem\n\nGiven a quadratic space with isometry (V f), return the characteristic polynomial of the underlying isometry f.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> characteristic_polynomial(Vf)\nx^2 + 2*x + 1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#det-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"det","text":"det(Vf::QuadSpaceWithIsom) -> QQFieldElem\n\nGiven a quadratic space with isometry (V f), return the determinant of the underlying space V.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> is_one(det(Vf))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#diagonal-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"diagonal","text":"diagonal(Vf::QuadSpaceWithIsom) -> Vector{QQFieldElem}\n\nGiven a quadratic space with isometry (V f), return the diagonal of the underlying space V.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> diagonal(Vf)\n2-element Vector{QQFieldElem}:\n 1\n 1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#dim-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"dim","text":"dim(Vf::QuadSpaceWithIsom) -> Integer\n\nGiven a quadratic space with isometry (V f), return the dimension of the underlying space of V.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> dim(Vf) == 2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#discriminant-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"discriminant","text":"discriminant(Vf::QuadSpaceWithIsom) -> QQFieldElem\n\nGiven a quadratic space with isometry (V f), return the discriminant of the underlying space V.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> discriminant(Vf)\n-1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#gram_matrix-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"gram_matrix","text":"gram_matrix(Vf::QuadSpaceWithIsom) -> QQMatrix\n\nGiven a quadratic space with isometry (V f), return the Gram matrix of the underlying space V with respect to its standard basis.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> is_one(gram_matrix(Vf))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#is_definite-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"is_definite","text":"is_definite(Vf::QuadSpaceWithIsom) -> Bool\n\nGiven a quadratic space with isometry (V f), return whether the underlying space V is definite.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> is_definite(Vf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#is_positive_definite-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"is_positive_definite","text":"is_positive_definite(Vf::QuadSpaceWithIsom) -> Bool\n\nGiven a quadratic space with isometry (V f), return whether the underlying space V is positive definite.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> is_positive_definite(Vf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#is_negative_definite-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"is_negative_definite","text":"is_negative_definite(Vf::QuadSpaceWithIsom) -> Bool\n\nGiven a quadratic space with isometry (V f), return whether the underlying space V is negative definite.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> is_negative_definite(Vf)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#minimal_polynomial-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"minimal_polynomial","text":"minimal_polynomial(Vf::QuadSpaceWithIsom) -> QQPolyRingElem\n\nGiven a quadratic space with isometry (V f), return the minimal polynomial of the underlying isometry f.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> minimal_polynomial(Vf)\nx + 1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#rank-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"rank","text":"rank(Vf::QuadSpaceWithIsom) -> Integer\n\nGiven a quadratic space with isometry (V f), return the rank of the underlying space V.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> rank(Vf) == 2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#signature_tuple-Tuple{QuadSpaceWithIsom}","page":"Quadratic space with isometry","title":"signature_tuple","text":"signature_tuple(Vf::QuadSpaceWithIsom) -> Tuple{Int, Int, Int}\n\nGiven a quadratic space with isometry (V f), return the signature tuple of the underlying space V.\n\nExamples\n\njulia> V = quadratic_space(QQ, 2);\n\njulia> Vf = quadratic_space_with_isometry(V; neg = true);\n\njulia> signature_tuple(Vf)\n(2, 0, 0)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"Similarly, some basic operations on quadratic spaces are available for quadratic spaces with isometry.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"Base.:^(::QuadSpaceWithIsom, ::Int)\nbiproduct(::Vector{QuadSpaceWithIsom})\ndirect_product(::Vector{QuadSpaceWithIsom})\ndirect_sum(::Vector{QuadSpaceWithIsom})\nrescale(::QuadSpaceWithIsom, ::RationalUnion)","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#^-Tuple{QuadSpaceWithIsom, Int64}","page":"Quadratic space with isometry","title":"^","text":"^(Vf::QuadSpaceWithIsom, n::Int) -> QuadSpaceWithIsom\n\nGiven a quadratic space with isometry (V f) and an integer n, return the pair (V f^n).\n\nExamples\n\njulia> V = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> f = matrix(QQ, 2, 2, [1 1;\n 0 -1])\n[1 1]\n[0 -1]\n\njulia> Vf = quadratic_space_with_isometry(V, f)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\njulia> Vf^2\nQuadratic space of dimension 2\n with isometry of finite order 1\n given by\n [1 0]\n [0 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#biproduct-Tuple{Vector{QuadSpaceWithIsom}}","page":"Quadratic space with isometry","title":"biproduct","text":"biproduct(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\nbiproduct(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic spaces with isometries (V_1 f_1) ldots (V_n f_n), return the quadratic space with isometry (V f) together with the injections V_i to V and the projections V to V_i, where V is the biproduct V = V_1 oplus ldots oplus V_n and f is the isometry of V induced by the diagonal actions of the f_i's.\n\nFor objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (V f) as a direct sum with the injections V_i to V, one should call direct_sum(x). If one wants to obtain (V f) as a direct product with the projections V to V_i, one should call direct_product(x).\n\nExamples\n\njulia> V1 = quadratic_space(QQ, QQ[2 5;\n 5 6])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[2 5]\n[5 6]\n\njulia> Vf1 = quadratic_space_with_isometry(V1, neg=true)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [-1 0]\n [ 0 -1]\n\njulia> V2 = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> f = matrix(QQ, 2, 2, [1 1;\n 0 -1])\n[1 1]\n[0 -1]\n\njulia> Vf2 = quadratic_space_with_isometry(V2, f)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\njulia> Vf3, inj, proj = biproduct(Vf1, Vf2)\n(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 2\nCodomain:\n=========\nQuadratic space of dimension 4, Map with following data\nDomain:\n=======\nQuadratic space of dimension 2\nCodomain:\n=========\nQuadratic space of dimension 4], AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 4\nCodomain:\n=========\nQuadratic space of dimension 2, Map with following data\nDomain:\n=======\nQuadratic space of dimension 4\nCodomain:\n=========\nQuadratic space of dimension 2])\n\njulia> Vf3\nQuadratic space of dimension 4\n with isometry of finite order 2\n given by\n [-1 0 0 0]\n [ 0 -1 0 0]\n [ 0 0 1 1]\n [ 0 0 0 -1]\n\njulia> space(Vf3)\nQuadratic space of dimension 4\n over rational field\nwith gram matrix\n[2 5 0 0]\n[5 6 0 0]\n[0 0 2 -1]\n[0 0 -1 2]\n\njulia> matrix(compose(inj[1], proj[1]))\n[1 0]\n[0 1]\n\njulia> matrix(compose(inj[1], proj[2]))\n[0 0]\n[0 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#direct_product-Tuple{Vector{QuadSpaceWithIsom}}","page":"Quadratic space with isometry","title":"direct_product","text":"direct_product(F::FreeMod{T}...; task::Symbol = :prod) where T\n\nGiven free modules F_1dots F_n, say, return the direct product prod_i=1^n F_i.\n\nAdditionally, return\n\na vector containing the canonical projections prod_i=1^n F_ito F_i if task = :prod (default),\na vector containing the canonical injections F_itoprod_i=1^n F_i if task = :sum,\ntwo vectors containing the canonical projections and injections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_product(M::ModuleFP{T}...; task::Symbol = :prod) where T\n\nGiven modules M_1dots M_n, say, return the direct product prod_i=1^n M_i.\n\nAdditionally, return\n\na vector containing the canonical projections prod_i=1^n M_ito M_i if task = :prod (default),\na vector containing the canonical injections M_itoprod_i=1^n M_i if task = :sum,\ntwo vectors containing the canonical projections and injections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_product(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}\ndirect_product(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic spaces with isometries (V_1 f_1) ldots (V_n f_n), return the quadratic space with isometry (V f) together with the projections V to V_i, where V is the direct product V = V_1 times ldots times V_n and f is the isometry of V induced by the diagonal actions of the f_i's.\n\nFor objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (V f) as a direct sum with the injections V_i to V, one should call direct_sum(x). If one wants to obtain (V f) as a biproduct with the injections V_i to V and the projections V to V_i, one should call biproduct(x).\n\nExamples\n\njulia> V1 = quadratic_space(QQ, QQ[2 5;\n 5 6])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[2 5]\n[5 6]\n\njulia> Vf1 = quadratic_space_with_isometry(V1, neg=true)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [-1 0]\n [ 0 -1]\n\njulia> V2 = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> f = matrix(QQ, 2, 2, [1 1;\n 0 -1])\n[1 1]\n[0 -1]\n\njulia> Vf2 = quadratic_space_with_isometry(V2, f)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\njulia> Vf3, proj = direct_product(Vf1, Vf2)\n(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 4\nCodomain:\n=========\nQuadratic space of dimension 2, Map with following data\nDomain:\n=======\nQuadratic space of dimension 4\nCodomain:\n=========\nQuadratic space of dimension 2])\n\njulia> Vf3\nQuadratic space of dimension 4\n with isometry of finite order 2\n given by\n [-1 0 0 0]\n [ 0 -1 0 0]\n [ 0 0 1 1]\n [ 0 0 0 -1]\n\njulia> space(Vf3)\nQuadratic space of dimension 4\n over rational field\nwith gram matrix\n[2 5 0 0]\n[5 6 0 0]\n[0 0 2 -1]\n[0 0 -1 2]\n\n\n\n\n\ndirect_product(algebras::AlgAss...; task::Symbol = :sum)\n -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\ndirect_product(algebras::Vector{AlgAss}; task::Symbol = :sum)\n -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\n\nReturns the algebra A = A_1 times cdots times A_k. task can be \":sum\", \":prod\", \":both\" or \":none\" and determines which canonical maps are computed as well: \":sum\" for the injections, \":prod\" for the projections.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#direct_sum-Tuple{Vector{QuadSpaceWithIsom}}","page":"Quadratic space with isometry","title":"direct_sum","text":"direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T\n\nGiven modules M_1dots M_n, say, return the direct sum bigoplus_i=1^n M_i. \n\nAdditionally, return \n\na vector containing the canonical injections M_itobigoplus_i=1^n M_i if task = :sum (default),\na vector containing the canonical projections bigoplus_i=1^n M_ito M_i if task = :prod,\ntwo vectors containing the canonical injections and projections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_sum(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}\ndirect_sum(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic spaces with isometries (V_1 f_1) ldots (V_n f_n), return the quadratic space with isometry (V f) together with the injections V_i to V, where V is the direct sum V = V_1 oplus ldots oplus V_n and f is the isometry of V induced by the diagonal actions of the f_i's.\n\nFor objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (V f) as a direct product with the projections V to V_i, one should call direct_product(x). If one wants to obtain (V f) as a biproduct with the injections V_i to V and the projections V to V_i, one should call biproduct(x).\n\nExamples\n\njulia> V1 = quadratic_space(QQ, QQ[2 5;\n 5 6])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[2 5]\n[5 6]\n\njulia> Vf1 = quadratic_space_with_isometry(V1, neg=true)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [-1 0]\n [ 0 -1]\n\njulia> V2 = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> f = matrix(QQ, 2, 2, [1 1;\n 0 -1])\n[1 1]\n[0 -1]\n\njulia> Vf2 = quadratic_space_with_isometry(V2, f)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\njulia> Vf3, inj = direct_sum(Vf1, Vf2)\n(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 2\nCodomain:\n=========\nQuadratic space of dimension 4, Map with following data\nDomain:\n=======\nQuadratic space of dimension 2\nCodomain:\n=========\nQuadratic space of dimension 4])\n\njulia> Vf3\nQuadratic space of dimension 4\n with isometry of finite order 2\n given by\n [-1 0 0 0]\n [ 0 -1 0 0]\n [ 0 0 1 1]\n [ 0 0 0 -1]\n\njulia> space(Vf3)\nQuadratic space of dimension 4\n over rational field\nwith gram matrix\n[2 5 0 0]\n[5 6 0 0]\n[0 0 2 -1]\n[0 0 -1 2]\n\n\n\n\n\ndirect_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls\n\nReturn the isometry class of the direct sum of two representatives.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#rescale-Tuple{QuadSpaceWithIsom, Union{Integer, QQFieldElem, ZZRingElem, Rational}}","page":"Quadratic space with isometry","title":"rescale","text":"rescale(Vf::QuadSpaceWithIsom, a::RationalUnion)\n\nGiven a quadratic space with isometry (V f), return the pair (V^a f) where V^a is the same space as V with the associated quadratic form rescaled by a.\n\nExamples\n\njulia> V = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> Vf = quadratic_space_with_isometry(V)\nQuadratic space of dimension 2\n with isometry of finite order 1\n given by\n [1 0]\n [0 1]\n\njulia> Vf2 = rescale(Vf, 1//2)\nQuadratic space of dimension 2\n with isometry of finite order 1\n given by\n [1 0]\n [0 1]\n\njulia> space(Vf2)\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 1 -1//2]\n[-1//2 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#Equality","page":"Quadratic space with isometry","title":"Equality","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic space with isometry","title":"Quadratic space with isometry","text":"We choose as a convention that two pairs (V f) and (V f) of quadratic spaces with isometries are equal if and only if V and V are the same space, and f and f are represented by the same matrix with respect to the standard basis of V = V.","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/developer/future/#Future-plans","page":"Future plans","title":"Future plans","text":"","category":"section"},{"location":"Nemo/developer/future/#Ring-and-CommRing","page":"Future plans","title":"Ring and CommRing","text":"","category":"section"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"Currently all commutative ring types belong to Ring and their elements to RingElem (and RingElement) and we have separate types for noncommutative rings and elements thereof, i.e. NCRing and NCRingElem etc.","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"However, it would be more logical to use Ring for not necessarily commutative rings and CommRing, CRing or CommutativeRing (the name has not been decided on yet) for commutative rings.","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"This is a big change and should happen with plenty of warning for the community. It would be convenient if a script could be made available to automate this.","category":"page"},{"location":"Nemo/developer/future/#Mono-repository","page":"Future plans","title":"Mono repository","text":"","category":"section"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"There is currently a proposal to place all Oscar related repositories, or some subset of them in a single repository called OscarMono.jl. The details are not finalised and it is not known what impact this will have on Nemo. However, Nemo developers should be aware that this may happen at some point in the fairly near future.","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"Users of Nemo should be unaffected, as Nemo will continue to exist as a separate package in the OscarMono.jl repository, even if it does become part of this repository. Julia supports multiple packages in the same repository nowadays.","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"The possibility will always exist to separate the repositories again if the experiment is unsuccessful or serves its purpose and is no longer needed.","category":"page"},{"location":"Nemo/developer/future/#Moving-implementations-from-Hecke","page":"Future plans","title":"Moving implementations from Hecke","text":"","category":"section"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"In the Hecke.jl project there are a vast number of implementations that were intended for AbstractAlgebra.jl and Nemo.jl. They exist in the src/Misc directory of that project.","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"These implementations will eventually all be moved over to the correct repositories. Code, documentation and performance improvements will be added.","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"A number of things must be taken into account when making such moves:","category":"page"},{"location":"Nemo/developer/future/","page":"Future plans","title":"Future plans","text":"Substantial chunks of code should be moved at a time. The code can be initially placed in a src/Misc directory in AbstractAlgebra or Nemo until it can finally be integrated fully into the correct place in those projects.\nSome of the code calls full parent object constructors in generic code. Such calls should be removed where possible.\nSome functions such as exp and the like require Base to be prepended, as we do not import these functions from Base into Generic.\nSome of the code calls back into convenience functions found only in Hecke. These have to be rewritten in terms of AbstractAlgebra/Nemo functions.\nSome of the code relies on ZZRingElem being available, but would otherwise be suitable for AbstractAlgebra. This code can hopefully be rewritten to be agnostic about the integer type.\nTodos, questions and so on should be moved to tickets.\nSometimes exception types differ between Hecke and Nemo, meaning that tests will fail due to the wrong type of exception being raised. Either the tests will have to be adjusted, or the Nemo exception types changed.\nRingElem is often used where RingElement is intended, etc. Also types are often unconstrained where Nemo would constrain them to RingElement.\nSome Hecke functions try to support generic types and specific concrete Nemo types in the same implementation. These will unfortunately have to either be split between AbstractAlgebra and Nemo or a completely generic implementation for abstract types will have to be made.\nSome Hecke implementations assume sub! and friends are available in generic code. These will have to be rewritten, usually by adding a single unary minus outside of a loop and switching to add! and friends inside the loops.\nTest code, docstrings and documentation will have to be added where they do not already exist.\nExports of the new functionality will have to be added.\nSome functions should be accompanied by similar functions that don't yet exist. For example if there is a blah_rows there probably should be a blah_cols function as well, etc.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/fraction/#Generic-fraction-fields","page":"Generic fraction fields","title":"Generic fraction fields","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"AbstractAlgebra.jl provides a module, implemented in src/Fraction.jl for fraction fields over any gcd domain belonging to the AbstractAlgebra.jl abstract type hierarchy.","category":"page"},{"location":"AbstractAlgebra/fraction/#Generic-fraction-types","page":"Generic fraction fields","title":"Generic fraction types","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"AbstractAlgebra.jl implements a generic fraction type Generic.Frac{T} where T is the type of elements of the base ring. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Parent objects of such fraction elements have type Generic.FracField{T}.","category":"page"},{"location":"AbstractAlgebra/fraction/#Factored-fraction-types","page":"Generic fraction fields","title":"Factored fraction types","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"AbstractAlgebra.jl also implements a fraction type Generic.FactoredFrac{T} with parent objects of such fractions having type Generic.FactoredFracField{T}. As opposed to the fractions of type Generic.Frac{T}, which are just a numerator and denominator, these fractions are maintained in factored form as much as possible.","category":"page"},{"location":"AbstractAlgebra/fraction/#Abstract-types","page":"Generic fraction fields","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"All fraction element types belong to the abstract type FracElem{T} and the fraction field types belong to the abstract type FracField{T}. This enables one to write generic functions that can accept any AbstractAlgebra fraction type.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"note: Note\nBoth the generic fraction field type Generic.FracField{T} and the abstract type it belongs to, FracField{T} are both called FracField. The former is a (parameterised) concrete type for a fraction field over a given base ring whose elements have type T. The latter is an abstract type representing all fraction field types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).","category":"page"},{"location":"AbstractAlgebra/fraction/#Fraction-field-constructors","page":"Generic fraction fields","title":"Fraction field constructors","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"In order to construct fractions in AbstractAlgebra.jl, one can first construct the fraction field itself. This is accomplished with the following constructor.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"fraction_field(R::Ring; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Given a base ring R return the parent object of the fraction field of R. By default the parent object S will depend only on R and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Here are some examples of creating fraction fields and making use of the resulting parent objects to coerce various elements into the fraction field.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = fraction_field(R)\nFraction field\n of univariate polynomial ring in x over integers\n\njulia> f = S()\n0\n\njulia> g = S(123)\n123\n\njulia> h = S(BigInt(1234))\n1234\n\njulia> k = S(x + 1)\nx + 1","category":"page"},{"location":"AbstractAlgebra/fraction/#Factored-Fraction-field-constructors","page":"Generic fraction fields","title":"Factored Fraction field constructors","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"The corresponding factored field uses the following constructor.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"FactoredFractionField(R::Ring; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> S = FactoredFractionField(R)\nFactored fraction field of Multivariate polynomial ring in 2 variables over integers\n\njulia> (X, Y) = (S(x), S(y))\n(x, y)\n\njulia> f = X^6*(X+Y)^2*(X^2+Y)^3*(X+2*Y)^-3*(X+3*Y)^-4\nx^6*(x + y)^2*(x^2 + y)^3/((x + 2*y)^3*(x + 3*y)^4)\n\njulia> numerator(f)\nx^14 + 2*x^13*y + x^12*y^2 + 3*x^12*y + 6*x^11*y^2 + 3*x^10*y^3 + 3*x^10*y^2 + 6*x^9*y^3 + 3*x^8*y^4 + x^8*y^3 + 2*x^7*y^4 + x^6*y^5\n\njulia> denominator(f)\nx^7 + 18*x^6*y + 138*x^5*y^2 + 584*x^4*y^3 + 1473*x^3*y^4 + 2214*x^2*y^5 + 1836*x*y^6 + 648*y^7\n\njulia> derivative(f, x)\nx^5*(x + y)*(x^2 + y)^2*(7*x^5 + 58*x^4*y + 127*x^3*y^2 + x^3*y + 72*x^2*y^3 + 22*x^2*y^2 + 61*x*y^3 + 36*y^4)/((x + 2*y)^4*(x + 3*y)^5)","category":"page"},{"location":"AbstractAlgebra/fraction/#Fraction-constructors","page":"Generic fraction fields","title":"Fraction constructors","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"One can construct fractions using the fraction field parent object, as for any ring or field.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"(R::FracField)() # constructs zero\n(R::FracField)(c::Integer)\n(R::FracField)(c::elem_type(R))\n(R::FracField{T})(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"One may also use the Julia double slash operator to construct elements of the fraction field without constructing the fraction field parent first.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"//(x::T, y::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = fraction_field(R)\nFraction field\n of univariate polynomial ring in x over rationals\n\njulia> f = S(x + 1)\nx + 1\n\njulia> g = (x^2 + x + 1)//(x^3 + 3x + 1)\n(x^2 + x + 1)//(x^3 + 3*x + 1)\n\njulia> x//f\nx//(x + 1)\n\njulia> f//x\n(x + 1)//x","category":"page"},{"location":"AbstractAlgebra/fraction/#Functions-for-types-and-parents-of-fraction-fields","page":"Generic fraction fields","title":"Functions for types and parents of fraction fields","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Fraction fields in AbstractAlgebra.jl implement the Ring interface.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"base_ring(R::FracField)\nbase_ring(a::FracElem)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Return the base ring of which the fraction field was constructed.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"parent(a::FracElem)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Return the fraction field of the given fraction.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"characteristic(R::FracField)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Return the characteristic of the base ring of the fraction field. If the characteristic is not known an exception is raised.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = fraction_field(R)\nFraction field\n of univariate polynomial ring in x over rationals\n\njulia> f = S(x + 1)\nx + 1\n\njulia> U = base_ring(S)\nUnivariate polynomial ring in x over rationals\n\njulia> V = base_ring(f)\nUnivariate polynomial ring in x over rationals\n\njulia> T = parent(f)\nFraction field\n of univariate polynomial ring in x over rationals\n\njulia> m = characteristic(S)\n0","category":"page"},{"location":"AbstractAlgebra/fraction/#Fraction-field-functions","page":"Generic fraction fields","title":"Fraction field functions","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/#Basic-functions","page":"Generic fraction fields","title":"Basic functions","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Fraction fields implement the Ring interface.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"zero(R::FracField)\none(R::FracField)\niszero(a::FracElem)\nisone(a::FracElem)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"inv(a::T) where T <: FracElem","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"They also implement the field interface.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"is_unit(f::FracElem)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"And they implement the fraction field interface.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"numerator(a::FracElem)\ndenominator(a::FracElem)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = fraction_field(R)\nFraction field\n of univariate polynomial ring in x over rationals\n\njulia> f = S(x + 1)\nx + 1\n\njulia> g = (x^2 + x + 1)//(x^3 + 3x + 1)\n(x^2 + x + 1)//(x^3 + 3*x + 1)\n\njulia> h = zero(S)\n0\n\njulia> k = one(S)\n1\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> r = deepcopy(f)\nx + 1\n\njulia> n = numerator(g)\nx^2 + x + 1\n\njulia> d = denominator(g)\nx^3 + 3*x + 1","category":"page"},{"location":"AbstractAlgebra/fraction/#Greatest-common-divisor","page":"Generic fraction fields","title":"Greatest common divisor","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"gcd{T <: RingElem}(::FracElem{T}, ::FracElem{T})","category":"page"},{"location":"AbstractAlgebra/fraction/#gcd-Union{Tuple{T}, Tuple{FracElem{T}, FracElem{T}}} where T<:RingElem","page":"Generic fraction fields","title":"gcd","text":"gcd(a::FracElem{T}, b::FracElem{T}) where {T <: RingElem}\n\nReturn a greatest common divisor of a and b if one exists. N.B: we define the GCD of ab and cd to be gcd(ad bc)bd, reduced to lowest terms. This requires the existence of a greatest common divisor function for the base ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> f = (x + 1)//(x^3 + 3x + 1)\n(x + 1)//(x^3 + 3*x + 1)\n\njulia> g = (x^2 + 2x + 1)//(x^2 + x + 1)\n(x^2 + 2*x + 1)//(x^2 + x + 1)\n\njulia> h = gcd(f, g)\n(x + 1)//(x^5 + x^4 + 4*x^3 + 4*x^2 + 4*x + 1)\n","category":"page"},{"location":"AbstractAlgebra/fraction/#Square-root","page":"Generic fraction fields","title":"Square root","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"is_square{T <: RingElem}(::FracElem{T})","category":"page"},{"location":"AbstractAlgebra/fraction/#is_square-Union{Tuple{FracElem{T}}, Tuple{T}} where T<:RingElem","page":"Generic fraction fields","title":"is_square","text":"is_square(a::FracElem{T}) where T <: RingElem\n\nReturn true if a is a square.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Base.sqrt(::FracElem{T}) where {T <: RingElem}","category":"page"},{"location":"AbstractAlgebra/fraction/#sqrt-Union{Tuple{FracElem{T}}, Tuple{T}} where T<:RingElem","page":"Generic fraction fields","title":"sqrt","text":"Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = fraction_field(R)\nFraction field\n of univariate polynomial ring in x over rationals\n\njulia> a = (21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)\n(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)\n\njulia> sqrt(a^2)\n(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)\n\njulia> is_square(a^2)\ntrue","category":"page"},{"location":"AbstractAlgebra/fraction/#Remove-and-valuation","page":"Generic fraction fields","title":"Remove and valuation","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"When working over a Euclidean domain, it is convenient to extend valuations to the fraction field. To facilitate this, we define the following functions.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"remove{T <: RingElem}(::FracElem{T}, ::T)","category":"page"},{"location":"AbstractAlgebra/fraction/#remove-Union{Tuple{T}, Tuple{FracElem{T}, T}} where T<:RingElem","page":"Generic fraction fields","title":"remove","text":"remove(z::FracElem{T}, p::T) where {T <: RingElem}\n\nReturn the tuple n x such that z = p^nx where x has valuation 0 at p.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"valuation{T <: RingElem}(::FracElem{T}, ::T)","category":"page"},{"location":"AbstractAlgebra/fraction/#valuation-Union{Tuple{T}, Tuple{FracElem{T}, T}} where T<:RingElem","page":"Generic fraction fields","title":"valuation","text":"valuation(z::FracElem{T}, p::T) where {T <: RingElem}\n\nReturn the valuation of z at p.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> f = (x + 1)//(x^3 + 3x + 1)\n(x + 1)//(x^3 + 3*x + 1)\n\njulia> g = (x^2 + 1)//(x^2 + x + 1)\n(x^2 + 1)//(x^2 + x + 1)\n\njulia> v, q = remove(f^3*g, x + 1)\n(3, (x^2 + 1)//(x^11 + x^10 + 10*x^9 + 12*x^8 + 39*x^7 + 48*x^6 + 75*x^5 + 75*x^4 + 66*x^3 + 37*x^2 + 10*x + 1))\n\njulia> v = valuation(f^3*g, x + 1)\n3\n","category":"page"},{"location":"AbstractAlgebra/fraction/#Random-generation","page":"Generic fraction fields","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Random fractions can be generated using rand. The parameters passed after the fraction field tell rand how to generate random elements of the base ring.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"rand(R::FracField, v...)","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> K = fraction_field(ZZ)\nRationals\n\njulia> f = rand(K, -10:10)\n-1//3\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = fraction_field(R)\nFraction field\n of univariate polynomial ring in x over integers\n\njulia> g = rand(S, -1:3, -10:10)\n(-4*x - 4)//(4*x^2 + x - 4)","category":"page"},{"location":"AbstractAlgebra/fraction/#Extra-functionality-for-factored-fractions","page":"Generic fraction fields","title":"Extra functionality for factored fractions","text":"","category":"section"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"The Generic.FactoredFrac{T} type implements an interface similar to that of the Fac{T} type for iterating over the terms in the factorisation. There is also the function push_term!(a, b, e) for efficiently performing a *= b^e, and the function normalise returns relatively prime terms.","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/fraction/","page":"Generic fraction fields","title":"Generic fraction fields","text":"julia> F = FactoredFractionField(ZZ)\nFactored fraction field of Integers\n\njulia> f = F(-1)\n-1\n\njulia> push_term!(f, 10, 10)\n-10^10\n\njulia> push_term!(f, 42, -8)\n-10^10/42^8\n\njulia> normalise(f)\n-5^10*2^2/21^8\n\njulia> unit(f)\n-1\n\njulia> collect(f)\n2-element Vector{Tuple{BigInt, Int64}}:\n (10, 10)\n (42, -8)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/#Gröbner/Standard-Bases-Over-\\mathbb-Z","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"In this section, we consider a polynomial ring mathbb Zx = mathbb Zx_1 dots x_n over the integers. As in the previous section on Gröbner/standard bases over fields, let be a monomial ordering on textMon_n(x). With respect to this ordering, the localization mathbb Zx_ and, given a nonzero element f in mathbb Zx_, the notions leading term, leading monomial, leading exponent, leading coefficient, and tail of f are defined as before.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"note: Note\nOver mathbb Z, the basic idea of multivariate polynomial division with remainder in OSCAR is as follows: If ax^alpha is the leading term of the intermediate dividend, f_i is some divisor whose leading monomial equals x^alpha, say textLT(f_i) = bx^alpha, and r is the remainder of a on division by b in mathbb Z, then ax^alpha is replaced by rx^alpha.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/#Examples","page":"Gröbner/Standard Bases Over mathbb Z","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"]);\n\njulia> reduce(3*x, [2*x])\nx\n\njulia> reduce(6*x, [5*x, 2*x])\n0","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"The notion of leading ideals as formulated in the previous section and the definitions of standard bases (Gröbner bases) carry over: A standard basis for an ideal Isubset Kx_ with respect to is a finite subset G of I such that textL_(G) = textL_(I) (a standard basis with respect to a global monomial ordering is also called a Gröbner basis).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"There is, however, a sublety: Over a field, the defining condition of a standard basis as stated above is equivalent to saying that the textLT_(g), gin Gsetminus0 generate textL_(I). Over mathbb Z, the latter condition implies the former one, but not vice versa. Consequently, over mathbb Z, a finite subset G of I satisfying the latter condition is called a strong standard basis for I (with respect to ).","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"We refer to the textbook William W. Adams, Philippe Loustaunau (1994) for more on this.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"note: Note\nOver mathbb Z, the standard bases returned by OSCAR are strong in the sense above.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/#Examples-2","page":"Gröbner/Standard Bases Over mathbb Z","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases_integers/","page":"Gröbner/Standard Bases Over mathbb Z","title":"Gröbner/Standard Bases Over mathbb Z","text":"julia> R, (x,y) = polynomial_ring(ZZ, [\"x\",\"y\"])\n(Multivariate polynomial ring in 2 variables over ZZ, ZZMPolyRingElem[x, y])\n\njulia> I = ideal(R, [3*x^2*y+7*y, 4*x*y^2-5*x])\nideal(3*x^2*y + 7*y, 4*x*y^2 - 5*x)\n\njulia> G = groebner_basis(I, ordering = lex(R))\nGröbner basis with elements\n1 -> 28*y^3 - 35*y\n2 -> 4*x*y^2 - 5*x\n3 -> 15*x^2 + 28*y^2\n4 -> 3*x^2*y + 7*y\n5 -> x^2*y^2 - 5*x^2 - 7*y^2\nwith respect to the ordering\nlex([x, y])","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#Projective-Varieties","page":"Projective Varieties","title":"Projective Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"A projective variety over an algebraically closed field is an irreducible projective algebraic set. See Projective Algebraic Sets.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"In practice we work over non-closed fields. To be called a variety an algebraic set V must stay irreducible when viewed over the algebraic closure.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"In Oscar projective varieties are Projective schemes and more formally defined as follows.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"AbsProjectiveVariety","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#AbsProjectiveVariety","page":"Projective Varieties","title":"AbsProjectiveVariety","text":"AbsProjectiveVariety <: AbsProjectiveAlgebraicSet\n\nA geometrically integral subscheme of a projective space over a field.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#Constructors","page":"Projective Varieties","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"variety(I::MPolyIdeal{<:MPolyDecRingElem}; check::Bool=true)\nvariety(X::AbsProjectiveScheme{<:Field}; check::Bool=true)\nvariety(R::Ring; check::Bool=true)\nvariety(f::MPolyDecRingElem; check=true)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#variety-Tuple{MPolyIdeal{<:MPolyDecRingElem}}","page":"Projective Varieties","title":"variety","text":"variety(I::MPolyIdeal; is_prime::Bool, check::Bool=true) -> ProjectiveVariety\n\nReturn the projective variety defined by the homogeneous prime ideal I.\n\nSince in our terminology varieties are irreducible over the algebraic closure, we check that I stays prime when viewed over the algebraic closure. This is an expensive check that can be disabled. Note that the ideal I must live in a standard graded ring.\n\njulia> P3 = projective_space(QQ,3)\nProjective space of dimension 3\n over rational field\nwith homogeneous coordinates [s0, s1, s2, s3]\n\njulia> (s0,s1,s2,s3) = homogeneous_coordinates(P3);\n\njulia> X = variety(s0^3 + s1^3 + s2^3 + s3^3)\nProjective variety\n in projective 3-space over QQ with coordinates [s0, s1, s2, s3]\ndefined by ideal(s0^3 + s1^3 + s2^3 + s3^3)\n\njulia> dim(X)\n2\n\njulia> Y = variety(ideal([s0^3 + s1^3 + s2^3 + s3^3, s0]))\nProjective variety\n in projective 3-space over QQ with coordinates [s0, s1, s2, s3]\ndefined by ideal(s0, s1^3 + s2^3 + s3^3)\n\njulia> dim(Y)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#variety-Tuple{AbsProjectiveScheme{<:Field}}","page":"Projective Varieties","title":"variety","text":"variety(X::AbsProjectiveScheme; is_reduced::Bool=false, check::Bool=true) -> ProjectiveVariety\n\nConvert X to a projective variety by considering its reduced structure\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#variety-Tuple{Ring}","page":"Projective Varieties","title":"variety","text":"variety(R::GradedRing; check::Bool=true)\n\nReturn the projective variety defined by the mathbbZ standard graded ring R.\n\nWe require that R is a finitely generated algebra over a field k and moreover that the base change of R to the algebraic closure bar k is an integral domain.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#variety-Tuple{MPolyDecRingElem}","page":"Projective Varieties","title":"variety","text":"variety(f::MPolyDecRingElem; check=true)\n\nReturn the projective variety defined by the homogeneous polynomial f.\n\nThis checks that f is absolutely irreducible.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#Attributes","page":"Projective Varieties","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"So far all are inherited from Projective Algebraic Sets and Projective schemes.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#Properties","page":"Projective Varieties","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"So far all are inherited from Projective Algebraic Sets and Projective schemes.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#Methods","page":"Projective Varieties","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"So far all are inherited from Projective Algebraic Sets and Projective schemes.","category":"page"},{"location":"Hecke/features/macros/#Macros","page":"Macros","title":"Macros","text":"","category":"section"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"We describe here various macros provided by Hecke.","category":"page"},{"location":"Hecke/features/macros/#Verbosity-macros","page":"Macros","title":"Verbosity macros","text":"","category":"section"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"There is a list of symbols called verbosity scopes which represent keywords used to trigger some particular macros within the codes. Each of these verbosity scopes is associated with a verbosity level, being set to 0 by default. A verbosity macro is joined to a verbosity scope S and a value k (set to 1 by default) such that, if the current verbosity level l of S is bigger than or equal to k, then the macro triggers a given action.","category":"page"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"add_verbosity_scope(s::Symbol)\nset_verbosity_level(s::Symbol, l::Int)\nget_verbosity_level(s::Symbol)","category":"page"},{"location":"Hecke/features/macros/#add_verbosity_scope-Tuple{Symbol}","page":"Macros","title":"add_verbosity_scope","text":"add_verbosity_scope(s::Symbol) -> Nothing\n\nAdd the symbol s to the list of (global) verbosity scopes.\n\nExamples\n\njulia> add_verbosity_scope(:MyScope)\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/features/macros/#set_verbosity_level-Tuple{Symbol, Int64}","page":"Macros","title":"set_verbosity_level","text":"set_verbosity_level(s::Symbol, l::Int) -> Int\n\nIf s represents a known verbosity scope, set the current verbosity level of s to l.\n\nOne can access the current verbosity level of s by calling the function get_verbosity_level.\n\nIf s is not yet known as a verbosity scope, the function raises an ErrorException showing the error message \"Not a valid symbol\". One can add s to the list of verbosity scopes by calling the function add_verbosity_scope.\n\nExamples\n\njulia> add_verbosity_scope(:MyScope)\n\njulia> set_verbosity_level(:MyScope, 4)\n4\n\njulia> set_verbosity_level(:MyScope, 0)\n0\n\n\n\n\n\n","category":"method"},{"location":"Hecke/features/macros/#get_verbosity_level-Tuple{Symbol}","page":"Macros","title":"get_verbosity_level","text":"get_verbosity_level(s::Symbol) -> Int\n\nIf s represents a known verbosity scope, return the current verbosity level of s.\n\nOne can modify the current verbosity level of s by calling the function set_verbosity_level.\n\nIf s is not yet known as a verbosity scope, the function raises an ErrorException showing the error message \"Not a valid symbol\". One can add s to the list of verbosity scopes by calling the function add_verbosity_scope.\n\nExamples\n\njulia> add_verbosity_scope(:MyScope)\n\njulia> get_verbosity_level(:MyScope)\n0\n\njulia> set_verbosity_level(:MyScope, 4)\n4\n\njulia> get_verbosity_level(:MyScope)\n4\n\njulia> set_verbosity_level(:MyScope, 0)\n0\n\njulia> get_verbosity_level(:MyScope)\n0\n\n\n\n\n\n","category":"method"},{"location":"Hecke/features/macros/#Printings","page":"Macros","title":"Printings","text":"","category":"section"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"@vprintln\n@vprint","category":"page"},{"location":"Hecke/features/macros/#@vprintln","page":"Macros","title":"@vprintln","text":"@vprintln(S::Symbol, k::Int, msg::String)\n@vprintln S k msg\n\n@vprintln(S::Symbol, msg::String)\n@vprintln S msg\n\nThis macro can be used to control printings inside the code.\n\nThe macro @vprintln takes two or three arguments: a symbol S specifying a verbosity scope, an optional integer k and a string msg. If k is not specified, it is set by default to 1.\n\nTo each verbosity scope S is associated a verbosity level l which is cached. If the verbosity level l of S is bigger than or equal to k, the macro @vprintln triggers the printing of the associated string msg followed by a newline.\n\nOne can add a new verbosity scope by calling the function add_verbosity_scope.\n\nWhen starting a new instance, all the verbosity levels are set to 0. One can adjust the verbosity level of a verbosity scope by calling the function set_verbosity_level.\n\nOne can access the current verbosity level of a verbosity scope by calling the function get_verbosity_level.\n\nExamples\n\nWe will set up different verbosity scopes with different verbosity levels in a custom function to show how to use this macro.\n\njulia> add_verbosity_scope(:Test1);\n\njulia> add_verbosity_scope(:Test2);\n\njulia> add_verbosity_scope(:Test3);\n\njulia> set_verbosity_level(:Test1, 1);\n\njulia> set_verbosity_level(:Test2, 3);\n\njulia> function vprint_example()\n @vprintln :Test1 \"Triggered\"\n @vprintln :Test2 2 \"Triggered\"\n @vprintln :Test3 \"Not triggered\"\n @vprintln :Test2 4 \"Not triggered\"\n end\nvprint_example (generic function with 1 method)\n\njulia> vprint_example()\nTriggered\nTriggered\n\nIf one does not setup in advance a verbosity scope, the macro will raise an ExceptionError showing the error message \"Not a valid symbol\".\n\n\n\n\n\n","category":"macro"},{"location":"Hecke/features/macros/#@vprint","page":"Macros","title":"@vprint","text":"@vprint(S::Symbol, k::Int, msg::String)\n@vprint S k msg\n\n@vprint(S::Symbol, msg::String)\n@vprint S msg\n\nThe same as @vprintln, but without the final newline.\n\n\n\n\n\n","category":"macro"},{"location":"Hecke/features/macros/#Actions","page":"Macros","title":"Actions","text":"","category":"section"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"@v_do","category":"page"},{"location":"Hecke/features/macros/#@v_do","page":"Macros","title":"@v_do","text":"@v_do(S::Symbol, k::Int, act::Expr)\n@v_do S k act\n\n@v_do(S::Symbol, act::Expr)\n@v_do S act\n\nThis macro can be used to control actions inside the code.\n\nThe macro @v_do takes two or three arguments: a symbol S specifying a verbosity scope, an optional integer k and an action act. If k is not specified, it is set by default to 1.\n\nTo each verbosity scope S is associated a verbosity level l. If the verbosity level l of S is bigger than or equal to k, the macro @v_do triggers the action act.\n\nOne can add a new verbosity scope by calling the function add_verbosity_scope.\n\nWhen starting a new instance, all the verbosity levels are set to 0. One can adjust the verbosity level of a verbosity scope by calling the function set_verbosity_level.\n\nOne can access the current verbosity level of a verbosity scope by calling the function get_verbosity_level.\n\nExamples\n\nWe will set up different verbosity scopes with different verbosity levels in a custom function to show how to use this macro.\n\njulia> add_verbosity_scope(:Test1);\n\njulia> add_verbosity_scope(:Test2);\n\njulia> add_verbosity_scope(:Test3);\n\njulia> set_verbosity_level(:Test1, 1);\n\njulia> set_verbosity_level(:Test2, 3);\n\njulia> function v_do_example(a::Int, b::Int, c::Int, d::Int)\n @v_do :Test1 a = 2*a\n @v_do :Test2 2 b = 3*b\n @v_do :Test3 c = 4*c\n @v_do :Test2 4 d = 5*d\n return (a, b, c, d)\n end\nv_do_example (generic function with 1 method)\n\njulia> v_do_example(1,1,1,1)\n(2, 3, 1, 1)\n\nIf one does not setup in advance a verbosity scope, the macro will raise an ExceptionError showing the error message \"Not a valid symbol\".\n\n\n\n\n\n","category":"macro"},{"location":"Hecke/features/macros/#Assertion-macros","page":"Macros","title":"Assertion macros","text":"","category":"section"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"There is a list of symbols called assertion scopes which represent keywords used to trigger some particular macros within the codes. Each of these assertion scopes is associated with an assertion level, being set to 0 by default. An assertion macro is joined to an assertion scope S and a value k (set to 1 by default) such that, if the current assertion level l of S is bigger than or equal to k, then the macro triggers an action on the given assertion","category":"page"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"add_assertion_scope(s::Symbol)\nset_assertion_level(s::Symbol, l::Int)\nget_assertion_level(s::Symbol)","category":"page"},{"location":"Hecke/features/macros/#add_assertion_scope-Tuple{Symbol}","page":"Macros","title":"add_assertion_scope","text":"add_assertion_scope(s::Symbol) -> Nothing\n\nAdd the symbol s to the list of (global) assertion scopes.\n\nExamples\n\njulia> add_assertion_scope(:MyScope)\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/features/macros/#set_assertion_level-Tuple{Symbol, Int64}","page":"Macros","title":"set_assertion_level","text":"set_assertion_level(s::Symbol, l::Int) -> Int\n\nIf s represents a known assertion scope, set the current assertion level of s to l.\n\nOne can access the current assertion level of s by calling the function get_assertion_level.\n\nIf s is not yet known as an assertion scope, the function raises an ErrorException showing the error message \"Not a valid symbol\". One can add s to the list of assertion scopes by calling the function add_assertion_scope.\n\nExamples\n\njulia> add_assertion_scope(:MyScope)\n\njulia> set_assertion_level(:MyScope, 4)\n4\n\njulia> set_assertion_level(:MyScope, 0)\n0\n\n\n\n\n\n","category":"method"},{"location":"Hecke/features/macros/#get_assertion_level-Tuple{Symbol}","page":"Macros","title":"get_assertion_level","text":"get_assertion_level(s::Symbol) -> Int\n\nIf s represents a symbol of a known assertion scope, return the current assertion level of s.\n\nOne can modify the current assertion level of s by calling the function set_assertion_level.\n\nIf s is not yet known as an assertion scope, the function raises an ErrorException showing the error message \"Not a valid symbol\". One can add s to the list of assertion scopes by calling the function add_assertion_scope.\n\nExamples\n\njulia> add_assertion_scope(:MyScope)\n\njulia> get_assertion_level(:MyScope)\n0\n\njulia> set_assertion_level(:MyScope, 1)\n1\n\njulia> get_assertion_level(:MyScope)\n1\n\njulia> set_assertion_level(:MyScope, 0)\n0\n\njulia> get_assertion_level(:MyScope)\n0\n\n\n\n\n\n","category":"method"},{"location":"Hecke/features/macros/#Check","page":"Macros","title":"Check","text":"","category":"section"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"@hassert","category":"page"},{"location":"Hecke/features/macros/#@hassert","page":"Macros","title":"@hassert","text":"@hassert(S::Symbol, k::Int, assert::Expr)\n@hassert S k assert\n\n@hassert(S::Symbol, assert::Expr)\n@hassert S assert\n\nThis macro can be used to control assertion checks inside the code.\n\nThe macro @hassert takes two or three arguments: a symbol S specifying an assertion scope, an optional integer k and an assertion assert. If k is not specified, it is set by default to 1.\n\nTo each assertion scope S is associated an assertion level l which is cached. If the assertion level l of S is bigger than or equal to k, the macro @hassert triggers the check of the assertion assert. If assert is wrong, an AssertionError is thrown.\n\nOne can add a new assertion scope by calling the function add_assertion_scope.\n\nWhen starting a new instance, all the assertion levels are set to 0. One can adjust the assertion level of an assertion scope by calling the function set_assertion_level.\n\nOne can access the current assertion level of an assertion scope by calling the function get_assertion_level.\n\nExamples\n\nWe will set up different assertion scopes with different assertion levels in a custom function to show how to use this macro.\n\njulia> add_assertion_scope(:MyScope)\n\njulia> get_assertion_level(:MyScope)\n0\n\njulia> function hassert_test(x::Int)\n @hassert :MyScope 700 mod(x, 3) == 0\n return div(x, 3)\n end\nhassert_test (generic function with 1 method)\n\njulia> hassert_test(2)\n0\n\njulia> set_assertion_level(:MyScope, 701);\n\njulia> try hassert_test(2)\n catch e e\n end\nAssertionError(\"\\$(Expr(:escape, :(mod(x, 3) == 0)))\")\n\njulia> hassert_test(3)\n1\n\njulia> set_assertion_level(:MyScope, 0)\n0\n\nIf one does not setup in advance an assertion scope, the macro will raise an ExceptionError showing the error message \"Not a valid symbol\".\n\n\n\n\n\n","category":"macro"},{"location":"Hecke/features/macros/#Miscellaneous","page":"Macros","title":"Miscellaneous","text":"","category":"section"},{"location":"Hecke/features/macros/","page":"Macros","title":"Macros","text":"@req","category":"page"},{"location":"Hecke/features/macros/#@req","page":"Macros","title":"@req","text":"@req(assert, msg)\n@req assert msg\n\nCheck whether the assertion assert is true. If not, throw an ArgumentError with error message msg.\n\nThe macro @req takes two arguments: the first one is an assertion assert (an expression which returns a boolean) and a string msg corresponding to the desired error message to be returned whenever assert is false.\n\nIf the number of arguments is not 2, an AssertionError is raised.\n\nExamples\n\njulia> function req_test(x::Int)\n @req iseven(x) \"x must be even\"\n return div(x,2)\n end\nreq_test (generic function with 1 method)\n\njulia> try req_test(3)\n catch e e\n end\nArgumentError(\"x must be even\")\n\njulia> try req_test(2)\n catch e e\n end\n1\n\n\n\n\n\n\n","category":"macro"},{"location":"Hecke/misc/#Miscalleneous","page":"Miscalleneous","title":"Miscalleneous","text":"","category":"section"},{"location":"Hecke/misc/#Integer-related","page":"Miscalleneous","title":"Integer related","text":"","category":"section"},{"location":"Hecke/misc/","page":"Miscalleneous","title":"Miscalleneous","text":"euler_phi_inv\nHecke.modord(::ZZRingElem, ::ZZRingElem)\nHecke.is_prime_power(::ZZRingElem)\nHecke.primes_up_to(::Int)","category":"page"},{"location":"Hecke/misc/#euler_phi_inv","page":"Miscalleneous","title":"euler_phi_inv","text":"euler_phi_inv(n::Integer) -> Vector{ZZRingElem}\n\nThe inverse of the Euler totient functions: find all x s.th. phi(x) = n holds.\n\n\n\n\n\neuler_phi_inv(n::ZZRingElem) -> Vector{ZZRingElem}\n\nThe inverse of the Euler totient functions: find all x s.th. phi(x) = n holds.\n\n\n\n\n\neuler_phi_inv(n::ZZRingElem, zk::NfAbsOrd{AnticNumberField, nf_elem}) -> Vector{NfOrdIdl}\n\nThe inverse of the ideal totient function: all ideals A s.th. the unit group of the residue ring has the required size.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/#modord-Tuple{ZZRingElem, ZZRingElem}","page":"Miscalleneous","title":"modord","text":"modord(a::ZZRingElem, m::ZZRingElem) -> Int\nmodord(a::Integer, m::Integer)\n\nThe multiplicative order of a modulo m (not a good algorithm).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#is_prime_power-Tuple{ZZRingElem}","page":"Miscalleneous","title":"is_prime_power","text":"is_prime_power(n::ZZRingElem) -> Bool\nis_prime_power(n::Integer) -> Bool\n\nTests if n is the exact power of a prime number.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#primes_up_to-Tuple{Int64}","page":"Miscalleneous","title":"primes_up_to","text":"primes_up_to(n::Int) -> Vector{Int}\n\nReturns a vector containing all the prime numbers up to n.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#Analytic","page":"Miscalleneous","title":"Analytic","text":"","category":"section"},{"location":"Hecke/misc/","page":"Miscalleneous","title":"Miscalleneous","text":"dickman_rho\nHecke.psi_guess\nHecke.psi_lower","category":"page"},{"location":"Hecke/misc/#dickman_rho","page":"Miscalleneous","title":"dickman_rho","text":"dickman_rho(x::Number, prec::Int=55) Number\n\nEvaluates the Dickman-rho function at x.\n\n\n\n\n\ndickman_rho(x::Number, e::AbstractUnitRange{Int}, prec::Int=55) Number[]\n\nEvaluates the Dickman-rho function at i*x for all iin e.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/#psi_guess","page":"Miscalleneous","title":"psi_guess","text":"psi_guess(x::Number, B::Int) Number\n\nUses the dickman_rho function to estimate psi(x B) the number of B-smooth integers bounded by x.\n\n\n\n\n\npsi_guess(x::Number, e::AbstractUnitRange, B::Int) Number\n\nUses the dickman_rho function to estimate psi(x^i B) the number of B-smooth integers bounded by x^i for i in e.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/#psi_lower","page":"Miscalleneous","title":"psi_lower","text":"psi_lower(N::Integer, B::Int, a::Int = 776) -> Vector{Int}, ZZAbsPowerSeriesRingElem\npsi_lower(N::ZZRingElem, B::Int, a::Int = 776) -> Vector{Int}, ZZAbsPowerSeriesRingElem\n\nUses Bernstein's ideas: https://cr.yp.to/papers/psi.pdf to compute lower bounds on the psi function counting smooth numbers. An array L is returned s.th. psi(2^i-1 B) ge L_i for 1le ile rceil log_2(B)lceil. The second return value is Bernstein's power series.\n\nThe optional other parameter a controls the precision of the result, it defaults to 776.\n\n\n\n\n\npsi_lower(N::Integer, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem\npsi_lower(N::ZZRingElem, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem\n\npsi_upper(N::Integer, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem\npsi_upper(N::ZZRingElem, B::NfFactorBase) -> Vector{Int}, ZZAbsPowerSeriesRingElem\n\nUses Bernstein's techniques to bound the number of ideals A of norm bounded by N that are smooth over the factor base B.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/#Linear-Algebra","page":"Miscalleneous","title":"Linear Algebra","text":"","category":"section"},{"location":"Hecke/misc/","page":"Miscalleneous","title":"Miscalleneous","text":"Hecke.largest_elementary_divisor\nHecke.maximal_elementary_divisor(::ZZMatrix)\nHecke.mod_sym(::ZZMatrix, ::ZZRingElem)\nHecke.mod_sym!(::ZZMatrix, ::ZZRingElem)\nHecke.mod!(::ZZMatrix, ::ZZRingElem)\nHecke.saturate(::ZZMatrix)\nHecke.elementary_divisors(::ZZMatrix)\nHecke.jordan_normal_form\nHecke.divisors(::ZZMatrix, ::ZZRingElem)\nHecke.snf_with_transform(::ZZMatrix)","category":"page"},{"location":"Hecke/misc/#largest_elementary_divisor","page":"Miscalleneous","title":"largest_elementary_divisor","text":"largest_elementary_divisor(A::ZZMatrix) -> ZZRingElem\n\nThe largest elementary divisor of A, that is, the last diagonal entry of the Smith normal form of A.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/#maximal_elementary_divisor-Tuple{ZZMatrix}","page":"Miscalleneous","title":"maximal_elementary_divisor","text":"maximal_elementary_divisor(A::ZZMatrix) -> ZZRingElem\n\nThe largest elementary divisor of A, that is, the last diagonal entry of the Smith normal form of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#mod_sym-Tuple{ZZMatrix, ZZRingElem}","page":"Miscalleneous","title":"mod_sym","text":"mod_sym(M::ZZMatrix, p::ZZRingElem) -> ZZMatrix\n\nReduces every entry modulo p into the symmetric residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#mod_sym!-Tuple{ZZMatrix, ZZRingElem}","page":"Miscalleneous","title":"mod_sym!","text":"mod_sym!(M::ZZMatrix, p::ZZRingElem)\n\nReduces every entry modulo p in-place, into the symmetric residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#mod!-Tuple{ZZMatrix, ZZRingElem}","page":"Miscalleneous","title":"mod!","text":"mod!(M::ZZMatrix, p::ZZRingElem)\n\nReduces every entry modulo p in-place, i.e. applies the mod function to every entry. Positive residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#saturate-Tuple{ZZMatrix}","page":"Miscalleneous","title":"saturate","text":"saturate(A::ZZMatrix) -> ZZMatrix\n\nComputes the saturation of A, that is, a basis for mathbfQotimes M cap mathbfZ^n, where M is the row span of A and n the number of columns of A.\n\nEquivalently, return TA (minus zero rows) for an invertible rational matrix T such that TA is integral and the elementary divisors of TA are all trivial.\n\nExamples\n\njulia> saturate(ZZ[1 2 3;4 5 6;7 0 7])\n[1 2 3]\n[1 1 1]\n[0 -1 -1]\n\njulia> saturate(ZZ[1 2 3;4 5 6;7 8 9])\n[1 2 3]\n[1 1 1]\n\njulia> saturate(ZZ[1 2 3;4 5 6])\n[1 2 3]\n[1 1 1]\n\njulia> saturate(ZZ[1 2;3 4;5 6])\n[1 2]\n[1 1]\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#elementary_divisors-Tuple{ZZMatrix}","page":"Miscalleneous","title":"elementary_divisors","text":"elementary_divisors(A::ZZMatrix) -> Vector{ZZRingElem}\n\nThe elementary divisors of A, that is, the diagonal entries of the Smith normal form of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#jordan_normal_form","page":"Miscalleneous","title":"jordan_normal_form","text":"jordan_normal_form(M::MatElem{T}) where T <: FieldElem -> MatElem{T}, MatElem{T}\n\nReturns matrices J and S such that J = SMS^-1 and J is in Jordan normal form.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/#divisors-Tuple{ZZMatrix, ZZRingElem}","page":"Miscalleneous","title":"divisors","text":"divisors(A::ZZMatrix, d::ZZRingElem) -> ZZRingElem\n\nReturns the diagonal entries of a diagonal form of A. We assume that all the elementary divisors are divisors of d.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#snf_with_transform-Tuple{ZZMatrix}","page":"Miscalleneous","title":"snf_with_transform","text":"snf_with_transform(A::ZZMatrix, l::Bool = true, r::Bool = true) -> ZZMatrix, ZZMatrix, ZZMatrix\n\nGiven some integer matrix A, compute the Smith normal form (elementary divisor normal form) of A. If l and/ or r are true, then the corresponding left and/ or right transformation matrices are computed as well.\n\n\n\n\n\nsnf_with_transform(A)\n\nReturn the tuple S T U consisting of the Smith normal form S of A together with invertible matrices T and U such that TAU = S.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/misc/#Polynomials","page":"Miscalleneous","title":"Polynomials","text":"","category":"section"},{"location":"Hecke/misc/#CRT","page":"Miscalleneous","title":"CRT","text":"","category":"section"},{"location":"Hecke/misc/","page":"Miscalleneous","title":"Miscalleneous","text":"induce_crt\nHecke.induce_rational_reconstruction","category":"page"},{"location":"Hecke/misc/#induce_crt","page":"Miscalleneous","title":"induce_crt","text":"induce_crt(a::ZZPolyRingElem, p::ZZRingElem, b::ZZPolyRingElem, q::ZZRingElem, signed::Bool = false) -> ZZPolyRingElem\n\nGiven integral polynomials a and b as well as coprime integer moduli p and q, find f = a bmod p and f=b bmod q. If signed is set, the symmetric representative is used, the positive one otherwise.\n\n\n\n\n\ninduce_crt(L::Vector{PolyElem}, c::crt_env{ZZRingElem}) -> ZZPolyRingElem\n\nGiven ZZRingElem_poly polynomials Li and a crt\\_env, apply the crt function to each coefficient resulting in a polynomial f = Li bmod pi.\n\n\n\n\n\ninduce_crt(L::Vector{MatElem}, c::crt_env{ZZRingElem}) -> ZZMatrix\n\nGiven matrices Li and a crt\\_env, apply the crt function to each coefficient resulting in a matrix M = Li bmod pi.\n\n\n\n\n\ninduce_crt(a::Generic.Poly{nf_elem}, p::ZZRingElem, b::Generic.Poly{nf_elem}, q::ZZRingElem) -> Generic.Poly{nf_elem}, ZZRingElem\n\nGiven polynomials a defined modulo p and b modulo q, apply the CRT to all coefficients recursively. Implicitly assumes that a and b have integral coefficients (i.e. no denominators).\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/#induce_rational_reconstruction","page":"Miscalleneous","title":"induce_rational_reconstruction","text":"induce_rational_reconstruction(a::ZZPolyRingElem, M::ZZRingElem) -> QQPolyRingElem\n\nApply rational_reconstruction to each coefficient of a, resulting in either a fail (return (false, s.th.)) or (true, g) for some rational polynomial g s.th. g equiv a bmod M.\n\n\n\n\n\ninduce_rational_reconstruction(a::Generic.Poly{nf_elem}, M::ZZRingElem) -> bool, Generic.Poly{nf_elem}\n\nApply rational reconstruction to the coefficients of a. Implicitly assumes the coefficients to be integral (no checks done) returns true iff this is successful for all coefficients.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/number_fields/conventions/#Number-fields","page":"-","title":"Number fields","text":"","category":"section"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"By an absolute number field we mean finite extensions of mathbf Q, which is of type AnticNumberField and whose elements are of type nf_elem. Such an absolute number field K is always given in the form K = mathbf Q(alpha) = mathbf QX(f), where f in mathbf QX is an irreducible polynomial. See here for more information on the different types of fields supported.","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"We call (1alphaalpha^2dotscalpha^d-1), where d is the degree K mathbf Q the power basis of K. If beta is any element of K, then the representation matrix of beta is the matrix representing K to K gamma mapsto beta gamma with respect to the power basis, that is,","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"beta cdot (1alphadotscalpha^d-1) = M_alpha (1 alpha dotsc alpha^d-1)","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"Let (rs) be the signature of K, that is, K has r real embeddings sigma_i colon K to mathbfR, 1 leq i leq r, and 2s complex embeddings sigma_i colon K to mathbfC, 1 leq i leq 2s. In Hecke the complex embeddings are always ordered such that sigma_i = overlinesigma_i+s for r + 1 leq i leq r + s. The mathbfQ-linear function","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"begingather*\n K longrightarrow mathbf R^d \n alpha longmapsto Bigl( sigma_1(alpha) dotsc sigma_r(alpha) sqrt2operatornameRebigl(sigma_r+1(alpha)bigr) sqrt2operatornameImbigl(sigma_r+1(alpha)bigr) dotsc sqrt2operatornameRebigl(sigma_r+s(alpha)bigr) sqrt2operatornameImbigl(sigma_r+s(alpha)bigr) Bigr)\nendgather*","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"is called the Minkowski map (or Minkowski embedding).","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"If K = mathbf Q(alpha) is an absolute number field, then an order mathcal O of K is a subring of the ring of integers mathcal O_K, which is free of rank K mathbf Q as a mathbf Z-module. The natural order mathbf Zalpha is called the equation order of K. In Hecke orders of absolute number fields are constructed (implicitly) by specifying a mathbf Z-basis, which is referred to as the basis of mathcal O. If (omega_1dotscomega_d) is the basis of mathcal O, then the matrix B in operatornameMat_d times d(mathbf Q) with","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"is called the basis matrix of mathcal O. We call det(B) the generalized index of mathcal O. In case mathbf Zalpha subseteq mathcal O, the determinant det(B)^-1 is in fact equal to mathcal O mathbf Zalpha and is called the index of mathcal O. The matrix","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"beginpmatrix\nsigma_1(omega_1) dotsc sigma_r(omega_1) sqrt2operatornameRe(sigma_r+1(omega_1)) sqrt2operatornameIm(sigma_r+1(omega_1)) dotsc sqrt2operatornameIm(sigma_r+s(omega_1)) \nsigma_1(omega_2) dotsc sigma_r(omega_2) sqrt2operatornameRe(sigma_r+1(omega_2)) sqrt2operatornameIm(sigma_r+1(omega_2)) dotsc sqrt2operatornameIm(sigma_r+s(omega_2)) \nvdots ddots vdots vdots vdots ddots vdots\nsigma_1(omega_d) dotsc sigma_r(omega_d) sqrt2operatornameRe(sigma_r+1(omega_d)) sqrt2operatornameIm(sigma_r+2(omega_d)) dotsc sqrt2operatornameIm(sigma_r+s(omega_d))\nendpmatrix\nin operatornameMat_dtimes d(mathbf R)","category":"page"},{"location":"Hecke/number_fields/conventions/","page":"-","title":"-","text":"is called the Minkowski matrix of mathcal O.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#Architecture-of-affine-schemes","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#Requirements-on-rings-and-ideals","page":"Architecture of affine schemes","title":"Requirements on rings and ideals","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Any type of ring R to be used within the schemes framework must come with its own ideal type IdealType<:Ideal for which we require the following interface to be implemented:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" # constructor of ideals in R\n ideal(R::RingType, g::Vector{<:RingElem})::Ideal\n\n # constructor for quotient rings\n quo(R::RingType, I::IdealType)::Tuple{<:Ring, <:Map}\n\n # ideal membership test\n in(f::RingElem, I::IdealType)::Bool\n\n # a (fixed) set of generators\n gens(I::IdealType)::Vector{<:RingElem}\n\n # writing an element as linear combination of the generators\n coordinates(f::RingElem, I::IdealType)::Vector{<:RingElem}","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"The latter function must return a vector v = (a_1dots a_r) of elements in R such that f = a_1 cdot g_1 + dots + a_r cdot g_r where g_1dotsg_r is the set of gens(I). When f does not belong to I, it must error. Note that the ring returned by quo must again be admissible for the AbsSpec interface.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"With a view towards the use of the ambient_coordinate_ring(X) for computations, it is customary to also implement","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" saturated_ideal(I::IdealType)::MPolyIdeal","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"returning an ideal J in the ambient_coordinate_ring(X) with the property that a in I for some element a in R if and only if lifted_numerator(a) is in J.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#Interplay-between-ambient-coordinate-ring-and-coordinate-ring","page":"Architecture of affine schemes","title":"Interplay between ambient coordinate ring and coordinate ring","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Let X be an affine variety. In practice, all computations in the coordinate ring R = OO(X) will be deferred to computations in P = ambient_coordinate_ring(X) in one way or the other; this is another reason to include the ambient affine space in our abstract interface for affine schemes. In order to make the ambient_coordinate_ring(X) accessible for this purpose, we need the following methods to be implemented for elements ain R of type RingElemType:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" lifted_numerator(a::RingElemType)\n lifted_denominator(a::RingElemType)","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"These must return representatives of the numerator and the denominator of a. Note that the denominator is equal to one(P) in case R cong P or R cong PI.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Recall that the coordinates x_i of X are induced by the coordinates of the ambient affine space. Moreover, we will assume that for homomorphisms from R there is a method","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" hom(R::RingType, S::Ring, a::Vector{<:RingElem})","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"where RingType is the type of R and a the images of the coordinates x_i in S. This will be important when we come to morphisms of affine schemes below.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Algebraically speaking, embedding the affine scheme X = Spec(R) over 𝕜 into an affine space with coordinate ring P = 𝕜x₁xₙ corresponds to a morphism of rings P R with the property that for every other (commutative) ring S and any homomorphism φ R S there is a morphism ψ P S factoring through φ and such that φ is uniquely determined by ψ. Note that the morphism P R is induced by natural coercions.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#Existing-types-of-affine-schemes-and-how-to-derive-new-types","page":"Architecture of affine schemes","title":"Existing types of affine schemes and how to derive new types","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"The abstract type for affine schemes is","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" AbsSpec{BaseRingType, RingType<:Ring}","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#AbsSpec","page":"Architecture of affine schemes","title":"AbsSpec","text":"AbsSpec{BaseRingType, RingType<:Ring}\n\nAn affine scheme X = Spec(R) with R of type RingType over a ring 𝕜 of type BaseRingType.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"For any concrete instance of this type, we require the following functions to be implemented:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"base_ring(X::AbsSpec),\nOO(X::AbsSpec).","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"A concrete instance of this type is","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" Spec{BaseRingType, RingType}","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#Spec","page":"Architecture of affine schemes","title":"Spec","text":"Spec{BaseRingType, RingType}\n\nAn affine scheme X = Spec(R) with R a Noetherian ring of type RingType over a base ring 𝕜 of type BaseRingType.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"It provides an implementation of affine schemes for rings R of type MPolyRing, MPolyQuoRing, MPolyLocRing, and MPolyQuoLocRing defined over the integers or algebraic field extensions of mathbb Q. This minimal implementation can be used internally, when deriving new concrete types MySpec<:AbsSpec such as, for instance, group schemes, toric schemes, schemes of a particular dimension like curves and surfaces, etc. To this end, one has to store an instance Y of Spec in MySpec and implement the methods","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" underlying_scheme(X::MySpec)::Spec # return Y as above","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Then all methods implemented for Spec are automatically forwarded to any instance of MySpec.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Note: The above method necessarily returns an instance of Spec! Of course, it can be overwritten for any higher type MySpec<:AbsSpec as needed.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#Existing-types-of-affine-scheme-morphisms-and-how-to-derive-new-types","page":"Architecture of affine schemes","title":"Existing types of affine scheme morphisms and how to derive new types","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Any abstract morphism of affine schemes is of the following type:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" AbsSpecMor{DomainType<:AbsSpec,\n CodomainType<:AbsSpec,\n PullbackType<:Hecke.Map,\n MorphismType,\n BaseMorType\n }","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#AbsSpecMor","page":"Architecture of affine schemes","title":"AbsSpecMor","text":"AbsSpecMor{DomainType<:AbsSpec, \n CodomainType<:AbsSpec, \n PullbackType<:Hecke.Map,\n MorphismType, \n BaseMorType\n }\n\nAbstract type for morphisms f X Y of affine schemes where\n\nX = Spec(S) is of type DomainType, \nY = Spec(R) is of type CodomainType, \nf^* R S is a ring homomorphism of type PullbackType, \nf itself is of type MorphismType (required for the Map interface),\nif f is defined over a morphism of base schemes BX BY (e.g. a field extension), then this base scheme morphism is of type BaseMorType; otherwise, this can be set to Nothing.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Any such morphism has the attributes domain, codomain and pullback. A concrete and minimalistic implementation exist for the type SpecMor:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" SpecMor{DomainType<:AbsSpec,\n CodomainType<:AbsSpec,\n PullbackType<:Hecke.Map\n }","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/#SpecMor","page":"Architecture of affine schemes","title":"SpecMor","text":"SpecMor{DomainType<:AbsSpec, \n CodomainType<:AbsSpec, \n PullbackType<:Hecke.Map\n }\n\nA morphism f X Y of affine schemes X = Spec(S) of type DomainType and Y = Spec(R) of type CodomainType, both defined over the same base_ring, with underlying ring homomorphism f^* R S of type PullbackType.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"This basic functionality consists of","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"compose(f::AbsSpecMor, g::AbsSpecMor),\nidentity_map(X::AbsSpec),\nrestrict(f::AbsSpecMor, X::AbsSpec, Y::AbsSpec; check::Bool=true),\n==(f::AbsSpecMor, g::AbsSpecMor),\npreimage(f::AbsSpecMor, Z::AbsSpec).","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"In particular, for every concrete instance of a type MySpec<:AbsSpec that implements underlying_scheme, this basic functionality of SpecMor should run naturally.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"We may derive higher types of morphisms of affine schemes MySpecMor<:AbsSpecMor by storing an instance g of SpecMor inside an instance f of MySpecMor and implementing","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":" underlying_morphism(f::MySpecMor)::SpecMor # return g","category":"page"},{"location":"AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"For example, this allows us to define closed embeddings.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/ToricSchemes/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"One can associate to a toric variety a scheme. The resulting class of schemes then benefits from the functionality that is available both for toric varieties and for schemes.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/#Content","page":"Introduction","title":"Content","text":"","category":"section"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"We currently provide the following basic conversions:","category":"page"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"Turn an affine toric variety into an affine scheme.\nTurn a normal toric variety into a covered scheme.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"Some (but not yet all) of the toric functionality is available for the resulting toric schemes.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/#Status","page":"Introduction","title":"Status","text":"","category":"section"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"This project is experimental. This means that names of functions may change without being announced. In addition, the existing functionality has not yet been tested for a long time, and so may break unexpectedly.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/#Long-term-goals","page":"Introduction","title":"Long term goals","text":"","category":"section"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"We aim for a robust interface between toric varieties and schemes.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"Martin Bies,\nMatthias Zach.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Experimental/ToricSchemes/introduction/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Elliptic-Curves","page":"Elliptic Curves","title":"Elliptic Curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"An elliptic plane curve is a projective plane curve of degree 3 together with a point of the curve, called the base point. An operation of addition of points can be defined on elliptic curves.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Constructor","page":"Elliptic Curves","title":"Constructor","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"An elliptic curve is a subtype of the abstract type ProjectivePlaneCurve. To define an elliptic curve over a field, one can either give as input an equation and the point at infinity, or just an equation in Weierstrass form. In the latter case, the point at infinity is (0 1 0).","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"Considering elliptic curves over a ring is helpful in some primality proving test. We introduce here a structure of elliptic curve over a ring. In that case, we always assume the equation to be in Weierstrass form, with infinity point (0 1 0).","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"ProjEllipticCurve","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#ProjEllipticCurve","page":"Elliptic Curves","title":"ProjEllipticCurve","text":"ProjEllipticCurve{S}(eq::Oscar.MPolyDecRingElem{S}) where {S <: FieldElem}\nProjEllipticCurve(eq::Oscar.MPolyDecRingElem{S}, P::Oscar.Geometry.ProjSpcElem{S}) where {S <: FieldElem}\nProjEllipticCurve(eq::Oscar.MPolyDecRingElem{S}) where {S <: Nemo.ZZModRingElem}\n\nReturn the Projective Elliptic Curve defined by the equation eq, with P as infinity point. If no point is specified it is expected that eq is in Weierstrass form, and the infinity point is (0:1:0).\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> F = T(-x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3)\n-x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(-1), QQ(1), QQ(0)])\n(-1 : 1 : 0)\n\njulia> E1 = Oscar.ProjEllipticCurve(F, P)\nProjective elliptic curve defined by -x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3\n\njulia> E2 = Oscar.ProjEllipticCurve(T(y^2*z - x^3 - x*z^2))\nProjective elliptic curve defined by -x^3 - x*z^2 + y^2*z\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Points-on-Elliptic-Curves","page":"Elliptic Curves","title":"Points on Elliptic Curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"We define a specific structure for the points on an elliptic curve, on which the operation of addition and multiplication by an integer are defined.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"Point_EllCurve","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Point_EllCurve","page":"Elliptic Curves","title":"Point_EllCurve","text":"Point_EllCurve(E::ProjEllipticCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where {S <: FieldElem}\nPoint_EllCurve(E::ProjEllipticCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where {S <: Nemo.ZZModRingElem}\n\nCreate the point P on the elliptic curve E.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> E = Oscar.ProjEllipticCurve(T(y^2*z - x^3 + 2*x*z^2))\nProjective elliptic curve defined by -x^3 + 2*x*z^2 + y^2*z\n\njulia> PP = Oscar.proj_space(E)\nProjective space of dim 2 over Rational field\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP, [QQ(2), QQ(2), QQ(1)])\n(2 : 2 : 1)\n\njulia> Q = Oscar.Point_EllCurve(E, P)\n(2 : 2 : 1)\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Methods","page":"Elliptic Curves","title":"Methods","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"Most of the functions described for projective plane curves are also available for elliptic curves over a field. We describe here the functions which are specific to elliptic curves.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Basic-functions","page":"Elliptic Curves","title":"Basic functions","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"proj_space(E::ProjEllipticCurve{S}) where S <: FieldElem\nproj_space(P::Point_EllCurve{S}) where S <: FieldElem\ncurve(P::Point_EllCurve{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#proj_space-Union{Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"proj_space","text":"proj_space(E::ProjEllipticCurve{S}) where S <: FieldElem\n\nReturn the projective space to which the base point of the elliptic curve E belongs.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#proj_space-Union{Tuple{Oscar.PlaneCurveModule.Point_EllCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"proj_space","text":"proj_space(P::Point_EllCurve{S}) where S <: FieldElem\n\nReturn the projective space to which the point P belongs.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#curve-Union{Tuple{Oscar.PlaneCurveModule.Point_EllCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"curve","text":"curve(P::Point_EllCurve{S}) where S <: FieldElem\n\nReturn the curve on which the point P is considered.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"Addition and multiplication by an integer of a point on an elliptic curve can be performed using the usual symbols + and *.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Example","page":"Elliptic Curves","title":"Example","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"julia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> E = Oscar.ProjEllipticCurve(T(y^2*z - x^3 + 2*x*z^2))\nProjective elliptic curve defined by -x^3 + 2*x*z^2 + y^2*z\n\njulia> PP = Oscar.proj_space(E)\nProjective space of dim 2 over Rational field\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP, [QQ(2), QQ(2), QQ(1)])\n(2 : 2 : 1)\n\njulia> Q = Oscar.Point_EllCurve(E, P)\n(2 : 2 : 1)\n\njulia> Q+Q\n(9//4 : -21//8 : 1)\n\njulia> 3*Q\n(338 : 6214 : 1)\n","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Weierstrass-form","page":"Elliptic Curves","title":"Weierstrass form","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"weierstrass_form(E::ProjEllipticCurve{S}) where {S <: FieldElem}\ntoweierstrass(C::ProjPlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#weierstrass_form-Union{Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"weierstrass_form","text":"weierstrass_form(E::ProjEllipticCurve{S}) where {S <: FieldElem}\n\nReturn the equation of a projective elliptic curve defined by an equation in Weierstrass form and which is linearly equivalent to E.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> F = T(-x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3)\n-x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(-1), QQ(1), QQ(0)])\n(-1 : 1 : 0)\n\njulia> E = Oscar.ProjEllipticCurve(F, P)\nProjective elliptic curve defined by -x^3 - 3*x^2*y - 3*x*y^2 - x*z^2 - y^3 + y^2*z - y*z^2 - 4*z^3\n\njulia> Oscar.weierstrass_form(E)\n-x^3 - x*z^2 + y^2*z - 4*z^3\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#toweierstrass-Union{Tuple{S}, Tuple{ProjPlaneCurve{S}, Oscar.Geometry.ProjSpcElem{S}}} where S<:FieldElem","page":"Elliptic Curves","title":"toweierstrass","text":"toweierstrass(C::ProjPlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}) where S <: FieldElem\n\nGiven a smooth plane cubic projective curve C and a point P on the curve, return an elliptic curve birationally equivalent to C given by an equation in long Weierstrass form.\n\nExamples\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> PP = proj_space(QQ, 2)\n(Projective space of dim 2 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2]])\n\njulia> Q = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(-1), QQ(1), QQ(0)])\n(-1 : 1 : 0)\n\njulia> D = ProjPlaneCurve(T(-x^3 - 3*x^2*y + 2*x^2*z - 3*x*y^2 + 3*x*y*z - 4*x*z^2 - y^3 - y*z^2 + 6*z^3))\nProjective plane curve defined by -x^3 - 3*x^2*y + 2*x^2*z - 3*x*y^2 + 3*x*y*z - 4*x*z^2 - y^3 - y*z^2 + 6*z^3\n\njulia> Oscar.toweierstrass(D, Q)\n-x^3 - 2*x^2*z + x*y*z - 4*x*z^2 + y^2*z + 3*y*z^2 - 6*z^3\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Invariant-of-Elliptic-Curves,-torsion-points...","page":"Elliptic Curves","title":"Invariant of Elliptic Curves, torsion points...","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"discriminant(E::ProjEllipticCurve{S}) where S <: FieldElem\nj_invariant(E::ProjEllipticCurve{S}) where S <: FieldElem\nis_torsion_point(P::Point_EllCurve{QQFieldElem})\ntorsion_points_lutz_nagell(E::ProjEllipticCurve{QQFieldElem})\ntorsion_points_division_poly(E::ProjEllipticCurve{QQFieldElem})\norder(P::Point_EllCurve{QQFieldElem})","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#discriminant-Union{Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"discriminant","text":"discriminant(E::ProjEllipticCurve{S}) where S <: FieldElem\n\nReturn the discriminant of the projective elliptic curve E.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#j_invariant-Union{Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"j_invariant","text":"j_invariant(E::ProjEllipticCurve{S}) where S <: FieldElem\n\nReturn the j-invariant of the projective elliptic curve E.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#is_torsion_point-Tuple{Oscar.PlaneCurveModule.Point_EllCurve{QQFieldElem}}","page":"Elliptic Curves","title":"is_torsion_point","text":"is_torsion_point(P::Point_EllCurve{QQFieldElem})\n\nReturn whether the point P is a torsion point.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#torsion_points_lutz_nagell-Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{QQFieldElem}}","page":"Elliptic Curves","title":"torsion_points_lutz_nagell","text":"torsion_points_lutz_nagell(E::ProjEllipticCurve{QQFieldElem})\n\nReturn the rational torsion points of the elliptic curve E using the Lutz-Nagell theorem.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#torsion_points_division_poly-Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{QQFieldElem}}","page":"Elliptic Curves","title":"torsion_points_division_poly","text":"torsion_points_division_poly(E::ProjEllipticCurve{QQFieldElem})\n\nReturn the rational torsion points of a rational elliptic curve E using division polynomials.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#order-Tuple{Oscar.PlaneCurveModule.Point_EllCurve{QQFieldElem}}","page":"Elliptic Curves","title":"order","text":"order(P::Point_EllCurve{QQFieldElem})\n\nReturn the order of the point P or 0 if the order is infinite.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"The following functions are implemented for elliptic curves over finite fields:","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"rand(E::ProjEllipticCurve{S}) where S <: FieldElem\nlist_rand(E::ProjEllipticCurve, N::Int)\norder(E::ProjEllipticCurve{S}) where S <: FieldElem","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#rand-Union{Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"rand","text":"rand(E::ProjEllipticCurve{S}) where S <: FieldElem\n\nReturn a random point on the elliptic curve E defined over a finite field.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#list_rand-Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve, Int64}","page":"Elliptic Curves","title":"list_rand","text":"list_rand(E::ProjEllipticCurve, N::Int)\n\nReturn a list of N random points on the elliptic curve E defined over a finite field.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#order-Union{Tuple{Oscar.PlaneCurveModule.ProjEllipticCurve{S}}, Tuple{S}} where S<:FieldElem","page":"Elliptic Curves","title":"order","text":"order(E::ProjEllipticCurve{S}) where S <: FieldElem\n\nGiven an elliptic curve E over a finite field mathbf F, computes E(mathbf F).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"The addition of points is not well defined for projective elliptic curves over a ring, that's why this case has to be considered separately. The following methods can for example be used for teaching purposes to show the steps of the Elliptic Curve Method.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"sum_Point_EllCurveZnZ(P::Point_EllCurve{S}, Q::Point_EllCurve{S}) where S <: Nemo.ZZModRingElem\nIntMult_Point_EllCurveZnZ(m::ZZRingElem, P::Point_EllCurve{S}) where S <: Nemo.ZZModRingElem\nrand_pair_EllCurve_Point(R::Oscar.MPolyDecRing{S}, PP::Oscar.Geometry.ProjSpc{S}) where S <: Nemo.ZZModRingElem","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#sum_Point_EllCurveZnZ-Union{Tuple{S}, Tuple{Oscar.PlaneCurveModule.Point_EllCurve{S}, Oscar.PlaneCurveModule.Point_EllCurve{S}}} where S<:ZZModRingElem","page":"Elliptic Curves","title":"sum_Point_EllCurveZnZ","text":"sum_Point_EllCurveZnZ(P::Point_EllCurve{S}, Q::Point_EllCurve{S}) where S <: Nemo.ZZModRingElem\n\nReturn, if possible, the sum of the points P and Q, and an error otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#IntMult_Point_EllCurveZnZ-Union{Tuple{S}, Tuple{ZZRingElem, Oscar.PlaneCurveModule.Point_EllCurve{S}}} where S<:ZZModRingElem","page":"Elliptic Curves","title":"IntMult_Point_EllCurveZnZ","text":"IntMult_Point_EllCurveZnZ(m::ZZRingElem, P::Point_EllCurve{S}) where S <: Nemo.ZZModRingElem\n\nReturn, if possible, the point mP, and an error otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#rand_pair_EllCurve_Point-Union{Tuple{S}, Tuple{MPolyDecRing{S}, Oscar.Geometry.ProjSpc{S}}} where S<:ZZModRingElem","page":"Elliptic Curves","title":"rand_pair_EllCurve_Point","text":"rand_pair_EllCurve_Point(R::Oscar.MPolyDecRing{S}, PP::Oscar.Geometry.ProjSpc{S}) where S <: Nemo.ZZModRingElem\n\nReturn a pair composed of an elliptic plane curve E with equation in R, and a point P on E.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Primality-proving","page":"Elliptic Curves","title":"Primality proving","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Elliptic-Curve-Method","page":"Elliptic Curves","title":"Elliptic Curve Method","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"Projective elliptic curves over a ring are for example used in the Elliptic Curve Method. We give here an example (see Example 7.1 of Lawrence C. Washington (2008)) on how to use the previous functions to apply it. ","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"julia> n = 4453\n4453\n\njulia> A = residue_ring(ZZ, ZZ(n))\nIntegers modulo 4453\n\njulia> S, (x,y,z) = polynomial_ring(A, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over ZZ/(4453), AbstractAlgebra.Generic.MPoly{ZZModRingElem}[x, y, z])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 3 variables over ZZ/(4453), MPolyDecRingElem{ZZModRingElem, AbstractAlgebra.Generic.MPoly{ZZModRingElem}}[x, y, z])\n\njulia> E = Oscar.ProjEllipticCurve(T(y^2*z - x^3 - 10*x*z^2 + 2*z^3))\nProjective elliptic curve defined by 4452*x^3 + 4443*x*z^2 + y^2*z + 2*z^3\n\njulia> PP = proj_space(A, 2)\n(Projective space of dim 2 over Integers modulo 4453\n, MPolyDecRingElem{ZZModRingElem, AbstractAlgebra.Generic.MPoly{ZZModRingElem}}[x[0], x[1], x[2]])\n\njulia> Q = Oscar.Geometry.ProjSpcElem(PP[1], [A(1), A(3), A(1)])\n(1 : 3 : 1)\n\njulia> P = Oscar.Point_EllCurve(E, Q)\n(1 : 3 : 1)\n\njulia> P2 = Oscar.IntMult_Point_EllCurveZnZ(ZZ(2), P)\n(4332 : 3230 : 1)\n\njulia> Oscar.sum_Point_EllCurveZnZ(P, P2)\nERROR: 61 is not invertible in the base ring, cannot perform the sum\n","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"The last sum is not defined, and the error which is shown when we ask for the sum gives us a factor of 4453. The Elliptic Curve Method is implemented and can be called using:","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"ECM(n::ZZRingElem; nbcurve::Int = 25000, multfact::ZZRingElem = factorial(ZZ(10^4)))","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#ECM-Tuple{ZZRingElem}","page":"Elliptic Curves","title":"ECM","text":"ECM(n::ZZRingElem; nbcurve::Int = 25000, multfact::ZZRingElem = factorial(ZZ(10^4)))\n\nReturn a factor of n, obtained with the Elliptic Curve Method.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Elliptic-Curve-Primality-Proving","page":"Elliptic Curves","title":"Elliptic Curve Primality Proving","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"Elliptic curves over finite fields or rings are used for the method called \"Elliptic Curve Primality Proving\". We implemented here the version relying on Atkin-Morain's test. The present implementation is not intended to be competitive.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"ECPP(n::ZZRingElem)","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#ECPP-Tuple{ZZRingElem}","page":"Elliptic Curves","title":"ECPP","text":"ECPP(n::ZZRingElem)\n\nThe algorithm returns true if the number is prime, false if not, and an error if it can't decide.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Other-algorithms","page":"Elliptic Curves","title":"Other algorithms","text":"","category":"section"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"TODO: The following algorithms are not directly related to Plane Curves, they might be moved to another section of the documentation.","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/","page":"Elliptic Curves","title":"Elliptic Curves","text":"cornacchia_algorithm(d::ZZRingElem, m::ZZRingElem)\nMiller_Rabin_test(N::ZZRingElem, k::Int64 = 20)\nPollard_rho(N::ZZRingElem, bound::Int = 50000)\nPollard_p_1(N::ZZRingElem, B::ZZRingElem = ZZ(10)^5)","category":"page"},{"location":"Experimental/PlaneCurve/elliptic_curves/#cornacchia_algorithm-Tuple{ZZRingElem, ZZRingElem}","page":"Elliptic Curves","title":"cornacchia_algorithm","text":"cornacchia_algorithm(d::ZZRingElem, m::ZZRingElem)\n\nReturn true and a solution of x^2 + d*y^2 = m if it exists, and false and (0, 0) otherwise.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Miller_Rabin_test","page":"Elliptic Curves","title":"Miller_Rabin_test","text":"Miller_Rabin_test(N::ZZRingElem, k::Int64 = 20)\n\nGiven an odd number N, return false if the number is composite, and true if it is probably prime.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Pollard_rho","page":"Elliptic Curves","title":"Pollard_rho","text":"Pollard_rho(N::ZZRingElem, bound::Int = 50000)\n\nThe algorithm computes a factor of N using the Pollard rho algorithm and returns it.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/PlaneCurve/elliptic_curves/#Pollard_p_1","page":"Elliptic Curves","title":"Pollard_p_1","text":"Pollard_p_1(N::ZZRingElem, B::ZZRingElem = ZZ(10)^5)\n\nThe algorithm computes a factor of N and returns it.\n\n\n\n\n\n","category":"function"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/action/#Group-Actions","page":"Group Actions","title":"Group Actions","text":"","category":"section"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"A group action of a group G on a set Ω (from the right) is defined by a map μ: Ω × G → Ω that satisfies the compatibility conditions μ(μ(x, g), h) = μ(x, g*h) and μ(x, one(G)) == x for all x ∈ Ω.","category":"page"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"The maps μ are implemented as functions that take two arguments, an element x of Ω and a group element g, and return the image of x under g.","category":"page"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"In many cases, a natural action is given by the types of the elements in Ω and in G. For example permutation groups act on positive integers by just applying the permutations. In such situations, the function ^ can be used as action function, and ^ is taken as the default whenever no other function is prescribed.","category":"page"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"However, the action is not always determined by the types of the involved objects. For example, permutations can act on vectors of positive integers by applying the permutations pointwise, or by permuting the entries; matrices can act on vectors by multiplying the vector with the matrix, or by multiplying the inverse of the matrix with the vector; and of course one can construct new custom actions in situations where default actions are already available.","category":"page"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"Thus it is in general necessary to specify the action function explicitly, see the following sections.","category":"page"},{"location":"Groups/action/#Common-actions-of-group-elements","page":"Group Actions","title":"Common actions of group elements","text":"","category":"section"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"on_tuples\non_sets\npermuted\non_indeterminates","category":"page"},{"location":"Groups/action/#on_tuples","page":"Group Actions","title":"on_tuples","text":"on_tuples(tuple::GAP.GapObj, x::GAPGroupElem)\non_tuples(tuple::Vector, x::GAPGroupElem)\non_tuples(tuple::T, x::GAPGroupElem) where T <: Tuple\n\nReturn the image of tuple under x, where the action is given by applying ^ to the entries of tuple.\n\nFor Vector and Tuple objects, one can also call ^ instead of on_tuples.\n\nExamples\n\njulia> g = symmetric_group(3); g[1]\n(1,2,3)\n\njulia> l = GAP.GapObj([1, 2, 4])\nGAP: [ 1, 2, 4 ]\n\njulia> on_tuples(l, g[1])\nGAP: [ 2, 3, 4 ]\n\njulia> on_tuples([1, 2, 4], g[1])\n3-element Vector{Int64}:\n 2\n 3\n 4\n\njulia> on_tuples((1, 2, 4), g[1])\n(2, 3, 4)\n\njulia> (1, 2, 4)^g[1]\n(2, 3, 4)\n\n\n\n\n\n","category":"function"},{"location":"Groups/action/#on_sets","page":"Group Actions","title":"on_sets","text":"on_sets(set::GAP.GapObj, x::GAPGroupElem)\non_sets(set::Vector, x::GAPGroupElem)\non_sets(set::Tuple, x::GAPGroupElem)\non_sets(set::AbstractSet, x::GAPGroupElem)\n\nReturn the image of set under x, where the action is given by applying ^ to the entries of set, and then turning the result into a sorted vector/tuple or a set, respectively.\n\nFor Set objects, one can also call ^ instead of on_sets.\n\nExamples\n\njulia> g = symmetric_group(3); g[1]\n(1,2,3)\n\njulia> l = GAP.GapObj([1, 3])\nGAP: [ 1, 3 ]\n\njulia> on_sets(l, g[1])\nGAP: [ 1, 2 ]\n\njulia> on_sets([1, 3], g[1])\n2-element Vector{Int64}:\n 1\n 2\n\njulia> on_sets((1, 3), g[1])\n(1, 2)\n\njulia> on_sets(Set([1, 3]), g[1])\nSet{Int64} with 2 elements:\n 2\n 1\n\njulia> BitSet([1, 3])^g[1]\nBitSet with 2 elements:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"Groups/action/#permuted","page":"Group Actions","title":"permuted","text":"permuted(pnt::GAP.GapObj, x::PermGroupElem)\npermuted(pnt::Vector, x::PermGroupElem)\npermuted(pnt::Tuple, x::PermGroupElem)\n\nReturn the image of pnt under x, where the action is given by permuting the entries of pnt with x.\n\nExamples\n\njulia> g = symmetric_group(3); g[1]\n(1,2,3)\n\njulia> a = [\"a\", \"b\", \"c\"]\n3-element Vector{String}:\n \"a\"\n \"b\"\n \"c\"\n\njulia> permuted(a, g[1])\n3-element Vector{String}:\n \"c\"\n \"a\"\n \"b\"\n\njulia> permuted((\"a\", \"b\", \"c\"), g[1])\n(\"c\", \"a\", \"b\")\n\njulia> l = GAP.GapObj(a, recursive = true)\nGAP: [ \"a\", \"b\", \"c\" ]\n\njulia> permuted(l, g[1])\nGAP: [ \"c\", \"a\", \"b\" ]\n\n\n\n\n\n","category":"function"},{"location":"Groups/action/#on_indeterminates","page":"Group Actions","title":"on_indeterminates","text":"on_indeterminates(f::GAP.GapObj, p::PermGroupElem)\non_indeterminates(f::MPolyRingElem, p::PermGroupElem)\non_indeterminates(f::MPolyIdeal, p::PermGroupElem)\non_indeterminates(f::GAP.GapObj, p::MatrixGroupElem)\non_indeterminates(f::MPolyRingElem{T}, p::MatrixGroupElem{T, S}) where T where S\non_indeterminates(f::MPolyIdeal, p::MatrixGroupElem)\n\nReturn the image of f under p. If p is a PermGroupElem then it acts via permuting the indeterminates, if p is a MatrixGroupElem then it acts via evaluating f at the vector obtained by multiplying p with the (column) vector of indeterminates.\n\nFor MPolyRingElem and MPolyIdeal objects, one can also call ^ instead of on_indeterminates.\n\nExamples\n\njulia> g = symmetric_group(3); p = g[1]\n(1,2,3)\n\njulia> R, x = polynomial_ring(QQ, [\"x1\", \"x2\", \"x3\"]);\n\njulia> f = x[1]*x[2] + x[2]*x[3]\nx1*x2 + x2*x3\n\njulia> f^p\nx1*x3 + x2*x3\n\njulia> x = [GAP.Globals.X(GAP.Globals.Rationals, i) for i in 1:3];\n\njulia> f = x[1]*x[2] + x[2]*x[3]\nGAP: x_1*x_2+x_2*x_3\n\njulia> on_indeterminates(f, p)\nGAP: x_1*x_3+x_2*x_3\n\njulia> g = general_linear_group(2, 5); m = g[2]\n[4 1]\n[4 0]\n\njulia> R, x = polynomial_ring(base_ring(g), degree(g));\n\njulia> f = x[1]*x[2] + x[1]\nx1*x2 + x1\n\njulia> f^m\nx1^2 + 4*x1*x2 + 4*x1 + x2\n\n\n\n\n\n","category":"function"},{"location":"Groups/action/#G-Sets","page":"Group Actions","title":"G-Sets","text":"","category":"section"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"The idea behind G-sets is to have objects that encode the permutation action induced by a group (that need not be a permutation group) on a given set. A G-set provides an explicit bijection between the elements of the set and the corresponding set of positive integers on which the induced permutation group acts, see action_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup.","category":"page"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"gset(G::GAPGroup, fun::Function, Omega)\npermutation\naction_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup\norbit(Omega::GSetByElements{<:GAPGroup}, omega::T) where T\norbit(G::PermGroup, omega)\norbits(Omega::T) where T <: GSetByElements{TG} where TG <: GAPGroup","category":"page"},{"location":"Groups/action/#gset-Tuple{Oscar.GAPGroup, Function, Any}","page":"Group Actions","title":"gset","text":"gset(G::GAPGroup[, fun::Function], seeds, closed::Bool = false)\n\nReturn the G-set Omega that consists of the closure of the seeds seeds under the action of G defined by fun.\n\nThis means that Omega contains all elements fun(omega, g) for omega in seeds and g in G.\n\nfun can be omitted if the element type of seeds implies a reasonable default, for example, if G is a PermGroup and seeds is a Vector{T} where T is one of Int, Set{Int}, Vector{Int}.\n\nIf closed is set to true then seeds is assumed to be closed under the action of G. In this case, collect(Omega) is guaranteed to be equal to collect(seeds); in particular, the ordering of points in seeds (if applicable) is kept. Note that the indexing of points in Omega is used by action_homomorphism.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> length(gset(G, [[1]])) # natural action\n4\n\njulia> length(gset(G, [[1, 2]])) # action on ordered pairs\n12\n\njulia> length(gset(G, on_sets, [[1, 2]])) # action on unordered pairs\n6\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#permutation","page":"Group Actions","title":"permutation","text":"permutation(Omega::GSetByElements{T}, g::BasicGAPGroupElem{T}) where T<:GAPGroup\n\nReturn the element of the permutation group that describes the action of g on Omega, where g is an element of acting_group(Omega).\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> Omega = gset(G, [[1, 2]]);\n\njulia> x = gen(G, 1)\n(1,2,3,4)\n\njulia> permutation(Omega, x)\n(1,2,4,7)(3,6,9,12)(5,8,10,11)\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/action/#action_homomorphism-Union{Tuple{Oscar.GSetByElements{T}}, Tuple{T}} where T<:Oscar.GAPGroup","page":"Group Actions","title":"action_homomorphism","text":"action_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup\n\nReturn the group homomorphism act with domain G = acting_group(Omega) and codomain symmetric_group(n) that describes the permutation action of G on Omega, where Omega has n elements.\n\nThis means that if an element g in G maps collect(Omega)[i] to collect(Omega)[j] then act(g) maps i to j.\n\nExamples\n\njulia> G = symmetric_group(6);\n\njulia> Omega = gset(G, [Set([1, 2])]); # action on unordered pairs\n\njulia> acthom = action_homomorphism(Omega)\nGroup homomorphism from \nSym( [ 1 .. 6 ] )\nto\nSym( [ 1 .. 15 ] )\n\njulia> g = gen(G, 1)\n(1,2,3,4,5,6)\n\njulia> elms = collect(Omega);\n\njulia> actg = acthom(g)\n(1,2,3,5,7,10)(4,6,8,11,14,13)(9,12,15)\n\njulia> elms[1]^g == elms[2]\ntrue\n\njulia> 1^actg == 2\ntrue\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#orbit-Union{Tuple{T}, Tuple{Oscar.GSetByElements{<:Oscar.GAPGroup}, T}} where T","page":"Group Actions","title":"orbit","text":"orbit(Omega::GSet, omega::T) where T\n\nReturn the G-set that consists of the elements fun(omega, g) where g is in the group of Omega and fun is the underlying action of Omega.\n\nExamples\n\njulia> G = sylow_subgroup(symmetric_group(6), 2)[1]\nGroup([ (1,2), (3,4), (1,3)(2,4), (5,6) ])\n\njulia> Omega = gset(G, [1, 5]);\n\njulia> length(orbit(Omega, 1))\n4\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#orbit-Tuple{PermGroup, Any}","page":"Group Actions","title":"orbit","text":"orbit(G::GAPGroup[, fun::Function], omega)\n\nReturn the G-set that consists of the images of omega under the action of G defined by fun.\n\nThis means that the result contains all elements fun(omega, g) for g in G.\n\nfun can be omitted if the type of Omega implies a reasonable default, for example, if G is a PermGroup and omega is one of Int, Set{Int}, Vector{Int}.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> length(orbit(G, 1))\n4\n\njulia> length(orbit(G, [1, 2]))\n12\n\njulia> length(orbit(G, on_sets, [1, 2]))\n6\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#orbits-Union{Tuple{T}, Tuple{TG}} where {TG<:Oscar.GAPGroup, T<:Oscar.GSetByElements{TG}}","page":"Group Actions","title":"orbits","text":"orbits(Omega::GSet)\n\nReturn the vector of transitive G-sets in Omega.\n\nExamples\n\njulia> G = sylow_subgroup(symmetric_group(6), 2)[1]\nGroup([ (1,2), (3,4), (1,3)(2,4), (5,6) ])\n\njulia> orbs = orbits(gset(G));\n\njulia> map(collect, orbs)\n2-element Vector{Vector{Int64}}:\n [1, 2, 3, 4]\n [5, 6]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#Stabilizers","page":"Group Actions","title":"Stabilizers","text":"","category":"section"},{"location":"Groups/action/","page":"Group Actions","title":"Group Actions","text":"stabilizer(G::Oscar.GAPGroup, pnt::Any, actfun::Function)","category":"page"},{"location":"Groups/action/#stabilizer-Tuple{Oscar.GAPGroup, Any, Function}","page":"Group Actions","title":"stabilizer","text":"stabilizer(G::Oscar.GAPGroup, pnt::Any[, actfun::Function])\n\nReturn the subgroup of G that consists of all those elements g that fix pnt under the action given by actfun, that is, actfun(pnt, g) == pnt holds.\n\nThe default for actfun depends on the types of G and pnt: If G is a PermGroup then the default actions on integers, Vectors of integers, and Sets of integers are given by ^, on_tuples, and on_sets, respectively. If G is a MatrixGroup then the default actions on FreeModuleElems, Vectors of them, and Sets of them are given by *, on_tuples, and on_sets, respectively.\n\nExamples\n\njulia> G = symmetric_group(5);\n\njulia> S = stabilizer(G, 1); order(S[1])\n24\n\njulia> S = stabilizer(G, [1, 2]); order(S[1])\n6\n\njulia> S = stabilizer(G, Set([1, 2])); order(S[1])\n12\n\njulia> S = stabilizer(G, [1, 1, 2, 2, 3], permuted); order(S[1])\n4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"This page lists the OSCAR features for tropical geometry, which are still at the very beginning of their development. For notation we refer to Diane Maclagan, Bernd Sturmfels (2015) and Michael Joswig (2021).","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"Lars Kastner,\nMarta Panizzut,\nYue Ren.","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Tropical-semirings","page":"Introduction","title":"Tropical semirings","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"TropicalSemiring\nTropicalSemiringMap\ntropical_polynomial","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#TropicalSemiring","page":"Introduction","title":"TropicalSemiring","text":"TropicalSemiring(M::Union{typeof(min),typeof(max)}=min)\n\nThe tropical semiring with min (default) or max.\n\nwarning: Warning\nThere is no subtraction in the tropical semiring. Any subtraction of two tropical numbers will yield an error.\n\nExamples (basic arithmetic)\n\njulia> T = TropicalSemiring() # = TropicalSemiring(min)\nTropical semiring (min)\n\njulia> T = TropicalSemiring(max)\nTropical semiring (max)\n\njulia> 0*T(3) + 1*T(1)^2 + inf(T) # = max(0+3,1+2*1,-∞)\n(3)\n\njulia> T(0) == 0 # checks whether the tropical number is 0\ntrue\n\njulia> iszero(T(0)) # checks whether the tropical number is neutral element of addition\nfalse\n\nExamples (polynomials)\n\njulia> T = TropicalSemiring()\nTropical semiring (min)\n\njulia> Tx,(x1,x2) = polynomial_ring(T,3)\n(Multivariate polynomial ring in 3 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x1, x2, x3])\n\njulia> f = x1 + -1*x2 + 0\nx1 + (-1)*x2 + (0)\n\njulia> evaluate(f,[T(-1//2),T(1//2)]) # warning: omitting T(0) gives an error\n(-1//2)\n\nExamples (matrices)\n\njulia> T = TropicalSemiring()\nTropical semiring (min)\n\njulia> A = [T(0) inf(T); inf(T) T(0)] # = tropical identity matrix\n2×2 Matrix{Oscar.TropicalSemiringElem{typeof(min)}}:\n (0) ∞\n ∞ (0)\n\njulia> 2*A\n2×2 Matrix{Oscar.TropicalSemiringElem{typeof(min)}}:\n (2) ∞\n ∞ (2)\n\njulia> A*A\n2×2 Matrix{Oscar.TropicalSemiringElem{typeof(min)}}:\n (0) ∞\n ∞ (0)\n\njulia> det(A)\n(0)\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#TropicalSemiringMap","page":"Introduction","title":"TropicalSemiringMap","text":"TropicalSemiringMap(K,p,M::Union{typeof(min),typeof(max)}=min)\n\nConstructs a map val from K to the min tropical semiring T (default) or the max tropical semiring that:\n\nis a semigroup homomorphism (K,*) -> (T,+),\npreserves the ordering on both sides.\n\nIn other words, val is either a valuation on K with image in TropicalSemiring(min) or the negative of a valuation on K with image in TropicalSemiring(max).\n\nThe role of val is to encode with respect to which valuation on K and under which convention (min or max) tropical computations should take place.\n\nCurrently, the only supported valuations are:\n\nthe t-adic valuation on mathbbQ(t)\nthe p-adic valuations on mathbbQ\nthe trivial valuation on any field\n\nExamples\n\np-adic valuation on mathbbQ:\n\njulia> val_2 = TropicalSemiringMap(QQ,2); # = TropicalSemiringMap(QQ,2,min)\n\njulia> val_2(4)\n(2)\njulia> val_2(1//4)\n(-2)\njulia> val_2 = TropicalSemiringMap(QQ,2,max);\n\njulia> val_2(4)\n(-2)\njulia> val_2(1//4)\n(2)\n\nt-adic valuation on mathbbQ(t):\n\njulia> Kt,t = RationalFunctionField(QQ,\"t\");\n\njulia> val_t = TropicalSemiringMap(Kt,t);\n\njulia> val_t(t^2)\n(2)\njulia> val_t(1//t^2)\n(-2)\n\nTrivial valuation on mathbbQ:\n\njulia> val = TropicalSemiringMap(QQ);\n\njulia> val(4)\n(0)\njulia> val(1//4)\n(0)\njulia> val(0)\n∞\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#tropical_polynomial","page":"Introduction","title":"tropical_polynomial","text":"tropical_polynomial(f::MPolyRingElem,M::Union{typeof(min),typeof(max)}=min)\n\nGiven a polynomial f over a field with an intrinsic valuation (i.e., a field on which a function valuation is defined such as PadicField(7,2)), returns the tropicalization of f as a polynomial over the min tropical semiring (default) or the max tropical semiring.\n\nExamples\n\njulia> K = PadicField(7, 2)\nField of 7-adic numbers\n\njulia> Kxy, (x,y) = K[\"x\", \"y\"]\n(Multivariate polynomial ring in 2 variables over QQ_7, AbstractAlgebra.Generic.MPoly{padic}[x, y])\n\njulia> f = 7*x+y+49\n(7^1 + O(7^3))*x + y + 7^2 + O(7^4)\n\njulia> tropical_polynomial(f,min)\n(1)*x + y + (2)\n\njulia> tropical_polynomial(f,max)\n(-1)*x + y + (-2)\n\n\n\n\n\ntropical_polynomial(f::MPolyRingElem,val::TropicalSemiringMap)\n\nGiven a polynomial f and a tropical semiring map val, returns the tropicalization of f as a polynomial over the tropical semiring.\n\nExamples\n\njulia> R, (x,y) = polynomial_ring(QQ,[\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> val = TropicalSemiringMap(QQ,7)\nThe 7-adic valuation on Rational field\n\njulia> f = 7*x+y+49\n7*x + y + 49\n\njulia> tropical_polynomial(f,val)\n(1)*x + y + (2)\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Tropical-curves","page":"Introduction","title":"Tropical curves","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"(no functions yet, under active development)","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"TropicalCurve","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#TropicalCurve","page":"Introduction","title":"TropicalCurve","text":"TropicalCurve(PC::PolyhedralComplex)\n\nConstruct a tropical curve from a polyhedral complex. If the curve is embedded, vertices must are points in mathbb R^n. If the curve is abstract, the polyhedral complex is empty, vertices must be 1, ..., n, and the graph is given as attribute.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2],[1,3],[1,4]])\n3×4 IncidenceMatrix\n[1, 2]\n[1, 3]\n[1, 4]\n\n\njulia> VR = [0 0; 1 0; -1 0; 0 1]\n4×2 Matrix{Int64}:\n 0 0\n 1 0\n -1 0\n 0 1\n\njulia> PC = polyhedral_complex(QQFieldElem, IM, VR)\nPolyhedral complex in ambient dimension 2\n\njulia> TC = TropicalCurve(PC)\nmin tropical curve in 2-dimensional Euclidean space\n\njulia> abs_TC = TropicalCurve(IM)\nAbstract min tropical curve\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"in work: chip firing, jacobians.","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Tropical-hypersurfaces","page":"Introduction","title":"Tropical hypersurfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"TropicalHypersurface\ndual_subdivision(TH::TropicalHypersurface{M, EMB}) where {M, EMB}","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#TropicalHypersurface","page":"Introduction","title":"TropicalHypersurface","text":"TropicalHypersurface(f::AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{T}})\n\nReturn the tropical hypersurface of a tropical polynomial f.\n\nExamples\n\njulia> T = TropicalSemiring(min)\nTropical semiring (min)\n\njulia> Txy,(x,y) = T[\"x\",\"y\"]\n(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])\n\njulia> f = x+y+1\nx + y + (1)\n\njulia> Tf = TropicalHypersurface(f)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\n\n\n\n\nTropicalHypersurface(f::MPolyRingElem,M::Union{typeof(min),typeof(max)}=min)\n\nGiven a polynomial f over a field with an intrinsic valuation (i.e., a field on which a function valuation is defined such as PadicField(7,2)), return the tropical hypersurface of f under the convention specified by M.\n\nExamples\n\njulia> K = PadicField(7, 2);\n\njulia> Kxy, (x,y) = K[\"x\", \"y\"]\n(Multivariate polynomial ring in 2 variables over QQ_7, AbstractAlgebra.Generic.MPoly{padic}[x, y])\n\njulia> f = 7*x+y+49;\n\njulia> TropicalHypersurface(f, min)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> TropicalHypersurface(f, max)\nmax tropical hypersurface embedded in 2-dimensional Euclidean space\n\n\n\n\n\nTropicalHypersurface(f::MPolyRingElem,M::Union{typeof(min),typeof(max)}=min)\n\nConstruct the tropical hypersurface from a polynomial f and a map to the tropical semiring val.\n\nExamples\n\njulia> Kx, (x1,x2) = polynomial_ring(QQ,2)\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x1, x2])\n\njulia> val = TropicalSemiringMap(QQ,7)\nThe 7-adic valuation on Rational field\n\njulia> f = 7*x1+x2+49;\n\njulia> TropicalHypersurface(f, val)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#dual_subdivision-Union{Tuple{TropicalHypersurface{M, EMB}}, Tuple{EMB}, Tuple{M}} where {M, EMB}","page":"Introduction","title":"dual_subdivision","text":"dual_subdivision(TH::TropicalHypersurface{M, EMB})\n\nReturn the dual subdivision of TH if it is embedded. Otherwise an error is thrown.\n\nExamples\n\nA tropical hypersurface in mathbbR^n is always of dimension n-1.\n\njulia> T = TropicalSemiring(min);\n\njulia> Txy,(x,y) = T[\"x\",\"y\"];\n\njulia> f = x+y+1;\n\njulia> tropicalLine = TropicalHypersurface(f);\n\njulia> dual_subdivision(tropicalLine)\nSubdivision of points in ambient dimension 3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"in work: minimal tropical polynomials of a hypersurface.","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Tropical-linear-spaces","page":"Introduction","title":"Tropical linear spaces","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"TropicalLinearSpace","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#TropicalLinearSpace","page":"Introduction","title":"TropicalLinearSpace","text":"TropicalLinearSpace(I::MPolyIdeal, val::TropicalSemiringMap)\n\nConstruct a tropical linear space from a degree 1 polynomial ideal I and a map to the tropical semiring val.\n\nExamples\n\njulia> R,(x1,x2,x3,x4,x5,x6) = polynomial_ring(ZZ,6)\n(Multivariate polynomial ring in 6 variables over ZZ, ZZMPolyRingElem[x1, x2, x3, x4, x5, x6])\n\njulia> I = ideal(R,[-x1+x3+x4,-x2+x3+x5,-x1+x2+x6])\nideal(-x1 + x3 + x4, -x2 + x3 + x5, -x1 + x2 + x6)\n\njulia> val = TropicalSemiringMap(ZZ)\nThe trivial valuation on Integer Ring\n\njulia> TropicalLinearSpace(I,val)\nTropicalLinearSpace{min, true}(Polyhedral complex in ambient dimension 6, #undef)\n\n\n\n\n\nTropicalLinearSpace(A::MatElem,val::TropicalSemiringMap)\n\nConstruct a tropical linear space from a matrix A and a map to the tropical semiring val.\n\nExamples\n\njulia> Kt, t = RationalFunctionField(QQ,\"t\");\n\njulia> val = TropicalSemiringMap(Kt,t);\n\njulia> A = matrix(Kt,[[t,4*t,0,2],[1,4,1,t^2]]);\n\njulia> TropicalLinearSpace(A, val)\nTropicalLinearSpace{min, true}(Polyhedral complex in ambient dimension 4, #undef)\n\njulia> p = 3;\n\njulia> val = TropicalSemiringMap(QQ, p);\n\njulia> A = matrix(QQ, [[3,7,5,1], [9,7,1,2]])\n[3 7 5 1]\n[9 7 1 2]\n\njulia> TropicalLinearSpace(A,val)\nTropicalLinearSpace{min, true}(Polyhedral complex in ambient dimension 4, #undef)\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Tropical-varieties","page":"Introduction","title":"Tropical varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"(no functions yet, under active development)","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"in work: tropical_variety(I::MPolyIdeal,val::TropicalSemiringMap)","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Groebner-bases-and-Groebner-polyhedra","page":"Introduction","title":"Groebner bases and Groebner polyhedra","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"groebner_basis(I::MPolyIdeal,val::TropicalSemiringMap,w::Vector{<: Union{Int,Rational{Int}} }; complete_reduction::Bool=false, return_lead::Bool=false)","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#groebner_basis-Tuple{MPolyIdeal, TropicalSemiringMap, Vector{<:Union{Rational{Int64}, Int64}}}","page":"Introduction","title":"groebner_basis","text":"groebner_basis(I::Ideal, val::TropicalSemiringMap, w::Vector; complete_reduction::Bool, return_lead::Bool)\n\nCompute a Groebner basis of I over a field with valuation val with respect to weight vector w, that is a finite generating set of I whose initial forms generate the initial ideal with respect to w.\n\nFor the definitions of initial form, initial ideal and Groebner basis see Section 2.4 of Diane Maclagan, Bernd Sturmfels (2015).\n\nwarning: Warning\nGroebner bases over fields with valuation are still in an experimental stage. I must be generated by homogeneous polynomials and val must be non-trivial.\n\nExamples\n\njulia> R,(x,y) = polynomial_ring(QQ,[\"x\",\"y\"]);\n\njulia> I = ideal([x^3-5*x^2*y,3*y^3-2*x^2*y])\nideal(x^3 - 5*x^2*y, -2*x^2*y + 3*y^3)\n\njulia> val_2 = TropicalSemiringMap(QQ,2);\n\njulia> w = [0,0];\n\njulia> groebner_basis(I,val_2,w)\n5-element Vector{QQMPolyRingElem}:\n 2*x^2*y - 3*y^3\n x^3 - 5*x^2*y\n x*y^3 - 5*y^4\n y^5\n x^2*y^3 + 69*y^5\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"in work: groebner_polyhedron(I::MPolyIdeal,val::TropicalSemiringMap,w::Vector{<: Union{Int,Rational{Int}})","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#Intersections-and-stable-intersections","page":"Introduction","title":"Intersections and stable intersections","text":"","category":"section"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"intersect(T1::TropicalVarietySupertype{M, EMB}, T2::TropicalVarietySupertype{M, EMB}) where {M, EMB}\nstably_intersect(T1::TropicalVarietySupertype{M, EMB}, T2::TropicalVarietySupertype{M, EMB}) where {M, EMB}","category":"page"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#intersect-Union{Tuple{EMB}, Tuple{M}, Tuple{Oscar.TropicalVarietySupertype{M, EMB}, Oscar.TropicalVarietySupertype{M, EMB}}} where {M, EMB}","page":"Introduction","title":"intersect","text":"intersect(T1, T2)\n\nIntersect two tropical varieties.\n\nExamples\n\njulia> RR = TropicalSemiring(min)\nTropical semiring (min)\n\njulia> S,(x,y) = RR[\"x\",\"y\"]\n(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])\n\njulia> f1 = x+y+1\nx + y + (1)\n\njulia> f2 = x^2+y^2+RR(-6)\nx^2 + y^2 + (-6)\n\njulia> hyp1 = TropicalHypersurface(f1)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> hyp2 = TropicalHypersurface(f2)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> tv12 = intersect(hyp1, hyp2)\nmin tropical variety of dimension 1 embedded in 2-dimensional Euclidean space\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/TropicalGeometry/intro/#stably_intersect-Union{Tuple{EMB}, Tuple{M}, Tuple{Oscar.TropicalVarietySupertype{M, EMB}, Oscar.TropicalVarietySupertype{M, EMB}}} where {M, EMB}","page":"Introduction","title":"stably_intersect","text":"intersect_stably(T1, T2)\n\nExamples\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/finite_fields/#Elliptic-curves-over-finite-fields","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"","category":"section"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/#Random-points","page":"Elliptic curves over finite fields","title":"Random points","text":"","category":"section"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":" rand(E::EllCrv{<: FinFieldElem})","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"Return a random point on the elliptic curve E defined over a finite field.","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"julia> E = elliptic_curve(GF(3), [1, 2]);\n\njulia> rand(E)\nPoint (2 : 0 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/#Cardinality-and-orders","page":"Elliptic curves over finite fields","title":"Cardinality and orders","text":"","category":"section"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"order(::EllCrv{<:FinFieldElem})\norder(::EllCrvPt{<:FinFieldElem})","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/#order-Tuple{EllCrv{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"order","text":"order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion\n\nReturn the order of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> order(cycle_structure(x)) == order(x), gens(g))\ntrue\n\n\n\n\n\norder(E::EllCrv{<: FinFieldElem}) -> ZZRingElem\n\nGiven an elliptic curve E over a finite field mathbf F, compute E(mathbf F).\n\nExamples\n\njulia> E = elliptic_curve(GF(101), [1, 2]);\n\njulia> order(E)\n100\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/finite_fields/#order-Tuple{EllCrvPt{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"order","text":"order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion\n\nReturn the order of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> order(cycle_structure(x)) == order(x), gens(g))\ntrue\n\n\n\n\n\norder(P::EllCrvPt, [fac::Fac{ZZRingElem}]) -> ZZRingElem\n\nGiven a point P on an elliptic curve E over a finite field, return the order of this point.\n\nOptionally, one can supply the factorization of a multiple of the point order, for example the order of E.\n\nExamples\n\njulia> E = elliptic_curve(GF(101), [1, 2]);\n\njulia> P = E([17, 65]);\n\njulia> order(P)\n100\n\njulia> fac = factor(order(E))\n1 * 5^2 * 2^2\n\njulia> order(P, fac)\n100\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/finite_fields/#Frobenius","page":"Elliptic curves over finite fields","title":"Frobenius","text":"","category":"section"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"trace_of_frobenius(::EllCrv{<:FinFieldElem})\ntrace_of_frobenius(::EllCrv{<:FinFieldElem}, ::Int)","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/#trace_of_frobenius-Tuple{EllCrv{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"trace_of_frobenius","text":"trace_of_frobenius(E::EllCrv{FinFieldElem}) -> Int\n\nReturn the trace of the Frobenius endomorphism on the elliptic curve E over mathbfF_q. This is equal to q + 1 - n where n is the number of points on E over mathbfF_q.\n\nExamples\n\njulia> E = elliptic_curve(GF(101), [1, 2]);\n\njulia> trace_of_frobenius(E) == 101 + 1 - order(E)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/finite_fields/#trace_of_frobenius-Tuple{EllCrv{<:FinFieldElem}, Int64}","page":"Elliptic curves over finite fields","title":"trace_of_frobenius","text":"trace_of_frobenius(E::EllCrv{<: FinFieldElem}, r::Int) -> ZZRingElem\n\nReturn the trace of the r-th power of the Frobenius endomorphism on the elliptic curve E.\n\njulia> E = elliptic_curve(GF(101, 2), [1, 2]);\n\njulia> trace_of_frobenius(E, 2)\n18802\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/finite_fields/#Group-structure-of-rational-points","page":"Elliptic curves over finite fields","title":"Group structure of rational points","text":"","category":"section"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"gens(::EllCrv{T}) where {T <: FinFieldElem}\nabelian_group(::EllCrv{<:FinFieldElem})","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/#gens-Union{Tuple{EllCrv{T}}, Tuple{T}} where T<:FinFieldElem","page":"Elliptic curves over finite fields","title":"gens","text":"gens(E::EllCrv{<:FinFieldElem}) -> Vector{EllCrvPt}\n\nReturn a list of generators of the group of rational points on E.\n\nExamples\n\njulia> E = elliptic_curve(GF(101, 2), [1, 2]);\n\njulia> gens(E)\n2-element Vector{EllCrvPt{fqPolyRepFieldElem}}:\n Point (93*o + 10 : 22*o + 69 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n Point (89*o + 62 : 14*o + 26 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\njulia> E = elliptic_curve(GF(101), [1, 2]);\n\njulia> gens(E)\n1-element Vector{EllCrvPt{fpFieldElem}}:\n Point (50 : 69 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/finite_fields/#abelian_group-Tuple{EllCrv{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"abelian_group","text":"abelian_group(E::EllCrv{<:FinFieldElem}) -> GrpAbFinGen, Map\n\nReturn an abelian group A isomorphic to the group of rational points of E and a map E to A.\n\nwarning: Warning\nThe map is not implemented yet.\n\njulia> E = elliptic_curve(GF(101, 2), [1, 2]);\n\njulia> A, _ = abelian_group(E);\n\njulia> A\nGrpAb: Z/2 x Z/5200\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/finite_fields/#Discrete-logarithm","page":"Elliptic curves over finite fields","title":"Discrete logarithm","text":"","category":"section"},{"location":"Hecke/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"disc_log(::EllCrvPt, ::EllCrvPt)","category":"page"},{"location":"Hecke/elliptic_curves/finite_fields/#disc_log-Tuple{EllCrvPt, EllCrvPt}","page":"Elliptic curves over finite fields","title":"disc_log","text":"disc_log(P::EllCrvPt, Q::EllCrvPt, [n::IntegerUnion]) -> ZZRingElem\n\nReturn the discrete logarithm m of Q with respect to the base P, that is, mP = Q.\n\nIf a multiple n of the order of P is known, this can be supplied as an optional argument.\n\njulia> E = elliptic_curve(GF(101), [1, 2]);\n\njulia> P = E([6, 74])\nPoint (6 : 74 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\njulia> Q = E([85, 43])\nPoint (85 : 43 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\njulia> disc_log(P, Q)\n13\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Free-Modules","page":"Free Modules","title":"Free Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"In this section, the expression free module refers to a free module of finite rank over a ring of type MPolyRing, MPolyQuoRing, MPolyLocRing, or MPolyQuoLocRing. More concretely, given a ring R of one of these types, the free R-modules considered are of type R^p, where we think of R^p as a free module with a given basis, namely the basis of standard unit vectors. Accordingly, elements of free modules are represented by coordinate vectors, and homomorphisms between free modules by matrices.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"note: Note\nBy convention, vectors are row vectors, and matrices operate by multiplication on the right.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Types","page":"Free Modules","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"All OSCAR types for the modules considered here belong to the abstract type ModuleFP{T}, where T is the element type of the underlying ring. Graded or not, the free modules belong to the abstract subtype AbstractFreeMod{T} <: ModuleFP{T}, they are modelled as objects of the concrete type FreeMod{T} <: AbstractFreeMod{T}.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"note: Note\nCanonical maps such us the canonical projection onto a quotient module arise in many constructions in commutative algebra. The FreeMod type is designed so that it allows for the caching of such maps when executing functions. The direct_sum function discussed in this section provides an example.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Constructors","page":"Free Modules","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"free_module(R::MPolyRing, n::Int, name::VarName = :e; cached::Bool = false)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#free_module","page":"Free Modules","title":"free_module","text":"free_module(R::MPolyRing, p::Int, name::VarName = :e; cached::Bool = false)\nfree_module(R::MPolyQuoRing, p::Int, name::VarName = :e; cached::Bool = false)\nfree_module(R::MPolyLocRing, p::Int, name::VarName = :e; cached::Bool = false)\nfree_module(R::MPolyQuoLocRing, p::Int, name::VarName = :e; cached::Bool = false)\n\nReturn the free R-module R^p, created with its basis of standard unit vectors.\n\nThe string name specifies how the basis vectors are printed. \n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> FR = free_module(R, 2)\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> x*FR[1]\nx*e[1]\n\njulia> P = ideal(R, [x, y, z]);\n\njulia> U = complement_of_prime_ideal(P);\n\njulia> RL, _ = Localization(R, U);\n\njulia> FRL = free_module(RL, 2, \"f\")\nFree module of rank 2 over Localization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal\n\njulia> RL(x)*FRL[1]\nx*f[1]\n\njulia> RQ, _ = quo(R, ideal(R, [2*x^2-y^3, 2*x^2-y^5]));\n\njulia> FRQ = free_module(RQ, 2, \"g\")\nFree module of rank 2 over RQ\n\njulia> RQ(x)*FRQ[1]\nx*g[1]\n\njulia> RQL, _ = Localization(RQ, U);\n\njulia> FRQL = free_module(RQL, 2, \"h\")\nFree module of rank 2 over Localization of quotient of multivariate polynomial ring at complement of prime ideal\n\njulia> RQL(x)*FRQL[1]\nx*h[1]\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"Over graded multivariate polynomial rings and their quotients, there are two basic ways of creating graded free modules: While the grade function allows one to create a graded free module by assigning a grading to a free module already constructed, the graded_free_module function is meant to create a graded free module all at once.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"grade(F::FreeMod, W::Vector{GrpAbFinGenElem})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#grade-Tuple{FreeMod, Vector{GrpAbFinGenElem}}","page":"Free Modules","title":"grade","text":"grade(F::FreeMod, W::Vector{GrpAbFinGenElem})\n\nGiven a free module F over a graded ring with grading group G, say, and given a vector W of ngens(F) elements of G, create a G-graded free module by assigning the entries of W as weights to the generators of F. Return the new module. \n\ngrade(F::FreeMod)\n\nAs above, with all weights set to zero(G).\n\nnote: Note\nThe function applies to free modules over both graded multivariate polynomial rings and their quotients.\n\nExamples\n\njulia> R, x, y = polynomial_ring(QQ, \"x\" => 1:2, \"y\" => 1:3);\n\njulia> G = abelian_group([0, 0])\nGrpAb: Z^2\n\njulia> g = gens(G)\n2-element Vector{GrpAbFinGenElem}:\n Element of G with components [1 0]\n Element of G with components [0 1]\n\njulia> W = [g[1], g[1], g[2], g[2], g[2]];\n\njulia> S, _ = grade(R, W)\n(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], y[1], y[2], y[3]])\n\njulia> F = free_module(S, 3)\nFree module of rank 3 over S\n\njulia> FF = grade(F)\nGraded free module S^3([0 0]) of rank 3 over S\n\njulia> F\nFree module of rank 3 over S\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"grade(F::FreeMod, W::Vector{<:Vector{<:IntegerUnion}})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#grade-Tuple{FreeMod, Vector{<:Vector{<:Union{Integer, ZZRingElem}}}}","page":"Free Modules","title":"grade","text":"grade(F::FreeMod, W::Vector{<:Vector{<:IntegerUnion}})\n\nGiven a free module F over a graded ring with grading group G = mathbb Z^m, and given a vector W of ngens(F) integer vectors of the same size m, say, define a G-grading on F by converting the vectors in W to elements of G, and assigning these elements as weights to the variables. Return the new module.\n\ngrade(F::FreeMod, W::Union{ZZMatrix, Matrix{<:IntegerUnion}})\n\nAs above, converting the columns of W.\n\ngrade(F::FreeMod, W::Vector{<:IntegerUnion})\n\nGiven a free module F over a graded ring with grading group G = mathbb Z, and given a vector W of ngens(F) integers, define a G-grading on F converting the entries of W to elements of G, and assigning these elements as weights to the variables. Return the new module.\n\nnote: Note\nThe function applies to free modules over both graded multivariate polynomial rings and their quotients.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1 0 1; 0 1 1])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> F = free_module(R, 2)\nFree module of rank 2 over R\n\njulia> FF = grade(F, [[1, 0], [0, 1]])\nGraded free module R^1([-1 0]) + R^1([0 -1]) of rank 2 over R\n\njulia> FFF = grade(F, [1 0; 0 1])\nGraded free module R^1([-1 0]) + R^1([0 -1]) of rank 2 over R\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [\"x\", \"y\"])\n(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])\n\njulia> S, _ = quo(R, [x*y])\n(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from\nR to S defined by a julia-function with inverse)\n\njulia> F = free_module(S, 2)\nFree module of rank 2 over S\n\njulia> FF = grade(F, [1, 2])\nGraded free module S^1([-1]) + S^1([-2]) of rank 2 over S\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"graded_free_module(R::Ring, p::Int, W::Vector{GrpAbFinGenElem}=[grading_group(R)[0] for i in 1:p], name::String=\"e\")","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#graded_free_module","page":"Free Modules","title":"graded_free_module","text":"graded_free_module(R::Ring, p::Int, W::Vector{GrpAbFinGenElem}=[grading_group(R)[0] for i in 1:p], name::String=\"e\")\n\nGiven a graded ring R with grading group G, say, and given a vector W with p elements of G, create the free module R^p equipped with its basis of standard unit vectors, and assign weights to these vectors according to the entries of W. Return the resulting graded free module.\n\ngraded_free_module(R::Ring, W::Vector{GrpAbFinGenElem}, name::String=\"e\")\n\nAs above, with p = length(W).\n\nnote: Note\nThe function applies to graded multivariate polynomial rings and their quotients.\n\nThe string name specifies how the basis vectors are printed. \n\nExamples\n\njulia> R, (x,y) = graded_polynomial_ring(QQ, [\"x\", \"y\"])\n(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])\n\njulia> graded_free_module(R,3)\nGraded free module R^3([0]) of rank 3 over R\n\njulia> G = grading_group(R)\nGrpAb: Z\n\njulia> graded_free_module(R, [G[1], 2*G[1]])\nGraded free module R^1([-1]) + R^1([-2]) of rank 2 over R\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"graded_free_module(R::Ring, W::Vector{<:Vector{<:IntegerUnion}}, name::String=\"e\")","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#graded_free_module-2","page":"Free Modules","title":"graded_free_module","text":"graded_free_module(R::Ring, W::Vector{<:Vector{<:IntegerUnion}}, name::String=\"e\")\n\nGiven a graded ring R with grading group G = mathbb Z^m, and given a vector W of integer vectors of the same size p, say, create the free module R^p equipped with its basis of standard unit vectors, and assign weights to these vectors according to the entries of W, converted to elements of G. Return the resulting graded free module.\n\ngraded_free_module(R::Ring, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String=\"e\")\n\nAs above, converting the columns of W.\n\ngraded_free_module(R::Ring, W::Vector{<:IntegerUnion}, name::String=\"e\")\n\nGiven a graded ring R with grading group G = mathbb Z, and given a vector W of integers, set p = length(W), create the free module R^p equipped with its basis of standard unit vectors, and assign weights to these vectors according to the entries of W, converted to elements of G. Return the resulting graded free module.\n\nThe string name specifies how the basis vectors are printed. \n\nnote: Note\nThe function applies to graded multivariate polynomial rings and their quotients.\n\nExamples\n\njulia> R, (x,y) = graded_polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = graded_free_module(R, [1, 2])\nGraded free module R^1([-1]) + R^1([-2]) of rank 2 over R\n\njulia> S, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1 0 1; 0 1 1]);\n\njulia> FF = graded_free_module(S, [[1, 2], [-1, 3]])\nGraded free module S^1([-1 -2]) + S^1([1 -3]) of rank 2 over S\n\njulia> FFF = graded_free_module(S, [1 -1; 2 3])\nGraded free module S^1([-1 -2]) + S^1([1 -3]) of rank 2 over S\n\njulia> FF == FFF\ntrue\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Data-Associated-to-Free-Modules","page":"Free Modules","title":"Data Associated to Free Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"If F is a free R-module, then","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"base_ring(F) refers to R,\nbasis(F), gens(F) to the basis vectors of F, \nrank(F), ngens(F), dim(F) to the number of these vectors, and\nF[i], basis(F, i), gen(F, i) to the i-th such vector.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Examples","page":"Free Modules","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = free_module(R, 3);\n\njulia> basis(F)\n3-element Vector{FreeModElem{QQMPolyRingElem}}:\n e[1]\n e[2]\n e[3]\n\njulia> rank(F)\n3","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"In the graded case, we also have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":" grading_group(F::FreeMod)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#grading_group-Tuple{FreeMod}","page":"Free Modules","title":"grading_group","text":"grading_group(F::FreeMod)\n\nReturn the grading group of base_ring(F).\n\nExamples\n\njulia> R, (x,y) = graded_polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = graded_free_module(R, 3)\nGraded free module R^3([0]) of rank 3 over R\n\njulia> grading_group(F)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"degrees_of_generators(F::FreeMod)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#degrees_of_generators-Tuple{FreeMod}","page":"Free Modules","title":"degrees_of_generators","text":"degrees_of_generators(F::FreeMod)\n\nReturn the degrees of the generators of F.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = graded_free_module(R, 2)\nGraded free module R^2([0]) of rank 2 over R\n\njulia> degrees_of_generators(F)\n2-element Vector{GrpAbFinGenElem}:\n [0]\n [0]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Elements-of-Free-Modules","page":"Free Modules","title":"Elements of Free Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"All OSCAR types for elements of the modules considered here belong to the abstract type ModuleElemFP{T}, where T is the element type of the underlying ring. The free modules belong to the abstract subtype AbstractFreeModElem{T} <: ModuleFPElem{T}. They are modelled as objects of the concrete type FreeModElem{T} <: AbstractFreeModElem{T} which implements an element f of a free module F as a sparse row, that is, as an object of type SRow{T}. This object specifies the coordinates of f with respect to the basis of standard unit vectors of F. To create an element, enter its coordinates as a sparse row or a vector: ","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"(F::FreeMod{T})(c::SRow{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"(F::FreeMod{T})(c::Vector{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"Alternatively, directly write the element as a linear combination of basis vectors of F:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Examples-2","page":"Free Modules","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = free_module(R, 3);\n\njulia> f = F(sparse_row(R, [(1,x),(3,y)]))\nx*e[1] + y*e[3]\n\njulia> g = F([x, zero(R), y])\nx*e[1] + y*e[3]\n\njulia> h = x*F[1] + y*F[3]\nx*e[1] + y*e[3]\n\njulia> f == g == h\ntrue","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"Given an element f of a free module F over a multivariate polynomial ring with element type T,","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"parent(f) refers to F, and\ncoordinates(f) to the coordinate vector of f, returned as an object of type SRow{T}.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Examples-3","page":"Free Modules","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = free_module(R, 3);\n\njulia> f = x*F[1] + y*F[3]\nx*e[1] + y*e[3]\n\njulia> parent(f)\nFree module of rank 3 over Multivariate polynomial ring in 2 variables over QQ\n\njulia> coordinates(f)\nSparse row with positions [1, 3] and values QQMPolyRingElem[x, y]\n","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"The zero element of a free module is obtained as follows:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"zero(F::AbstractFreeMod)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#zero-Tuple{Oscar.AbstractFreeMod}","page":"Free Modules","title":"zero","text":"zero(F::AbstractFreeMod)\n\nReturn the zero element of F.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"Whether a given element of a free module is zero can be tested as follows:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"is_zero(f::AbstractFreeModElem)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#is_zero-Tuple{Oscar.AbstractFreeModElem}","page":"Free Modules","title":"is_zero","text":"is_zero(f::AbstractFreeModElem)\n\nReturn true if f is zero, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"is_homogeneous(f::FreeModElem)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#is_homogeneous-Tuple{FreeModElem}","page":"Free Modules","title":"is_homogeneous","text":"is_homogeneous(f::FreeModElem)\n\nGiven an element f of a graded free module, return true if f is homogeneous, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [1, 2, 3]);\n\njulia> F = free_module(R, 2)\nFree module of rank 2 over R\n\njulia> FF = grade(F, [1,4])\nGraded free module R^1([-1]) + R^1([-4]) of rank 2 over R\n\njulia> f = y^2*2*FF[1]-x*FF[2]\n2*y^2*e[1] - x*e[2]\n\njulia> is_homogeneous(f)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"degree(f::FreeModElem)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#degree-Tuple{FreeModElem}","page":"Free Modules","title":"degree","text":"degree(f::FreeModElem)\n\nGiven a homogeneous element f of a graded free module, return the degree of f.\n\ndegree(::Type{Vector{Int}}, f::FreeModElem)\n\nGiven a homogeneous element f of a mathbb Z^m-graded free module, return the degree of f, converted to a vector of integer numbers.\n\ndegree(::Type{Int}, f::FreeModElem)\n\nGiven a homogeneous element f of a mathbb Z-graded free module, return the degree of f, converted to an integer number.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> f = y^2*z − x^2*w\n-w*x^2 + y^2*z\n\njulia> degree(f)\n[3]\n\njulia> typeof(degree(f))\nGrpAbFinGenElem\n\njulia> degree(Int, f)\n3\n\njulia> typeof(degree(Int, f))\nInt64\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Tests-on-Free-Modules","page":"Free Modules","title":"Tests on Free Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"The tests is_graded, is_standard_graded, is_z_graded, and is_zm_graded carry over analogously to free modules. They return true if the corresponding property is satisfied, and false otherwise. In addition, we have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"==(F::FreeMod, G::FreeMod)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#==-Tuple{FreeMod, FreeMod}","page":"Free Modules","title":"==","text":"==(F::FreeMod, G::FreeMod)\n\nReturn true if F and G are equal, false otherwise.\n\nHere, F and G are equal iff either \n\nboth modules are ungraded and their base rings, ranks, and names for printing the basis elements are equal, \n\nor else \n\nboth modules are graded, the above holds, and for each i, the degrees of the i-th basis elements are equal.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"is_isomorphic(F::FreeMod, G::FreeMod)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#is_isomorphic-Tuple{FreeMod, FreeMod}","page":"Free Modules","title":"is_isomorphic","text":"is_isomorphic(F::FreeMod, G::FreeMod)\n\nReturn true if F and G are isomorphic as (graded) modules, false otherwise.\n\nThat is, either \n\nboth modules are ungraded and their base rings and ranks are equal, \n\nor else \n\nboth modules are graded, the above holds, and the multisets of the degrees of the basis elements are equal.\n\nExamples\n\njulia> R, _= polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z)=grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F = graded_free_module(Rg, [1,1,3,2]);\n\njulia> G1 = graded_free_module(Rg, [1,1,2,3]);\n\njulia> is_isomorphic(F, G1)\ntrue\n\njulia> G2 = graded_free_module(Rg, [1,1,5,6]);\n\njulia> is_isomorphic(F, G2)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"is_zero(F::AbstractFreeMod)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#is_zero-Tuple{Oscar.AbstractFreeMod}","page":"Free Modules","title":"is_zero","text":"is_zero(F::AbstractFreeMod)\n\nReturn true if F is the zero module, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#Homomorphisms-from-Free-Modules","page":"Free Modules","title":"Homomorphisms from Free Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"All OSCAR types for homomorphisms of the modules considered here belong to the abstract type ModuleFPHom{T1, T2}, where T1 and T2 are the types of domain and codomain respectively. A homomorphism Fto M from a free module F is determined by specifying the images of the basis vectors of F in M. For such homomorphisms, OSCAR provides the concrete type FreeModuleHom{T1, T2} <: ModuleFPHom{T1, T2} as well as the following constructors:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"hom(F::FreeMod, M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T ","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#hom-Union{Tuple{T}, Tuple{FreeMod, ModuleFP{T}, Vector{<:ModuleFPElem{T}}}} where T","page":"Free Modules","title":"hom","text":"hom(F::FreeMod, M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T\n\nGiven a vector V of rank(F) elements of M, return the homomorphism F to M which sends the i-th basis vector of F to the i-th entry of V.\n\nhom(F::FreeMod, M::ModuleFP{T}, A::MatElem{T}) where T\n\nGiven a matrix A with rank(F) rows and ngens(M) columns, return the homomorphism F to M which sends the i-th basis vector of F to the linear combination sum_j Aij*Mj of the generators M[j] of M.\n\nnote: Note\nThe module M may be of type FreeMod or SubquoMod. If both modules F and M are graded, the data must define a graded module homomorphism of some degree. If this degree is the zero element of the (common) grading group, we refer to the homomorphism under consideration as a homogeneous module homomorphism.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 3)\nFree module of rank 3 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> G = free_module(R, 2)\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]\n3-element Vector{FreeModElem{QQMPolyRingElem}}:\n y*e[1]\n x*e[1] + y*e[2]\n z*e[2]\n\njulia> a = hom(F, G, V)\nMap with following data\nDomain:\n=======\nFree module of rank 3 over Multivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> a(F[2])\nx*e[1] + y*e[2]\n\njulia> B = R[y 0; x y; 0 z]\n[y 0]\n[x y]\n[0 z]\n\njulia> b = hom(F, G, B)\nMap with following data\nDomain:\n=======\nFree module of rank 3 over Multivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> a == b\ntrue\n\njulia> R, _= polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F1 = graded_free_module(Rg, 3)\nGraded free module Rg^3([0]) of rank 3 over Rg\n\njulia> G1 = graded_free_module(Rg, 2)\nGraded free module Rg^2([0]) of rank 2 over Rg\n\njulia> V1 = [y*G1[1], (x+y)*G1[1]+y*G1[2], z*G1[2]]\n3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n (x + y)*e[1] + y*e[2]\n z*e[2]\n\njulia> a1 = hom(F1, G1, V1)\nF1 -> G1\ne[1] -> y*e[1]\ne[2] -> (x + y)*e[1] + y*e[2]\ne[3] -> z*e[2]\nGraded module homomorphism of degree [1]\n\njulia> F2 = graded_free_module(Rg, [1,1,1])\nGraded free module Rg^3([-1]) of rank 3 over Rg\n\njulia> G2 = graded_free_module(Rg, [0,0])\nGraded free module Rg^2([0]) of rank 2 over Rg\n\njulia> V2 = [y*G2[1], (x+y)*G2[1]+y*G2[2], z*G2[2]]\n3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n (x + y)*e[1] + y*e[2]\n z*e[2]\n\njulia> a2 = hom(F2, G2, V2)\nF2 -> G2\ne[1] -> y*e[1]\ne[2] -> (x + y)*e[1] + y*e[2]\ne[3] -> z*e[2]\nHomogeneous module homomorphism\n\njulia> B = Rg[y 0; x+y y; 0 z]\n[ y 0]\n[x + y y]\n[ 0 z]\n\njulia> b = hom(F2, G2, B)\nF2 -> G2\ne[1] -> y*e[1]\ne[2] -> (x + y)*e[1] + y*e[2]\ne[3] -> z*e[2]\nHomogeneous module homomorphism\n\njulia> a2 == b\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"hom(F::FreeMod, M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, h::RingMapType) where {T, RingMapType}","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#hom-Union{Tuple{RingMapType}, Tuple{T}, Tuple{FreeMod, ModuleFP{T}, Vector{<:ModuleFPElem{T}}, RingMapType}} where {T, RingMapType}","page":"Free Modules","title":"hom","text":"hom(F::FreeMod, M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, h::RingMapType) where {T, RingMapType}\n\nGiven a vector V of rank(F) elements of M and a ring map h from base_ring(F) to base_ring(M), return the base_ring(F)-homomorphism F to M which sends the i-th basis vector of F to the i-th entry of V, and the scalars in base_ring(F) to their images under h.\n\nhom(F::FreeMod, M::ModuleFP{T}, A::MatElem{T}, h::RingMapType) where {T, RingMapType}\n\nGiven a matrix A over base_ring(M) with rank(F) rows and ngens(M) columns and a ring map h from base_ring(F) to base_ring(M), return the base_ring(F)-homomorphism F to M which sends the i-th basis vector of F to the linear combination sum_j Aij*Mj of the generators M[j] of M, and the scalars in base_ring(F) to their images under h.\n\nnote: Note\nThe module M may be of type FreeMod or SubquoMod. If both modules F and M are graded, the data must define a graded module homomorphism of some degree. If this degree is the zero element of the (common) grading group, we refer to the homomorphism under consideration as a homogeneous module homomorphism.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"Given a homomorphism of type FreeModuleHom, a matrix representing it is recovered by the following function:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"matrix(a::FreeModuleHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#matrix-Tuple{FreeModuleHom}","page":"Free Modules","title":"matrix","text":"matrix(a::FreeModuleHom)\n\nGiven a homomorphism a : F → M of type FreeModuleHom, return a matrix A over base_ring(M) with rank(F) rows and ngens(M) columns such that a(Fi) = sum_j Aij*Mj.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 3)\nFree module of rank 3 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> G = free_module(R, 2)\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]];\n\njulia> a = hom(F, G, V);\n\njulia> matrix(a)\n[y 0]\n[x y]\n[0 z]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"The domain and codomain of a homomorphism a of type FreeModuleHom can be recovered by entering domain(a) and codomain(a), respectively.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"The functions below test whether a homomorphism of type FreeModuleHom is graded and homogeneous, respectively.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"is_graded(a::FreeModuleHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#is_graded-Tuple{FreeModuleHom}","page":"Free Modules","title":"is_graded","text":"is_graded(a::FreeModuleHom)\n\nReturn true if a is graded, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = graded_free_module(R, 3)\nGraded free module R^3([0]) of rank 3 over R\n\njulia> G = graded_free_module(R, 2)\nGraded free module R^2([0]) of rank 2 over R\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]\n3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n x*e[1] + y*e[2]\n z*e[2]\n\njulia> a = hom(F, G, V)\nF -> G\ne[1] -> y*e[1]\ne[2] -> x*e[1] + y*e[2]\ne[3] -> z*e[2]\nGraded module homomorphism of degree [1]\n\njulia> is_graded(a)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"is_homogeneous(a::FreeModuleHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#is_homogeneous-Tuple{FreeModuleHom}","page":"Free Modules","title":"is_homogeneous","text":"is_homogeneous(a::FreeModuleHom)\n\nReturn true if a is homogeneous, false otherwise\n\nHere, if G is the grading group of a, a is homogeneous if a is graded of degree zero(G).\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = graded_free_module(R, 3)\nGraded free module R^3([0]) of rank 3 over R\n\njulia> G = graded_free_module(R, 2)\nGraded free module R^2([0]) of rank 2 over R\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]\n3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n x*e[1] + y*e[2]\n z*e[2]\n\njulia> a = hom(F, G, V)\nF -> G\ne[1] -> y*e[1]\ne[2] -> x*e[1] + y*e[2]\ne[3] -> z*e[2]\nGraded module homomorphism of degree [1]\n\njulia> is_homogeneous(a)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"degree(a::FreeModuleHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#degree-Tuple{FreeModuleHom}","page":"Free Modules","title":"degree","text":"degree(a::FreeModuleHom)\n\nIf a is graded, return the degree of a.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = graded_free_module(R, 3)\nGraded free module R^3([0]) of rank 3 over R\n\njulia> G = graded_free_module(R, 2)\nGraded free module R^2([0]) of rank 2 over R\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]\n3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n x*e[1] + y*e[2]\n z*e[2]\n\njulia> a = hom(F, G, V)\nF -> G\ne[1] -> y*e[1]\ne[2] -> x*e[1] + y*e[2]\ne[3] -> z*e[2]\nGraded module homomorphism of degree [1]\n\njulia> degree(a)\n[1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"grading_group(a::FreeModuleHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#grading_group-Tuple{FreeModuleHom}","page":"Free Modules","title":"grading_group","text":"grading_group(a::FreeModuleHom)\n\nIf a is graded, return the grading group of a.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = graded_free_module(R, 3)\nGraded free module R^3([0]) of rank 3 over R\n\njulia> G = graded_free_module(R, 2)\nGraded free module R^2([0]) of rank 2 over R\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]]\n3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n x*e[1] + y*e[2]\n z*e[2]\n\njulia> a = hom(F, G, V)\nF -> G\ne[1] -> y*e[1]\ne[2] -> x*e[1] + y*e[2]\ne[3] -> z*e[2]\nGraded module homomorphism of degree [1]\n\njulia> is_graded(a)\ntrue\n\njulia> grading_group(a)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"NumberTheory/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"The number theory part of OSCAR provides functionality for algebraic number theory.","category":"page"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"It is under development with regard to providing both the functionality and the documentation. ","category":"page"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"Henri Cohen (1993)\nHenri Cohen (2000)\nDaniel A. Marcus (2018)\nM. Pohst, H. Zassenhaus (1997)","category":"page"},{"location":"NumberTheory/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"Claus Fieker,\nTommy Hofmann.","category":"page"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Ring-Interface","page":"Ring Interface","title":"Ring Interface","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"AbstractAlgebra.jl generic code makes use of a standardised set of functions which it expects to be implemented for all rings. Here we document this interface. All libraries which want to make use of the generic capabilities of AbstractAlgebra.jl must supply all of the required functionality for their rings.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In addition to the required functions, there are also optional functions which can be provided for certain types of rings, e.g. GCD domains or fields, etc. If implemented, these allow the generic code to provide additional functionality for those rings, or in some cases, to select more efficient algorithms.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Types","page":"Ring Interface","title":"Types","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Most rings must supply two types:","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"a type for the parent object (representing the ring itself)\na type for elements of that ring","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For example, the generic univariate polynomial type in AbstractAlgebra.jl provides two types in generic/GenericTypes.jl:","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Generic.PolyRing{T} for the parent objects\nGeneric.Poly{T} for the actual polynomials","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"The parent type must belong to Ring and the element type must belong to RingElem. Of course, the types may belong to these abstract types transitively, e.g. Poly{T} actually belongs to PolyRingElem{T} which in turn belongs to RingElem.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For parameterised rings, we advise that the types of both the parent objects and element objects to be parameterised by the types of the elements of the base ring (see the function base_ring below for a definition).","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"There can be variations on this theme: e.g. in some areas of mathematics there is a notion of a coefficient domain, in which case it may make sense to parameterise all types by the type of elements of this coefficient domain. But note that this may have implications for the ad hoc operators one might like to explicitly implement.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#RingElement-type-union","page":"Ring Interface","title":"RingElement type union","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Because of its lack of multiple inheritance, Julia does not allow Julia Base types to belong to RingElem. To allow us to work equally with AbstractAlgebra and Julia types that represent elements of rings we define a union type RingElement in src/julia/JuliaTypes.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"So far, in addition to RingElem the union type RingElement includes the Julia types Integer, Rational and AbstractFloat.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Most of the generic code in AbstractAlgebra makes use of the union type RingElement instead of RingElem so that the generic functions also accept the Julia Base ring types.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"note: Note\nOne must be careful when defining ad hoc binary operations for ring element types. It is often necessary to define separate versions of the functions for RingElem then for each of the Julia types separately in order to avoid ambiguity warnings.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Note that even though RingElement is a union type we still have the following inclusion","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"RingElement <: NCRingElement","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Parent-object-caches","page":"Ring Interface","title":"Parent object caches","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In many cases, it is desirable to have only one object in the system to represent each ring. This means that if the same ring is constructed twice, elements of the two rings will be compatible as far as arithmetic is concerned.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In order to facilitate this, global caches of rings are stored in AbstractAlgebra.jl, usually implemented using dictionaries. For example, the Generic.PolyRing parent objects are looked up in a dictionary PolyID to see if they have been previously defined.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Whether these global caches are provided or not, depends on both mathematical and algorithmic considerations. E.g. in the case of number fields, it isn't desirable to identify all number fields with the same defining polynomial, as they may be considered with distinct embeddings into one another. In other cases, identifying whether two rings are the same may be prohibitively expensive. Generally, it may only make sense algorithmically to identify two rings if they were constructed from identical data.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If a global cache is provided, it must be optionally possible to construct the parent objects without caching. This is done by passing a boolean value cached to the inner constructor of the parent object. See generic/GenericTypes.jl for examples of how to construct and handle such caches.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Required-functions-for-all-rings","page":"Ring Interface","title":"Required functions for all rings","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In the following, we list all the functions that are required to be provided for rings in AbstractAlgebra.jl or by external libraries wanting to use AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"We give this interface for fictitious types MyParent for the type of the ring parent object R and MyElem for the type of the elements of the ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"note: Note\nGeneric functions in AbstractAlgebra.jl may not rely on the existence of functions that are not documented here. If they do, those functions will only be available for rings that implement that additional functionality, and should be documented as such.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Data-type-and-parent-object-methods","page":"Ring Interface","title":"Data type and parent object methods","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"parent_type(::Type{MyElem})","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the type of the corresponding parent object for the given element type. For example, parent_type(Generic.Poly{T}) will return Generic.PolyRing{T}.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"elem_type(::Type{MyParent})","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the type of the elements of the ring whose parent object has the given type. This is the inverse of the parent_type function, i.e. elem_type(Generic.PolyRing{T}) will return Generic.Poly{T}.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"base_ring(R::MyParent)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Given a parent object R, representing a ring, this function returns the parent object of any base ring that parameterises this ring. For example, the base ring of the ring of polynomials over the integers would be the integer ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If the ring is not parameterised by another ring, this function must return Union{}.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"note: Note\nThere is a distinction between a base ring and other kinds of parameters. For example, in the ring mathbbZnmathbbZ, the modulus n is a parameter, but the only base ring is mathbbZ. We consider the ring mathbbZnmathbbZ to have been constructed from the base ring mathbbZ by taking its quotient by a (principal) ideal.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"parent(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the parent object of the given element, i.e. return the ring to which the given element belongs.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"This is usually stored in a field parent in each ring element. (If the parent objects have mutable struct types, the internal overhead here is just an additional machine pointer stored in each element of the ring.)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For some element types it isn't necessary to append the parent object as a field of every element. This is the case when the parent object can be reconstructed just given the type of the elements. For example, this is the case for the ring of integers and in fact for any ring element type that isn't parameterised or generic in any way.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"is_domain_type(::Type{MyElem})","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return true if every element of the given element type (which may be parameterised or an abstract type) necessarily has a parent that is an integral domain, otherwise if this cannot be guaranteed, the function returns false.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For example, if MyElem was the type of elements of generic residue rings of a polynomial ring, the answer to the question would depend on the modulus of the residue ring. Therefore is_domain_type would have to return false, since we cannot guarantee that we are dealing with elements of an integral domain in general. But if the given element type was for rational integers, the answer would be true, since every rational integer has as parent the ring of rational integers, which is an integral domain.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Note that this function depends only on the type of an element and cannot access information about the object itself, or its parent.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"is_exact_type(::Type{MyElem})","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return true if every element of the given type is represented exactly. For example, p-adic numbers, real and complex floating point numbers and power series are not exact, as we can only represent them in general with finite truncations. Similarly polynomials and matrices over inexact element types are themselves inexact.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Integers, rationals, finite fields and polynomials and matrices over them are always exact.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Note that MyElem may be parameterised or an abstract type, in which case every element of every type represented by MyElem must be exact, otherwise the function must return false.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Base.hash(f::MyElem, h::UInt)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return a hash for the object f of type UInt. This is used as a hopefully cheap way to distinguish objects that differ arithmetically.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If the object has components, e.g. the coefficients of a polynomial or elements of a matrix, these should be hashed recursively, passing the same parameter h to all levels. Each component should then be xor'd with h before combining the individual component hashes to give the final hash.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"The hash functions in AbstractAlgebra.jl usually start from some fixed 64 bit hexadecimal value that has been picked at random by the library author for that type. That is then truncated to fit a UInt (in case the latter is not 64 bits). This ensures that objects that are the same arithmetically (or that have the same components), but have different types (or structures), are unlikely to hash to the same value.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"deepcopy_internal(f::MyElem, dict::IdDict)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return a copy of the given element, recursively copying all components of the object.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Obviously the parent, if it is stored in the element, should not be copied. The new element should have precisely the same parent as the old object.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For types that cannot self-reference themselves anywhere internally, the dict argument may be ignored.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In the case that internal self-references are possible, please consult the Julia documentation on how to implement deepcopy_internal.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Constructors","page":"Ring Interface","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Outer constructors for most AbstractAlgebra types are provided by overloading the call syntax for parent objects.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If R is a parent object for a given ring we provide the following constructors.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"(R::MyParent)()","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the zero object of the given ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"(R::MyParent)(a::Integer)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Coerce the given integer into the given ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"(R::MyParent)(a::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If a belongs to the given ring, the function returns it (without making a copy). Otherwise an error is thrown.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For parameterised rings we also require a function to coerce from the base ring into the parent ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"(R::MyParent{T})(a::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Coerce a into the ring R if a belongs to the base ring of R.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Basic-manipulation-of-rings-and-elements","page":"Ring Interface","title":"Basic manipulation of rings and elements","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"zero(R::MyParent)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the zero element of the given ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"one(R::MyParent)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the multiplicative identity of the given ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"iszero(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return true if the given element is the zero element of the ring it belongs to.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"isone(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return true if the given element is the multiplicative identity of the ring it belongs to.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Canonicalisation","page":"Ring Interface","title":"Canonicalisation","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"canonical_unit(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"When fractions are created with two elements of the given type, it is nice to be able to represent them in some kind of canonical form. This is of course not always possible. But for example, fractions of integers can be canonicalised by first removing any common factors of the numerator and denominator, then making the denominator positive.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In AbstractAlgebra.jl, the denominator would be made positive by dividing both the numerator and denominator by the canonical unit of the denominator. For a negative denominator, this would be -1.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For elements of a field, canonical_unit simply returns the element itself. In general, canonical_unit of an invertible element should be that element. Finally, if a = ub we should have the identity canonical_unit(a) = canonical_unit(u)*canonical_unit(b).","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For some rings, it is completely impractical to implement this function, in which case it may return 1 in the given ring. The function must however always exist, and always return an element of the ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#String-I/O","page":"Ring Interface","title":"String I/O","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"show(io::IO, R::MyParent)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"This should print an English description of the parent ring (to the given IO object). If the ring is parameterised, it can call the corresponding show function for any rings it depends on.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"show(io::IO, f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"This should print a human readable, textual representation of the object (to the given IO object). It can recursively call the corresponding show functions for any of its components.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Expressions","page":"Ring Interface","title":"Expressions","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"To obtain best results when printing composed types derived from other types, e.g., polynomials, the following method should be implemented.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"expressify(f::MyElem; context = nothing)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"which must return either Expr, Symbol, Integer or String.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For a type which implements expressify, one can automatically derive show methods supporting output as plain text, LaTeX and html by using the following:","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"@enable_all_show_via_expressify MyElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"This defines the following show methods for the specified type MyElem:","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"function Base.show(io::IO, a::MyElem)\n show_via_expressify(io, a)\nend\n\nfunction Base.show(io::IO, mi::MIME\"text/plain\", a::MyElem)\n show_via_expressify(io, mi, a)\nend\n\nfunction Base.show(io::IO, mi::MIME\"text/latex\", a::MyElem)\n show_via_expressify(io, mi, a)\nend\n\nfunction Base.show(io::IO, mi::MIME\"text/html\", a::MyElem)\n show_via_expressify(io, mi, a)\nend","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"As an example, assume that an object f of type MyElem has two components f.a and f.b of integer type, which should be printed as a^b, this can be implemented as","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"expressify(f::MyElem; context = nothing) = Expr(:call, :^, f.a, f.b)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If f.a and f.b themselves are objects that can be expressified, this can be implemented as","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"function expressify(f::MyElem; context = nothing)\n return Expr(:call, :^, expressify(f.a, context = context),\n expressify(f.b, context = context))\nend","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"As noted above, expressify should return an Expr, Symbol, Integer or String. The rendering of such expressions with a particular MIME type to an output context is controlled by the following rules which are subject to change slightly in future versions of AbstracAlgebra.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Integer: The printing of integers is straightforward and automatically includes transformations such as 1 + (-2)*x => 1 - 2*x as this is cumbersome to implement per-type.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Symbol: Since variable names are stored as mere symbols in AbstractAlgebra, some transformations related to subscripts are applied to symbols automatically in latex output. The \\operatorname{ in the following table is actually replaced with the more portable \\mathop{\\mathrm{.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"expressify latex output\nSymbol(\"a\") a\nSymbol(\"α\") {\\alpha}\nSymbol(\"x1\") \\operatorname{x1}\nSymbol(\"xy_1\") \\operatorname{xy}_{1}\nSymbol(\"sin\") \\operatorname{sin}\nSymbol(\"sin_cos\") \\operatorname{sin\\_cos}\nSymbol(\"sin_1\") \\operatorname{sin}_{1}\nSymbol(\"sin_cos_1\") \\operatorname{sin\\_cos}_{1}\nSymbol(\"αaβb_1_2\") \\operatorname{{\\alpha}a{\\beta}b}_{1,2}","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Expr: These are the most versatile as the Expr objects themselves contain a symbolic head and any number of arguments. What looks like f(a,b) in textual output is Expr(:call, :f, :a, :b) under the hood. AbstractAlgebra currently contains the following printing rules for such expressions.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"expressify output latex notes\nExpr(:call, :+, a, b) a + b \nExpr(:call, :*, a, b) a*b one space for implied multiplication\nExpr(:call, :cdot, a, b) a * b a real \\cdot is used\nExpr(:call, :^, a, b) a^b may include some courtesy parentheses\nExpr(:call, ://, a, b) a//b will create a fraction box\nExpr(:call, :/, a, b) a/b will not create a fraction box\nExpr(:call, a, b, c) a(b, c) \nExpr(:ref, a, b, c) a[b, c] \nExpr(:vcat, a, b) [a; b] actually vertical\nExpr(:vect, a, b) [a, b] \nExpr(:tuple, a, b) (a, b) \nExpr(:list, a, b) {a, b} \nExpr(:series, a, b) a, b \nExpr(:sequence, a, b) ab \nExpr(:row, a, b) a b combine with :vcat to make matrices\nExpr(:hcat, a, b) a b ","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"String: Strings are printed verbatim and should only be used as a last resort as they provide absolutely no precedence information on their contents.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Unary-operations","page":"Ring Interface","title":"Unary operations","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"-(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return -f.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Binary-operations","page":"Ring Interface","title":"Binary operations","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"+(f::MyElem, g::MyElem)\n-(f::MyElem, g::MyElem)\n*(f::MyElem, g::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return f + g, f - g or fg, respectively.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Comparison","page":"Ring Interface","title":"Comparison","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"==(f::MyElem, g::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return true if f and g are arithmetically equal. In the case where the two elements are inexact, the function returns true if they agree to the minimum precision of the two.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"isequal(f::MyElem, g::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For exact rings, this should return the same thing as == above. For inexact rings, this returns true only if the two elements are arithmetically equal and have the same precision.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Powering","page":"Ring Interface","title":"Powering","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"^(f::MyElem, e::Int)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return f^e. The function should throw a DomainError() if negative exponents don't make sense but are passed to the function.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Exact-division","page":"Ring Interface","title":"Exact division","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"divexact(f::MyElem, g::MyElem; check::Bool=true)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return fg, though note that Julia uses / for floating point division. Here we mean exact division in the ring, i.e. return q such that f = gq. A DivideError() should be thrown if g is zero.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If check=true the function should check that the division is exact and throw an exception if not.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"If check=false the check may be omitted for performance reasons. The behaviour is then undefined if a division is performed that is not exact. This may include throwing an exception, returning meaningless results, hanging or crashing. The function should only be called with check=false if it is already known that the division will be exact.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Inverse","page":"Ring Interface","title":"Inverse","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"inv(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the inverse of f, i.e. 1f, though note that Julia uses / for floating point division. Here we mean exact division in the ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"A fallback for this function is provided in terms of divexact so an implementation can be omitted if preferred.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Unsafe-operators","page":"Ring Interface","title":"Unsafe operators","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"To speed up polynomial and matrix arithmetic, it sometimes makes sense to mutate values in place rather than replace them with a newly created object every time they are modified.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For this purpose, certain mutating operators are required. In order to support immutable types (struct in Julia) and systems that don't have in-place operators, all unsafe operators must return the (ostensibly) mutated value. Only the returned value is used in computations, so this lifts the requirement that the unsafe operators actually mutate the value.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Note the exclamation point is a convention, which indicates that the object may be mutated in-place.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"To make use of these functions, one must be certain that no other references are held to the object being mutated, otherwise those values will also be changed!","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"The results of deepcopy and all arithmetic operations, including powering and division can be assumed to be new objects without other references being held, as can objects returned from constructors.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"note: Note\nIt is important to recognise that R(a) where R is the ring a belongs to, does not create a new value. For this case, use deepcopy(a).","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"zero!(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Set the value f to zero in place. Return the mutated value.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"mul!(c::MyElem, a::MyElem, b::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Set c to the value ab in place. Return the mutated value. Aliasing is permitted.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"add!(c::MyElem, a::MyElem, b::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Set c to the value a + b in place. Return the mutated value. Aliasing is permitted.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"addeq!(a::MyElem, b::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Set a to a + b in place. Return the mutated value. Aliasing is permitted.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Random-generation","page":"Ring Interface","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"The random functions are only used for test code to generate test data. They therefore don't need to provide any guarantees on uniformity, and in fact, test values that are known to be a good source of corner cases can be supplied.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"rand(R::MyParent, v...)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return a random element in the given ring of the specified size.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"There can be as many arguments as is necessary to specify the size of the test example which is being produced.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Promotion-rules","page":"Ring Interface","title":"Promotion rules","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"AbstractAlgebra currently has a very simple coercion model. With few exceptions only simple coercions are supported. For example if x in mathbbZ and y in mathbbZx then x + y can be computed by coercing x into the same ring as y and then adding in that ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Complex coercions such as adding elements of mathbbQ and mathbbZx are not supported, as this would require finding and creating a common overring in which the elements could be added.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"AbstractAlgebra supports simple coercions by overloading parent object call syntax R(x) to coerce the object x into the ring R. However, to coerce elements up a tower of rings, one needs to also have a promotion system similar to Julia's type promotion system.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"As for Julia, AbstractAlgebra's promotion system only specifies what happens to types. It is the coercions themselves that must deal with the mathematical situation at the level of rings, including checking that the object can even be coerced into the given ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"We now describe the required AbstractAlgebra type promotion rules.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For every ring, one wants to be able to coerce integers into the ring. And for any ring constructed over a base ring, one would like to be able to coerce from the base ring into the ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"The required promotion rules to support this look a bit different depending on whether the element type is parameterised or not and whether it is built on a base ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For ring element types MyElem that are neither parameterised nor built over a base ring, the promotion rules can be defined as follows:","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"promote_rule(::Type{MyElem}, ::Type{T}) where {T <: Integer} = MyElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For ring element types MyElem that aren't parameterised, but which have a base ring with concrete element type T the promotion rules can be defined as follows:","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"promote_rule(::Type{MyElem}, ::Type{U}) where U <: Integer = MyElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"promote_rule(::Type{MyElem}, ::Type{T}) = MyElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For ring element types MyElem{T} that are parameterised by the type of elements of the base ring, the promotion rules can be defined as follows:","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"promote_rule(::Type{MyElem{T}}, ::Type{MyElem{T}}) where T <: RingElement = MyElem{T}","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"function promote_rule(::Type{MyElem{T}}, ::Type{U}) where {T <: RingElement, U <: RingElement}\n promote_rule(T, U) == T ? MyElem{T} : Union{}\nend","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Required-functionality-for-inexact-rings","page":"Ring Interface","title":"Required functionality for inexact rings","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/#Approximation-(floating-point-and-ball-arithmetic-only)","page":"Ring Interface","title":"Approximation (floating point and ball arithmetic only)","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"isapprox(f::MyElem, g::MyElem; atol::Real=sqrt(eps()))","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"This is used by test code that uses rings involving floating point or ball arithmetic. The function should return true if all components of f and g are equal to within the square root of the Julia epsilon, since numerical noise may make an exact comparison impossible.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For parameterised rings over an inexact ring, we also require the following ad hoc approximation functionality.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"isapprox(f::MyElem{T}, g::T; atol::Real=sqrt(eps())) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"isapprox(f::T, g::MyElem{T}; atol::Real=sqrt(eps())) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"These notionally coerce the element of the base ring into the parameterised ring and do a full comparison.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Optional-functionality","page":"Ring Interface","title":"Optional functionality","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Some functionality is difficult or impossible to implement for all rings in the system. If it is provided, additional functionality or performance may become available. Here is a list of all functions that are considered optional and can't be relied on by generic functions in the AbstractAlgebra Ring interface.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"It may be that no algorithm, or no efficient algorithm is known to implement these functions. As these functions are optional, they do not need to exist. Julia will already inform the user that the function has not been implemented if it is called but doesn't exist.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Optional-basic-manipulation-functionality","page":"Ring Interface","title":"Optional basic manipulation functionality","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"is_unit(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return true if the given element is a unit in the ring it belongs to.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"is_zero_divisor(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return true if the given element is a zero divisor in the ring it belongs to. When this function does not exist for a given ring then the total ring of fractions may not be usable over that ring. All fields in the system have a fallback defined for this function.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"characteristic(R::MyParent)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the characteristic of the ring. The function should not be defined if it is not possible to unconditionally give the characteristic. AbstractAlgebra will raise an exception is such cases.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Optional-binary-ad-hoc-operators","page":"Ring Interface","title":"Optional binary ad hoc operators","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"By default, ad hoc operations are handled by AbstractAlgebra.jl if they are not defined explicitly, by coercing both operands into the same ring and then performing the required operation.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In some cases, e.g. for matrices, this leads to very inefficient behaviour. In such cases, it is advised to implement some of these operators explicitly.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"It can occasionally be worth adding a separate set of ad hoc binary operators for the type Int, if this can be done more efficiently than for arbitrary Julia Integer types.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"+(f::MyElem, c::Integer)\n-(f::MyElem, c::Integer)\n*(f::MyElem, c::Integer)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"+(c::Integer, f::MyElem)\n-(c::Integer, f::MyElem)\n*(c::Integer, f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"For parameterised types, it is also sometimes more performant to provide explicit ad hoc operators with elements of the base ring.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"+(f::MyElem{T}, c::T) where T <: RingElem\n-(f::MyElem{T}, c::T) where T <: RingElem\n*(f::MyElem{T}, c::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"+(c::T, f::MyElem{T}) where T <: RingElem\n-(c::T, f::MyElem{T}) where T <: RingElem\n*(c::T, f::MyElem{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Optional-ad-hoc-comparisons","page":"Ring Interface","title":"Optional ad hoc comparisons","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"==(f::MyElem, c::Integer)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"==(c::Integer, f::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"==(f::MyElem{T}, c:T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"==(c::T, f::MyElem{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Optional-ad-hoc-exact-division-functions","page":"Ring Interface","title":"Optional ad hoc exact division functions","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"divexact(a::MyElem{T}, b::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"divexact(a::MyElem, b::Integer)","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Optional-powering-functions","page":"Ring Interface","title":"Optional powering functions","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"^(f::MyElem, e::BigInt)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"In case f cannot explode in size when powered by a very large integer, and it is practical to do so, one may provide this function to support powering with BigInt exponents (or for external modules, any other big integer type).","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Optional-unsafe-operators","page":"Ring Interface","title":"Optional unsafe operators","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"addmul!(c::MyElem, a::MyElem, b::MyElem, t::MyElem)","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Set c = c + ab in-place. Return the mutated value. The value t should be a temporary of the same type as a, b and c, which can be used arbitrarily by the implementation to speed up the computation. Aliasing between a, b and c is permitted.","category":"page"},{"location":"AbstractAlgebra/ring_interface/#Minimal-example-of-ring-implementation","page":"Ring Interface","title":"Minimal example of ring implementation","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Here is a minimal example of implementing the Ring Interface for a constant polynomial type (i.e. polynomials of degree less than one).","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"# ConstPoly.jl : Implements constant polynomials\n\nusing AbstractAlgebra\n\nusing Random: Random, SamplerTrivial, GLOBAL_RNG\nusing RandomExtensions: RandomExtensions, Make2, AbstractRNG\n\nimport AbstractAlgebra: parent_type, elem_type, base_ring, parent, is_domain_type,\n is_exact_type, canonical_unit, isequal, divexact, zero!, mul!, add!, addeq!,\n get_cached!, is_unit, characteristic, Ring, RingElem, expressify\n\nimport Base: show, +, -, *, ^, ==, inv, isone, iszero, one, zero, rand,\n deepcopy_internal, hash\n\nmutable struct ConstPolyRing{T <: RingElement} <: Ring\n base_ring::Ring\n\n function ConstPolyRing{T}(R::Ring, cached::Bool) where T <: RingElement\n return get_cached!(ConstPolyID, R, cached) do\n new{T}(R)\n end::ConstPolyRing{T}\n end\nend\n\nconst ConstPolyID = AbstractAlgebra.CacheDictType{Ring, ConstPolyRing}()\n \nmutable struct ConstPoly{T <: RingElement} <: RingElem\n c::T\n parent::ConstPolyRing{T}\n\n function ConstPoly{T}(c::T) where T <: RingElement\n return new(c)\n end\nend\n\n# Data type and parent object methods\n\nparent_type(::Type{ConstPoly{T}}) where T <: RingElement = ConstPolyRing{T}\n\nelem_type(::Type{ConstPolyRing{T}}) where T <: RingElement = ConstPoly{T}\n\nbase_ring(R::ConstPolyRing) = R.base_ring\n\nparent(f::ConstPoly) = f.parent\n\nis_domain_type(::Type{ConstPoly{T}}) where T <: RingElement = is_domain_type(T)\n\nis_exact_type(::Type{ConstPoly{T}}) where T <: RingElement = is_exact_type(T)\n\nfunction hash(f::ConstPoly, h::UInt)\n r = 0x65125ab8e0cd44ca\n return xor(r, hash(f.c, h))\nend\n\nfunction deepcopy_internal(f::ConstPoly{T}, dict::IdDict) where T <: RingElement\n r = ConstPoly{T}(deepcopy_internal(f.c, dict))\n r.parent = f.parent # parent should not be deepcopied\n return r\nend\n\n# Basic manipulation\n\nzero(R::ConstPolyRing) = R()\n\none(R::ConstPolyRing) = R(1)\n\niszero(f::ConstPoly) = iszero(f.c)\n\nisone(f::ConstPoly) = isone(f.c)\n\nis_unit(f::ConstPoly) = is_unit(f.c)\n\ncharacteristic(R::ConstPolyRing) = characteristic(base_ring(R))\n\n# Canonical unit\n\ncanonical_unit(f::ConstPoly) = canonical_unit(f.c)\n\n# String I/O\n\nfunction show(io::IO, R::ConstPolyRing)\n print(io, \"Constant polynomials over \")\n show(io, base_ring(R))\nend\n\nfunction show(io::IO, f::ConstPoly)\n print(io, f.c)\nend\n\n# Expressification (optional)\n\nfunction expressify(R::ConstPolyRing; context = nothing)\n return Expr(:sequence, Expr(:text, \"Constant polynomials over \"),\n expressify(base_ring(R), context = context))\nend\n\nfunction expressify(f::ConstPoly; context = nothing)\n return expressify(f.c, context = context)\nend\n\n# Unary operations\n\nfunction -(f::ConstPoly)\n R = parent(f)\n return R(-f.c)\nend\n\n# Binary operations\n\nfunction +(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n parent(f) != parent(g) && error(\"Incompatible rings\")\n R = parent(f)\n return R(f.c + g.c)\nend\n\nfunction -(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n parent(f) != parent(g) && error(\"Incompatible rings\")\n R = parent(f)\n return R(f.c - g.c)\nend\n\nfunction *(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n parent(f) != parent(g) && error(\"Incompatible rings\")\n R = parent(f)\n return R(f.c*g.c)\nend\n\n# Comparison\n\nfunction ==(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n parent(f) != parent(g) && error(\"Incompatible rings\")\n return f.c == g.c\nend\n\nfunction isequal(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n parent(f) != parent(g) && error(\"Incompatible rings\")\n return isequal(f.c, g.c)\nend\n\n# Powering need not be implemented if * is\n\n# Exact division\n\nfunction divexact(f::ConstPoly{T}, g::ConstPoly{T}; check::Bool = true) where T <: RingElement\n parent(f) != parent(g) && error(\"Incompatible rings\")\n R = parent(f)\n return R(divexact(f.c, g.c, check = check))\nend\n\n# Inverse\n\nfunction inv(f::ConstPoly)\n R = parent(f)\n return R(AbstractAlgebra.inv(f.c))\nend\n\n# Unsafe operators\n\nfunction zero!(f::ConstPoly)\n f.c = zero(base_ring(parent(f)))\n return f\nend\n\nfunction mul!(f::ConstPoly{T}, g::ConstPoly{T}, h::ConstPoly{T}) where T <: RingElement\n f.c = g.c*h.c\n return f\nend\n\nfunction add!(f::ConstPoly{T}, g::ConstPoly{T}, h::ConstPoly{T}) where T <: RingElement\n f.c = g.c + h.c\n return f\nend\n\nfunction addeq!(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n f.c += g.c\n return f\nend\n\n# Random generation\n\nRandomExtensions.maketype(R::ConstPolyRing, _) = elem_type(R)\n\nrand(rng::AbstractRNG, sp::SamplerTrivial{<:Make2{ConstPoly,ConstPolyRing}}) =\n sp[][1](rand(rng, sp[][2]))\n\nrand(rng::AbstractRNG, R::ConstPolyRing, n::UnitRange{Int}) = R(rand(rng, n))\n\nrand(R::ConstPolyRing, n::UnitRange{Int}) = rand(Random.GLOBAL_RNG, R, n)\n\n# Promotion rules\n\npromote_rule(::Type{ConstPoly{T}}, ::Type{ConstPoly{T}}) where T <: RingElement = ConstPoly{T}\n\nfunction promote_rule(::Type{ConstPoly{T}}, ::Type{U}) where {T <: RingElement, U <: RingElement}\n promote_rule(T, U) == T ? ConstPoly{T} : Union{}\nend\n\n# Constructors\n\nfunction (R::ConstPolyRing{T})() where T <: RingElement\n r = ConstPoly{T}(base_ring(R)(0))\n r.parent = R\n return r\nend\n\nfunction (R::ConstPolyRing{T})(c::Integer) where T <: RingElement\n r = ConstPoly{T}(base_ring(R)(c))\n r.parent = R\n return r\nend\n\n# Needed to prevent ambiguity\nfunction (R::ConstPolyRing{T})(c::T) where T <: Integer\n r = ConstPoly{T}(base_ring(R)(c))\n r.parent = R\n return r\nend\n\nfunction (R::ConstPolyRing{T})(c::T) where T <: RingElement\n base_ring(R) != parent(c) && error(\"Unable to coerce element\")\n r = ConstPoly{T}(c)\n r.parent = R\n return r\nend\n\nfunction (R::ConstPolyRing{T})(f::ConstPoly{T}) where T <: RingElement\n R != parent(f) && error(\"Unable to coerce element\")\n return f\nend\n\n# Parent constructor\n\nfunction ConstantPolynomialRing(R::Ring, cached::Bool=true)\n T = elem_type(R)\n return ConstPolyRing{T}(R, cached)\nend","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"The above implementation of ConstantPolynomialRing may be tested as follows.","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"using Test\ninclude(joinpath(pathof(AbstractAlgebra), \"..\", \"..\", \"test\", \"Rings-conformance-tests.jl\"))\n\nS, _ = polynomial_ring(QQ, \"x\")\n\nfunction test_elem(R::ConstPolyRing{elem_type(S)})\n return R(rand(base_ring(R), 1:6, -999:999))\nend\n\ntest_Ring_interface(ConstantPolynomialRing(S))","category":"page"},{"location":"Hecke/elliptic_curves/number_fields/#Elliptic-curves-over-rationals-and-number-fields","page":"Elliptic curves over rationals and number fields","title":"Elliptic curves over rationals and number fields","text":"","category":"section"},{"location":"Hecke/orders/frac_ideals/#Fractional-ideals","page":"Fractional ideals","title":"Fractional ideals","text":"","category":"section"},{"location":"Hecke/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"A fractional ideal in the number field K is a Z_K-module A such that there exists an integer d0 which dA is an (integral) ideal in Z_K. Due to the Dedekind property of Z_K, the ideals for a multiplicative group.","category":"page"},{"location":"Hecke/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"Fractional ideals are represented as an integral ideal and an additional denominator. They are of type NfOrdFracIdl.","category":"page"},{"location":"Hecke/orders/frac_ideals/#Creation","page":"Fractional ideals","title":"Creation","text":"","category":"section"},{"location":"Hecke/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"fractional_ideal(::NfOrd, ::ZZMatrix)\nfractional_ideal(::NfOrd, ::ZZMatrix, ::ZZRingElem)\nfractional_ideal(::NfOrd, ::FakeFmpqMat)\nfractional_ideal(::NfOrd, ::NfOrdIdl)\nfractional_ideal(::NfOrd, ::NfOrdIdl, ::ZZRingElem)\nfractional_ideal(::NfOrd, ::nf_elem)\nfractional_ideal(::NfOrd, ::NfOrdElem)\ninv(::NfOrdIdl)","category":"page"},{"location":"Hecke/orders/frac_ideals/#fractional_ideal-Tuple{NfOrd, ZZMatrix}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::NfAbsOrd, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> NfAbsOrdFracIdl\n\nCreates the fractional ideal of mathcal O with basis matrix Mb. If M_in_hnf is set, then it is assumed that A is already in lower left HNF.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#fractional_ideal-Tuple{NfOrd, ZZMatrix, ZZRingElem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::NfAbsOrd, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> NfAbsOrdFracIdl\n\nCreates the fractional ideal of mathcal O with basis matrix Mb. If M_in_hnf is set, then it is assumed that A is already in lower left HNF.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#fractional_ideal-Tuple{NfOrd, FakeFmpqMat}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::NfAbsOrd, M::FakeFmpqMat; M_in_hnf::Bool = false) -> NfAbsOrdFracIdl\n\nCreates the fractional ideal of mathcal O with basis matrix M. If M_in_hnf is set, then it is assumed that the numerator of M is already in lower left HNF.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#fractional_ideal-Tuple{NfOrd, NfOrdIdl}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::NfOrd, I::NfAbsOrdIdl) -> NfOrdFracIdl\n\nThe fractional ideal of O generated by a Z-basis of I.\n\n\n\n\n\nfractional_ideal(O::NfAbsOrd, I::NfAbsOrdIdl) -> NfAbsOrdFracIdl\n\nTurns the ideal I into a fractional ideal of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#fractional_ideal-Tuple{NfOrd, NfOrdIdl, ZZRingElem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::NfAbsOrd, I::NfAbsOrdIdl, b::ZZRingElem) -> NfAbsOrdFracIdl\n\nCreates the fractional ideal Ib of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#fractional_ideal-Tuple{NfOrd, nf_elem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::NfAbsOrd, a::nf_elem) -> NfAbsOrdFracIdl\n\nCreates the principal fractional ideal (a) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#fractional_ideal-Tuple{NfOrd, NfOrdElem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::NfAbsOrd, a::NfAbsOrdElem) -> NfAbsOrdFracIdl\n\nCreates the principal fractional ideal (a) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#inv-Tuple{NfOrdIdl}","page":"Fractional ideals","title":"inv","text":" inv(a::LocElem{T}, checked::Bool = true) where {T <: RingElem}\n\nReturns the inverse element of a if a is a unit. If 'checked = false' the invertibility of a is not checked and the corresponding inverse element of the Fraction Field is returned.\n\n\n\n\n\ninv(A::NfAbsOrdIdl) -> NfOrdFracIdl\n\nComputes the inverse of A, that is, the fractional ideal B such that AB = mathcal O_K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#Arithmetic","page":"Fractional ideals","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"All the normal operations are provided as well.","category":"page"},{"location":"Hecke/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"inv(::NfOrdFracIdl)\nintegral_split(::NfOrdFracIdl)\nnumerator(::NfRelOrdFracIdl)\ndenominator(::NfRelOrdFracIdl)","category":"page"},{"location":"Hecke/orders/frac_ideals/#inv-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Fractional ideals","title":"inv","text":" inv(a::LocElem{T}, checked::Bool = true) where {T <: RingElem}\n\nReturns the inverse element of a if a is a unit. If 'checked = false' the invertibility of a is not checked and the corresponding inverse element of the Fraction Field is returned.\n\n\n\n\n\ninv(A::NfAbsOrdFracIdl) -> NfAbsOrdFracIdl\n\nReturns the fractional ideal B such that AB = mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#integral_split-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Fractional ideals","title":"integral_split","text":"integral_split(A::NfAbsOrdFracIdl) -> NfAbsOrdIdl, NfAbsOrdIdl\n\nComputes the unique coprime integral ideals N and D s.th. A = ND^-1\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#numerator-Tuple{Hecke.NfRelOrdFracIdl}","page":"Fractional ideals","title":"numerator","text":"numerator(a::NfRelOrdFracIdl) -> NfRelOrdIdl\n\nReturns the ideal d*a where d is the denominator of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#denominator-Tuple{Hecke.NfRelOrdFracIdl}","page":"Fractional ideals","title":"denominator","text":"denominator(a::NfRelOrdFracIdl) -> ZZRingElem\n\nReturns the smallest positive integer d such that da is contained in the order of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#Miscaellenous","page":"Fractional ideals","title":"Miscaellenous","text":"","category":"section"},{"location":"Hecke/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"order(::NfOrdFracIdl)\nbasis_matrix(::NfOrdFracIdl)\nbasis_mat_inv(::NfOrdFracIdl)\nbasis(::NfOrdFracIdl)\nnorm(::NfOrdFracIdl)","category":"page"},{"location":"Hecke/orders/frac_ideals/#order-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Fractional ideals","title":"order","text":"order(::Type{T} = ZZRingElem, c::CycleType) where T <: IntegerUnion\n\nReturn the order of the permutations with cycle structure c.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> all(x -> order(cycle_structure(x)) == order(x), gens(g))\ntrue\n\n\n\n\n\norder(a::NfAbsOrdFracIdl) -> NfAbsOrd\n\nThe order that was used to define the ideal a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#basis_matrix-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Fractional ideals","title":"basis_matrix","text":"basis_matrix(I::NfAbsOrdFracIdl) -> FakeFmpqMat\n\nReturns the basis matrix of I with respect to the basis of the order.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#basis_mat_inv-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Fractional ideals","title":"basis_mat_inv","text":"basis_mat_inv(I::NfAbsOrdFracIdl) -> FakeFmpqMat\n\nReturns the inverse of the basis matrix of I.\n\n\n\n\n\nbasis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat\n\nReturn the inverse of the basis matrix of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#basis-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Fractional ideals","title":"basis","text":"basis(I::NfAbsOrdFracIdl) -> Vector{nf_elem}\n\nReturns the mathbf Z-basis of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/orders/frac_ideals/#norm-Tuple{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Fractional ideals","title":"norm","text":"norm(I::NfAbsOrdFracIdl) -> QQFieldElem\n\nReturns the norm of I.\n\n\n\n\n\nnorm(a::NfRelOrdIdl) -> NfOrdIdl\n\nReturns the norm of a.\n\n\n\n\n\nnorm(a::NfRelOrdFracIdl{T, S}) -> S\n\nReturns the norm of a.\n\n\n\n\n\nnorm(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd; copy::Bool = true) -> QQFieldElem\n\nReturns the norm of a considered as an (possibly fractional) ideal of O.\n\n\n\n\n\nnorm(a::AlgAssRelOrdIdl{S, T, U}, O::AlgAssRelOrd{S, T, U}; copy::Bool = true)\n where { S, T, U } -> T\n\nReturns the norm of a considered as an (possibly fractional) ideal of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#Factored-Elements","page":"Factored Elements","title":"Factored Elements","text":"","category":"section"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"In many applications in number theory related to the multiplicative structure of number fields, interesting elements, e.g. units, are extremely large when written wrt. to a fxied basis for the field: for the fundamental unit in Qsqrt d it is known that the coefficients wrt. the canonical basis 1 sqrt d can have O(exp sqrt d) many digits. All currently known, fast methods construct those elements as power products of smaller elements, allowing the computer to handle them.","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"Mathematically, one can think of factored elements to formally live in the ring ZK the group ring of the non-zero field elements. Thus elements are of the form $ \\prod ai^{ei}$ where a_i are elements in K, typically small and the e_iin Z are frequently large exponents. We refer to the a_i as the base and the e_i as the exponents of the factored element.","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"Since K is, in general, no PID, this presentation is non-unique, elements in this form can easily be multiplied, raised to large powers, but in general not compared and not added.","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"In Hecke, this is caputured more generally by the type FacElem, parametrized by the type of the elements in the base and the type of their parent.","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"Important special cases are","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"FacElem{ZZRingElem, ZZRing}, factored integers\nFacElem{nf_elem, AnticNumberField}, factored algerbaic numbers\nFacElem{NfAbsOrdIdl, NfAbsOrdIdlSet}, factored ideals","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"It should be noted that an object of type `FacElemZZRingElem ZZRing will, in general, not represent an integer as the exponents can be negative.","category":"page"},{"location":"Hecke/FacElem/#Construction","page":"Factored Elements","title":"Construction","text":"","category":"section"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"In general one can define factored elements by giving 2 arrays, the base and the exponent, or a dictionary containing the pairs:","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"FacElem\nFacElem(a::nf_elem)","category":"page"},{"location":"Hecke/FacElem/#FacElem","page":"Factored Elements","title":"FacElem","text":"FacElem{B, S}\n\nType for factored elements, that is elements of the form prod ai^ki for elements a_i of type B in a ring of type S.\n\n\n\n\n\n","category":"type"},{"location":"Hecke/FacElem/#FacElem-Tuple{nf_elem}","page":"Factored Elements","title":"FacElem","text":"FacElem{B}(R, base::Vector{B}, exp::Vector{ZZRingElem}) -> FacElem{B}\n\nReturns the element prod b_i^e_i, un-expanded.\n\n\n\n\n\nFacElem{B}(base::Vector{B}, exp::Vector{ZZRingElem}) -> FacElem{B}\n\nReturns the element prod b_i^e_i, un-expanded.\n\n\n\n\n\nFacElem{B}(R, d::Dict{B, ZZRingElem}) -> FacElem{B}\nFacElem{B}(R, d::Dict{B, Integer}) -> FacElem{B}\n\nReturns the element prod b^dp, un-expanded.\n\n\n\n\n\nFacElem{B}(d::Dict{B, ZZRingElem}) -> FacElem{B}\nFacElem{B}(d::Dict{B, Integer}) -> FacElem{B}\n\nReturns the element prod b^dp, un-expanded.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"ideal(::NfOrd, ::FacElem{nf_elem, AnticNumberField})","category":"page"},{"location":"Hecke/FacElem/#ideal-Tuple{NfOrd, FacElem{nf_elem, AnticNumberField}}","page":"Factored Elements","title":"ideal","text":" ideal(O::NfOrd, a::FacElem{nf_elem, AnticNumberField)\n\nThe factored fractional ideal a*O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#Conversion","page":"Factored Elements","title":"Conversion","text":"","category":"section"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"The process of computing the value defined by a factored element is available as evaluate. Depending on the types involved this can be very efficient.","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"evaluate(::FacElem{ZZRingElem, S}) where S\nevaluate(::FacElem{QQFieldElem, S} where S)\nevaluate(::FacElem{T,S} where S) where T\nevaluate_naive(::FacElem{T,S} where S) where T","category":"page"},{"location":"Hecke/FacElem/#evaluate-Union{Tuple{FacElem{ZZRingElem, S}}, Tuple{S}} where S","page":"Factored Elements","title":"evaluate","text":"evaluate{T}(x::FacElem{T}) -> T\n\nExpands or evaluates the factored element, i.e. actually computes the value. Does \"square-and-multiply\" on the exponent vectors.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#evaluate-Tuple{FacElem{QQFieldElem}}","page":"Factored Elements","title":"evaluate","text":"evaluate(x::FacElem{QQFieldElem}) -> QQFieldElem\nevaluate(x::FacElem{ZZRingElem}) -> ZZRingElem\n\nExpands or evaluates the factored element, i.e. actually computes the the element. Works by first obtaining a simplified version of the power product into coprime base elements.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#evaluate-Union{Tuple{FacElem{T}}, Tuple{T}} where T","page":"Factored Elements","title":"evaluate","text":"evaluate{T}(x::FacElem{T}) -> T\n\nExpands or evaluates the factored element, i.e. actually computes the value. Does \"square-and-multiply\" on the exponent vectors.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#evaluate_naive-Union{Tuple{FacElem{T}}, Tuple{T}} where T","page":"Factored Elements","title":"evaluate_naive","text":"evaluate_naive{T}(x::FacElem{T}) -> T\n\nExpands or evaluates the factored element, i.e. actually computes the value. Uses the obvious naive algorithm. Faster for input in finite rings.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#Special-functions","page":"Factored Elements","title":"Special functions","text":"","category":"section"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"In the case where the parent of the base allows for efficient gcd computation, power products can be made unique:","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"simplify(x::FacElem{NfOrdIdl, NfOrdIdlSet})\nsimplify(x::FacElem{QQFieldElem,S} where S)","category":"page"},{"location":"Hecke/FacElem/#simplify-Tuple{FacElem{NfOrdIdl, Hecke.NfAbsOrdIdlSet{AnticNumberField, nf_elem}}}","page":"Factored Elements","title":"simplify","text":"simplify(x::FacElem{NfOrdIdl, NfOrdIdlSet}) -> FacElem\nsimplify(x::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}) -> FacElem\n\nUses coprime_base to obtain a simplified version of x, ie. in the simplified version all base ideals will be pariwise coprime but not necessarily prime!.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#simplify-Tuple{FacElem{QQFieldElem}}","page":"Factored Elements","title":"simplify","text":"simplify(x::FacElem{QQFieldElem}) -> FacElem{QQFieldElem}\nsimplify(x::FacElem{ZZRingElem}) -> FacElem{ZZRingElem}\n\nSimplfies the factored element, i.e. arranges for the base to be coprime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"The simplified version can then be used further:","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"isone(x::FacElem{QQFieldElem, S} where S)\nfactor_coprime(::FacElem{ZZRingElem, S} where S)\nfactor_coprime(::FacElem{NfOrdIdl, NfOrdIdlSet})\nfactor_coprime(::FacElem{NfOrdFracIdl, NfOrdFracIdlSet})\nfactor_coprime(::NfOrdIdlSet, ::FacElem{nf_elem, AnticNumberField})\nfactor(::FacElem{NfOrdFracIdl, NfOrdFracIdlSet})\nfactor(::NfOrdIdlSet, ::FacElem{nf_elem, AnticNumberField})","category":"page"},{"location":"Hecke/FacElem/#isone-Tuple{FacElem{QQFieldElem}}","page":"Factored Elements","title":"isone","text":"isone(x::FacElem{QQFieldElem}) -> Bool\nisone(x::FacElem{ZZRingElem}) -> Bool\n\nTests if x represents 1 without an evaluation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#factor_coprime-Tuple{FacElem{ZZRingElem}}","page":"Factored Elements","title":"factor_coprime","text":"factor_coprime(x::FacElem{ZZRingElem}) -> Fac{ZZRingElem}\n\nComputed a partial factorisation of x, ie. writes x as a product of pariwise coprime integers.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#factor_coprime-Tuple{FacElem{NfOrdIdl, Hecke.NfAbsOrdIdlSet{AnticNumberField, nf_elem}}}","page":"Factored Elements","title":"factor_coprime","text":"factor_coprime(x::FacElem{NfOrdIdl, NfOrdIdlSet}) -> Dict{NfOrdIdl, Int}\n\nComputed a partial factorisation of x, ie. writes x as a product of pariwise coprime integral ideals.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#factor_coprime-Tuple{FacElem{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfAbsOrdFracIdlSet{AnticNumberField, nf_elem}}}","page":"Factored Elements","title":"factor_coprime","text":"factor_coprime(Q::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}) -> Dict{NfOrdIdl, Int}\n\nA coprime factorisation of Q: each ideal in Q is split using \\code{integral_split} and then a coprime basis is computed. This does {\\bf not} use any factorisation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#factor_coprime-Tuple{Hecke.NfAbsOrdIdlSet{AnticNumberField, nf_elem}, FacElem{nf_elem, AnticNumberField}}","page":"Factored Elements","title":"factor_coprime","text":"factor_coprime(I::NfOrdIdlSet, a::FacElem{nf_elem, AnticNumberField}) -> Dict{NfOrdIdl, ZZRingElem}\n\nFactors the rincipal ideal generated by a into coprimes by computing a coprime basis from the principal ideals in the factorisation of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#factor-Tuple{FacElem{Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfAbsOrdFracIdlSet{AnticNumberField, nf_elem}}}","page":"Factored Elements","title":"factor","text":" factor(Q::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}) -> Dict{NfOrdIdl, Int}\n\nThe factorisation of Q, by refining a coprime factorisation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#factor-Tuple{Hecke.NfAbsOrdIdlSet{AnticNumberField, nf_elem}, FacElem{nf_elem, AnticNumberField}}","page":"Factored Elements","title":"factor","text":"factor(I::NfOrdIdlSet, a::FacElem{nf_elem, AnticNumberField}) -> Dict{NfOrdIdl, ZZRingElem}\n\nFactors the principal ideal generated by a by refining a coprime factorisation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"For factorised algebraic numbers a unique simplification is not possible, however, this allows still do obtain partial results:","category":"page"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"compact_presentation(a::FacElem{nf_elem, AnticNumberField}, n::Int = 2)","category":"page"},{"location":"Hecke/FacElem/#compact_presentation","page":"Factored Elements","title":"compact_presentation","text":"compact_presentation(a::FacElem{nf_elem, AnticNumberField}, n::Int = 2; decom, arb_prec = 100, short_prec = 1000) -> FacElem\n\nComputes a presentation a = prod a_i^n_i where all the exponents n_i are powers of n and, the elements a_i are \"small\", generically, they have a norm bounded by d^n2 where d is the discriminant of the maximal order. As the algorithm needs the factorisation of the principal ideal generated by a, it can be passed in in \\code{decom}.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"valuation(::FacElem{nf_elem,AnticNumberField}, ::NfAbsOrdIdl{AnticNumberField,nf_elem})\nvaluation(::FacElem{NfAbsOrdIdl{AnticNumberField,nf_elem},Hecke.NfAbsOrdIdlSet{AnticNumberField,nf_elem}}, ::NfAbsOrdIdl{AnticNumberField,nf_elem})\nevaluate_mod(::FacElem{nf_elem,AnticNumberField}, ::NfOrdFracIdl)\nreduce_ideal(::FacElem{NfAbsOrdIdl{AnticNumberField,nf_elem},Hecke.NfAbsOrdIdlSet{AnticNumberField,nf_elem}})\nmodular_proj(::FacElem{nf_elem,AnticNumberField}, ::Hecke.modular_env)","category":"page"},{"location":"Hecke/FacElem/#valuation-Tuple{FacElem{nf_elem, AnticNumberField}, NfOrdIdl}","page":"Factored Elements","title":"valuation","text":"valuation(a::FacElem{nf_elem, AnticNumberField}, P::NfOrdIdl) -> ZZRingElem\n\nThe valuation of a at P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#valuation-Tuple{FacElem{NfOrdIdl, Hecke.NfAbsOrdIdlSet{AnticNumberField, nf_elem}}, NfOrdIdl}","page":"Factored Elements","title":"valuation","text":"valuation(A::FacElem{NfOrdFracIdl, NfOrdFracIdlSet}, p::NfOrdIdl)\nvaluation(A::FacElem{NfOrdIdl, NfOrdIdlSet}, p::NfOrdIdl)\n\nThe valuation of A at P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#evaluate_mod-Tuple{FacElem{nf_elem, AnticNumberField}, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}}","page":"Factored Elements","title":"evaluate_mod","text":"evaluate_mod(a::FacElem{nf_elem, AnticNumberField}, B::NfOrdFracIdl) -> nf_elem\n\nEvaluates a using CRT and small primes. Assumes that the ideal generated by a is in fact B. Useful in cases where a has huge exponents, but the evaluated element is actually \"small\".\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#reduce_ideal-Tuple{FacElem{NfOrdIdl, Hecke.NfAbsOrdIdlSet{AnticNumberField, nf_elem}}}","page":"Factored Elements","title":"reduce_ideal","text":"reduce_ideal(A::FacElem{NfOrdIdl}) -> NfOrdIdl, FacElem{nf_elem}\n\nComputes B and alpha in factored form, such that alpha B = A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#modular_proj-Tuple{FacElem{nf_elem, AnticNumberField}, Hecke.modular_env}","page":"Factored Elements","title":"modular_proj","text":"modular_proj(a::FacElem{nf_elem, AnticNumberField}, me::modular_env) -> Vector{fqPolyRepFieldElem}\n\nGiven an algebraic number a in factored form and data \\code{me} as computed by \\code{modular_init}, project a onto the residue class fields.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#Positivity-and-Signs","page":"Factored Elements","title":"Positivity & Signs","text":"","category":"section"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"Factored elements can be used instead of number field elements for the functions sign, signs, is_positive, is_negative and is_totally_positive, see Positivity & Signs","category":"page"},{"location":"Hecke/FacElem/#Miscellaneous","page":"Factored Elements","title":"Miscellaneous","text":"","category":"section"},{"location":"Hecke/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"max_exp(a::FacElem)\nmin_exp(a::FacElem)\nmaxabs_exp(a::FacElem)","category":"page"},{"location":"Hecke/FacElem/#max_exp-Tuple{FacElem}","page":"Factored Elements","title":"max_exp","text":"max_exp(a::FacElem)\n\nFinds the largest exponent in the factored element a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#min_exp-Tuple{FacElem}","page":"Factored Elements","title":"min_exp","text":"min_exp(a::FacElem)\n\nFinds the smallest exponent in the factored element a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/FacElem/#maxabs_exp-Tuple{FacElem}","page":"Factored Elements","title":"maxabs_exp","text":"maxabs_exp(a::FacElem)\n\nFinds the largest exponent by absolute value in the factored element a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/#Sparse-distributed-multivariate-Laurent-polynomials","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"Every element of the multivariate Laurent polynomial ring Rx_1 x_1^-1 dots x_n x_n^-1 can be presented as a sum of products of powers of the x_i where the power can be any integer. Therefore, the interface for sparse multivarate polynomials carries over with the additional feature that exponents can be negative.","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/#Generic-multivariate-Laurent-polynomial-types","page":"Sparse distributed multivariate Laurent polynomials","title":"Generic multivariate Laurent polynomial types","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"AbstractAlgebra.jl provides a generic implementation of multivariate Laurent polynomials, built in terms of regular multivariate polynomials, in the file src/generic/LaurentMPoly.jl.","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"The type LaurentMPolyWrap{T, ...} <: LaurentMPolyRingElem{T} implements generic multivariate Laurent polynomials by wrapping regular polynomials: a Laurent polynomial l wraps a polynomial p and a vector of integers n_i such that l = prod_i x_i^n_i * p. The representation is said to be normalized when each n_i is as large as possible (or zero when l is zero), but the representation of a given element is not required to be normalized internally.","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"The corresponding parent type is LaurentMPolyWrapRing{T, ...} <: LaurentMPolyRing{T}.","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/#Abstract-types","page":"Sparse distributed multivariate Laurent polynomials","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"Two abstract types LaurentMPolyRingElem{T} and LaurentMPolyRing{T} are defined to represent Laurent polynomials and rings thereof, parameterized on a base ring T.","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/#Multivate-Laurent-polynomial-operations","page":"Sparse distributed multivariate Laurent polynomials","title":"Multivate Laurent polynomial operations","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"Since, from the point of view of the interface, Laurent polynomials are simply regular polynomials with possibly negative exponents, the following functions from the polynomial interface are completely analogous. As with regular polynomials, an implementation must provide access to the elements as a sum of individual terms in some order. This order currently cannot be specified in the constructor.","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"LaurentPolynomialRing(R::Ring, S::Vector{<:VarName}; cached::Bool = true)\nLaurentPolynomialRing(R::Ring, n::Int, s::VarName; cached::Bool = false)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"(S::LaurentMPolyRing{T})(A::Vector{T}, m::Vector{Vector{Int}})","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"MPolyBuildCtx(R::LaurentMPolyRing)\npush_term!(M::LaurentMPolyBuildCtx, c::RingElem, v::Vector{Int})\nfinish(M::LaurentMPolyBuildCtx)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"symbols(S::LaurentMPolyRing)\nnvars(f::LaurentMPolyRing)\ngens(S::LaurentMPolyRing)\ngen(S::LaurentMPolyRing, i::Int)\nis_gen(x::LaurentMPolyRingElem)\nvar_index(p::LaurentMPolyRingElem)\nlength(f::LaurentMPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"coefficients(p::LaurentMPolyRingElem)\nmonomials(p::LaurentMPolyRingElem)\nterms(p::LaurentMPolyRingElem)\nexponent_vectors(p::LaurentMPolyRingElem)\nleading_coefficient(p::LaurentMPolyRingElem)\nleading_monomial(p::LaurentMPolyRingElem)\nleading_term(p::LaurentMPolyRingElem)\nleading_exponent_vector(p::LaurentMPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"change_base_ring(::Ring, p::LaurentMPolyRingElem)\nchange_coefficient_ring(::Ring, p::LaurentMPolyRingElem)\nmap_coefficients(::Any, p::LaurentMPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"evaluate(p::LaurentMPolyRingElem, ::Vector)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"derivative(p::LaurentMPolyRingElem, x::LaurentMPolyRingElem)\nderivative(p::LaurentMPolyRingElem, i::Int)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"rand(R::LaurentMPolyRingElem, length_range::UnitRange{Int}, exp_range::UnitRange{Int}, v...)","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"The choice of canonical unit for Laurent polynomials includes the product prod_i x_i^n_i from the normalized representation. In particular, this means that the output of gcd will not have any negative exponents.","category":"page"},{"location":"AbstractAlgebra/laurent_mpolynomial/","page":"Sparse distributed multivariate Laurent polynomials","title":"Sparse distributed multivariate Laurent polynomials","text":"julia> R, (x, y) = LaurentPolynomialRing(ZZ, [\"x\", \"y\"]);\n\njulia> canonical_unit(2*x^-5 - 3*x + 4*y^-4 + 5*y^2)\n-x^-5*y^-4\n\njulia> gcd(x^-3 - y^3, x^-2 - y^2)\nx*y - 1","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Fields/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"The fields part of OSCAR provides functionality for handling various kinds of fields:","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"the field of rationals\nNumber fields\nGeneric fraction fields\nlocal fields (Padics and Qadics)\nfinite fields","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"Henri Cohen (1993)\nHenri Cohen (2000)\nRudolf Lidl, Harald Niederreiter (1997)\nDaniel A. Marcus (2018)\nM. Pohst, H. Zassenhaus (1997)","category":"page"},{"location":"Fields/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"Claus Fieker,\nTommy Hofmann,\nMax Horn.","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Hecke/dev/test/#Testing","page":"Testing","title":"Testing","text":"","category":"section"},{"location":"Hecke/dev/test/#Structure","page":"Testing","title":"Structure","text":"","category":"section"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"The Hecke tests can be found in Hecke/test/ and are organized in such a way that the file hierarchy mirrors the source directory Hecke/src/. For example, here is a subset of the src/QuadForm and the test/QuadForm directories:","category":"page"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"├── src\n│   ├── QuadForm\n│   │   ├── Enumeration.jl\n│   │   ├── Herm\n│   │   │   ├── Genus.jl\n│   │   ├── Quad\n│   │   │   ├── Genus.jl\n│   │   │   ├── GenusRep.jl\n│   │   │   ├── NormalForm.jl\n│   │   │   ├── Spaces.jl\n│   │   │   ├── Types.jl\n│   │   │   ├── ZGenus.jl\n│   │   │   └── ZLattices.jl\n│   │   ├── QuadBin.jl\n│   │   ├── Torsion.jl\n│   ├── QuadForm.jl\n│\n│\n│\n├── test\n│   ├── QuadForm\n│   │   ├── Enumeration.jl\n│   │   ├── Herm\n│   │   │   ├── Genus.jl\n│   │   ├── Quad\n│   │   │   ├── Genus.jl\n│   │   │   ├── GenusRep.jl\n│   │   │   ├── NormalForm.jl\n│   │   │   ├── Spaces.jl\n│   │   │   ├── ZGenus.jl\n│   │   │   └── ZLattices.jl\n│   │   ├── QuadBin.jl\n│   │   └── Torsion.jl\n│   ├── QuadForm.jl","category":"page"},{"location":"Hecke/dev/test/#Adding-tests","page":"Testing","title":"Adding tests","text":"","category":"section"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"If one adds functionality to a file, say src/QuadForm/Quad/Genus.jl, a corresponding a test should be added to the corresponding test file. In this case this would be test/QuadForm/Quad/Genus.jl.\nAssume one adds a new file, say src/QuadForm/New.jl, which is included in src/QuadForm.jl. Then a corresponding file test/QuadForm/Test.jl containing the tests must be added. This new file must then also be included in test/QuadForm.jl.\nSimilar to the above, if a new directory in src/ is added, the same must apply in test/.","category":"page"},{"location":"Hecke/dev/test/#Adding-long-tests","page":"Testing","title":"Adding long tests","text":"","category":"section"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"If one knows that running a particular test will take a long time, one can use @long_test instead of @test inside the test suite. When running the test suite, tests annotated with @long_test will not be run, unless specifically asked for (see below). The continuous integration servers will run at least one job including the long tests.","category":"page"},{"location":"Hecke/dev/test/#Running-the-tests","page":"Testing","title":"Running the tests","text":"","category":"section"},{"location":"Hecke/dev/test/#Running-all-tests","page":"Testing","title":"Running all tests","text":"","category":"section"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"All tests can be run as usual with Pkg.test(\"Hecke\"). The whole test suite can be run in parallel using the following options:","category":"page"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"Set the environment variable HECKE_TEST_VARIABLE=n, where n is the number of processes.\nOn julia >= 1.3, run Pkg.test(\"Hecke\", test_args = [\"-j$(n)\"]), where n is the number of processes.","category":"page"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"The tests annotated with @long_test can be invoked by setting HECKE_TESTLONG=1 or adding \"long\" to the test_args keyword argument on julia >= 1.3.","category":"page"},{"location":"Hecke/dev/test/#Running-a-subset-of-tests","page":"Testing","title":"Running a subset of tests","text":"","category":"section"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"Because the test structure mirrors the source directory, it is easy to run only a subset of tests. For example, to run all the tests in test/QuadForm/Quad/Genus.jl, one can invoke:","category":"page"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"julia> Hecke.test_module(\"QuadForm/Quad/Genus\")","category":"page"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"This also works on the directory level. If one wants to add run all tests for quadratic forms, one can just run","category":"page"},{"location":"Hecke/dev/test/","page":"Testing","title":"Testing","text":"julia> Hecke.test_module(\"QuadForm\")","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/ideal/#Ideal-functionality","page":"Ideal functionality","title":"Ideal functionality","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"AbstractAlgebra.jl provides a module, implemented in src/generic/Ideal.jl for ideals of a Euclidean domain (assuming the existence of a gcdx function) or of a univariate or multivariate polynomial ring over the integers. Univariate and multivariate polynomial rings over other domains (other than fields) are not supported at this time.","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"info: Info\nA more complete implementation for ideals defined over other rings is provided by Hecke and Oscar.","category":"page"},{"location":"AbstractAlgebra/ideal/#Generic-ideal-types","page":"Ideal functionality","title":"Generic ideal types","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"AbstractAlgebra.jl provides a generic ideal type based on Julia arrays which is implemented in src/generic/Ideal.jl.","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"These generic ideals have type Generic.Ideal{T} where T is the type of elements of the ring the ideals belong to. Internally they consist of a Julia array of generators and some additional fields for a parent object, etc. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Parent objects of ideals have type Generic.IdealSet{T}.","category":"page"},{"location":"AbstractAlgebra/ideal/#Abstract-types","page":"Ideal functionality","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"All ideal types belong to the abstract type Ideal{T} and their parents belong to the abstract type Set. This enables one to write generic functions that can accept any AbstractAlgebra ideal type.","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"note: Note\nBoth the generic ideal type Generic.Ideal{T} and the abstract type it belongs to, Ideal{T}, are called Ideal. The former is a (parameterised) concrete type for an ideal in the ring whose elements have type T. The latter is an abstract type representing all ideal types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).","category":"page"},{"location":"AbstractAlgebra/ideal/#Ideal-constructors","page":"Ideal functionality","title":"Ideal constructors","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"One may construct ideals in AbstractAlgebra.jl with the following constructor.","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Generic.Ideal(R::Ring, V::Vector{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Given a set of elements V in the ring R, construct the ideal of R generated by the elements V. Note that V may be arbitrary, e.g. it can contain duplicates, zero entries or be empty.","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"]; ordering=:degrevlex)\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> V = [3*x^2*y - 3*y^2, 9*x^2*y + 7*x*y]\n2-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:\n 3*x^2*y - 3*y^2\n 9*x^2*y + 7*x*y\n\njulia> I = Generic.Ideal(R, V)\nAbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.MPoly{BigInt}}(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[7*x*y + 9*y^2, 243*y^3 - 147*y^2, x*y^2 + 36*y^3 - 21*y^2, x^2*y + 162*y^3 - 99*y^2])\n\njulia> W = map(ZZ, [2, 5, 7])\n3-element Vector{BigInt}:\n 2\n 5\n 7\n\njulia> J = Generic.Ideal(ZZ, W)\nAbstractAlgebra.Generic.Ideal{BigInt}(Integers, BigInt[1])","category":"page"},{"location":"AbstractAlgebra/ideal/#Ideal-functions","page":"Ideal functionality","title":"Ideal functions","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/#Basic-functionality","page":"Ideal functionality","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"gens(::Generic.Ideal{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ideal/#gens-Union{Tuple{AbstractAlgebra.Generic.Ideal{T}}, Tuple{T}} where T<:RingElement","page":"Ideal functionality","title":"gens","text":"gens(I::Ideal{T}) where T <: RingElement\n\nReturn a list of generators of the ideal I in reduced form and canonicalised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> V = [1 + 2x^2 + 3x^3, 5x^4 + 1, 2x - 1]\n3-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:\n 3*x^3 + 2*x^2 + 1\n 5*x^4 + 1\n 2*x - 1\n\njulia> I = Generic.Ideal(R, V)\nAbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.Poly{BigInt}}(Univariate polynomial ring in x over integers, AbstractAlgebra.Generic.Poly{BigInt}[3, x + 1])\n\njulia> gens(I)\n2-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:\n 3\n x + 1","category":"page"},{"location":"AbstractAlgebra/ideal/#Arithmetic-of-Ideals","page":"Ideal functionality","title":"Arithmetic of Ideals","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Ideals support addition, multiplication, scalar multiplication and equality testing of ideals.","category":"page"},{"location":"AbstractAlgebra/ideal/#Containment","page":"Ideal functionality","title":"Containment","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"contains(::Generic.Ideal{T}, ::Generic.Ideal{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ideal/#contains-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.Ideal{T}, AbstractAlgebra.Generic.Ideal{T}}} where T<:RingElement","page":"Ideal functionality","title":"contains","text":"Base.contains(I::Ideal{T}, J::Ideal{T}) where T <: RingElement\n\nReturn true if the ideal J is contained in the ideal I.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"intersection(::Generic.Ideal{T}, ::Generic.Ideal{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ideal/#intersection-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.Ideal{T}, AbstractAlgebra.Generic.Ideal{T}}} where T<:RingElement","page":"Ideal functionality","title":"intersection","text":"intersection(I::Ideal{T}, J::Ideal{T}) where T <: RingElement\n\nReturn the intersection of the ideals I and J.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> V = [1 + 2x^2 + 3x^3, 5x^4 + 1, 2x - 1]\n3-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:\n 3*x^3 + 2*x^2 + 1\n 5*x^4 + 1\n 2*x - 1\n\njulia> W = [1 + 2x^2 + 3x^3, 5x^4 + 1]\n2-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:\n 3*x^3 + 2*x^2 + 1\n 5*x^4 + 1\n\njulia> I = Generic.Ideal(R, V)\nAbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.Poly{BigInt}}(Univariate polynomial ring in x over integers, AbstractAlgebra.Generic.Poly{BigInt}[3, x + 1])\n\njulia> J = Generic.Ideal(R, W)\nAbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.Poly{BigInt}}(Univariate polynomial ring in x over integers, AbstractAlgebra.Generic.Poly{BigInt}[282, 3*x + 255, x^2 + 107])\n\njulia> contains(J, I)\nfalse\n\njulia> contains(I, J)\ntrue\n\njulia> intersection(I, J) == J\ntrue","category":"page"},{"location":"AbstractAlgebra/ideal/#Normal-form","page":"Ideal functionality","title":"Normal form","text":"","category":"section"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"For ideal of polynomial rings it is possible to return the normal form of a polynomial with respect to an ideal.","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"normal_form(::U, ::Generic.Ideal{U}) where {T <: RingElement, U <: Union{PolyRingElem{T}, MPolyRingElem{T}}}","category":"page"},{"location":"AbstractAlgebra/ideal/#normal_form-Union{Tuple{U}, Tuple{T}, Tuple{U, AbstractAlgebra.Generic.Ideal{U}}} where {T<:RingElement, U<:Union{MPolyRingElem{T}, PolyRingElem{T}}}","page":"Ideal functionality","title":"normal_form","text":"normal_form(p::U, I::Ideal{U}) where {T <: RingElement, U <: Union{AbstractAlgebra.PolyRingElem{T}, AbstractAlgebra.MPolyRingElem{T}}}\n\nReturn the normal form of the polynomial p with respect to the ideal I.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/ideal/","page":"Ideal functionality","title":"Ideal functionality","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"]; ordering=:degrevlex)\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> V = [3*x^2*y - 3*y^2, 9*x^2*y + 7*x*y]\n2-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:\n 3*x^2*y - 3*y^2\n 9*x^2*y + 7*x*y\n\njulia> I = Generic.Ideal(R, V)\nAbstractAlgebra.Generic.Ideal{AbstractAlgebra.Generic.MPoly{BigInt}}(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[7*x*y + 9*y^2, 243*y^3 - 147*y^2, x*y^2 + 36*y^3 - 21*y^2, x^2*y + 162*y^3 - 99*y^2])\n\n\njulia> normal_form(30x^5*y + 2x + 1, I)\n135*y^4 + 138*y^3 - 147*y^2 + 2*x + 1","category":"page"},{"location":"manualindex/","page":"Index","title":"Index","text":"","category":"page"},{"location":"Experimental/Singularities/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/Singularities/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/Singularities/intro/","page":"Introduction","title":"Introduction","text":"The singularities part of OSCAR provides functionality for handling","category":"page"},{"location":"Experimental/Singularities/intro/","page":"Introduction","title":"Introduction","text":"space germs\nmap germs","category":"page"},{"location":"Experimental/Singularities/intro/","page":"Introduction","title":"Introduction","text":"For readers' convenience, the documentation is organised by typical settings, This, on the other hand, implies that certain keywords may appear in several settings. In particular, there are overlaps between hypersurface singularities and curve singularities and between hypersurface singularities and isolated complete intersection singularities","category":"page"},{"location":"Experimental/Singularities/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nMost of the functions discussed here rely on standard bases. These are implemented in OSCAR for localizations of multivariate polynomial rings over fields (exact fields supported by OSCAR) at points with coordinates in said field. This explained in more detail in Generalities on Space Germs.","category":"page"},{"location":"Experimental/Singularities/intro/","page":"Introduction","title":"Introduction","text":"Textbooks offering details on theory (and some algorithms) include:","category":"page"},{"location":"Experimental/Singularities/intro/","page":"Introduction","title":"Introduction","text":"G.-M. Greuel, C. Lossen, E. Shustin (2007) \nTheo de Jong, Gerhard Pfister (2000)\nJose Luis Cisneros Molina, Dung Trang Le, Jose Seade (2020)\nJose Luis Cisneros Molina, Dung Trang Le, Jose Seade (2021)","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/gfp/#Galois-fields","page":"Galois fields","title":"Galois fields","text":"","category":"section"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"Nemo allows the creation of Galois fields of the form mathbbZpmathbbZ for a prime p. Note that these are not the same as finite fields of degree 1, as Conway polynomials are not used and no generator is given.","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"For convenience, the following constructors are provided.","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"GF(n::UInt)\nGF(n::Int)\nGF(n::ZZRingElem)","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"For example, one can create the Galois field of characteristic 7 as follows.","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"R = GF(7)","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"Elements of the field are then created in the usual way.","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"a = R(3)","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"Elements of Galois fields have type fpFieldElem when p is given to the constructor as an Int or UInt, and of type FpFieldElem if p is given as an ZZRingElem, and the type of the parent objects is fpField or FpField respectively.","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"The modulus p of an element of a Galois field is stored in its parent object.","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"The fpFieldElem and FpFieldElem types belong to the abstract type FinFieldElem and the fpField and FpField parent object types belong to the abstract type FinField.","category":"page"},{"location":"Nemo/gfp/#Galois-field-functionality","page":"Galois fields","title":"Galois field functionality","text":"","category":"section"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"Galois fields in Nemo provide all the residue ring functionality of AbstractAlgebra.jl:","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/residue","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"In addition, all the functionality for rings is available:","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/ring","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"Below we describe the functionality that is provided in addition to these.","category":"page"},{"location":"Nemo/gfp/#Basic-manipulation","page":"Galois fields","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"Examples","category":"page"},{"location":"Nemo/gfp/","page":"Galois fields","title":"Galois fields","text":"julia> F = GF(3)\nFinite field of characteristic 3\n\njulia> a = characteristic(F)\n3\n\njulia> b = order(F)\n3","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/polynomial/#Univariate-polynomials","page":"Univariate polynomials","title":"Univariate polynomials","text":"","category":"section"},{"location":"Nemo/polynomial/#Introduction","page":"Univariate polynomials","title":"Introduction","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Nemo allow the creation of dense, univariate polynomials over any computable ring R. There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of polynomials over numerous specific rings, usually provided by C/C++ libraries.","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"The following table shows each of the polynomial types available in Nemo, the base ring R, and the Julia/Nemo types for that kind of polynomial (the type information is mainly of concern to developers).","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl Generic.Poly{T} Generic.PolyRing{T}\nmathbbZ Flint ZZPolyRingElem ZZPolyRing\nmathbbZnmathbbZ (small n) Flint zzModPolyRingElem zzModPolyRing\nmathbbZnmathbbZ (large n) Flint ZZModPolyRingElem ZZModPolyRing\nmathbbQ Flint QQPolyRingElem QQPolyRing\nmathbbZpmathbbZ (small prime p) Flint fpPolyRingElem fpPolyRing\nmathbbZpmathbbZ (large prime p) Flint FpPolyRingElem FpPolyRing\nmathbbF_p^n (small p) Flint fqPolyRepPolyRingElem fqPolyRepPolyRing\nmathbbF_p^n (large p) Flint FqPolyRepPolyRingElem FqPolyRepPolyRing\nmathbbR (arbitrary precision) Arb RealPoly RealPolyRing\nmathbbC (arbitrary precision) Arb ComplexPoly ComplexPolyRing\nmathbbR (fixed precision) Arb arb_poly ArbPolyRing\nmathbbC (fixed precision) Arb acb_poly AcbPolyRing","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"The string representation of the variable and the base ring R of a generic polynomial is stored in its parent object. ","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"All polynomial element types belong to the abstract type PolyRingElem and all of the polynomial ring types belong to the abstract type PolyRing. This enables one to write generic functions that can accept any Nemo univariate polynomial type.","category":"page"},{"location":"Nemo/polynomial/#Polynomial-functionality","page":"Univariate polynomials","title":"Polynomial functionality","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"All univariate polynomial types in Nemo provide the AbstractAlgebra univariate polynomial functionality:","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/polynomial","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Generic polynomials are also available.","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"We describe here only functions that are in addition to that guaranteed by AbstractAlgebra.jl, for specific coefficient rings.","category":"page"},{"location":"Nemo/polynomial/#Remove-and-valuation","page":"Univariate polynomials","title":"Remove and valuation","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"evaluate2(::RealPoly, ::RealFieldElem)","category":"page"},{"location":"Nemo/polynomial/#evaluate2-Tuple{RealPoly, RealFieldElem}","page":"Univariate polynomials","title":"evaluate2","text":"evaluate2(x::RealPoly, y::RingElement)\n\nReturn a tuple p q consisting of the polynomial x evaluated at y and its derivative evaluated at y.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"evaluate2(::ComplexPoly, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/polynomial/#evaluate2-Tuple{ComplexPoly, ComplexFieldElem}","page":"Univariate polynomials","title":"evaluate2","text":"evaluate2(x::ComplexPoly, y::RingElement; prec::Int = precision(Balls))\n\nReturn a tuple p q consisting of the polynomial x evaluated at y and its derivative evaluated at y.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Examples","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"RR = RealField(64)\nT, z = polynomial_ring(RR, \"z\")\n \nh = z^2 + 2z + 1\n\ns, t = evaluate2(h, RR(\"2.0 +/- 0.1\"))","category":"page"},{"location":"Nemo/polynomial/#Signature","page":"Univariate polynomials","title":"Signature","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"signature(::ZZPolyRingElem)\nsignature(::QQPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#signature-Tuple{ZZPolyRingElem}","page":"Univariate polynomials","title":"signature","text":"signature(f::ZZPolyRingElem)\n\nReturn the signature of f, i.e. a tuple (r s) such that r is the number of real roots of f and s is half the number of complex roots.\n\nExamples\n\njulia> R, x = polynomial_ring(ZZ, \"x\");\n\njulia> signature(x^3 + 3x + 1)\n(1, 1)\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#signature-Tuple{QQPolyRingElem}","page":"Univariate polynomials","title":"signature","text":"signature(f::QQPolyRingElem)\n\nReturn the signature of f, i.e. a tuple (r s) such that r is the number of real roots of f and s is half the number of complex roots.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\");\n\njulia> signature(x^3 + 3x + 1)\n(1, 1)\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#Root-finding","page":"Univariate polynomials","title":"Root finding","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"roots(::ComplexPoly)","category":"page"},{"location":"Nemo/polynomial/#roots-Tuple{ComplexPoly}","page":"Univariate polynomials","title":"roots","text":"roots(x::ComplexPoly; target=0, isolate_real=false, initial_prec=0, max_prec=0, max_iter=0)\n\nAttempts to isolate the complex roots of the complex polynomial x by iteratively refining balls in which they lie.\n\nThis is done by increasing the working precision, starting at initial_prec. The maximal number of iterations can be set using max_iter and the maximal precision can be set using max_prec.\n\nIf isolate_real is set and x is strictly real, then the real roots will be isolated from the non-real roots. Every root will have either zero, positive or negative real part.\n\nIt is assumed that x is squarefree.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Examples","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"CC = ComplexField(64)\nC, y = polynomial_ring(CC, \"y\")\n\nm = y^2 + 2y + 3\nn = m + CC(\"0 +/- 0.0001\", \"0 +/- 0.0001\")\n\nr = roots(n)\n\np = y^7 - 1\n\nr = roots(n, isolate_real = true)","category":"page"},{"location":"Nemo/polynomial/#Construction-from-roots","page":"Univariate polynomials","title":"Construction from roots","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"from_roots(::ArbPolyRing, ::Vector{arb})\nfrom_roots(::AcbPolyRing, ::Vector{acb})","category":"page"},{"location":"Nemo/polynomial/#from_roots-Tuple{ArbPolyRing, Vector{arb}}","page":"Univariate polynomials","title":"from_roots","text":"from_roots(R::ArbPolyRing, b::Vector{arb})\n\nConstruct a polynomial in the given polynomial ring from a list of its roots.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#from_roots-Tuple{AcbPolyRing, Vector{acb}}","page":"Univariate polynomials","title":"from_roots","text":"from_roots(R::AcbPolyRing, b::Vector{acb})\n\nConstruct a polynomial in the given polynomial ring from a list of its roots.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Examples","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"RR = RealField(64)\nR, x = polynomial_ring(RR, \"x\")\n\nxs = arb[inv(RR(i)) for i=1:5]\nf = from_roots(R, xs)","category":"page"},{"location":"Nemo/polynomial/#Bounding-absolute-values-of-roots","page":"Univariate polynomials","title":"Bounding absolute values of roots","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"roots_upper_bound(::RealPoly)\nroots_upper_bound(::ComplexPoly)","category":"page"},{"location":"Nemo/polynomial/#roots_upper_bound-Tuple{RealPoly}","page":"Univariate polynomials","title":"roots_upper_bound","text":"roots_upper_bound(x::RealPoly) -> arb\n\nReturns an upper bound for the absolute value of all complex roots of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#roots_upper_bound-Tuple{ComplexPoly}","page":"Univariate polynomials","title":"roots_upper_bound","text":"roots_upper_bound(x::ComplexPoly) -> arb\n\nReturns an upper bound for the absolute value of all complex roots of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#Lifting","page":"Univariate polynomials","title":"Lifting","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"When working over a residue ring it is useful to be able to lift to the base ring of the residue ring, e.g. from mathbbZnmathbbZ to mathbbZ.","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"lift(::ZZPolyRing, ::zzModPolyRingElem)\nlift(::ZZPolyRing, ::fpPolyRingElem)\nlift(::ZZPolyRing, ::ZZModPolyRingElem)\nlift(::ZZPolyRing, ::FpPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#lift-Tuple{ZZPolyRing, zzModPolyRingElem}","page":"Univariate polynomials","title":"lift","text":"lift(R::ZZPolyRing, y::zzModPolyRingElem)\n\nLift from a polynomial over mathbbZnmathbbZ to a polynomial over mathbbZ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#lift-Tuple{ZZPolyRing, fpPolyRingElem}","page":"Univariate polynomials","title":"lift","text":"lift(R::ZZPolyRing, y::fpPolyRingElem)\n\nLift from a polynomial over mathbbZnmathbbZ to a polynomial over mathbbZ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#lift-Tuple{ZZPolyRing, ZZModPolyRingElem}","page":"Univariate polynomials","title":"lift","text":"lift(R::ZZPolyRing, y::ZZModPolyRingElem)\n\nLift from a polynomial over mathbbZnmathbbZ to a polynomial over mathbbZ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#lift-Tuple{ZZPolyRing, FpPolyRingElem}","page":"Univariate polynomials","title":"lift","text":"lift(R::ZZPolyRing, y::FpPolyRingElem)\n\nLift from a polynomial over mathbbZnmathbbZ to a polynomial over mathbbZ with minimal reduced nonnegative coefficients. The ring R specifies the ring to lift into.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Examples","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"R = residue_ring(ZZ, 123456789012345678949)\nS, x = polynomial_ring(R, \"x\")\nT, y = polynomial_ring(ZZ, \"y\")\n\nf = x^2 + 2x + 1\n\na = lift(T, f)","category":"page"},{"location":"Nemo/polynomial/#Overlapping-and-containment","page":"Univariate polynomials","title":"Overlapping and containment","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Occasionally it is useful to be able to tell when inexact polynomials overlap or contain other exact or inexact polynomials. The following functions are provided for this purpose.","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"overlaps(::RealPoly, ::RealPoly)\noverlaps(::ComplexPoly, ::ComplexPoly)","category":"page"},{"location":"Nemo/polynomial/#overlaps-Tuple{RealPoly, RealPoly}","page":"Univariate polynomials","title":"overlaps","text":"overlaps(x::RealPoly, y::RealPoly)\n\nReturn true if the coefficient balls of x overlap the coefficient balls of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#overlaps-Tuple{ComplexPoly, ComplexPoly}","page":"Univariate polynomials","title":"overlaps","text":"overlaps(x::ComplexPoly, y::ComplexPoly)\n\nReturn true if the coefficient boxes of x overlap the coefficient boxes of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"contains(::RealPoly, ::RealPoly)\ncontains(::ComplexPoly, ::ComplexPoly)","category":"page"},{"location":"Nemo/polynomial/#contains-Tuple{RealPoly, RealPoly}","page":"Univariate polynomials","title":"contains","text":"contains(x::RealPoly, y::RealPoly)\n\nReturn true if the coefficient balls of x contain the corresponding coefficient balls of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#contains-Tuple{ComplexPoly, ComplexPoly}","page":"Univariate polynomials","title":"contains","text":"contains(x::ComplexPoly, y::ComplexPoly)\n\nReturn true if the coefficient boxes of x contain the corresponding coefficient boxes of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"contains(::RealPoly, ::ZZPolyRingElem)\ncontains(::RealPoly, ::QQPolyRingElem)\ncontains(::ComplexPoly, ::ZZPolyRingElem)\ncontains(::ComplexPoly, ::QQPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#contains-Tuple{RealPoly, ZZPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::RealPoly, y::ZZPolyRingElem)\n\nReturn true if the coefficient balls of x contain the corresponding exact coefficients of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#contains-Tuple{RealPoly, QQPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::RealPoly, y::QQPolyRingElem)\n\nReturn true if the coefficient balls of x contain the corresponding exact coefficients of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#contains-Tuple{ComplexPoly, ZZPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::ComplexPoly, y::ZZPolyRingElem)\n\nReturn true if the coefficient boxes of x contain the corresponding exact coefficients of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#contains-Tuple{ComplexPoly, QQPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::ComplexPoly, y::QQPolyRingElem)\n\nReturn true if the coefficient boxes of x contain the corresponding exact coefficients of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"It is sometimes also useful to be able to determine if there is a unique integer contained in the coefficient of an inexact constant polynomial.","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"unique_integer(::RealPoly)\nunique_integer(::ComplexPoly)","category":"page"},{"location":"Nemo/polynomial/#unique_integer-Tuple{RealPoly}","page":"Univariate polynomials","title":"unique_integer","text":"unique_integer(x::RealPoly)\n\nReturn a tuple (t, z) where t is true if there is a unique integer contained in each of the coefficients of x, otherwise sets t to false. In the former case, z is set to the integer polynomial.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#unique_integer-Tuple{ComplexPoly}","page":"Univariate polynomials","title":"unique_integer","text":"unique_integer(x::ComplexPoly)\n\nReturn a tuple (t, z) where t is true if there is a unique integer contained in the (constant) polynomial x, along with that integer z in case it is, otherwise sets t to false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Examples","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"RR = RealField(64)\nCC = ComplexField(64)\nR, x = polynomial_ring(RR, \"x\")\nC, y = polynomial_ring(CC, \"y\")\nZx, zx = polynomial_ring(ZZ, \"x\")\nQx, qx = polynomial_ring(QQ, \"x\")\n\nf = x^2 + 2x + 1\nh = f + RR(\"0 +/- 0.0001\")\nk = f + RR(\"0 +/- 0.0001\") * x^4\nm = y^2 + 2y + 1\nn = m + CC(\"0 +/- 0.0001\", \"0 +/- 0.0001\")\n\ncontains(h, f)\noverlaps(f, k)\ncontains(n, m)\nt, z = unique_integer(k)\nisreal(n)","category":"page"},{"location":"Nemo/polynomial/#Factorisation","page":"Univariate polynomials","title":"Factorisation","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Certain polynomials can be factored (ZZPolyRingElem',zzModPolyRingElem,fpPolyRingElem,ZZModPolyRingElem,FpPolyRingElem,FqPolyRepPolyRingElem,fqPolyRepPolyRingElem`) and the interface follows the specification in AbstractAlgebra.jl. The following additional functions are available.","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"factor_distinct_deg(::zzModPolyRingElem)\nfactor_distinct_deg(::fpPolyRingElem)\nfactor_distinct_deg(::ZZModPolyRingElem)\nfactor_distinct_deg(::FpPolyRingElem)\nfactor_distinct_deg(::FqPolyRepPolyRingElem)\nfactor_distinct_deg(::fqPolyRepPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#factor_distinct_deg-Tuple{zzModPolyRingElem}","page":"Univariate polynomials","title":"factor_distinct_deg","text":"factor_distinct_deg(x::zzModPolyRingElem)\n\nReturn the distinct degree factorisation of a squarefree polynomial x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#factor_distinct_deg-Tuple{fpPolyRingElem}","page":"Univariate polynomials","title":"factor_distinct_deg","text":"factor_distinct_deg(x::fpPolyRingElem)\n\nReturn the distinct degree factorisation of a squarefree polynomial x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#factor_distinct_deg-Tuple{ZZModPolyRingElem}","page":"Univariate polynomials","title":"factor_distinct_deg","text":"factor_distinct_deg(x::ZZModPolyRingElem)\n\nReturn the distinct degree factorisation of a squarefree polynomial x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#factor_distinct_deg-Tuple{FpPolyRingElem}","page":"Univariate polynomials","title":"factor_distinct_deg","text":"factor_distinct_deg(x::ZZModPolyRingElem)\n\nReturn the distinct degree factorisation of a squarefree polynomial x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#factor_distinct_deg-Tuple{FqPolyRepPolyRingElem}","page":"Univariate polynomials","title":"factor_distinct_deg","text":"factor_distinct_deg(x::FqPolyRepPolyRingElem)\n\nReturn the distinct degree factorisation of a squarefree polynomial x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/#factor_distinct_deg-Tuple{fqPolyRepPolyRingElem}","page":"Univariate polynomials","title":"factor_distinct_deg","text":"factor_distinct_deg(x::fqPolyRepPolyRingElem)\n\nReturn the distinct degree factorisation of a squarefree polynomial x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Examples","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"R = residue_ring(ZZ, 23)\nS, x = polynomial_ring(R, \"x\")\n\nf = x^2 + 2x + 1\ng = x^3 + 3x + 1\n\nR = factor(f*g)\nS = factor_squarefree(f*g)\nT = factor_distinct_deg((x + 1)*g*(x^5+x^3+x+1))","category":"page"},{"location":"Nemo/polynomial/#Special-functions","page":"Univariate polynomials","title":"Special functions","text":"","category":"section"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"cyclotomic(::Int, ::ZZPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#cyclotomic-Tuple{Int64, ZZPolyRingElem}","page":"Univariate polynomials","title":"cyclotomic","text":"cyclotomic(n::Int, x::ZZPolyRingElem)\n\nReturn the nth cyclotomic polynomial, defined as Phi_n(x) = prod_omega (x-omega) where omega runs over all the nth primitive roots of unity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"swinnerton_dyer(::Int, ::ZZPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#swinnerton_dyer-Tuple{Int64, ZZPolyRingElem}","page":"Univariate polynomials","title":"swinnerton_dyer","text":"swinnerton_dyer(n::Int, x::ZZPolyRingElem)\n\nReturn the Swinnerton-Dyer polynomial S_n, defined as the integer polynomial S_n = prod (x pm sqrt2 pm sqrt3 pm sqrt5 pm ldots pm sqrtp_n) where p_n denotes the n-th prime number and all combinations of signs are taken. This polynomial has degree 2^n and is irreducible over the integers (it is the minimal polynomial of sqrt2 + ldots + sqrtp_n).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"cos_minpoly(::Int, ::ZZPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#cos_minpoly-Tuple{Int64, ZZPolyRingElem}","page":"Univariate polynomials","title":"cos_minpoly","text":"cos_minpoly(n::Int, x::ZZPolyRingElem)\n\nReturn the minimal polynomial of 2 cos(2 pi n). For suitable choice of n, this gives the minimal polynomial of 2 cos(a pi) or 2 sin(a pi) for any rational a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"theta_qexp(::Int, ::Int, ::ZZPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#theta_qexp-Tuple{Int64, Int64, ZZPolyRingElem}","page":"Univariate polynomials","title":"theta_qexp","text":"theta_qexp(e::Int, n::Int, x::ZZPolyRingElem)\n\nReturn the q-expansion to length n of the Jacobi theta function raised to the power r, i.e. vartheta(q)^r where vartheta(q) = 1 + sum_k=1^infty q^k^2.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"eta_qexp(::Int, ::Int, ::ZZPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#eta_qexp-Tuple{Int64, Int64, ZZPolyRingElem}","page":"Univariate polynomials","title":"eta_qexp","text":"eta_qexp(e::Int, n::Int, x::ZZPolyRingElem)\n\nReturn the q-expansion to length n of the Dedekind eta function (without the leading factor q^124) raised to the power r, i.e. (q^-124 eta(q))^r = prod_k=1^infty (1 - q^k)^r. In particular, r = -1 gives the generating function of the partition function p(k), and r = 24 gives, after multiplication by q, the modular discriminant Delta(q) which generates the Ramanujan tau function tau(k).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"Examples","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"R, x = polynomial_ring(ZZ, \"x\")\nS, y = polynomial_ring(R, \"y\")\n\nh = cyclotomic(120, x)\nj = swinnerton_dyer(5, x)\nk = cos_minpoly(30, x)\nl = theta_qexp(3, 30, x)\nm = eta_qexp(24, 30, x)\no = cyclotomic(10, 1 + x + x^2)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#Toric-Divisors","page":"Toric Divisors","title":"Toric Divisors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#Introduction","page":"Toric Divisors","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"Toric divisors are those divisors that are invariant under the torus action. They are formal sums of the codimension one orbits, and these in turn correspond to the rays of the underlying fan.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#Constructors","page":"Toric Divisors","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#General-constructors","page":"Toric Divisors","title":"General constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"divisor_of_character(v::AbstractNormalToricVariety, character::Vector{T}) where {T <: IntegerUnion}\ntoric_divisor(v::AbstractNormalToricVariety, coeffs::Vector{T}) where {T <: IntegerUnion}","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#divisor_of_character-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Divisors","title":"divisor_of_character","text":"divisor_of_character(v::AbstractNormalToricVariety, character::Vector{T}) where {T <: IntegerUnion}\n\nConstruct the torus invariant divisor associated to a character of the normal toric variety v.\n\nExamples\n\njulia> divisor_of_character(projective_space(NormalToricVariety, 2), [1, 2])\nTorus-invariant, non-prime divisor on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#toric_divisor-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Divisors","title":"toric_divisor","text":"toric_divisor(v::AbstractNormalToricVariety, coeffs::Vector{T}) where {T <: IntegerUnion}\n\nConstruct the torus invariant divisor on the normal toric variety v as linear combination of the torus invariant prime divisors of v. The coefficients of this linear combination are passed as list of integers as first argument.\n\nExamples\n\njulia> toric_divisor(projective_space(NormalToricVariety, 2), [1, 1, 2])\nTorus-invariant, non-prime divisor on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#Addition,-subtraction-and-scalar-multiplication","page":"Toric Divisors","title":"Addition, subtraction and scalar multiplication","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"Toric divisors can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#Special-divisors","page":"Toric Divisors","title":"Special divisors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"trivial_divisor(v::AbstractNormalToricVariety)\nanticanonical_divisor(v::AbstractNormalToricVariety)\ncanonical_divisor(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#trivial_divisor-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Divisors","title":"trivial_divisor","text":"trivial_divisor(v::AbstractNormalToricVariety)\n\nConstruct the trivial divisor of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> trivial_divisor(v)\nTorus-invariant, non-prime divisor on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#anticanonical_divisor-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Divisors","title":"anticanonical_divisor","text":"anticanonical_divisor(v::AbstractNormalToricVariety)\n\nConstruct the anticanonical divisor of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> anticanonical_divisor(v)\nTorus-invariant, non-prime divisor on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#canonical_divisor-Tuple{Oscar.AbstractNormalToricVariety}","page":"Toric Divisors","title":"canonical_divisor","text":"canonical_divisor(v::AbstractNormalToricVariety)\n\nConstruct the canonical divisor of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> canonical_divisor(v)\nTorus-invariant, non-prime divisor on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#Properties-of-toric-divisors","page":"Toric Divisors","title":"Properties of toric divisors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"Equality of toric divisors can be tested via ==.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"To check if a toric divisor is trivial, one can invoke is_trivial. This checks if all coefficients of the toric divisor in question are zero. This must not be confused with a toric divisor being principal, for which we support the following:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"is_principal(td::ToricDivisor)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_principal-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_principal","text":"is_principal(td::ToricDivisor)\n\nDetermine whether the toric divisor td is principal.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_principal(td)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"Beyond this, we support the following properties of toric divisors:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"is_ample(td::ToricDivisor)\nis_basepoint_free(td::ToricDivisor)\nis_cartier(td::ToricDivisor)\nis_effective(td::ToricDivisor)\nis_integral(td::ToricDivisor)\nis_nef(td::ToricDivisor)\nis_prime(td::ToricDivisor)\nis_q_cartier(td::ToricDivisor)\nis_very_ample(td::ToricDivisor)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_ample-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_ample","text":"is_ample(td::ToricDivisor)\n\nDetermine whether the toric divisor td is ample.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_ample(td)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_basepoint_free-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_basepoint_free","text":"is_basepoint_free(td::ToricDivisor)\n\nDetermine whether the toric divisor td is basepoint free.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_basepoint_free(td)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_cartier-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_cartier","text":"is_cartier(td::ToricDivisor)\n\nChecks if the divisor td is Cartier.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_cartier(td)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_effective-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_effective","text":"is_effective(td::ToricDivisor)\n\nDetermine whether the toric divisor td is effective, i.e. if all of its coefficients are non-negative.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety,2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(P2, [1,-1,0])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> is_effective(td)\nfalse\n\njulia> td2 = toric_divisor(P2, [1,2,3])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> is_effective(td2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_integral-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_integral","text":"is_integral(td::ToricDivisor)\n\nDetermine whether the toric divisor td is integral.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_integral(td)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_nef-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_nef","text":"is_nef(td::ToricDivisor)\n\nDetermine whether the toric divisor td is nef.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_nef(td)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_prime-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_prime","text":"is_prime(td::ToricDivisor)\n\nDetermine whether the toric divisor td is a prime divisor.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_prime(td)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_q_cartier-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_q_cartier","text":"is_q_cartier(td::ToricDivisor)\n\nDetermine whether the toric divisor td is Q-Cartier.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_q_cartier(td)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#is_very_ample-Tuple{ToricDivisor}","page":"Toric Divisors","title":"is_very_ample","text":"is_very_ample(td::ToricDivisor)\n\nDetermine whether the toric divisor td is very ample.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_very_ample(td)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#Attributes","page":"Toric Divisors","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"coefficients(td::ToricDivisor)\npolyhedron(td::ToricDivisor)\ntoric_variety(td::ToricDivisor)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#coefficients-Tuple{ToricDivisor}","page":"Toric Divisors","title":"coefficients","text":"coefficients(td::ToricDivisor)\n\nIdentify the coefficients of a toric divisor in the group of torus invariant Weil divisors.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> D = toric_divisor(F4, [1, 2, 3, 4])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> coefficients(D)\n4-element Vector{ZZRingElem}:\n 1\n 2\n 3\n 4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#polyhedron-Tuple{ToricDivisor}","page":"Toric Divisors","title":"polyhedron","text":"polyhedron(td::ToricDivisor)\n\nConstruct the polyhedron P_D of a torus invariant divisor D=td as in 4.3.2 of David A. Cox, John B. Little, Henry K. Schenck (2011). The lattice points of this polyhedron correspond to the global sections of the divisor.\n\nExamples\n\nThe polyhedron of the divisor with all coefficients equal to zero is a point, if the ambient variety is complete. Changing the coefficients corresponds to moving hyperplanes. One direction moves the hyperplane away from the origin, the other moves it across. In the latter case there are no global sections anymore and the polyhedron becomes empty.\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> td0 = toric_divisor(F4, [0,0,0,0])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> is_feasible(polyhedron(td0))\ntrue\n\njulia> dim(polyhedron(td0))\n0\n\njulia> td1 = toric_divisor(F4, [1,0,0,0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_feasible(polyhedron(td1))\ntrue\n\njulia> td2 = toric_divisor(F4, [-1,0,0,0])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> is_feasible(polyhedron(td2))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#toric_variety-Tuple{ToricDivisor}","page":"Toric Divisors","title":"toric_variety","text":"toric_variety(td::ToricDivisor)\n\nReturn the toric variety of a torus-invariant Weil divisor.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4);\n\njulia> D = toric_divisor(F4, [1, 2, 3, 4]);\n\njulia> toric_variety(D)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Combinatorics/partitions/#Partitions","page":"Partitions","title":"Partitions","text":"","category":"section"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"Partition\ngetindex_safe","category":"page"},{"location":"Combinatorics/partitions/#Partition","page":"Partitions","title":"Partition","text":"Partition{T<:IntegerUnion} <: AbstractVector{T}\n\nA partition of a non-negative integer n is a decreasing sequence λ₁ λ₂ λᵣ of positive integers λᵢ such that n = λ₁ + + λᵣ. The λᵢ are called the parts of the partition and r is called the length. \n\nA partition can be encoded as an array with elements λᵢ. We provide the parametric type Partition{T} which is a subtype of AbstractVector{T} where T can be any subtype of IntegerUnion. All functions that can be used for vectors (1-dimensional arrays) can thus be used for partitions as well. There is no performance impact by using an own type for partitions rather than simply using arrays. The parametric type allows to increase performance by using smaller integer types. For efficiency, the Partition constructor does not check whether the given array is indeed a decreasing sequence.\n\nA partition can be created by either calling partition on an array of integers or by calling partition with arguments being the sequence of parts, with the possibility to provide the element type as the first argument.\n\nExamples\n\njulia> P = partition([6,4,4,2]) #The partition 6+4+4+2 of 16.\n[6, 4, 4, 2]\n\njulia> P = partition(6,4,4,2) #Same as above but less to type\n[6, 4, 4, 2]\n\njulia> length(P)\n4\n\njulia> P[1]\n6\n\nUsually, λ n is called the size of λ. In Julia, the function size for arrays already exists and returns the dimension of an array. Instead, you can use the Julia function sum to get the sum of the parts.\n\njulia> P = partition(6,4,4,2)\n[6, 4, 4, 2]\n\njulia> sum(P) \n16\n\nYou can create partitions with smaller integer types as follows.\n\njulia> P = partition(Int8,6,4,4,2) #Or partition(Int8[6,4,4,2])\nInt8[6, 4, 4, 2]\n\nThere is a unique partition of 0, namely the empty partition (of length 0). It can be created as follows.\n\njulia> P = partition() #Or partition([])\nInt64[]\njulia> sum(P)\n0\njulia> length(P)\n0\njulia> P = partition(Int8) #Or partition(Int8[])\nInt8[]\n\nReferences\n\nWilliam Fulton (1997)\nDonald E. Knuth (2011), Section 7.2.1.4 (starting on page 390).\n\n\n\n\n\n","category":"type"},{"location":"Combinatorics/partitions/#getindex_safe","page":"Partitions","title":"getindex_safe","text":"getindex_safe(P::Partition, i::IntegerUnion)\n\nIn algorithms involving partitions it is sometimes convenient to be able to access parts beyond the length of the partition and then one wants to get the value zero instead of an error. This function is a shortcut for\n\nreturn (i>length(P.p) ? 0 : getindex(P.p,i))\n\nIf you are sure that P[i] exists, use getindex because this will be faster.\n\nExamples\n\njulia> P = partition([3,2,1])\n[3, 2, 1]\n\njulia> getindex_safe(P, 3)\n1\n\njulia> getindex_safe(P, 4)\n0\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/partitions/#Generating-and-counting","page":"Partitions","title":"Generating and counting","text":"","category":"section"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"partitions(::Oscar.IntegerUnion)\nnum_partitions(::Oscar.IntegerUnion)","category":"page"},{"location":"Combinatorics/partitions/#partitions-Tuple{Union{Integer, ZZRingElem}}","page":"Partitions","title":"partitions","text":"partitions(n::IntegerUnion)\n\nA list of all partitions of a non-negative integer n, produced in lexicographically descending order. This ordering is like in Sage, but opposite to GAP. You can apply the function reverse to reverse the order. As usual, you may increase performance by using smaller integer types.\n\nAlgorithm\n\nThe algorithm used is \"Algorithm ZS1\" by A. Zoghbi, I. Stojmenovic (1998). This algorithm is also discussed in Donald E. Knuth (2011), Algorithm P (page 392).\n\nExamples\n\njulia> partitions(4) # Use partitions(Int8(4)) to use 8-bit integers\n5-element Vector{Partition{Int64}}:\n [4]\n [3, 1]\n [2, 2]\n [2, 1, 1]\n [1, 1, 1, 1]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#num_partitions-Tuple{Union{Integer, ZZRingElem}}","page":"Partitions","title":"num_partitions","text":"num_partitions(n::IntegerUnion)\n\nThe number of integer partitions of the non-negative integer n. \n\nExamples\n\njulia> num_partitions(1000)\n24061467864032622473692149727991\n\nAlgorithm\n\nWe use the function arith_number_of_partitions from W. B. Hart (2010) which is very fast. It is based on the Hardy-Ramanujan-Rademacher formula, see Fredrik Johansson (2012) for details. \n\nFurther references\n\nDonald E. Knuth (2011), Section 7.2.1.4 (starting on page 395).\nOEIS Foundation Inc. (2023), A000041\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#Partitions-with-restrictions","page":"Partitions","title":"Partitions with restrictions","text":"","category":"section"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"How many ways are there to pay one euro, using coins worth 1, 2, 5, 10, 20, 50, and/or 100 cents? What if you are allowed to use at most two of each coin? ","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"This is Exercise 11 in Knu11, Section 7.2.1.4 (page 408). It goes back to the famous \"Ways to change one dollar\" problem, see Pol56. Generally, the problem is to generate and/or count partitions satisfying some restrictions. Of course, one could generate the list of all partitions of 100 (there are about 190 million) and then filter the result by the restrictions. But for certain types of restrictions there are much more efficient algorithms. The functions in this section implement some of these. In combination with Julia's filter function one can also handle more general types of restrictions.","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"For example, there are precisely six ways for the second question in the exercise quoted above:","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> partitions(100, [1,2,5,10,20,50], [2,2,2,2,2,2])\n6-element Vector{Partition{Int64}}:\n [50, 50]\n [50, 20, 20, 10]\n [50, 20, 20, 5, 5]\n [50, 20, 10, 10, 5, 5]\n [50, 20, 20, 5, 2, 2, 1]\n [50, 20, 10, 10, 5, 2, 2, 1]","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"and there are 4562 ways for the first question in the exercise:","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> length(partitions(100, [1,2,5,10,20,50]))\n4562","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"The original \"Ways to change one dollar\" problem has 292 solutions:","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> length(partitions(100,[1,5,10,25,50]))\n292","category":"page"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"partitions(::T, ::Oscar.IntegerUnion, ::Oscar.IntegerUnion, ::Oscar.IntegerUnion) where T <: Oscar.IntegerUnion\npartitions(::T, ::Oscar.IntegerUnion) where T <: Oscar.IntegerUnion\nnum_partitions(::Oscar.IntegerUnion, ::Oscar.IntegerUnion)\npartitions(::T, ::Oscar.IntegerUnion, ::Vector{T}, ::Vector{S}) where {T <: Oscar.IntegerUnion, S<:Oscar.IntegerUnion}\npartitions(::T, ::Vector{T}, ::Vector{S}) where {T <: Oscar.IntegerUnion, S<:Oscar.IntegerUnion}\npartitions(::T, ::Vector{T}) where T <: Oscar.IntegerUnion","category":"page"},{"location":"Combinatorics/partitions/#partitions-Union{Tuple{T}, Tuple{T, Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}} where T<:Union{Integer, ZZRingElem}","page":"Partitions","title":"partitions","text":"partitions(m::T, n::IntegerUnion, l1::IntegerUnion, l2::IntegerUnion; only_distinct_parts::Bool = false) where T <: IntegerUnion\n\nA list of all partitions of a non-negative integer m into n >= 0 parts with lower bound l1 >= 0 and upper bound l2 for the parts. There are two choices for the parameter only_distinct_parts:\n\nfalse: no further restriction (default);\ntrue: only distinct parts. The partitions are produced in decreasing order.\n\nExamples\n\nWe compute all partitions of 7 into 3 parts where all parts are between 1 and 4:\n\njulia> partitions(7, 3, 1, 4)\n3-element Vector{Partition{Int64}}:\n [4, 2, 1]\n [3, 3, 1]\n [3, 2, 2]\n\nSame as above but requiring all parts to be distinct:\n\njulia> partitions(7, 3, 1, 4 ; only_distinct_parts=true)\n1-element Vector{Partition{Int64}}:\n [4, 2, 1]\n\nAlgorithm\n\nThe algorithm used is \"parta\" in W. Riha, K. R. James (1976), de-gotoed from old ALGOL 60 code by E. Thiel.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#partitions-Union{Tuple{T}, Tuple{T, Union{Integer, ZZRingElem}}} where T<:Union{Integer, ZZRingElem}","page":"Partitions","title":"partitions","text":"partitions(m::T, n::IntegerUnion) where T<:IntegerUnion\n\nAll partitions of a non-negative integer m into n parts (no further restrictions).\n\nExamples\n\n# All partitions of 7 into 3 parts.\njulia> partitions(7, 3)\n4-element Vector{Partition{Int64}}:\n [5, 1, 1]\n [4, 2, 1]\n [3, 3, 1]\n [3, 2, 2]\n\nAlgorithm\n\nThis function is a shortcut for partitions(m,n,1,m;only_distinct_parts=false).\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#num_partitions-Tuple{Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Partitions","title":"num_partitions","text":"num_partitions(n::IntegerUnion, k::IntegerUnion)\n\nThe number of integer partitions of the non-negative integer n into k >= 0 parts. \n\nAlgorithm\n\nWe use the recurrence relation p_k(n) = p_k-1(n-1) + p_k(n-k), where p_k(n) denotes the number of partitions of n into k parts; see Donald E. Knuth (2011), Section 7.2.1.4, Equation (39) on page 399.\n\nReferences\n\nOEIS Foundation Inc. (2023), A008284\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#partitions-Union{Tuple{S}, Tuple{T}, Tuple{T, Union{Integer, ZZRingElem}, Vector{T}, Vector{S}}} where {T<:Union{Integer, ZZRingElem}, S<:Union{Integer, ZZRingElem}}","page":"Partitions","title":"partitions","text":"partitions(m::T, n::IntegerUnion, v::Vector{T}, mu::Vector{S}) where {T<:IntegerUnion, S<:IntegerUnion}\n\nAll partitions of a non-negative integer m into n >= 0 parts, where each part is an element in the vector v of positive integers and each v[i] occurs a maximum of mu[i] > 0 times. We assume (without loss of generality) that the entries in v are strictly increasing. The partitions are produced in lexicographically decreasing order. \n\nExamples\n\nWe compute the partitions of 100 into seven parts, where the parts are required to be elements from {1, 2, 5, 10, 20, 50} and each part is allowed to occur at most twice.\n\njulia> partitions(100, 7, [1,2,5,10,20,50], [2,2,2,2,2,2])\n1-element Vector{Partition{Int64}}:\n [50, 20, 20, 5, 2, 2, 1]\n\nAlgorithm\n\nThe algorithm used is \"partb\" in W. Riha, K. R. James (1976), de-gotoed from old ALGOL 60 code by E. Thiel. The algorithm as published in the paper has several issues and we hope to have fixed them all, see the code for details. Some initial fixing was done by T. Schmit.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#partitions-Union{Tuple{S}, Tuple{T}, Tuple{T, Vector{T}, Vector{S}}} where {T<:Union{Integer, ZZRingElem}, S<:Union{Integer, ZZRingElem}}","page":"Partitions","title":"partitions","text":"partitions(m::T, v::Vector{T}, mu::Vector{S}) where {T<:IntegerUnion,S<:IntegerUnion}\n\nAll partitions of a non-negative integer m where each part is an element in the vector v of positive integers and each v[i] occurs a maximum of mu[i] > 0 times. We assume (without loss of generality) that the entries in v are strictly increasing.\n\nExample\n\nWe compute all partitions of 100 where the parts are from {1, 2, 5, 10, 20, 50} and each part is allowed to occur at most twice:\n\njulia> partitions(100, [1,2,5,10,20,50], [2,2,2,2,2,2])\n6-element Vector{Partition{Int64}}:\n [50, 50]\n [50, 20, 20, 10]\n [50, 20, 20, 5, 5]\n [50, 20, 10, 10, 5, 5]\n [50, 20, 20, 5, 2, 2, 1]\n [50, 20, 10, 10, 5, 2, 2, 1]\n\nAlgorithm\n\nWe use the function partitions(m,n,v,mu), looping over the number of possible parts of partitions.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#partitions-Union{Tuple{T}, Tuple{T, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Partitions","title":"partitions","text":"function partitions(m::T, v::Vector{T}) where T<:IntegerUnion\n\nAll partitions of a non-negative integer m where each part is an element in the vector v. We assume (without loss of generality) that the entries in v are strictly increasing. \n\nExample\n\nWe compute the number of partitions of 100 where the parts are from {1, 2, 5, 10, 20, 50}:\n\njulia> length(partitions(100, [1,2,5,10,20,50]))\n4562\n\nAlgorithm\n\nWe use the function partitions(m,n,v,mu), looping over the number of possible parts of partitions.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/partitions/#Operations","page":"Partitions","title":"Operations","text":"","category":"section"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"conjugate","category":"page"},{"location":"Combinatorics/partitions/#conjugate","page":"Partitions","title":"conjugate","text":"conjugate(lambda::Partition{T}) where T<:IntegerUnion\n\nThe conjugate of a partition is obtained by considering its Young diagram (see Tableaux) and then flipping it along its main diagonal.\n\nExamples\n\njulia> conjugate(partition(8,8,8,7,2,1,1))\n[7, 5, 4, 4, 4, 4, 4, 3]\n\nReferences\n\nWilliam Fulton (1997), page 2\nDonald E. Knuth (2011), Section 7.2.1.4, page 394.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/partitions/#Relations","page":"Partitions","title":"Relations","text":"","category":"section"},{"location":"Combinatorics/partitions/","page":"Partitions","title":"Partitions","text":"dominates","category":"page"},{"location":"Combinatorics/partitions/#dominates","page":"Partitions","title":"dominates","text":"dominates(lambda::Partition, mu::Partition)\n\nThe dominance order on partitions is the partial order defined by λ μ if and only if λ₁ + + λᵢ μ₁ + + μᵢ for all i. If λ μ one says that λ dominates μ. This function returns true if and only if lambda dominates mu.\n\nNote that whereas the lexicographic ordering is a total ordering, the dominance ordering is not.\n\nExamples\n\njulia> dominates( partition(3,1), partition(2,2) )\ntrue\n\njulia> dominates( partition(4,1), partition(3,3) )\nfalse\n\nRemarks\n\nDonald E. Knuth (2011) says majorizes instead of dominates and uses the symbol instead of .\n\nReferences\n\nWilliam Fulton (1997), page 26\nDonald E. Knuth (2011), Section 7.2.1.4, Exercise 54 (page 412)\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#The-Chow-ring","page":"The Chow ring","title":"The Chow ring","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"Algebraic cycles are formal linear sum of irreducible subvarieies over the integers. Perse, algebraic cycles do not admit a well-defined intersection product.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"To see this, think of intersecting a non-trivial algebraic cycle C with itself. Of course, in set theory we can intersect C with itself and the result is again C. However, for a well-defined intersection theory, we would ask that the self-intersection of C is an algebraic cycle of strictly smaller dimension.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"In theory, this is resolved by saying that the self-intersection of C is given by intersecting C with a distinct algebraic cycle D which is obtained by moving C a little bit. The general phrase for this is to \"move C in general position\".","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"This leads to a famous notion of equivalence among algebraic cycles, the so-called rational equivalence. The set of equivalence classes of algebraic cycles together with the intersection product then furnishes the Chow ring of the variety in question.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"For complete and simplicial toric varieties, many things are known about the Chow ring and algebraic cycles (cf. section 12.5 in David A. Cox, John B. Little, Henry K. Schenck (2011):","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"By therorem 12.5.3 of David A. Cox, John B. Little, Henry K. Schenck (2011), there is an isomorphism","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"among the Chow ring and the cohomology ring. Note that the cohomology ring is naturally graded (cf. last paragraph on page 593 in David A. Cox, John B. Little, Henry K. Schenck (2011)). However, the Chow ring is usually considered as a non-graded ring. To match this general convention, and in particular the implementation of the Chow ring for matroids in OSCAR, the toric Chow ring is constructed as a non-graded ring.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"By therorem 12.5.3 of David A. Cox, John B. Little, Henry K. Schenck (2011), the Chow ring is isomorphic","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"to the quotient of the non-graded Cox ring and a certain ideal. Specifically, the ideal in question is the sum of the ideal of linear relations and the Stanley-Reisner ideal.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"It is worth noting that the ideal of linear relations is not","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"homogeneous with respect to the class group grading of the Cox ring. In order to construct the cohomology ring, one can introduce a mathbbZ-grading on the Cox ring such that the ideal of linear relations and the Stanley-Reißner ideal are homogeneous.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"Finally, by lemma 12.5.1 of David A. Cox, John B. Little, Henry K. Schenck (2011), generators of the","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"rational equivalence classes of algebraic cycles are one-to-one to the cones in the fan of the toric variety.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Constructors","page":"The Chow ring","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#General-constructors","page":"The Chow ring","title":"General constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"rational_equivalence_class(v::AbstractNormalToricVariety, p::MPolyQuoRingElem)\nrational_equivalence_class(v::AbstractNormalToricVariety, coefficients::Vector{T}) where {T <: IntegerUnion}","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Tuple{Oscar.AbstractNormalToricVariety, MPolyQuoRingElem}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(v::AbstractNormalToricVariety, p::MPolyQuoRingElem)\n\nConstruct the rational equivalence class of algebraic cycles corresponding to a linear combination of cones.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> chow_ring(P2)\nQuotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1 - x3, x2 - x3, x1*x2*x3)\n\njulia> (x1, x2, x3) = gens(chow_ring(P2))\n3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x1\n x2\n x3\n\njulia> rational_equivalence_class(P2, x1)\nRational equivalence classon a normal toric variety represented by V(x3)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(v::AbstractNormalToricVariety, coefficients::Vector{T}) where {T <: IntegerUnion}\n\nConstruct the rational equivalence class of algebraic cycles corresponding to a linear combination of cones.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> rational_equivalence_class(P2, [6, 5, 4, 3, 2, 1])\nRational equivalence class on a normal toric variety represented by 15V(x1,x3)+6V(x3)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Special-constructors","page":"The Chow ring","title":"Special constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"rational_equivalence_class(d::ToricDivisor)\nrational_equivalence_class(c::ToricDivisorClass)\nrational_equivalence_class(l::ToricLineBundle)\nrational_equivalence_class(cc::CohomologyClass)\nrational_equivalence_class(sv::ClosedSubvarietyOfToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Tuple{ToricDivisor}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(d::ToricDivisor)\n\nConstruct the rational equivalence class of algebraic cycles corresponding to the toric divisor d.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(P2, [1, 2, 3])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Tuple{ToricDivisorClass}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(c::ToricDivisorClass)\n\nConstruct the algebraic cycle corresponding to the toric divisor class c.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> tdc = toric_divisor_class(P2, [2])\nDivisor class on a normal toric variety\n\njulia> rational_equivalence_class(tdc)\nRational equivalence class on a normal toric variety represented by 2V(x3)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Tuple{ToricLineBundle}","page":"The Chow ring","title":"rational_equivalence_class","text":"RationalEquivalenceClass(l::ToricLineBundle)\n\nConstruct the toric algebraic cycle corresponding to the toric line bundle l.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> l = toric_line_bundle(P2, [2])\nToric line bundle on a normal toric variety\n\njulia> polynomial(rational_equivalence_class(l))\n2*x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Tuple{CohomologyClass}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(cc::CohomologyClass)\n\nConstruct the toric algebraic cycle corresponding to the cohomology class cc.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> (x1, x2, x3) = gens(cohomology_ring(P2))\n3-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n x1\n x2\n x3\n\njulia> cc = CohomologyClass(P2, x1+x2)\nCohomology class on a normal toric variety given by x1 + x2\n\njulia> rational_equivalence_class(cc)\nRational equivalence class on a normal toric variety represented by 2V(x3)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Tuple{ClosedSubvarietyOfToricVariety}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(sv::ClosedSubvarietyOfToricVariety)\n\nConstruct the rational equivalence class of algebraic cycles of a closed subvariety of a normal toric variety.\n\nExamples\n\njulia> ntv = normal_toric_variety(Oscar.normal_fan(Oscar.cube(2)))\nNormal toric variety\n\njulia> set_coordinate_names(ntv, [\"x1\", \"x2\", \"y1\", \"y2\"]);\n\njulia> (x1, x2, y1, y2) = gens(cox_ring(ntv))\n4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n y1\n y2\n\njulia> sv = closed_subvariety_of_toric_variety(ntv, [x1^2+x1*x2+x2^2, y2])\nClosed subvariety of a normal toric variety\n\njulia> rational_equivalence_class(sv)\nRational equivalence class on a normal toric variety represented by 2V(x2,y2)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Addition,-subtraction-and-scalar-multiplication","page":"The Chow ring","title":"Addition, subtraction and scalar multiplication","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"Algebraic cycles can be added and subtracted via the usual + and - operators. Moreover, multiplication by scalars from the left is supported for scalars which are integers or of type ZZRingElem.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"Note that one can easily define the Chow ring also a formal linear sums of irreducible subvarieties with coefficients being rational numbers. We support this more general ring and therefore also allow for left multiplication with scalars of type QQFieldElem.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Intersection-product","page":"The Chow ring","title":"Intersection product","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"The intersection product of algebraic cycles is implemented via *. This makes sense, since algebraic cycles on toric varieties are elements of the Chow ring, which in turn is (a certain) quotient of the Cox ring. Hence, internally, an algebraic cycle can be thought of as a polynomial in this ring and the intersection product corresponds to the product of two (equivalence classes of) polynomials.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"An algebraic cycle can be intersected n- with itself via ^n, where n can be an integer of of type ZZRingElem.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"A closed subvarieties defines in a natural way a rational equivalence class (cf. section on special constructors above). This allows to compute intersection products among closed subvarieties and rational equivalence classes in the Chow ring.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Attributes","page":"The Chow ring","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Defining-attributes","page":"The Chow ring","title":"Defining attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"toric_variety(ac::RationalEquivalenceClass)\npolynomial(ac::RationalEquivalenceClass)\npolynomial(ring::MPolyQuoRing, ac::RationalEquivalenceClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#toric_variety-Tuple{RationalEquivalenceClass}","page":"The Chow ring","title":"toric_variety","text":"toric_variety(ac::RationalEquivalenceClass)\n\nReturn the normal toric variety of a rational equivalence class of algebraic cycles.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> ac = rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)\n\njulia> toric_variety(ac)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#polynomial-Tuple{RationalEquivalenceClass}","page":"The Chow ring","title":"polynomial","text":"polynomial(ac::RationalEquivalenceClass)\n\nOn a simplicial and complete toric variety, the Chow ring is isomorphic to a certain quotient of the Cox ring. This function returns the ring element corresponding to a given rational equivalence class of algebraic cycles.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> ac = rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)\n\njulia> polynomial(ac)\n6*x3 + e1 + 7*e2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#polynomial-Tuple{MPolyQuoRing, RationalEquivalenceClass}","page":"The Chow ring","title":"polynomial","text":"polynomial(ring::MPolyQuoRing, ac::RationalEquivalenceClass)\n\nOn a simplicial and complete toric variety, the Chow ring is isomorphic to a certain quotient of the Cox ring. This function returns the ring element corresponding to a given rational equivalence class of algebraic cycles. The first argument of this function allows to obtain this ring element in a different ring. This allows to change the coefficient ring if desired.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> ac = rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)\n\njulia> R, _ = polynomial_ring(QQ, 5)\n(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x1, x2, x3, x4, x5])\n\njulia> (x1, x2, x3, x4, x5) = gens(R)\n5-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n x4\n x5\n\njulia> sr_and_linear_relation_ideal = ideal([x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5])\nideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)\n\njulia> R_quo = quo(R, sr_and_linear_relation_ideal)[1]\nQuotient\n of multivariate polynomial ring in 5 variables over QQ\n by ideal(x1*x3, x1*x5, x2*x4, x2*x5, x3*x4, x1 + x2 - x5, x2 + x3 - x4 - x5)\n\njulia> polynomial(R_quo, ac)\n6*x3 + x4 + 7*x5\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Representatives","page":"The Chow ring","title":"Representatives","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"In order to see a geometric interpretation of rational equivalence classes of algebraic cycles most efficiently, it is best to replace self-intersections by transverse complete intersections. Indeed, within the regime of simplicial, complete toric varieties this is always possible. However, this involves a choice. Consequently, the following methods will pick a special choice and return values for that particular choice of representative of the rational equivalence class in question.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"representative(ac::RationalEquivalenceClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#representative-Tuple{RationalEquivalenceClass}","page":"The Chow ring","title":"representative","text":"representative(ac::RationalEquivalenceClass)\n\nReturn a polynomial in the Cox ring mapping to polynomial(ac).\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> ac = rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)\n\njulia> ac*ac\nRational equivalence class on a normal toric variety represented by 34V(x2,x3)\n\njulia> representative(ac*ac)\n34*x2*x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"It can be rather convenient to investigate such a representative in order to understand the geometric meaning of a rational equivalence class. For this purpose, we support the following methods.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"coefficients(ac::RationalEquivalenceClass)\ncomponents(ac::RationalEquivalenceClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#coefficients-Tuple{RationalEquivalenceClass}","page":"The Chow ring","title":"coefficients","text":"coefficients(ac::RationalEquivalenceClass)\n\nReturn the coefficients of polynomial(ac).\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> ac = rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)\n\njulia> coefficients(ac*ac)\n1-element Vector{QQFieldElem}:\n -34\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#components-Tuple{RationalEquivalenceClass}","page":"The Chow ring","title":"components","text":"components(ac::RationalEquivalenceClass)\n\nTurn each monomial of representative(ac) into a closed subvariety and return the list formed from these subvarieties. Note that each of these subvarieties is irreducible and their formal linear sum, with the coefficients computed by the method coefficients(ac::RationalEquivalenceClass), defines an algebraic cycle, whose rational equivalence class is identical to the one given to this method.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> ac = rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)\n\njulia> length(components(ac*ac))\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Other-attributes","page":"The Chow ring","title":"Other attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"cohomology_class(ac::RationalEquivalenceClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#cohomology_class-Tuple{RationalEquivalenceClass}","page":"The Chow ring","title":"cohomology_class","text":"cohomology_class(ac::RationalEquivalenceClass)\n\nReturn the cohomology class of a rational equilvalence class of algebraic cycles.\n\nExamples\n\njulia> dP2 = del_pezzo_surface(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> d = toric_divisor(dP2, [1, 2, 3, 4, 5])\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> ac = rational_equivalence_class(d)\nRational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)\n\njulia> cohomology_class(ac)\nCohomology class on a normal toric variety given by 6*x3 + e1 + 7*e2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Properties","page":"The Chow ring","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"One can check if a rational equivalence class of algebraic cycles is trivial via is_trivial. Equality can be tested with ==.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#Special-attributes-of-toric-varieties","page":"The Chow ring","title":"Special attributes of toric varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"chow_ring(v::AbstractNormalToricVariety)\ngens_of_rational_equivalence_classes(v::AbstractNormalToricVariety)\nmap_gens_of_chow_ring_to_cox_ring(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#chow_ring-Tuple{Oscar.AbstractNormalToricVariety}","page":"The Chow ring","title":"chow_ring","text":"chow_ring(v::AbstractNormalToricVariety)\n\nReturn the Chow ring of the simplicial toric variety v.\n\nWhile David A. Cox, John B. Little, Henry K. Schenck (2011) focus on simplicial and complete varieties to define the Chow ring, it was described in Christoph Pegel (2014) that this notion can also be extended to non-complete varieties. We explicitly support the Chow ring also for non-complete varieties.\n\nThis is demonstrated by the following example. Note that the computation for the non-complete variety leads to a Chow ring which is identical to the Chow ring of a certain matroid. This observation can be anticipated by e.g. the results in Eva Maria Feichtner, Sergey Yuzvinsky (2004).\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> is_complete(p2)\ntrue\n\njulia> ngens(chow_ring(p2))\n3\n\njulia> v = normal_toric_variety([[1, 0], [0, 1], [-1, -1]], [[1], [2], [3]])\nNormal toric variety\n\njulia> is_complete(v)\nfalse\n\njulia> set_coordinate_names(v, [\"x_{1}\", \"x_{2}\", \"x_{3}\"])\n\njulia> chow_ring(v)\nQuotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x_{1} - x_{3}, x_{2} - x_{3}, x_{1}*x_{2}, x_{1}*x_{3}, x_{2}*x_{3})\n\njulia> M = cycle_matroid(complete_graph(3))\nMatroid of rank 2 on 3 elements\n\njulia> chow_ring(M)\nQuotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x_{1} - x_{2}, x_{1} - x_{3}, x_{1}*x_{2}, x_{1}*x_{3}, x_{2}*x_{3})\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#gens_of_rational_equivalence_classes-Tuple{Oscar.AbstractNormalToricVariety}","page":"The Chow ring","title":"gens_of_rational_equivalence_classes","text":"gens_of_rational_equivalence_classes(v::AbstractNormalToricVariety)\n\nReturn a list of generators of the Chow ring of a complete, simplicial toric variety.\n\nRecall that the cones of a complete, simplicial toric variety can be seen as generators of the Chow ring (lemma 12.5.1 in David A. Cox, John B. Little, Henry K. Schenck (2011)). This function first maps each cone to an element of the Chow ring and then removes elements by taking rational equivalence into account.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> gens_of_rational_equivalence_classes(p2)\n6-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x3^2\n x3^2\n x3^2\n x3\n x3\n x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#map_gens_of_chow_ring_to_cox_ring-Tuple{Oscar.AbstractNormalToricVariety}","page":"The Chow ring","title":"map_gens_of_chow_ring_to_cox_ring","text":"map_gens_of_chow_ring_to_cox_ring(v::AbstractNormalToricVariety)\n\nReturn a dictionary which maps the generators of the chow ring to monomials in the Cox ring. This dictionary involves a choice, i.e. is not unique.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> map_gens_of_chow_ring_to_cox_ring(p2)\nDict{QQMPolyRingElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:\n x3^2 => x1*x3\n x3 => x3\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/FTheoryTools/tate/#Global-Tate-models","page":"Global Tate models","title":"Global Tate models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/#Introduction","page":"Global Tate models","title":"Introduction","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"A global Tate model describes a particular form of an elliptic fibration. We focus on an elliptic fibration over a base B. Consider the weighted projective space mathbbP^231 with coordinates x y z. In addition, consider","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"a_1 in H^0( B_3 overlineK_B ),\na_2 in H^0( B_3 overlineK_B^otimes 2 ),\na_3 in H^0( B_3 overlineK_B^otimes 3 ),\na_4 in H^0( B_3 overlineK_B^otimes 4 ),\na_6 in H^0( B_3 overlineK_B^otimes 6 ).","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"Then form a mathbbP^231-bundle over B such that","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"x transforms as a section of 2 overlineK_B,\ny transforms as a section of 3 overlineK_B,\nz transforms as a section of 0 overlineK_B = mathcalO_B.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"In this 5-fold ambient space, a global Tate model is the hypersurface defined by the vanishing of the Tate polynomial P_T = x^3 - y^2 - x y z a_1 + x^2 z^2 a_2 - y z^3 a_3 + x z^4 a_4 + z^6 a_6.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"Crucially, for non-trivial F-theory settings, the elliptic fibration in question must be singular. In fact, by construction, one usually engineers certain singularities. For this, vanishing orders of the sections a_i above need to specified. The following table–-often referred to as the Tate table and taken from Timo Weigand (2010)–-summarizes the singularities introduced by certain vanishing orders:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"sing. type mathrmord(Delta) singularity group G a_1 a_2 a_3 a_4 a_6\nI_0 0 0 0 0 0 0\nI_1 1 0 0 1 1 1\nI_2 2 A_1 SU(2) 0 0 1 1 2\nI_2k^ns 2k C_k Sp(k) 0 0 k k 2k\nI_2k^s 2k A_2k-1 SU(2k) 0 1 k k 2k\nI_2k+1^ns 2k+1 Sp(k) 0 0 k+1 k+1 2k+1\nI_2k+1^s 2k+1 A_2k SU(2k+1) 0 1 k k+1 2k+1\nII 2 1 1 1 1 1\nIII 3 A_1 SU(2) 1 1 1 1 2\nIV^ns 4 Sp(1) 1 1 1 2 2\nIV^s 4 A_2 SU(3) 1 1 1 2 3\nI_0^*ns 6 G_2 G_2 1 1 2 2 3\nI_0^*ss 6 B_3 SO(7) 1 1 2 2 4\nI_0^*s 6 D_4 SO(8) 1 1 2 2 4\nI_1^*ns 7 B_4 SO(9) 1 1 2 3 4\nI_1^*s 7 D_5 SO(10) 1 1 2 3 5\nI_2^*ns 8 B_5 SO(11) 1 1 3 3 5\nI_2^*s 8 D_6 SO(12) 1 1 3 3 5\nI_2k-3^*ns 2k+3 B_2k SO(4k+1) 1 1 k k+1 2k\nI_2k-3^*s 2k+3 D_2k+1 SO(4k+2) 1 1 k k+1 2k+1\nI_2k-2^*ns 2k+4 B_2k+1 SO(4k+3) 1 1 k+1 k+1 2k+1\nI_2k-2^*s 2k+4 D_2k+2 SO(4k+4) 1 1 k+1 k+1 2k+1\nIV^*ns 8 F_4 F_4 1 2 2 3 4\nIV^*s 8 E_6 E_6 1 2 2 3 5\nIII^* 9 E_7 E_7 1 2 3 3 5\nII^* 10 E_8 E_8 1 2 3 4 5\nnon-min. 12 1 2 3 4 6","category":"page"},{"location":"Experimental/FTheoryTools/tate/#Constructors","page":"Global Tate models","title":"Constructors","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"We aim to provide support for global Tate models over the following bases:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"a toric variety,\na toric scheme,\na (covered) scheme.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"Often, one also wishes to obtain information about a global Tate model without explicitly specifying the base space. Also for this application, we provide support. Finally, we provide support for some standard constructions.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"Before we detail these constructors, we must comment on the constructors over toric base spaces. Namely, in order to construct a global Tate model as a hypersurface in an ambient space, we first wish to construct the ambient space in question. For a toric base, one way to achieve this is to first focus on the Cox ring of the toric ambient space. This ring must be graded such that the Tate polynomial is homogeneous and cuts out a Calabi-Yau hypersurface. Given this grading, one can perform a triangulation task. Typically, this combinatorial task is very demanding, consumes a lot of computational power and takes a long time to complete. Even more, it will yield a large, often huge, number of candidate ambient spaces of which the typical user will only pick one. For instance, a common and often appropriate choice is a toric ambient space which contains the toric base space in a manifest way.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"To circumvent this very demanding computation, our toric constructors operate in the opposite direction. That is, they begin by extracting the rays and maximal cones of the chosen toric base space. Subsequently, those rays and cones are extended to form one of the many toric ambient spaces. This proves hugely superior in performance than going through the triangulation task of enumerating all possible toric ambient spaces. One downside of this strategy is that the so-constructed ambient space need not be smooth.","category":"page"},{"location":"Experimental/FTheoryTools/tate/#A-toric-variety-as-base-space","page":"Global Tate models","title":"A toric variety as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"We require that the provided toric base space is complete. This is a technical limitation as of now. The functionality of OSCAR only allows us to compute a section basis (or a finite subset thereof) for complete toric varieties. In the future, this could be extended.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"However, completeness is an expensive check. Therefore, we provide an optional argument which one can use to disable this check if desired. To this end, one passes the optional argument completeness_check = false as last argument to the constructor. The following examples demonstrate this:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"global_tate_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)\nglobal_tate_model(base::AbstractNormalToricVariety, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}","category":"page"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model-Tuple{Oscar.AbstractNormalToricVariety}","page":"Global Tate models","title":"global_tate_model","text":"global_tate_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)\n\nThis method constructs a global Tate model over a given toric base 3-fold. The Tate sections a_i are taken with (pseudo) random coefficients.\n\nExamples\n\njulia> t = global_tate_model(sample_toric_variety(); completeness_check = false)\nGlobal Tate model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model-Union{Tuple{T}, Tuple{Oscar.AbstractNormalToricVariety, Vector{T}}} where T<:MPolyRingElem","page":"Global Tate models","title":"global_tate_model","text":"global_tate_model(base::AbstractNormalToricVariety, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}\n\nThis method operates analogously to global_tate_model(base::AbstractNormalToricVariety). The only difference is that the Tate sections a_i can be specified with non-generic values.\n\nExamples\n\njulia> base = sample_toric_variety()\nNormal toric variety\n\njulia> a1 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base))]);\n\njulia> a2 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^2)]);\n\njulia> a3 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^3)]);\n\njulia> a4 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^4)]);\n\njulia> a6 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^6)]);\n\njulia> t = global_tate_model(base, [a1, a2, a3, a4, a6]; completeness_check = false)\nGlobal Tate model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#A-toric-scheme-as-base-space","page":"Global Tate models","title":"A toric scheme as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"For the same reasons as above, the toric base must be complete. Similar to toric varieties as bases, we can use the optional argument completeness_check = false to switch off the expensive completeness check. The following examples demonstrate this:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"global_tate_model(base::ToricCoveredScheme; completeness_check::Bool = true)\nglobal_tate_model(base::ToricCoveredScheme, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}","category":"page"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model-Tuple{ToricCoveredScheme}","page":"Global Tate models","title":"global_tate_model","text":"global_tate_model(base::ToricCoveredScheme; completeness_check::Bool = true)\n\nThis method constructs a global Tate model over a given toric scheme base 3-fold. The Tate sections a_i are taken with (pseudo) random coefficients.\n\nExamples\n\njulia> t = global_tate_model(sample_toric_scheme(); completeness_check = false)\nGlobal Tate model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model-Union{Tuple{T}, Tuple{ToricCoveredScheme, Vector{T}}} where T<:MPolyRingElem","page":"Global Tate models","title":"global_tate_model","text":"global_tate_model(base::ToricCoveredScheme, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}\n\nThis method operates analogously to global_tate_model(base::ToricCoveredScheme). The only difference is that the Tate sections a_i can be specified with non-generic values.\n\nExamples\n\njulia> base = sample_toric_scheme()\nScheme of a toric variety\n\njulia> a1 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base)))]);\n\njulia> a2 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^2)]);\n\njulia> a3 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^3)]);\n\njulia> a4 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^4)]);\n\njulia> a6 = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^6)]);\n\njulia> t = global_tate_model(base, [a1, a2, a3, a4, a6]; completeness_check = false)\nGlobal Tate model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#A-(covered)-scheme-as-base-space","page":"Global Tate models","title":"A (covered) scheme as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"This functionality does not yet exist.","category":"page"},{"location":"Experimental/FTheoryTools/tate/#Base-space-not-specified","page":"Global Tate models","title":"Base space not specified","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"This method constructs a global Tate model over a base space, where this base space is not (fully) specified. Consequently, we simply assume that a base space exists such that the Tate sections a_i as introduced above do exist.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"For many practical applications, one wishes to assume a further factorization of the Tate sections a_i. This has the advantage that one can engineer singularity loci or even the singularity type over a specific locus. This is the backbone of many F-theory constructions. For example, we could consider the factorization:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"a_1 = a_10 w^0,\na_2 = a_21 w^1,\na_3 = a_32 w^2,\na_4 = a_43 w^3,\na_6 = a_65 w^5,","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"In this case, it is useful to consider the polynomial ring with indeterminates a_10, a_21, a_32, a_43, a_65 and w. In theory, one can consider these indeterminates as local coordinate of an auxiliary base space. Indeed, for our computer implementation the polynomial ring with these indeterminates serve as the coordinate ring of an auxiliary toric base space. Despite this auxiliary base space being toric, the predictions from such an analysis are not limited to the world of toric varieties.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"For constructions along these lines, we support the following constructor:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"global_tate_model(auxiliary_base_ring::MPolyRing, auxiliary_base_grading::Matrix{Int64}, d::Int, ais::Vector{T}) where {T<:MPolyRingElem}","category":"page"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model-Union{Tuple{T}, Tuple{MPolyRing, Matrix{Int64}, Int64, Vector{T}}} where T<:MPolyRingElem","page":"Global Tate models","title":"global_tate_model","text":"global_tate_model(auxiliary_base_ring::MPolyRing, auxiliary_base_grading::Matrix{Int64}, d::Int, ais::Vector{T}) where {T<:MPolyRingElem}\n\nThis method constructs a global Tate model over a base space that is not fully specified.\n\nNote that many studies in the literature use the class of the anticanonical bundle in their analysis. We anticipate this by adding this class as a variable of the auxiliary base space, unless the user already provides this grading. Our convention is that the first grading refers to Kbar and that the homogeneous variable corresponding to this class carries the name \"Kbar\".\n\nThe following example exemplifies this approach.\n\nExamples\n\njulia> auxiliary_base_ring, (a10, a21, a32, a43, a65, w) = QQ[\"a10\", \"a21\", \"a32\", \"a43\", \"a65\", \"w\"];\n\njulia> auxiliary_base_grading = [1 2 3 4 6 0; 0 -1 -2 -3 -5 1]\n2×6 Matrix{Int64}:\n 1 2 3 4 6 0\n 0 -1 -2 -3 -5 1\n\njulia> a1 = a10;\n\njulia> a2 = a21 * w;\n\njulia> a3 = a32 * w^2;\n\njulia> a4 = a43 * w^3;\n\njulia> a6 = a65 * w^5;\n\njulia> ais = [a1, a2, a3, a4, a6];\n\njulia> t = global_tate_model(auxiliary_base_ring, auxiliary_base_grading, 3, ais)\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#Standard-constructions","page":"Global Tate models","title":"Standard constructions","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"We provide convenient constructions of global Tate models over standard base spaces. Currently, we support the following:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"global_tate_model_over_projective_space(d::Int)\nglobal_tate_model_over_hirzebruch_surface(r::Int)\nglobal_tate_model_over_del_pezzo_surface(b::Int)","category":"page"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model_over_projective_space-Tuple{Int64}","page":"Global Tate models","title":"global_tate_model_over_projective_space","text":"global_tate_model_over_projective_space(d::Int)\n\nThis method constructs a global Tate model over the projective space.\n\nExamples\n\njulia> global_tate_model_over_projective_space(3)\nGlobal Tate model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model_over_hirzebruch_surface-Tuple{Int64}","page":"Global Tate models","title":"global_tate_model_over_hirzebruch_surface","text":"global_tate_model_over_hirzebruch_surface(r::Int)\n\nThis method constructs a global Tate model over a Hirzebruch surface.\n\nExamples\n\njulia> global_tate_model_over_hirzebruch_surface(1)\nGlobal Tate model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model_over_del_pezzo_surface-Tuple{Int64}","page":"Global Tate models","title":"global_tate_model_over_del_pezzo_surface","text":"global_tate_model_over_del_pezzo_surface(b::Int)\n\nThis method constructs a global Tate model over a del-Pezzo surface.\n\nExamples\n\njulia> global_tate_model_over_del_pezzo_surface(3)\nGlobal Tate model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#Attributes","page":"Global Tate models","title":"Attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/#Basic-attributes","page":"Global Tate models","title":"Basic attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"For all global Tate models – irrespective over whether the base is toric or not – we support the following attributes:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"tate_section_a1(t::GlobalTateModel)\ntate_section_a2(t::GlobalTateModel)\ntate_section_a3(t::GlobalTateModel)\ntate_section_a4(t::GlobalTateModel)\ntate_section_a6(t::GlobalTateModel)\ntate_polynomial(t::GlobalTateModel)","category":"page"},{"location":"Experimental/FTheoryTools/tate/#tate_section_a1-Tuple{GlobalTateModel}","page":"Global Tate models","title":"tate_section_a1","text":"tate_section_a1(t::GlobalTateModel)\n\nReturn the Tate section a_1.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> tate_section_a1(t)\na1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#tate_section_a2-Tuple{GlobalTateModel}","page":"Global Tate models","title":"tate_section_a2","text":"tate_section_a2(t::GlobalTateModel)\n\nReturn the Tate section a_2.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> tate_section_a2(t)\na21*w\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#tate_section_a3-Tuple{GlobalTateModel}","page":"Global Tate models","title":"tate_section_a3","text":"tate_section_a3(t::GlobalTateModel)\n\nReturn the Tate section a_3.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> tate_section_a3(t)\na32*w^2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#tate_section_a4-Tuple{GlobalTateModel}","page":"Global Tate models","title":"tate_section_a4","text":"tate_section_a4(t::GlobalTateModel)\n\nReturn the Tate section a_4.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> tate_section_a4(t)\na43*w^3\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#tate_section_a6-Tuple{GlobalTateModel}","page":"Global Tate models","title":"tate_section_a6","text":"tate_section_a6(t::GlobalTateModel)\n\nReturn the Tate section a_6.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> tate_section_a6(t)\n0\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#tate_polynomial-Tuple{GlobalTateModel}","page":"Global Tate models","title":"tate_polynomial","text":"tate_polynomial(t::GlobalTateModel)\n\nReturn the Tate polynomial of the global Tate model.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> tate_polynomial(t)\n-a1*x*y*z + a21*w*x^2*z^2 - a32*w^2*y*z^3 + a43*w^3*x*z^4 + x^3 - y^2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"In case the global Tate model is constructed over a not fully specified base, recall that we construct an auxiliary (toric) base space as well as an auxiliary (toric) ambient space. The (auxiliary) base and ambient space can be accessed with the following functions:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"base_space(t::GlobalTateModel)\nambient_space(t::GlobalTateModel)\nfiber_ambient_space(t::GlobalTateModel)","category":"page"},{"location":"Experimental/FTheoryTools/tate/#base_space-Tuple{GlobalTateModel}","page":"Global Tate models","title":"base_space","text":"base_space(t::GlobalTateModel)\n\nReturn the base space of the global Tate model.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> base_space(t)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#ambient_space-Tuple{GlobalTateModel}","page":"Global Tate models","title":"ambient_space","text":"ambient_space(t::GlobalTateModel)\n\nReturn the ambient space of the global Tate model.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> ambient_space(t)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#fiber_ambient_space-Tuple{GlobalTateModel}","page":"Global Tate models","title":"fiber_ambient_space","text":"fiber_ambient_space(t::GlobalTateModel)\n\nReturn the fiber ambient space of the global Tate model.\n\njulia> t = su5_tate_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base\n\njulia> fiber_ambient_space(t)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"The following method allows to tell if the base/ambient space is auxiliary or not:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"base_fully_specified(t::GlobalTateModel)","category":"page"},{"location":"Experimental/FTheoryTools/tate/#base_fully_specified-Tuple{GlobalTateModel}","page":"Global Tate models","title":"base_fully_specified","text":"base_fully_specified(t::GlobalTateModel)\n\nReturn true if the Tate model has a concrete base space and false otherwise.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> base_fully_specified(t)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"The user can decide to get an information whenever an auxiliary base space, auxiliary ambient space or auxiliary hypersurface have been computed. To this end, one invokes set_verbosity_level(:GlobalTateModel, 1). More background information is available here.","category":"page"},{"location":"Experimental/FTheoryTools/tate/#Advanced-attributes","page":"Global Tate models","title":"Advanced attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"The following attributes are currently only supported in a toric setting:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"calabi_yau_hypersurface(t::GlobalTateModel)\nweierstrass_model(t::GlobalTateModel)","category":"page"},{"location":"Experimental/FTheoryTools/tate/#calabi_yau_hypersurface-Tuple{GlobalTateModel}","page":"Global Tate models","title":"calabi_yau_hypersurface","text":"calabi_yau_hypersurface(t::GlobalTateModel)\n\nReturn the Calabi-Yau hypersurface in the toric ambient space which defines the global Tate model.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> calabi_yau_hypersurface(t)\nClosed subvariety of a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#weierstrass_model-Tuple{GlobalTateModel}","page":"Global Tate models","title":"weierstrass_model","text":"weierstrass_model(t::GlobalTateModel)\n\nReturn the Weierstrass model which is equivalent to the given Tate model.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> weierstrass_model(t)\nWeierstrass model over a not fully specified base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"Note that for applications in F-theory, singular elliptic fibrations are key (cf. Timo Weigand (2018) and references therein). Consequently the discriminant locus as well as the singular loci of the fibration in question are of ample importance:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"discriminant(t::GlobalTateModel)\nsingular_loci(t::GlobalTateModel)","category":"page"},{"location":"Experimental/FTheoryTools/tate/#discriminant-Tuple{GlobalTateModel}","page":"Global Tate models","title":"discriminant","text":"discriminant(t::GlobalTateModel)\n\nReturn the discriminant of the global Tate model.\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> discriminant(t);\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#singular_loci-Tuple{GlobalTateModel}","page":"Global Tate models","title":"singular_loci","text":"singular_loci(t::GlobalTateModel)\n\nReturn the singular loci of the global Tate model, along with the order of vanishing of (f g Delta)` at each locus and the refined Tate fiber type.\n\nFor the time being, we either explicitly or implicitly focus on toric varieties as base spaces. Explicitly, in case the user provides such a variety as base space, and implicitly, in case we work over a non-fully specified base. This has the advantage that we can \"filter out\" trivial singular loci.\n\nSpecifically, recall that every closed subvariety of a simplicial toric variety is of the form V(I), where I is a homogeneous ideal of the Cox ring. Let B be the irrelevant ideal of this toric variety. Then, by proposition 5.2.6. of David A. Cox, John B. Little, Henry K. Schenck (2011), V(I) is trivial/empty iff B^l subseteq I for a suitable l geq 0. This can be checked by checking if the saturation IB^infty is the ideal generated by 1.\n\nBy treating a non-fully specified base space implicitly as a toric space, we can extend this result straightforwardly to this situation also. This is the reason for constructing this auxiliary base space.\n\nLet us demonstrate the functionality by computing the singular loci of a Type III Tate model Sheldon Katz, David R. Morrison, Sakura Schafer-Nameki, James Sully (2011). In this case, we will consider Global Tate model over a non-fully specified base. The Tate sections are factored as follows:\n\na_1 = a_11 w^1,\na_2 = a_21 w^1,\na_3 = a_31 w^1,\na_4 = a_41 w^1,\na_6 = a_62 w^2.\n\nFor this factorization, we expect a singularity of Kodaira type III over the divisor W = w = 0, as desired. So this should be one irreducible component of the discriminant. Moreover, we should find that the discriminant vanishes to order 3 on W = w = 0, while the Weierstrass sections f and g vanish to orders 1 and 2, respectively. Let us verify this.\n\njulia> auxiliary_base_ring, (a11, a21, a31, a41, a62, w) = QQ[\"a10\", \"a21\", \"a32\", \"a43\", \"a65\", \"w\"];\n\njulia> auxiliary_base_grading = [1 2 3 4 6 0; -1 -1 -1 -1 -2 1];\n\njulia> a1 = a11 * w;\n\njulia> a2 = a21 * w;\n\njulia> a3 = a31 * w;\n\njulia> a4 = a41 * w;\n\njulia> a6 = a62 * w^2;\n\njulia> ais = [a1, a2, a3, a4, a6];\n\njulia> t = global_tate_model(auxiliary_base_ring, auxiliary_base_grading, 3, ais)\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base\n\njulia> length(singular_loci(t))\n2\n\njulia> singular_loci(t)[2]\n(ideal(w), (1, 2, 3), \"III\")\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#Methods","page":"Global Tate models","title":"Methods","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/#Fiber-study","page":"Global Tate models","title":"Fiber study","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"In F-theory, it is standard to not work with the singular space directly. Rather, one resolves its singularities in order to obtain a smooth space instead. Subsequently, one performs computations on this smooth space.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"In order to perform such a resolution, one wishes to analyze the fibration in detail. The following method aims at giving a first window into this analysis by working out the fiber components and their intersection pattern over a particular locus of the base.","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"analyze_fibers(model::GlobalTateModel, centers::Vector{<:Vector{<:Integer}})","category":"page"},{"location":"Experimental/FTheoryTools/tate/#analyze_fibers-Tuple{GlobalTateModel, Vector{<:Vector{<:Integer}}}","page":"Global Tate models","title":"analyze_fibers","text":"analyze_fibers(model::GlobalTateModel, centers::Vector{<:Vector{<:Integer}})\n\nDetermine the fiber of a (singular) global Tate model over a particular base locus. ```\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/numberfield/#Number-field-arithmetic","page":"Number field arithmetic","title":"Number field arithmetic","text":"","category":"section"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Number fields are provided in Nemo by Antic. This allows construction of absolute number fields and basic arithmetic computations therein.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Number fields are constructed using the AnticNumberField function. However, for convenience we define","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"number_field = AnticNumberField","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"so that number fields can be constructed using number_field rather than AnticNumberField. ","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"The types of number field elements in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Library Field Element type Parent type\nAntic mathbbQx(f) nf_elem AnticNumberField","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"All the number field types belong to the Field abstract type and the number field element types belong to the FieldElem abstract type.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"The Hecke.jl library radically expands on number field functionality, providing ideals, orders, class groups, relative extensions, class field theory, etc.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"The basic number field element type used in Hecke is the Nemo/antic number field element type, making the two libraries tightly integrated.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"https://thofma.github.io/Hecke.jl/stable/","category":"page"},{"location":"Nemo/numberfield/#Number-field-functionality","page":"Number field arithmetic","title":"Number field functionality","text":"","category":"section"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"The number fields in Nemo provide all of the AbstractAlgebra field functionality:","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Below, we document the additional functionality provided for number field elements.","category":"page"},{"location":"Nemo/numberfield/#Constructors","page":"Number field arithmetic","title":"Constructors","text":"","category":"section"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"In order to construct number field elements in Nemo, one must first construct the number field itself. This is accomplished with one of the following constructors.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"number_field(::QQPolyRingElem, ::VarName)\ncyclotomic_field(::Int, ::VarName)\ncyclotomic_real_subfield(::Int, ::VarName)","category":"page"},{"location":"Nemo/numberfield/#number_field-Tuple{QQPolyRingElem, Union{Char, AbstractString, Symbol}}","page":"Number field arithmetic","title":"number_field","text":"number_field(f::QQPolyRingElem, s::VarName;\n cached::Bool = true, check::Bool = true)\n\nReturn a tuple R x consisting of the parent object R and generator x of the number field mathbbQx(f) where f is the supplied polynomial. The supplied string s specifies how the generator of the number field should be printed. If s is not specified, it defaults to _a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/#cyclotomic_field-Tuple{Int64, Union{Char, AbstractString, Symbol}}","page":"Number field arithmetic","title":"cyclotomic_field","text":"cyclotomic_field(n::Int, s::VarName = \"z_$n\", t = \"_\\$\"; cached = true)\n\nReturn a tuple R x consisting of the parent object R and generator x of the n-th cyclotomic field, mathbbQ(zeta_n). The supplied string s specifies how the generator of the number field should be printed. If provided, the string t specifies how the generator of the polynomial ring from which the number field is constructed, should be printed. If it is not supplied, a default dollar sign will be used to represent the variable.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/#cyclotomic_real_subfield-Tuple{Int64, Union{Char, AbstractString, Symbol}}","page":"Number field arithmetic","title":"cyclotomic_real_subfield","text":"cyclotomic_real_subfield(n::Int, s::VarName = \"(z_$n + 1/z_$n)\", t = \"\\$\"; cached = true)\n\nReturn a tuple R x consisting of the parent object R and generator x of the totally real subfield of the n-th cyclotomic field, mathbbQ(zeta_n). The supplied string s specifies how the generator of the number field should be printed. If provided, the string t specifies how the generator of the polynomial ring from which the number field is constructed, should be printed. If it is not supplied, a default dollar sign will be used to represent the variable.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Here are some examples of creating number fields and making use of the resulting parent objects to coerce various elements into those fields.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Examples","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"R, x = polynomial_ring(QQ, \"x\")\nK, a = number_field(x^3 + 3x + 1, \"a\")\nL, b = CyclotomicField(5, \"b\")\nM, c = CyclotomicRealField(5, \"c\")\n\nd = K(3)\nf = L(b)\ng = L(ZZ(11))\nh = L(ZZ(11)//3)\nk = M(x)","category":"page"},{"location":"Nemo/numberfield/#Number-field-element-constructors","page":"Number field arithmetic","title":"Number field element constructors","text":"","category":"section"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"gen(::AnticNumberField)","category":"page"},{"location":"Nemo/numberfield/#gen-Tuple{AnticNumberField}","page":"Number field arithmetic","title":"gen","text":"gen(a::AnticNumberField)\n\nReturn the generator of the given number field, i.e., a symbolic root of the defining polynomial.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"The easiest way of constructing number field elements is to use element arithmetic with the generator, to construct the desired element by its representation as a polynomial. See the following examples for how to do this.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Examples","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"R, x = polynomial_ring(QQ, \"x\")\nK, a = number_field(x^3 + 3x + 1, \"a\")\n\nd = gen(K)\nf = a^2 + 2a - 7","category":"page"},{"location":"Nemo/numberfield/#Basic-functionality","page":"Number field arithmetic","title":"Basic functionality","text":"","category":"section"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"mul_red!(::nf_elem, ::nf_elem, ::nf_elem, ::Bool)","category":"page"},{"location":"Nemo/numberfield/#mul_red!-Tuple{nf_elem, nf_elem, nf_elem, Bool}","page":"Number field arithmetic","title":"mul_red!","text":"mul_red!(z::nf_elem, x::nf_elem, y::nf_elem, red::Bool)\n\nMultiply x by y and set the existing number field element z to the result. Reduction modulo the defining polynomial is only performed if red is set to true. Note that x and y must be reduced. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"reduce!(::nf_elem)","category":"page"},{"location":"Nemo/numberfield/#reduce!-Tuple{nf_elem}","page":"Number field arithmetic","title":"reduce!","text":"reduce!(x::nf_elem)\n\nReduce the given number field element by the defining polynomial, in-place. This only needs to be done after accumulating values computed by mul_red! where reduction has not been performed. All standard Nemo number field functions automatically reduce their outputs.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"The following coercion function is provided for a number field R.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"R(f::QQPolyRingElem)","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Coerce the given rational polynomial into the number field R, i.e. consider the polynomial to be the representation of a number field element and return it.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Conversely, if R is the polynomial ring to which the generating polynomial of a number field belongs, then we can coerce number field elements into the ring R using the following function.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"R(b::nf_elem)","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Coerce the given number field element into the polynomial ring R of which the number field is a quotient.","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Examples","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"R, x = polynomial_ring(QQ, \"x\")\nK, a = number_field(x^3 + 3x + 1, \"a\")\n\nf = R(a^2 + 2a + 3)\ng = K(x^2 + 2x + 1)","category":"page"},{"location":"Nemo/numberfield/#Basic-manipulation","page":"Number field arithmetic","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"var(::AnticNumberField)","category":"page"},{"location":"Nemo/numberfield/#var-Tuple{AnticNumberField}","page":"Number field arithmetic","title":"var","text":"var(a::AnticNumberField)\n\nReturns the identifier (as a symbol, not a string), that is used for printing the generator of the given number field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"is_gen(::nf_elem)","category":"page"},{"location":"Nemo/numberfield/#is_gen-Tuple{nf_elem}","page":"Number field arithmetic","title":"is_gen","text":"is_gen(a::nf_elem)\n\nReturn true if the given number field element is the generator of the number field, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"coeff(::nf_elem, ::Int)","category":"page"},{"location":"Nemo/numberfield/#coeff-Tuple{nf_elem, Int64}","page":"Number field arithmetic","title":"coeff","text":"coeff(x::nf_elem, n::Int)\n\nReturn the n-th coefficient of the polynomial representation of the given number field element. Coefficients are numbered from 0, starting with the constant coefficient.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"denominator(::nf_elem)","category":"page"},{"location":"Nemo/numberfield/#denominator-Tuple{nf_elem}","page":"Number field arithmetic","title":"denominator","text":"denominator(a::nf_elem)\n\nReturn the denominator of the polynomial representation of the given number field element.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"degree(::AnticNumberField)","category":"page"},{"location":"Nemo/numberfield/#degree-Tuple{AnticNumberField}","page":"Number field arithmetic","title":"degree","text":"degree(a::AnticNumberField)\n\nReturn the degree of the given number field, i.e. the degree of its defining polynomial.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Examples","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"R, x = polynomial_ring(QQ, \"x\")\nK, a = number_field(x^3 + 3x + 1, \"a\")\n\nd = a^2 + 2a - 7\nm = gen(K)\n\nc = coeff(d, 1)\nis_gen(m)\nq = degree(K)\nr, s = signature(K)\nv = var(R)","category":"page"},{"location":"Nemo/numberfield/#Norm-and-trace","page":"Number field arithmetic","title":"Norm and trace","text":"","category":"section"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"norm(::nf_elem)","category":"page"},{"location":"Nemo/numberfield/#norm-Tuple{nf_elem}","page":"Number field arithmetic","title":"norm","text":"norm(a::nf_elem)\n\nReturn the absolute norm of a. The result will be a rational number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"tr(::nf_elem)","category":"page"},{"location":"Nemo/numberfield/#tr-Tuple{nf_elem}","page":"Number field arithmetic","title":"tr","text":"tr(a::nf_elem)\n\nReturn the absolute trace of a. The result will be a rational number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"Examples","category":"page"},{"location":"Nemo/numberfield/","page":"Number field arithmetic","title":"Number field arithmetic","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over QQ, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Number field of degree 3 over QQ, a)\n\njulia> c = 3a^2 - a + 1\n3*a^2 - a + 1\n\njulia> d = norm(c)\n113\n\njulia> f = tr(c)\n-15","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/univpolynomial/#Universal-polynomial","page":"Universal polynomial","title":"Universal polynomial","text":"","category":"section"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"AbstractAlgebra.jl provides a module, implemented in src/generic/UnivPoly.jl for a universal polynomial ring. This is very similar to the multivariate polynomial rings, except that variables can be added to the ring at any time.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"To compensate for the fact that the number of variables may change, many of the functions relax their restrictions on exponent vectors. For example, if one creates a polynomial when the ring only has two variables, each exponent vector would consist of two integers. Later, when the ring has more variable, these exponent vectors will still be accepted. The exponent vectors are simply padded out to the full number of variables behind the scenes.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/#Generic-sparse-distributed-universal-multivariable-polynomial-types","page":"Universal polynomial","title":"Generic sparse distributed universal multivariable polynomial types","text":"","category":"section"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"AbstractAlgebra provides a generic universal polynomial type Generic.UnivPoly{T, U} where T is the type of elements of the coefficient ring and U is the type of the elements of the underlying multivariate polynomial ring. Essentially, U can be any type belonging to MPolyRingElem{T}.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"Parent objects of such polynomials have type Generic.UniversalPolyRing{T, U}.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/#Abstract-types","page":"Universal polynomial","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"AbstractAlgebra also provides abstract types for universal polynomials and their rings. These are UniversalPolyRingElem{T, U} and UniversalPolyRing{T, U} respectively. These in turn belong to Ring.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/#Polynomial-ring-constructors","page":"Universal polynomial","title":"Polynomial ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"In order to construct universal polynomials in AbstractAlgebra.jl, one must first construct the universal polynomial ring itself. This is unique given a base ring.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"The universal polynomial ring over a given base ring R is constructed with one of the following constructor functions.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"UniversalPolynomialRing(R::Ring; cached::Bool = true, ordering::Symbol=:lex)","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"Given a base ring R and an array S of strings, return an object representing the universal polynomial ring S = Rldots with no variables in it initially.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"Examples","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"julia> S = UniversalPolynomialRing(ZZ)\nUniversal Polynomial Ring over Integers","category":"page"},{"location":"AbstractAlgebra/univpolynomial/#Adding-variables","page":"Universal polynomial","title":"Adding variables","text":"","category":"section"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"There are two ways to add variables to a universal polynomial ring S.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"gen(S::UniversalPolyRing, var::VarName)\ngens(S::UniversalPolyRing, vars::Vector{VarName})","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"Examples","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"julia> S = UniversalPolynomialRing(ZZ)\nUniversal Polynomial Ring over Integers\n\njulia> x = gen(S, \"x\")\nx\n\njulia> y, z = gens(S, [\"y\", \"z\"])\n(y, z)","category":"page"},{"location":"AbstractAlgebra/univpolynomial/#Universal-polynomial-functionality","page":"Universal polynomial","title":"Universal polynomial functionality","text":"","category":"section"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"The universal polynomial ring behaves exactly like a multivariate polynomial ring with the few differences noted above.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"The only functionality not implemented is the ability to do divrem by an ideal of polynomials.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"The universal polynomial ring is very useful for doing symbolic manipulation. However, it is important to understand that AbstractAlgebra is not a symbolic system and the performance of the universal polynomial ring will closely match that of a multivariate polynomial ring with the same number of variables.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"The disadvantage of this approach to symbolic manipulation is that some manipulations that would be offered by a symbolic system are not available, as variables are not identified by their names alone in AbstractAlgebra, as would be the case symbolically, but by objects.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"The most powerful symbolic tools we offer are the generalised evaluation functions, the multivariate coefficient functionality, the ability to change coefficient ring and to map coefficients according to a supplied function and the ability to convert a multivariate which happens to have just one variable into a dense univariate polynomial.","category":"page"},{"location":"AbstractAlgebra/univpolynomial/","page":"Universal polynomial","title":"Universal polynomial","text":"Further facilities may be added in future to ease symbolic manipulations.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/grouphom/#Group-homomorphisms","page":"Group homomorphisms","title":"Group homomorphisms","text":"","category":"section"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"In OSCAR, a group homomorphism from G to H is an object of parametric type GAPGroupHomomorphism{S,T}, where S and T are the types of G and H respectively.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"A homomorphism from G to H can be defined in two ways.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"Writing explicitly the images of the generators of G:","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"f = hom(G,H,[x1,x2,...],[y1,y2,...])","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"Here, [x1,x2,...] must be a generating set for G (not necessarily minimal) and [y1,y2,...] is a vector of elements of H of the same length of [x1,x2,...]. This assigns to f the value of the group homomorphism sending x_i into y_i.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"An exception is thrown if such a homomorphism does not exist.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"Taking an existing function g satisfying the group homomorphism properties:","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"f = hom(G,H,g)","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"An exception is thrown if the function g does not define a group homomorphism.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"Example: The following procedures define the same homomorphism (conjugation by x) in the two ways explained above.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"julia> S=symmetric_group(4);\n\njulia> x=S[1];\n\njulia> f=hom(S,S,gens(S),[S[1]^x,S[2]^x]);\n\njulia> g=hom(S,S,y->y^x);\n\njulia> f==g\ntrue","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"hom(G::GAPGroup, H::GAPGroup, img::Function)\nhom(G::GAPGroup, H::GAPGroup, gensG::Vector, imgs::Vector)\nimage(f::GAPGroupHomomorphism, x::GAPGroupElem)\npreimage(f::GAPGroupHomomorphism, x::GAPGroupElem)\nrestrict_homomorphism(f::GAPGroupHomomorphism, H::GAPGroup)","category":"page"},{"location":"Groups/grouphom/#hom-Tuple{Oscar.GAPGroup, Oscar.GAPGroup, Function}","page":"Group homomorphisms","title":"hom","text":"hom(G::GAPGroup, H::GAPGroup, f::Function)\n\nReturn the group homomorphism defined by the function f.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#hom-Tuple{Oscar.GAPGroup, Oscar.GAPGroup, Vector, Vector}","page":"Group homomorphisms","title":"hom","text":"hom(G::GAPGroup, H::GAPGroup, gensG::Vector = gens(G), imgs::Vector; check::Bool = true)\n\nReturn the group homomorphism defined by gensG[i] -> imgs[i] for every i. In order to work, the elements of gensG must generate G.\n\nIf check is set to false then it is not checked whether the mapping defines a group homomorphism.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#image-Tuple{GAPGroupHomomorphism, GAPGroupElem}","page":"Group homomorphisms","title":"image","text":"image(f::GAPGroupHomomorphism, x::GAPGroupElem)\n(f::GAPGroupHomomorphism)(x::GAPGroupElem)\n\nReturn f(x).\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#preimage-Tuple{GAPGroupHomomorphism, GAPGroupElem}","page":"Group homomorphisms","title":"preimage","text":"preimage(f::GAPGroupHomomorphism, x::GAPGroupElem)\n\nReturn an element y in the domain of f with the property f(y) == x. See haspreimage(f::GAPGroupHomomorphism, x::GAPGroupElem; check::Bool = true) for a check whether x has such a preimage.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#restrict_homomorphism-Tuple{GAPGroupHomomorphism, Oscar.GAPGroup}","page":"Group homomorphisms","title":"restrict_homomorphism","text":"restrict_homomorphism(f::GAPGroupHomomorphism, H::Group)\nrestrict_homomorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::T) where T <: Group\n\nReturn the restriction of f to H. An exception is thrown if H is not a subgroup of domain(f).\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"OSCAR has also the following standard homomorphism.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"id_hom\ntrivial_morphism","category":"page"},{"location":"Groups/grouphom/#id_hom","page":"Group homomorphisms","title":"id_hom","text":"id_hom(G::GAPGroup)\n\nReturn the identity homomorphism on the group G.\n\n\n\n\n\nid_hom(T::TorQuadModule) -> TorQuadModuleMor\n\nAlias for identity_map.\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouphom/#trivial_morphism","page":"Group homomorphisms","title":"trivial_morphism","text":"trivial_morphism(G::GAPGroup, H::GAPGroup = G)\n\nReturn the homomorphism from G to H sending every element of G into the identity of H.\n\n\n\n\n\ntrivial_morphism(T::TorQuadModule, U::TorQuadModule) -> TorQuadModuleMor\n\nReturn the abelian group homomorphism between T and U sending every elements of T to the zero element of U.\n\n\n\n\n\ntrivial_morphism(T::TorQuadModule) -> TorQuadModuleMor\n\nReturn the abelian group endomorphism of T sending every elements of T to the zero element of T.\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"To evaluate the homomorphism f in the element x of G, it is possible to use the instruction","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"image(f,x)","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"or the more compact notations f(x) and x^f.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"Example:","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"julia> S=symmetric_group(4);\n\njulia> f=hom(S,S,x->x^S[1]);\n\njulia> x=cperm(S,[1,2]);\n\njulia> image(f,x)\n(2,3)\n\njulia> f(x)\n(2,3)\n\njulia> x^f\n(2,3)","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"A sort of \"inverse\" of the evaluation is the following","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"haspreimage(f::GAPGroupHomomorphism, x::GAPGroupElem; check::Bool = true)","category":"page"},{"location":"Groups/grouphom/#haspreimage-Tuple{GAPGroupHomomorphism, GAPGroupElem}","page":"Group homomorphisms","title":"haspreimage","text":"haspreimage(f::GAPGroupHomomorphism, x::GAPGroupElem; check::Bool = true)\n\nReturn (true, y) if there exists y in domain(f) such that f(y) = x holds; otherwise, return (false, o) where o is the identity of domain(f).\n\nIf check is set to false then the test whether x is an element of image(f) is omitted.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"Example:","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"julia> S=symmetric_group(4);\n\njulia> f=hom(S,S,x->x^S[1]);\n\njulia> x=cperm(S,[1,2]);\n\njulia> haspreimage(f,x)\n(true, (1,4))","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"warning: Warning\nDo not confuse haspreimage with the function has_preimage, which works on variable of type GrpGenToGrpGenMor.","category":"page"},{"location":"Groups/grouphom/#Operations-on-homomorphisms","page":"Group homomorphisms","title":"Operations on homomorphisms","text":"","category":"section"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"OSCAR supports the following operations on homomorphisms.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"inv(f) = the inverse of f. An exception is thrown if f is not bijective.\nf^n = the homomorphism f composed n times with itself. An exception is thrown if the domain and the codomain of f do not coincide (unless n=1). If n is negative, the result is the inverse of f composed n times with itself.\ncompose(f, g) = composition of f and g. This works only if the codomain of f coincides with the domain of g. Shorter equivalent expressions are f*g and g(f).\nExample:","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"julia> S=symmetric_group(4);\n\njulia> f=hom(S,S,x->x^S[1]);\n\njulia> g=hom(S,S,x->x^S[2]);\n\njulia> f*g==hom(S,S,x->x^(S[1]*S[2]))\ntrue\n\njulia> f==f^-3\ntrue","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"note: Note\nThe composition operation * has to be read from the right to the left. So, (f*g)(x) is equivalent to g(f(x)).","category":"page"},{"location":"Groups/grouphom/#Properties-of-homomorphisms","page":"Group homomorphisms","title":"Properties of homomorphisms","text":"","category":"section"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"OSCAR implements the following attributes of homomorphisms, in addition to the usual domain and codomain.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"is_injective(f::GAPGroupHomomorphism)\nis_surjective(f::GAPGroupHomomorphism)\nis_bijective(f::GAPGroupHomomorphism)\nis_invertible(f::GAPGroupHomomorphism)\nis_invariant(f::GAPGroupHomomorphism, H::GAPGroup)","category":"page"},{"location":"Groups/grouphom/#is_injective-Tuple{GAPGroupHomomorphism}","page":"Group homomorphisms","title":"is_injective","text":"is_injective(f::GAPGroupHomomorphism)\n\nReturn whether f is injective.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#is_surjective-Tuple{GAPGroupHomomorphism}","page":"Group homomorphisms","title":"is_surjective","text":"is_surjective(f::GAPGroupHomomorphism)\n\nReturn whether f is surjective.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#is_bijective-Tuple{GAPGroupHomomorphism}","page":"Group homomorphisms","title":"is_bijective","text":"is_bijective(f::GAPGroupHomomorphism)\n\nReturn whether f is bijective.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#is_invertible-Tuple{GAPGroupHomomorphism}","page":"Group homomorphisms","title":"is_invertible","text":"is_invertible(f::GAPGroupHomomorphism)\n\nReturn whether f is invertible.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#is_invariant-Tuple{GAPGroupHomomorphism, Oscar.GAPGroup}","page":"Group homomorphisms","title":"is_invariant","text":"is_invariant(f::GAPGroupHomomorphism, H::Group)\nis_invariant(f::GAPGroupElem{AutomorphismGroup{T}}, H::T)\n\nReturn whether f(H) == H holds. An exception is thrown if domain(f) and codomain(f) are not equal or if H is not contained in domain(f).\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#Subgroups-described-by-homomorphisms","page":"Group homomorphisms","title":"Subgroups described by homomorphisms","text":"","category":"section"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"The following functions compute subgroups or quotients of either the domain or the codomain. Analogously to the functions described in Sections Subgroups and Quotients, the output consists of a pair (H, g), where H is a subgroup (resp. quotient) and g is its embedding (resp. projection) homomorphism.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"kernel(f::GAPGroupHomomorphism)\nimage(f::GAPGroupHomomorphism)\nimage(f::GAPGroupHomomorphism{S, T}, H::S) where S <: GAPGroup where T <: GAPGroup\ncokernel(f::GAPGroupHomomorphism)\npreimage(f::GAPGroupHomomorphism{S, T}, H::T) where S <: GAPGroup where T <: GAPGroup","category":"page"},{"location":"Groups/grouphom/#kernel-Tuple{GAPGroupHomomorphism}","page":"Group homomorphisms","title":"kernel","text":"kernel(f::GAPGroupHomomorphism)\n\nReturn the kernel of f, together with its embedding into domain(f).\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#image-Tuple{GAPGroupHomomorphism}","page":"Group homomorphisms","title":"image","text":"image(f::GAPGroupHomomorphism)\n\nReturn the image of f as subgroup of codomain(f), together with the embedding homomorphism.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#image-Union{Tuple{S}, Tuple{T}, Tuple{GAPGroupHomomorphism{S, T}, S}} where {T<:Oscar.GAPGroup, S<:Oscar.GAPGroup}","page":"Group homomorphisms","title":"image","text":"image(f::GAPGroupHomomorphism{S, T}, H::S) where S <: GAPGroup where T <: GAPGroup\n(f::GAPGroupHomomorphism{S, T})(H::S)\n\nReturn f(H), together with the embedding homomorphism into codomain(f).\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#cokernel-Tuple{GAPGroupHomomorphism}","page":"Group homomorphisms","title":"cokernel","text":"cokernel(f::GAPGroupHomomorphism)\n\nReturn the cokernel of f, that is, the quotient of the codomain of f by the normal closure of the image.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#preimage-Union{Tuple{S}, Tuple{T}, Tuple{GAPGroupHomomorphism{S, T}, T}} where {T<:Oscar.GAPGroup, S<:Oscar.GAPGroup}","page":"Group homomorphisms","title":"preimage","text":"preimage(f::GAPGroupHomomorphism{S, T}, H::T) where S <: GAPGroup where T <: GAPGroup\n\nIf H is a subgroup of the codomain of f, return the subgroup f^-1(H), together with its embedding homomorphism into the domain of f.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#Group-isomorphisms","page":"Group homomorphisms","title":"Group isomorphisms","text":"","category":"section"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"is_isomorphic(G::GAPGroup, H::GAPGroup)\nis_isomorphic_with_map(G::GAPGroup, H::GAPGroup)\nisomorphism(G::GAPGroup, H::GAPGroup)","category":"page"},{"location":"Groups/grouphom/#is_isomorphic-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Group homomorphisms","title":"is_isomorphic","text":"is_isomorphic(G::Group, H::Group)\n\nReturn true if G and H are isomorphic groups, and false otherwise.\n\nExamples\n\njulia> is_isomorphic(symmetric_group(3), dihedral_group(6))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#is_isomorphic_with_map-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Group homomorphisms","title":"is_isomorphic_with_map","text":"is_isomorphic_with_map(G::Group, H::Group)\n\nReturn (true,f) if G and H are isomorphic groups, where f is a group isomorphism. Otherwise, return (false,f), where f is the trivial homomorphism.\n\nExamples\n\njulia> is_isomorphic_with_map(symmetric_group(3), dihedral_group(6))\n(true, Group homomorphism from\nSym( [ 1 .. 3 ] )\nto\n)\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#isomorphism-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Group homomorphisms","title":"isomorphism","text":"isomorphism(G::Group, H::Group)\n\nReturn a group isomorphism between G and H if they are isomorphic groups. Otherwise throw an exception.\n\nExamples\n\njulia> isomorphism(symmetric_group(3), dihedral_group(6))\nGroup homomorphism from\nSym( [ 1 .. 3 ] )\nto\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"isomorphism(::Type{T}, G::GAPGroup) where T <: Union{FPGroup, PcGroup, PermGroup}\nisomorphism(::Type{GrpAbFinGen}, G::GAPGroup)\nsimplified_fp_group(G::FPGroup)","category":"page"},{"location":"Groups/grouphom/#isomorphism-Union{Tuple{T}, Tuple{Type{T}, Oscar.GAPGroup}} where T<:Union{FPGroup, PcGroup, PermGroup}","page":"Group homomorphisms","title":"isomorphism","text":"isomorphism(::Type{T}, G::GAPGroup) where T <: Union{FPGroup, PcGroup, PermGroup}\n\nReturn an isomorphism from G to a group of type T. An exception is thrown if no such isomorphism exists.\n\nIsomorphisms are cached in G, subsequent calls of isomorphism with the same T yield identical results.\n\nIf only the image of such an isomorphism is needed, use T(G).\n\nExamples\n\njulia> G = dihedral_group(6)\n\n\njulia> iso = isomorphism(PermGroup, G)\nGroup homomorphism from\n\nto\nGroup([ (1,2)(3,6)(4,5), (1,3,5)(2,4,6) ])\n\njulia> PermGroup(G)\nGroup([ (1,2)(3,6)(4,5), (1,3,5)(2,4,6) ])\n\njulia> codomain(iso) === ans\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#isomorphism-Tuple{Type{GrpAbFinGen}, Oscar.GAPGroup}","page":"Group homomorphisms","title":"isomorphism","text":"isomorphism(::Type{GrpAbFinGen}, G::GAPGroup)\n\nReturn a map from G to an isomorphic (additive) group of type GrpAbFinGen. An exception is thrown if G is not abelian or not finite.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#simplified_fp_group-Tuple{FPGroup}","page":"Group homomorphisms","title":"simplified_fp_group","text":"simplified_fp_group(G::FPGroup)\n\nReturn a group H of type FPGroup and an isomorphism f from G to H, where the presentation of H was obtained from the presentation of G by applying Tietze transformations in order to reduce it with respect to the number of generators, the number of relators, and the relator lengths.\n\nExamples\n\njulia> F = free_group(3)\n\n\njulia> G = quo(F, [gen(F,1)])[1]\n\n\njulia> simplified_fp_group(G)[1]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#Other-homomorphisms","page":"Group homomorphisms","title":"Other homomorphisms","text":"","category":"section"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"epimorphism_from_free_group(G::GAPGroup)","category":"page"},{"location":"Groups/grouphom/#epimorphism_from_free_group-Tuple{Oscar.GAPGroup}","page":"Group homomorphisms","title":"epimorphism_from_free_group","text":"epimorphism_from_free_group(G::GAPGroup)\n\nReturn an epimorphism epi from a free group F == domain(epi) onto G, where F has the same number of generators as G and such that for each i it maps gen(F,i) to gen(G,i).\n\nA useful application of this function is expressing an element of G as a word in its generators.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> epi = epimorphism_from_free_group(G)\nGroup homomorphism from\n\nto\nSym( [ 1 .. 4 ] )\n\njulia> pi = G([2,4,3,1])\n(1,2,4)\n\njulia> w = preimage(epi, pi);\n\njulia> map_word(w, gens(G))\n(1,2,4)\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/design_decisions/#Design-Decisions","page":"Design Decisions","title":"Design Decisions","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"This document covers the ideas and design decisions behind OSCAR, as well as some pitfalls to avoid.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/#OSCAR-what-is-the-idea","page":"Design Decisions","title":"OSCAR - what is the idea","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"OSCAR is the innovative, next generation Computer Algebra System. The ultimate goal for OSCAR is to compete with (and ideally beat) Magma and Sage in our areas of expertise. OSCAR should be accessible, even for the youngest student who is familiar with these objects. OSCAR should follow general mathematical conventions to support the widest possible range of applications.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"The key idea for development of OSCAR is to pick a single textbook for every area and follow the conventions in there. This way we get a consistent interface.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/#OSCAR-and-Julia","page":"Design Decisions","title":"OSCAR and Julia","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"OSCAR is written in Julia, but is not Julia, nor can it be. Some examples to illustrate what that means: Julia's matrices are arrays (of arbitrary dimension), parameterized by the type of the entries (apart from banded, sparse, ... special matrices). In the numerical world, the type mostly defines the representation of an object","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"double and variations\ncomplex\nBigFloat\nInt\nBigInt","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"In algebra, this is either not true or terribly inefficient (or impossible) Take mathbbZnmathbbZ integers modulo n, and matrices over it","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"Then either:","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"n is part of the type -> every function is recompiled for every n - which kills all modular (Chinese remainder theorem (CRT) based) algorithms\nn is not part of the type, then it needs to be elsewhere, e.g. in the parent, or in every element, or by passing additional arguments, or ...","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"Furthermore, if n is BigInt (ZZRingElem), so no bittype, then it cannot be part of the type.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"For non-empty matrices, this can be compensated if the entries store enough information, but for empty matrices this information needs to be collected elsewhere.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"To summarize, normal Julia infrastructure does not suffice for our purposes in many places. Hence we provide our own, which any code contributions should use. If functions are missing in it, then please","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"add them\nor tell us","category":"page"},{"location":"DeveloperDocumentation/design_decisions/#Mathematical-Context-in-OSCAR","page":"Design Decisions","title":"Mathematical Context in OSCAR","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"When studying mathematics, the exact meaning of a term or object is determined by context. In OSCAR, this does not work. The meaning has to be part of either","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"the object\nor the question posed about the object","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"As an example: in classical number theory there is the convention that many definitions that are trivial for fields are silently applied to the ring of integers. One speaks of the unit group of the number field, meaning the unit group of the ring of integers. Let alpha be an element explicitly constructed as an element of the number field, not of the ring of integers, then","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"is_unit will just test if it is non-zero (unit in a field as a special type of ring)\nis_unit_in_ring_of_integers would supply the context for the other interpretation.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"In OSCAR, this context is mostly supplied by the type of the object and possibly the parent, e.g. the containing ring/ field/ group.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/#What-Do-We-Have:","page":"Design Decisions","title":"What Do We Have:","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"We have a large codebase for infrastructure in place, comprising at least","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"matrices\npolynomials (univariate and multivariate)\npower series\nnumber fields\n(abelian) groups\npolytopes, cones, linear programs\npolyhedral fans\n... and MUCH more","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"For specialized functionality we can access the entirety of the following software frameworks on a lower level:","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"polymake\nSingular\nGap","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"So: Please use it. It is safe to assume all can be improved, however, if we try to perfect every single line of code again and again, we we won't get anywhere; there is a balance to be found. For preference: ","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"Correctness > Interoperability, Readability\nInteroperability > Speed\nReadability > Speed","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"Having said that: of course, sometimes pure speed matters, but not nearly as often as people think.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/#What-Is-Missing?","page":"Design Decisions","title":"What Is Missing?","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"The infrastructure is incomplete, e.g. we do not have","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"combinatorial manifolds\nsurfaces\ntropical polytopes\n....","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"Since we are a relatively small team and OSCAR is still very new, the usual","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"I work for 6 month in a separate repo on a branch and then will dazzle you\nwith perfect code and cool examples","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"approach is not going to work for now. It will result in everyone fixing the same infrastructure problems over and over again. Please consider to work, e.g. in a file/directory in Oscar/examples and push on a regular basis, even, or in particular, incomplete code. Break it down into small pull requests. Please also see the Introduction for new developers.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/#Practical-Development","page":"Design Decisions","title":"Practical Development","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/#Creating-New-Basic-Types","page":"Design Decisions","title":"Creating New Basic Types","text":"","category":"section"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"If you encounter the need for a new basic type, say a new multivariate ring, please consider the ramifications:","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"can you do matrices?\nmodules?\nideals?\ngraded stuff?\n\"complete\" arithmetic?\ninteraction with other types? (map to residue rings, apply automorphisms, ...)\nin fact, everything the other MPoly type can?","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"If no: at least use \"our\" types to interface your function, better still, use our type and complain about lack of functionality/ speed/ interface (or provide patches).","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"This applies to all foundations! They are all incomplete, and they can all be improved BUT if everyone does their own foundations, we cannot work together.","category":"page"},{"location":"DeveloperDocumentation/design_decisions/","page":"Design Decisions","title":"Design Decisions","text":"danger: Expert definitions\nAs a reminder, please stick to \"global definitions\" and not \"experts\" versions of definitions. Reasoning such as: \"but all experts know and expect this - it is always done this way\" will make your function impossible to be used by outsiders. Feel free to add the other \"expert\" definition layer if you need.","category":"page"},{"location":"AbstractAlgebra/#AbstractAlgebra.jl","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/#Introduction","page":"AbstractAlgebra.jl","title":"Introduction","text":"","category":"section"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"AbstractAlgebra.jl is a computer algebra package for the Julia programming language, maintained by William Hart, Tommy Hofmann, Claus Fieker and Fredrik Johansson and other interested contributors.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"Source code","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"AbstractAlgebra.jl grew out of the Nemo project after a number of requests from the community for the pure Julia part of Nemo to be split off into a separate project. See the Nemo repository for more details about Nemo.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"Nemo repository","category":"page"},{"location":"AbstractAlgebra/#Features","page":"AbstractAlgebra.jl","title":"Features","text":"","category":"section"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"The features of AbstractAlgebra.jl include:","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"Use of Julia multiprecision integers and rationals\nFinite fields (prime order, naive implementation only)\nNumber fields (naive implementation only)\nUnivariate polynomials\nMultivariate polynomials\nRelative and absolute power series\nLaurent series\nFraction fields\nResidue rings, including mathbbZnmathbbZ\nMatrices and linear algebra","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"All implementations are fully recursive and generic, so that one can build matrices over polynomial rings, over a finite field, for example.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"AbstractAlgebra.jl also provides a set of abstract types for Groups, Rings, Fields, Modules and elements thereof, which allow external types to be made part of the AbstractAlgebra.jl type hierarchy.","category":"page"},{"location":"AbstractAlgebra/#Installation","page":"AbstractAlgebra.jl","title":"Installation","text":"","category":"section"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"To use AbstractAlgebra we require Julia 1.6 or higher. Please see https://julialang.org/downloads/ for instructions on how to obtain Julia for your system.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"At the Julia prompt simply type","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"julia> using Pkg; Pkg.add(\"AbstractAlgebra\")","category":"page"},{"location":"AbstractAlgebra/#Quick-start","page":"AbstractAlgebra.jl","title":"Quick start","text":"","category":"section"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"Here are some examples of using AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"This example makes use of multivariate polynomials.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"using AbstractAlgebra\n\nR, (x, y, z) = polynomial_ring(ZZ, [\"x\", \"y\", \"z\"])\n\nf = x + y + z + 1\n\np = f^20;\n\n@time q = p*(p+1);","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"Here is an example using generic recursive ring constructions.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"using AbstractAlgebra\n\nR = GF(7)\n\nS, y = polynomial_ring(R, \"y\")\n\nT = residue_ring(S, y^3 + 3y + 1)\n\nU, z = polynomial_ring(T, \"z\")\n\nf = (3y^2 + y + 2)*z^2 + (2*y^2 + 1)*z + 4y + 3;\n\ng = (7y^2 - y + 7)*z^2 + (3y^2 + 1)*z + 2y + 1;\n\ns = f^4;\n\nt = (s + g)^4;\n\n@time resultant(s, t)","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"Here is an example using matrices.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"using AbstractAlgebra\n\nR, x = polynomial_ring(ZZ, \"x\")\n\nS = matrix_space(R, 10, 10)\n\nM = rand(S, 0:3, -10:10);\n\n@time det(M)","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"And here is an example with power series.","category":"page"},{"location":"AbstractAlgebra/","page":"AbstractAlgebra.jl","title":"AbstractAlgebra.jl","text":"using AbstractAlgebra\n\nR, x = QQ[\"x\"]\n\nS, t = power_series_ring(R, 30, \"t\")\n\nu = t + O(t^100)\n\n@time divexact((u*exp(x*u)), (exp(u)-1));","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/Singularities/space_germs/#Space-Germs","page":"Space Germs","title":"Space Germs","text":"","category":"section"},{"location":"Experimental/Singularities/space_germs/#space_germ_generalities","page":"Space Germs","title":"Generalities on Space germs","text":"","category":"section"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"The geometric notion of a space germ is a local concept. A space germ (Xx) at a point x is an equivalence class of ringed spaces, each of which contains x in its underlying topological space, and the equivalence relation is precisely the existence of an open neighbourhood of x on which the spaces coincide.","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Depending on the kind of ringed space in question, space germs arise in different forms:","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"a space germ in the context of affine schemes is the geometric object arising from a given scheme by localization at a point, leading to the stalk of the structure sheaf at the respective prime ideal.\nin the context of singularity theory, the (anti-)equivalence of categories between complex space germs and analytic mathbb CC-algebras allows the direct definition of a space germ from algebraic data","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Note that analytic algebras as mentioned above, have two computational problems. On one hand, exact computations can only be performed over fields in OSCAR permitting exact computations, in particular not over mathbb R or mathbb C. This usually does not pose a problem, if the input data is in an exact smaller field. But unfortunately, also analytic algebras themselves do not allow exact computations so that applications have to be considered in a localization of an affine algebra. With due care, output may again be interpreted in terms of a multivariate formal power series using the following inclusions:","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"mathbb Qunderlinex_langle x rangle hookrightarrow\n mathbb Qunderlinexhookrightarrow\n mathbb Qunderlinex","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"At particular points, where this difficulty of interpretation manifests itself prominently, a suitable warning, note or example has been placed (but certainly not everywhere). ","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Textbooks covering space germs in the sense of analytic algebras and singularity theory are:","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"G.-M. Greuel, C. Lossen, E. Shustin (2007)\nTheo de Jong, Gerhard Pfister (2000)","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"For the point of view of schemes, we refer to the page on schemes and the references given there; an example of a standard textbook is","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Robin Hartshorne (1977).","category":"page"},{"location":"Experimental/Singularities/space_germs/#Creating-Space-Germs-in-OSCAR","page":"Space Germs","title":"Creating Space Germs in OSCAR","text":"","category":"section"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"In general, space germs in OSCAR are created in the following ways:","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"localization of an affine scheme at a point\nSpaceGerm(X::AbsSpec, I::Ideal)\nwhere I is a (maximal) ideal describing the chosen mathbb k-point on the affine mathbb k-scheme X. Provides: SpaceGerm.\ngerm_at_point(X::AbsSpec, I::Ideal)\nwhere I is a (maximal) ideal describing the chosen mathbb k-point on the affine mathbb k-scheme. \nProvides: SpaceGerm, restriction map.","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"localization of a polynomial ring at a point\ngerm_at_point(R::MPolyRing, I::MPolyIdeal)\ngerm_at_point(R::MPolyQuoRing, I::MPolyIdeal)\nwhere I is a maximal ideal describing the chosen base_ring(R)-point.\nProvides: space germ and restriction map.\nlocalized ring with respect to complement of prime ideal or complement of maximal ideal)\nSpaceGerm(R::MPolyLocRing)\nSpaceGerm(R::MPolyQuoLocRing)\nProvides: Space germ\ngerm_at_point(R::MPolyLocRing)\ngerm_at_point(R::MPolyQuoLocRing)\nProvides: Space germ, restriction map \n(point inherited from underlying local ring)","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"As for all affine schemes, morphisms of space germs are in 11 correspondence with morphisms of the underlying local rings. Hence also handled in this way in OSCAR.","category":"page"},{"location":"Experimental/Singularities/space_germs/#Basic-functionality-for-space-germs","page":"Space Germs","title":"Basic functionality for space germs","text":"","category":"section"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Most of the basic functionality immediately falls back to the underlying affine algebra or affine scheme and is just provided on the geometric side for convenience and consistence of functionality:","category":"page"},{"location":"Experimental/Singularities/space_germs/#internal-data-of-a-space-germ","page":"Space Germs","title":"internal data of a space germ","text":"","category":"section"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Pass from the germ (Xx) back to some affine scheme X=Spec R, where with the appropriate localization at x, where R is a quotient of a multivariate polynomial ring, by\nrepresentative(X::SpaceGerm)\nProvides: AffineScheme \nGiven the space germ (Xx), the point x is returned by:\npoint(X:SpaceGerm)\nProvides: Vector describing of point coordinates","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"note: Note\nThe returned ideal is a prime ideal in the ring of a representative of the germ. At first use of it or at the latest upon the first call of representative, the respective affine scheme is cached and subsequently used for all further purposes requiring a representative","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Given a space germ (Xx), the corresponding local ring mathcal O_(Xx) is returned by:\nring(X::SpaceGerm)\nProvides: MPolyQuoLocRing or MPolyLocRing\nAnalogously, the modulus of the ring of a given germ (Xx) can be obtained by:\nideal(X::SpaceGerm)\nProvides: Ideal\nFor technical reasons all germs (Xx) in OSCAR are embedded and the smooth ambient germ can be accessed by:\nambient_germ(X::SpaceGerm)\nProvides: SpaceGerm","category":"page"},{"location":"Experimental/Singularities/space_germs/#containment/equality-of-space-germs","page":"Space Germs","title":"containment/equality of space germs","text":"","category":"section"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"containment \nissubset(X::SpaceGerm, Y::SpaceGerm)\nTest whether X is a subgerm of Y. \nProvides: Boolean Value","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"note: Note\nThe name 'issubset' has been chosen for consistency with other types, but is slightly misleading, as the function does not only test containment of the underlying sets, but in the scheme-theoretic sense.","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"equality\nX ==Y\nProvides: Boolean Value","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"note: Note\nEquality of the germs X and Y is tested in the sense of equality of subgerms of the same ambient space germ. ","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"emptyness\nFor the test of equality to the empty germ, a separate function is available:\nis_empty(X::SpaceGerm)\nProvides: Boolean Value\nintersection\nintersect(X::SpaceGerm,Y::SpaceGerm)\nComputes the intersection of two subgerms of a common larger germ.\nProvides: SpaceGerm ","category":"page"},{"location":"Experimental/Singularities/space_germs/#singular-locus","page":"Space Germs","title":"singular locus","text":"","category":"section"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"singular_locus(X::SpaceGerm)","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Computes the germ of the singular locus of the given germ.","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Provides: SpaceGerm ","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"If a test for smoothness is the goal, the following functions can be used","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"is_smooth(X::SpaceGerm)","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"Provides: Boolean Value","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"","category":"page"},{"location":"Experimental/Singularities/space_germs/","page":"Space Germs","title":"Space Germs","text":"","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"NumberTheory/galois/#Galois-Theory","page":"Galois Theory","title":"Galois Theory","text":"","category":"section"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Let K be a finite (separable) field extension of k. Then, in contrast to most of the literature we distinguish two concepts","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"the automorphism group\nthe Galois group","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"The automorphism group deals with the actual automorphism of K fixing k and thus is, in general trivial. Access is via two constructions:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"a list of all automorphisms (usually only the identity)\nthe group of automorphisms, returned as an abstract group and a map linking group elements to actual automorphisms","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"On the other hand, the Galois group is isomorphic to the automorphism group of the normal closure and is explicitly given as a group of permutations of the roots of the defining polynomial. Thus even in the case of K over k being normal, elements of the Galois group do not immediately give automorphisms at all.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Currently, the computation of Galois groups is possible for","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"K a simple extension of the rationals (AnticNumberField)\nK a simple extension of an AnticNumberField \nK a finite extension of the rational function field over the rationals. In this case the monodromy group can be computed as well, ie. the automorphism group over the complex numbers.\nf a polynomial over the rationals, or an AnticNumberField","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Independently of the Galois group, subfields, that is intermediate fields between K and k can be computed as well.","category":"page"},{"location":"NumberTheory/galois/#Automorphism-Group","page":"Galois Theory","title":"Automorphism Group","text":"","category":"section"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"The automorphisms are computed using various specialised factoring algorithms: lifting the roots of the defining polynomial in the given field modulo suitable prime ideal powers and recovering the true roots from this information.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"The main information is included in the number field chapter, see for example","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"automorphism_list(::Hecke.NumFieldMor)\nautomorphism_group(::NumField)\nautomorphism_group(::NumField, ::NumField)","category":"page"},{"location":"NumberTheory/galois/#Subfields","page":"Galois Theory","title":"Subfields","text":"","category":"section"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"The main information is included in the number field chapter, see","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"subfields(K::SimpleNumField; degree::Int = -1)\nHecke.principal_subfields(K::SimpleNumField)\nsubfields(FF::Generic.FunctionField{QQFieldElem})","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"By setting set_verbose_level(:Subfields, n::Int) to 1 or 2 information about the progress can be obtained.","category":"page"},{"location":"NumberTheory/galois/#Galois-Group","page":"Galois Theory","title":"Galois Group","text":"","category":"section"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"The computation of Galois groups follows Stauduhars algorithm with many improvements, see ... for an overview.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"The entrire computation can also be thought of finding a description of the splitting field of the polynomial. In fact, the information returned can be used to verify any algebraic identity between the roots, and find explicit subfields of the splitting field as well.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Information about the progress is available via","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"set_verbose_level(:GaloisGroup, n::Int)\nset_verbose_level(:GaloisInvariants, n::Int)","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"galois_group(K::AnticNumberField, extra::Int = 5; useSubfields::Bool = true, pStart::Int = 2*degree(K), prime::Int = 0)\ngalois_group(f::PolyRingElem{<:FieldElem})","category":"page"},{"location":"NumberTheory/galois/#galois_group","page":"Galois Theory","title":"galois_group","text":"galois_group(K::AnticNumberField, extra::Int = 5; useSubfields::Bool = true, pStart::Int = 2*degree(K)) -> PermGroup, GaloisCtx\n\nComputes the Galois group of the splitting field of the defining polynomial of K. Currently the polynomial needs to be monic.\n\nThe group is returned as an explicit permutation group permuting the roots as contained in the context object (the 2nd return value). The roots live in a suitable unramifed extension of the p-adics.\n\nExamples\n\njulia> K, a = cyclotomic_field(5);\n\njulia> G, C = galois_group(K)\n(Group([ (1,4,2,3), (1,2)(3,4) ]), Galois Context for x^4 + x^3 + x^2 + x + 1 and prime 19)\n\njulia> describe(G)\n\"C4\"\n\njulia> roots(C, 2)\n4-element Vector{qadic}:\n (4*19^0 + 2*19^1 + O(19^2))*a + 5*19^0 + 9*19^1 + O(19^2)\n (15*19^0 + 16*19^1 + O(19^2))*a + 9*19^0 + 7*19^1 + O(19^2)\n (18*19^0 + 18*19^1 + O(19^2))*a + 12*19^0 + O(19^2)\n (19^0 + O(19^2))*a + 11*19^0 + 19^1 + O(19^2)\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/galois/#galois_group-Tuple{PolyRingElem{<:FieldElem}}","page":"Galois Theory","title":"galois_group","text":"galois_group(f::PolyRingElem{<:FieldElem})\n\nComputes the automorphism group of a splitting field of f as an explicit group of permutations of the roots. Furthermore, the GaloisCtx is returned allowing algorithmic access to the splitting field.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Over the rational function field, we can also compute the monodromy group:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"DocTestFilters = r\"Group\\(.*\\]\\)\"","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> Qt, t = RationalFunctionField(QQ, \"t\");\n\njulia> Qtx, x = Qt[\"x\"];\n\njulia> F, a = function_field(x^6 + 108*t^2 + 108*t + 27);\n\njulia> subfields(F)\n4-element Vector{Any}:\n (Function Field over Rational field with defining polynomial a^3 + 54*t + 27, (1//12*_a^4 + (3//2*t + 3//4)*_a)//(t + 1//2))\n (Function Field over Rational field with defining polynomial a^2 + 108*t^2 + 108*t + 27, _a^3)\n (Function Field over Rational field with defining polynomial a^3 - 108*t^2 - 108*t - 27, -_a^2)\n (Function Field over Rational field with defining polynomial a^3 - 54*t - 27, (-1//12*_a^4 + (3//2*t + 3//4)*_a)//(t + 1//2))\n\njulia> galois_group(F)\n(Group([ (), (1,5)(2,3)(4,6), (1,3,4)(2,5,6) ]), Galois Context for s^6 + 108*t^2 + 540*t + 675)\n\njulia> G, C, k = galois_group(F, overC = true)\n(Group([ (1,4,3)(2,6,5) ]), Galois Context for s^6 + 108*t^2 + 540*t + 675, Number field of degree 2 over QQ)\n","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"So, while the splitting field over Q(t) has degree 6, the galois group there is isomorphic to the S(3) or D(3) (on 6 points), the splitting field over C(t) is only of degree 3. Here the group collapses to a cyclic group of degree 3, the algebraic closure of Q in the splitting field is the quadratic field returned last. It can be seen to be isomorphic to a cyclotomic field:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"DocTestFilters = nothing","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> is_isomorphic(k, cyclotomic_field(3)[1])\ntrue","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"The information returned consists always at least of a group G and a GaloisCtx: C. Jointly, they can be used to further work with the information:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"roots(C::Oscar.GaloisGrp.GaloisCtx{Hecke.qAdicRootCtx}, pr::Int)\nOscar.GaloisGrp.upper_bound\nOscar.GaloisGrp.isinteger\nOscar.GaloisGrp.resolvent(C::Oscar.GaloisGrp.GaloisCtx, G::PermGroup, U::PermGroup, extra::Int = 5)","category":"page"},{"location":"NumberTheory/galois/#roots-Tuple{Oscar.GaloisGrp.GaloisCtx{Hecke.qAdicRootCtx}, Int64}","page":"Galois Theory","title":"roots","text":"roots(G::GaloisCtx, pr::Int)\n\nThe roots of the polynomial used to define the Galois context in the fixed order used in the algorithm. The roots are returned up to a precision of pr p-adic digits, thus they are correct modulo p^pr\n\nFor non-monic polynomials the roots are scaled by the leading coefficient. If raw is set to true, the scaling is omitted. The bound in the GaloisCtx is also adjusted.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/#upper_bound","page":"Galois Theory","title":"upper_bound","text":"upper_bound(G::GaloisCtx, f...)\n\nGiven a GaloisCtx and some multivariate function, upper_bound the image of f upon evaluation at the roots implicit in G.\n\nf can be\n\na multivariate polynomial or straight-line polynomial (strictly: any object allowing evaluate\nelementary_symmetric or power_sum, in which case more arguments are needed: the array with the values and the index. upper_bound(G, power_sum, A, i) is equivalent to upper_bound(G, power_sum(A, i)) but more efficient.\n\nIn every case a univariate polynomial (over the integers) can be added, it will act as a Tschirnhaus-transformation, ie. the roots (bounds) implicit in G will first be transformed.\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/galois/#isinteger","page":"Galois Theory","title":"isinteger","text":"isinteger(C::GaloisCtx, B::BoundRingElem, v)\n\nFor an element v representing an integral polynomial evaluated at the roots stored in C, known to be bounded from above by B, either return true and an explicit (algebraic) integer in the base ring of the context or return false.\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/galois/#resolvent","page":"Galois Theory","title":"resolvent","text":"resolvent(C::GaloisCtx, G::PermGroup, U::PermGroup)\n\nFind a G-relative H-invariant I and form the corresponding resolvent polynomial prod (x-I^t) where the product runs over all coset-representatives of G/U.\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"To illustrate:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> Qx, x = QQ[\"x\"];\n\njulia> f = (x^2-2)*(x^2-3);\n\njulia> G, C = galois_group(f)\n(Group([ (1,2), (3,4) ]), Galois Context for x^4 - 5*x^2 + 6 and prime 11)\n\njulia> r = roots(C, 5)\n4-element Vector{qadic}:\n 5*11^0 + 2*11^1 + 6*11^2 + 8*11^3 + 11^4 + O(11^5)\n 6*11^0 + 8*11^1 + 4*11^2 + 2*11^3 + 9*11^4 + O(11^5)\n (11^0 + 6*11^1 + 6*11^2 + 2*11^4 + O(11^5))*a + 9*11^0 + 4*11^1 + 6*11^2 + 7*11^3 + 11^4 + O(11^5)\n (10*11^0 + 4*11^1 + 4*11^2 + 10*11^3 + 8*11^4 + O(11^5))*a + 2*11^0 + 6*11^1 + 4*11^2 + 3*11^3 + 9*11^4 + O(11^5)\n\njulia> r[1]^2\n3*11^0 + O(11^5)\n\njulia> r[3]^2\n2*11^0 + O(11^5)","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"To illustrate the use as a splitting field, we will prove that r[1]^2 is actually an integer - and that r[1]+r[3] is not.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Any multivariate polynomial in four variables and with integer coefficients defines via evaluation at the roots an element in the splitting field. In case the evaluation is actually an integer, this can be proven with the tools provided.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> I, s = polynomial_ring(ZZ, 4);\n\njulia> s[1]^2\nx1^2\n","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Next, we need a bound for the evaluation as a complex number, and compute the precision necessary:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> B = Oscar.GaloisGrp.upper_bound(C, s[1]^2)\n(x <= 36)\n\njulia> pr = Oscar.GaloisGrp.bound_to_precision(C, B)\n7\n","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Finally, we evaluate the polynomial at the roots and verify that the exact value is 3:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> evaluate(s[1]^2, roots(C, 7))\n3*11^0 + O(11^7)\n\njulia> Oscar.GaloisGrp.isinteger(C, B, ans)\n(true, 3)","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Now, to show that r[1] + r[3] is not an integer:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> B = Oscar.GaloisGrp.upper_bound(C, s[1] + s[3])\n(x <= 12)\n\njulia> Oscar.GaloisGrp.isinteger(C, B, evaluate(s[1] + s[3], roots(C, 7)))\n(false, nothing)","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"More interestingly, we can use this to find the minimal polynomial of r[1] + r[3]. Generically, the Galois-conjugates of r[1]+r[3] should be the G-orbit of s[1]+s[3] evaluated at the roots.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Once the orbit is known, the coefficients of the minimal polynomial are just the elementary symmetric functions evaluated at the roots: ","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> o = collect(orbit(G, s[1]+s[3]))\n4-element Vector{ZZMPolyRingElem}:\n x1 + x3\n x1 + x4\n x2 + x4\n x2 + x3\n\njulia> for i=1:4\n B = Oscar.GaloisGrp.upper_bound(C, elementary_symmetric, o, i)\n pr = Oscar.GaloisGrp.bound_to_precision(C, B)\n co = [evaluate(x, roots(C, pr)) for x = o]\n println(i, \": \", Oscar.GaloisGrp.isinteger(C, B, elementary_symmetric(co, i)))\n end\n1: (true, 0)\n2: (true, -10)\n3: (true, 0)\n4: (true, 1)","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"So, x^4-10x^2+1 should be the minimal polynomial to sqrt 3 + sqrt 2 - which it is.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"In the case of computations over the rational function field, both the precision and the bound are more complicated - but can be used in the same way: Here, the roots are power series with q-adic coefficients, thus the precision has to cover both the precision of the coefficient as well as the number of terms in the series. Similarly, in this context, an isinteger is now a polynomial with integer coefficients. Thus the bound needs to bound the degree as well as the coefficient size.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> Qt,t = RationalFunctionField(QQ, \"t\");\n\njulia> Qtx, x = Qt[\"x\"];\n\njulia> F, a = function_field(x^3+t+2);\n\njulia> G, C = galois_group(F);\n\njulia> describe(G)\n\"S3\"\n\njulia> _, s = slpoly_ring(ZZ, 3);\n\njulia> B = Oscar.GaloisGrp.upper_bound(C, prod(s))\n(x <= (9261, 2, 1))\n\njulia> pr = Oscar.GaloisGrp.bound_to_precision(C, B)\n(2, 2)\n\njulia> Oscar.GaloisGrp.isinteger(C, B, evaluate(prod(s), roots(C, pr)))\n(true, -t - 2)","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"galois_quotient(C::Oscar.GaloisGrp.GaloisCtx, Q::PermGroup)\ngalois_quotient(C::Oscar.GaloisGrp.GaloisCtx, d::Int)\ngalois_quotient(C::Oscar.GaloisGrp.GaloisCtx, d::Int, n::Int)\ngalois_quotient(f::PolyRingElem, p::Vector{Int})\nfixed_field(GC::Oscar.GaloisGrp.GaloisCtx, U::PermGroup, extra::Int = 5)\nminpoly(C::Oscar.GaloisGrp.GaloisCtx, I, extra::Int = 5)","category":"page"},{"location":"NumberTheory/galois/#galois_quotient-Tuple{Oscar.GaloisGrp.GaloisCtx, PermGroup}","page":"Galois Theory","title":"galois_quotient","text":"galois_quotient(C::GaloisCtx, Q::PermGroup)\n\nFinds all(?) subfields of the splitting field s.th. the galois group will be permutation isomorphic to Q.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/#galois_quotient-Tuple{Oscar.GaloisGrp.GaloisCtx, Int64}","page":"Galois Theory","title":"galois_quotient","text":"galois_quotient(C::GaloisCtx, d::Int)\n\nFinds all(?) subfields (up to isomorphism) of the splitting field of degree d with galois group isomorphic to the original one.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> G, C = galois_group(x^3-2);\n\njulia> galois_quotient(C, 6)\n1-element Vector{Any}:\n Number field of degree 6 over QQ\n\njulia> galois_group(ans[1])\n(Group([ (), (1,5)(2,4)(3,6), (1,2,3)(4,5,6) ]), Galois Context for x^6 + 324*x^4 - 4*x^3 + 34992*x^2 + 1296*x + 1259716 and prime 13)\n\njulia> is_isomorphic(ans[1], G)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/#galois_quotient-Tuple{Oscar.GaloisGrp.GaloisCtx, Int64, Int64}","page":"Galois Theory","title":"galois_quotient","text":"galois_quotient(C::GaloisCtx, d::Int, n::Int)\n\nFinds all subfields of the splitting field with galois group the n-th transitive group in degree d\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/#galois_quotient-Tuple{PolyRingElem, Vector{Int64}}","page":"Galois Theory","title":"galois_quotient","text":"galois_quotient(f::PolyRingElem, p::Vector{Int})\n\nEquivalent to\n\ngalois_quotient(galois_group(f)[2], p[1], p[2])\n\nFinds all subfields of the splitting field of f with galois group the p[2]-th transitive group of degree p[1]\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/#fixed_field","page":"Galois Theory","title":"fixed_field","text":"fixed_field(GC::GaloisCtx, U::PermGroup, extra::Int = 5)\n\nGiven the GaloisCtx as returned by a call to galois_group and a subgroup U of the Galois group, compute the field fixed by U as a simple extension.\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/galois/#minpoly","page":"Galois Theory","title":"minpoly","text":"minpoly(C::GaloisCtx, I, extra::Int = 5)\n\nComputes the minimal polynomial of I evaluated at the roots stored in C.\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Oscar.GaloisGrp.cauchy_ideal(f::PolyRingElem{<:FieldElem})\nOscar.GaloisGrp.galois_ideal(C::Oscar.GaloisGrp.GaloisCtx, extra::Int = 5)","category":"page"},{"location":"NumberTheory/galois/#cauchy_ideal-Tuple{PolyRingElem{<:FieldElem}}","page":"Galois Theory","title":"cauchy_ideal","text":"cauchy_ideal(f::PolyRingElem{<:FieldElem})\n\nThe coefficients of f are the elementary symmetric functions evaluated at the roots of f. The cauchy_ideal is the ideal generated by the differences between the elementary symmetric functions and the coefficients.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> cauchy_ideal(x^4-2)\nideal(x4^4 - 2, x3^3 + x3^2*x4 + x3*x4^2 + x4^3, x2^2 + x2*x3 + x2*x4 + x3^2 + x3*x4 + x4^2, x1 + x2 + x3 + x4)\n\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/#galois_ideal","page":"Galois Theory","title":"galois_ideal","text":"galois_ideal(C::GaloisCtx, extra::Int = 5)\n\nThe so-called Galois ideal is a description of the splitting field of the polynomial underlying Cas a quotient by some maximal ideal. Algebraically, this ideal is an irreducible component of the Cauchy ideal, the ideal generated by the elementary symmetric functions and the coefficients of the polynomial.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> i = galois_ideal(galois_group(x^4-2)[2])\nideal(x4^4 - 2, x3^3 + x3^2*x4 + x3*x4^2 + x4^3, x2^2 + x2*x3 + x2*x4 + x3^2 + x3*x4 + x4^2, x1 + x2 + x3 + x4, x1*x3 + x2*x4, x1^2*x3^2 + x2^2*x4^2 - 4, x1^4 - 2, x2^4 - 2, x3^4 - 2, x4^4 - 2)\n\njulia> k, _ = number_field(i);\n\n\njulia> length(roots(k, x^4-2))\n4\n\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"Over the integers, if the Galois group is solvable, the roots can be expressed as radicals:","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"solve(f::ZZPolyRingElem)\nfixed_field(C::Oscar.GaloisGrp.GaloisCtx, s::Vector{PermGroup})","category":"page"},{"location":"NumberTheory/galois/#solve-Tuple{ZZPolyRingElem}","page":"Galois Theory","title":"solve","text":"Oscar.solve(f::ZZPolyRingElem; max_prec::Int=typemax(Int))\nOscar.solve(f::QQPolyRingElem; max_prec::Int=typemax(Int))\n\nCompute a presentation of the roots of f in a radical tower. The necessary roots of unity are not themselves computed as radicals.\n\nSee also galois_group.\n\nVERBOSE\n\nSupports set_verbose_level(:SolveRadical, i) to obtain information.\n\nExamples\n\njulia> Qx,x = QQ[\"x\"];\n\njulia> K, r = solve(x^3+3*x+5)\n(Relative number field over with defining polynomial x^3 + (3*z_3 + 3//2)*a2 + 135//2\n over Relative number field over with defining polynomial x^2 + 783\n over Number field over Rational Field with defining polynomial x^2 + x + 1, Any[((1//81*z_3 + 1//162)*a2 - 5//18)*a3^2 + 1//3*a3, ((-1//162*z_3 + 1//162)*a2 + 5//18*z_3 + 5//18)*a3^2 + 1//3*z_3*a3, ((-1//162*z_3 - 1//81)*a2 - 5//18*z_3)*a3^2 + (-1//3*z_3 - 1//3)*a3])\n\njulia> #z_3 indicates the 3-rd root-of-1 used\n\njulia> map(x^3+3*x+5, r)\n3-element Vector{Hecke.NfRelElem{Hecke.NfRelElem{nf_elem}}}:\n 0\n 0\n 0\n\njulia> solve(cyclotomic(12, x)) #zeta_12 as radical\n(Relative number field over with defining polynomial x^2 - 3//4\n over Number field over Rational Field with defining polynomial x^2 + 1, Any[a2 + 1//2*a1, a2 - 1//2*a1, -a2 - 1//2*a1, -a2 + 1//2*a1])\n\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/galois/#fixed_field-Tuple{Oscar.GaloisGrp.GaloisCtx, Vector{PermGroup}}","page":"Galois Theory","title":"fixed_field","text":"fixed_field(C::GaloisCtx, s::Vector{PermGroup})\n\nGiven a descending chain of subgroups, each being maximal in the previous one, compute the corresponding subfields as a tower.\n\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> G, C = galois_group(x^3-3*x+17)\n(Sym( [ 1 .. 3 ] ), Galois Context for x^3 - 3*x + 17 and prime 7)\n\njulia> d = derived_series(G)\n3-element Vector{PermGroup}:\n Sym( [ 1 .. 3 ] )\n Alt( [ 1 .. 3 ] )\n Group(())\n\njulia> fixed_field(C, d)\n(Relative number field of degree 3 over number field, a2)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#Weierstrass-models","page":"Weierstrass models","title":"Weierstrass models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"A Weierstrass model describes a particular form of an elliptic fibration. We focus on an elliptic fibration over a complete base B. Consider the weighted projective space mathbbP^231 with coordinates x y z. In addition, consider","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"f in H^0( B overlineK_B^otimes 4 ),\ng in H^0( B overlineK_B^otimes 6 ),","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"Then form a mathbbP^231-bundle over B such that","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"x transforms as a section of 2 overlineK_B,\ny transforms as a section of 3 overlineK_B,\nz transforms as a section of 0 overlineK_B = mathcalO_B.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"In this 5-fold ambient space, a Weierstrass model is the hypersurface defined by the vanishing of the Weierstrass polynomial P_W = x^3 - y^2 + f x z^4 + g z^6.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"Crucially, for non-trivial F-theory settings, the elliptic fibration in question must be singular. In fact, by construction, one usually engineers certain singularities. This can be read-off from the Weierstrass table, which we have reproduced from Timo Weigand (2018) with small corrections:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"type mathrmord(f) mathrmord(g) mathrmord(Delta) sing. monodromy cover algebra mathfrakg comp.\nI_0 geq 0 geq 0 0 \nI_1 0 0 1 \nII geq 1 1 2 \nIII 1 geq 2 3 A_1 mathfraksu(2) \nIV^ns geq 2 2 4 A_2 left psi^2 - fracgw^2 right_w = 0 mathfraksp(1) 1\nIV^s geq 2 2 4 A_2 left psi^2 - fracgw^2 right_w = 0 mathfraksu(3) 2\nI_m^ns 0 0 m A_m - 1 left psi^2 + frac9g2f right_w = 0 mathfraksp(lfloor fracm2 rfloor) 1\nI_m^s 0 0 m A_m - 1 left psi^2 + frac9g2f right_w = 0 mathfraksu(m) 2\nI_0^*ns geq 2 geq 3 6 D_4 left psi^3 + psi cdot fracfw^2 + fracgw^3 right_w = 0 mathfrakg_2 1\nI_0^*ss geq 2 geq 3 6 D_4 left psi^3 + psi cdot fracfw^2 + fracgw^3 right_w = 0 mathfrakso(7) 2\nI_0^*s geq 2 geq 3 6 D_4 left psi^3 + psi cdot fracfw^2 + fracgw^3 right_w = 0 mathfrakso(8) 3\nI_2n-5^*ns (n geq 3) 2 3 2n+1 D_2n-1 left psi^2 + frac14 left( fracDeltaw^2n+1 right) left( frac2wf9g right)^3 right_w = 0 mathfrakso(4n-3) 1\nI_2n-5^*s (n geq 3) 2 3 2n+1 D_2n-1 left psi^2 + frac14 left( fracDeltaw^2n+1 right) left( frac2wf9g right)^3 right_w = 0 mathfrakso(4n-2) 2\nI_2n-4^*ns (n geq 3) 2 3 2n+2 D_2n left psi^2 + left( fracDeltaw^2n+2 right) left( frac2wf9g right)^2 right_w = 0 mathfrakso(4n-1) 1\nI_2n-4^*s (n geq 3) 2 3 2n+2 D_2n left psi^2 + left( fracDeltaw^2n+2 right) left( frac2wf9g right)^2 right_w = 0 mathfrakso(4n) 2\nIV^*ns geq 3 4 8 E_6 left psi^2 - fracgw^4 right_w = 0 mathfrakf_4 1\nIV^*s geq 3 4 8 E_6 left psi^2 - fracgw^4 right_w = 0 mathfrake_6 2\nIII^* 3 geq 5 9 E_7 mathfrake_7 \nII^* geq 4 5 10 E_8 mathfrake_8 \nnon-min. geq 4 geq 6 geq 12 non-can. ","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#Constructors","page":"Weierstrass models","title":"Constructors","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"We aim to provide support for Weierstrass models over the following bases:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"a toric variety,\na toric scheme,\na (covered) scheme.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"Often, one also wishes to obtain information about a Weierstrass model without explicitly specifying the base space. Also for this application, we provide support. Finally, we provide support for some standard constructions.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"Before we detail these constructors, we must comment on the constructors over toric base spaces. Namely, in order to construct a Weierstrass model as a hypersurface in an ambient space, we first wish to construct the ambient space in question. For a toric base, one way to achieve this is to first focus on the Cox ring of the toric ambient space. This ring must be graded such that the Weierstrass polynomial is homogeneous and cuts out a Calabi-Yau hypersurface. Given this grading, one can perform a triangulation task. Typically, this combinatorial task is very demanding, consumes a lot of computational power and takes a long time to complete. Even more, it will yield a large, often huge, number of candidate ambient spaces of which the typical user will only pick one. For instance, a common and often appropriate choice is a toric ambient space which contains the toric base space in a manifest way.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"To circumvent this very demanding computation, our toric constructors operate in the opposite direction. That is, they begin by extracting the rays and maximal cones of the chosen toric base space. Subsequently, those rays and cones are extended to form one of the many toric ambient spaces. This proves hugely superior in performance than going through the triangulation task of enumerating all possible toric ambient spaces. One downside of this strategy is that the so-constructed ambient space need not be smooth.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#A-toric-variety-as-base-space","page":"Weierstrass models","title":"A toric variety as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"We require that the provided toric base space is complete. This is a technical limitation as of now. The functionality of OSCAR only allows us to compute a section basis (or a finite subset thereof) for complete toric varieties. In the future, this could be extended.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"However, completeness is an expensive check. Therefore, we provide an optional argument which one can use to disable this check if desired. To this end, one passes the optional argument completeness_check = false as last argument to the constructor. The following examples demonstrate this:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"weierstrass_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)\nweierstrass_model(base::AbstractNormalToricVariety, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model-Tuple{Oscar.AbstractNormalToricVariety}","page":"Weierstrass models","title":"weierstrass_model","text":"weierstrass_model(base::AbstractNormalToricVariety; completeness_check::Bool = true)\n\nThis method constructs a Weierstrass model over a given toric base 3-fold. The Weierstrass sections f and g are taken with (pseudo)random coefficients.\n\nExamples\n\njulia> w = weierstrass_model(sample_toric_variety(); completeness_check = false)\nWeierstrass model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model-Tuple{Oscar.AbstractNormalToricVariety, MPolyRingElem, MPolyRingElem}","page":"Weierstrass models","title":"weierstrass_model","text":"weierstrass_model(base::AbstractNormalToricVariety, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)\n\nThis method operates analogously to weierstrass_model(base::AbstractNormalToricVariety). The only difference is that the Weierstrass sections f and g can be specified with non-generic values.\n\nExamples\n\njulia> base = sample_toric_variety()\nNormal toric variety\n\njulia> f = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^4)]);\n\njulia> g = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(base)^6)]);\n\njulia> w = weierstrass_model(base, f, g; completeness_check = false)\nWeierstrass model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#A-toric-scheme-as-base-space","page":"Weierstrass models","title":"A toric scheme as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"For the same reasons as above, the toric base must be complete. Similar to toric varieties as bases, we can use the optional argument completeness_check = false to switch off the expensive completeness check. The following examples demonstrate this:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"weierstrass_model(base::ToricCoveredScheme; completeness_check::Bool = true)\nweierstrass_model(base::ToricCoveredScheme, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model-Tuple{ToricCoveredScheme}","page":"Weierstrass models","title":"weierstrass_model","text":"weierstrass_model(base::ToricCoveredScheme; completeness_check::Bool = true)\n\nThis method constructs a Weierstrass model over a given toric base 3-fold. The Weierstrass sections f and g are taken with (pseudo)random coefficients.\n\nExamples\n\njulia> w = weierstrass_model(sample_toric_scheme(); completeness_check = false)\nWeierstrass model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model-Tuple{ToricCoveredScheme, MPolyRingElem, MPolyRingElem}","page":"Weierstrass models","title":"weierstrass_model","text":"weierstrass_model(base::ToricCoveredScheme, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)\n\nThis method operates analogously to weierstrass_model(base::ToricCoveredScheme). The only difference is that the Weierstrass sections f and g can be specified with non-generic values.\n\nExamples\n\njulia> base = sample_toric_scheme()\nScheme of a toric variety\n\njulia> f = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^4)]);\n\njulia> g = sum([rand(Int) * b for b in basis_of_global_sections(anticanonical_bundle(underlying_toric_variety(base))^6)]);\n\njulia> w = weierstrass_model(base, f, g; completeness_check = false)\nWeierstrass model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#A-(covered)-scheme-as-base-space","page":"Weierstrass models","title":"A (covered) scheme as base space","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"This functionality does not yet exist.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#Base-space-not-specified","page":"Weierstrass models","title":"Base space not specified","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"A Weierstrass model can also be constructed over a base space that is not fully specified. Rather, it assumes that a base space exists such that the Weierstrass sections f and g are well-defined, so that the Weierstrass model in question is well-defined.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"For many practical applications, one wishes to assume a further specialize the Weierstrass sections f and g. This has the advantage that one can engineer singularity loci or even the singularity type over a specific locus. To some extend, this is the backbone of many F-theory constructions. It is useful to consider a polynomial ring whose variables are the sections used in the desired factorization of the Weierstrass sections f and g. In theory, one can consider the indeterminates of this polynomial ring as local coordinate of an auxiliary base space. Indeed, for our computer implementation the polynomial ring with these indeterminates serve as the coordinate ring of an auxiliary toric base space. Despite this auxiliary base space being toric, the predictions from such an analysis are not limited to the world of toric varieties.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"For constructions along these lines, we support the following constructor:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"weierstrass_model(auxiliary_base_ring::MPolyRing, auxiliary_base_grading::Matrix{Int64}, d::Int, weierstrass_f::MPolyRingElem, weierstrass_g::MPolyRingElem)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model-Tuple{MPolyRing, Matrix{Int64}, Int64, MPolyRingElem, MPolyRingElem}","page":"Weierstrass models","title":"weierstrass_model","text":"weierstrass_model(auxiliary_base_ring::MPolyRing, auxiliary_base_grading::Matrix{Int64}, d::Int, weierstrass_f::MPolyRingElem, weierstrass_g::MPolyRingElem)\n\nThis method constructs a Weierstrass model over a base space that is not fully specified.\n\nNote that many studies in the literature use the class of the anticanonical bundle in their analysis. We anticipate this by adding this class as a variable of the auxiliary base space, unless the user already provides this grading. Our convention is that the first grading refers to Kbar and that the homogeneous variable corresponding to this class carries the name \"Kbar\".\n\nThe following example illustrates this approach.\n\nExamples\n\njulia> auxiliary_base_ring, (f, g, Kbar, v) = QQ[\"f\", \"g\", \"Kbar\", \"u\"]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])\n\njulia> auxiliary_base_grading = [4 6 1 0]\n1×4 Matrix{Int64}:\n 4 6 1 0\n\njulia> w = weierstrass_model(auxiliary_base_ring, auxiliary_base_grading, 3, f, g)\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#Standard-constructions","page":"Weierstrass models","title":"Standard constructions","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"We provide convenient constructions of Weierstrass models over famous base spaces. Currently, we support the following:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"weierstrass_model_over_projective_space(d::Int)\nweierstrass_model_over_hirzebruch_surface(r::Int)\nweierstrass_model_over_del_pezzo_surface(b::Int)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model_over_projective_space-Tuple{Int64}","page":"Weierstrass models","title":"weierstrass_model_over_projective_space","text":"weierstrass_model_over_projective_space(d::Int)\n\nThis method constructs a Weierstrass model over the projective space.\n\nExamples\n\njulia> weierstrass_model_over_projective_space(3)\nWeierstrass model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model_over_hirzebruch_surface-Tuple{Int64}","page":"Weierstrass models","title":"weierstrass_model_over_hirzebruch_surface","text":"weierstrass_model_over_hirzebruch_surface(r::Int)\n\nThis method constructs a Weierstrass model over a Hirzebruch surface.\n\nExamples\n\njulia> weierstrass_model_over_hirzebruch_surface(1)\nWeierstrass model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model_over_del_pezzo_surface-Tuple{Int64}","page":"Weierstrass models","title":"weierstrass_model_over_del_pezzo_surface","text":"weierstrass_model_over_del_pezzo_surface(b::Int)\n\nThis method constructs a Weierstrass model over a del-Pezzo surface.\n\nExamples\n\njulia> weierstrass_model_over_del_pezzo_surface(3)\nWeierstrass model over a concrete base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#Literature-models","page":"Weierstrass models","title":"Literature models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"Certain Weierstrass models have been studied in the physics literature over and over again. Thereby, these constructions became famous and some were given special names. We aim to provide support for such standard constructions. Currently, we provide support for the following:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"su5_weierstrass_model_over_arbitrary_3d_base()","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#su5_weierstrass_model_over_arbitrary_3d_base-Tuple{}","page":"Weierstrass models","title":"su5_weierstrass_model_over_arbitrary_3d_base","text":"su5_weierstrass_model_over_arbitrary_3d_base()\n\nReturn the SU(5) Weierstrass model over an arbitrary 3-dimensional base space. For more details see e.g. Timo Weigand (2018) and references therein.\n\njulia> tm = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#Attributes","page":"Weierstrass models","title":"Attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/#Basic-attributes","page":"Weierstrass models","title":"Basic attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"For all Weierstrass models – irrespective over whether the base is toric or not – we support the following attributes:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"weierstrass_section_f(w::WeierstrassModel)\nweierstrass_section_g(w::WeierstrassModel)\nweierstrass_polynomial(w::WeierstrassModel)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_section_f-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"weierstrass_section_f","text":"weierstrass_section_f(w::WeierstrassModel)\n\nReturn the polynomial f used for the construction of the Weierstrass model.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> weierstrass_section_f(w);\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_section_g-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"weierstrass_section_g","text":"weierstrass_section_g(w::WeierstrassModel)\n\nReturn the polynomial g used for the construction of the Weierstrass model.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> weierstrass_section_g(w);\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_polynomial-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"weierstrass_polynomial","text":"weierstrass_polynomial(w::WeierstrassModel)\n\nReturn the Weierstrass polynomial of the Weierstrass model.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> weierstrass_polynomial(w);\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"In case the Weierstrass model is constructed over a not fully specified base, recall that we construct an auxiliary (toric) base space as well as an auxiliary (toric) ambient space. The (auxiliary) base and ambient space can be accessed with the following functions:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"base_space(w::WeierstrassModel)\nambient_space(w::WeierstrassModel)\nfiber_ambient_space(w::WeierstrassModel)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#base_space-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"base_space","text":"base_space(w::WeierstrassModel)\n\nReturn the base space of the Weierstrass model.\n\n```jldoctest julia> w = su5weierstrassmodeloverarbitrary3dbase() Weierstrass model over a not fully specified base\n\njulia> base_space(w) Scheme of a toric variety with fan spanned by RayVector{QQFieldElem}[[1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#ambient_space-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"ambient_space","text":"ambient_space(w::WeierstrassModel)\n\nReturn the base space of the Weierstrass model.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> ambient_space(w)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#fiber_ambient_space-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"fiber_ambient_space","text":"fiber_ambient_space(w::WeierstrassModel)\n\nReturn the fiber ambient space of the Weierstrass model.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> fiber_ambient_space(w)\nScheme of a toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"The following method allows to tell if the base/ambient space is auxiliary or not:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"base_fully_specified(w::WeierstrassModel)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#base_fully_specified-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"base_fully_specified","text":"base_fully_specified(w::WeierstrassModel)\n\nReturn true is the Weierstrass model has a concrete base space and false otherwise.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> base_fully_specified(w)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"The user can decide to get an information whenever an auxiliary base space, auxiliary ambient space or auxiliary hypersurface have been computed. To this end, one invokes set_verbosity_level(:WeierstrassModel, 1). More background information is available here.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#Advanced-attributes","page":"Weierstrass models","title":"Advanced attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"The following attributes are currently only supported in a toric setting:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"calabi_yau_hypersurface(w::WeierstrassModel)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#calabi_yau_hypersurface-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"calabi_yau_hypersurface","text":"calabi_yau_hypersurface(w::WeierstrassModel)\n\nReturn the Calabi-Yau hypersurface in the toric ambient space which defines the Weierstrass model.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> calabi_yau_hypersurface(w)\nClosed subvariety of a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"Note that for applications in F-theory, singular elliptic fibrations are key (cf. Timo Weigand (2018) and references therein). Consequently the discriminant locus as well as the singular loci of the fibration in question are of ample importance:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"discriminant(w::WeierstrassModel)\nsingular_loci(w::WeierstrassModel)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#discriminant-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"discriminant","text":"discriminant(w::WeierstrassModel)\n\nReturn the discriminant Delta = 4 f^3 + 27 g^2.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> discriminant(w);\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#singular_loci-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"singular_loci","text":"singular_loci(w::WeierstrassModel)\n\nReturn the singular loci of the Weierstrass model, along with the order of vanishing of (f g Delta) at each locus and the refined Tate fiber type.\n\nFor the time being, we either explicitly or implicitly focus on toric varieties as base spaces. Explicitly, in case the user provides such a variety as base space, and implicitly, in case we work over a non-fully specified base. This has the advantage that we can \"filter out\" trivial singular loci.\n\nSpecifically, recall that every closed subvariety of a simplicial toric variety is of the form V(I), where I is a homogeneous ideal of the Cox ring. Let B be the irrelevant ideal of this toric variety. Then, by proposition 5.2.6. of David A. Cox, John B. Little, Henry K. Schenck (2011), V(I) is trivial/empty iff B^l subseteq I for a suitable l geq 0. This can be checked by checking if the saturation IB^infty is the ideal generated by 1.\n\nBy treating a not-fully specified base space implicitly as toric space, we can extend this result straightforwardly to this situation also. This is the reason for constructing this auxiliary base space.\n\njulia> w = su5_weierstrass_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base\n\njulia> length(singular_loci(w))\n2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#Methods","page":"Weierstrass models","title":"Methods","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/#Towards-resolution-of-singularities","page":"Weierstrass models","title":"Towards resolution of singularities","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"To come.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/module/#Finitely-presented-modules","page":"Finitely presented modules","title":"Finitely presented modules","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"AbstractAlgebra allows the construction of finitely presented modules (i.e. with finitely many generators and relations), starting from free modules.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"The generic code provided by AbstractAlgebra will only work for modules over euclidean domains.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Free modules can be built over both commutative and noncommutative rings. Other types of module are restricted to fields and euclidean rings.","category":"page"},{"location":"AbstractAlgebra/module/#Abstract-types","page":"Finitely presented modules","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"AbstractAlgebra provides two abstract types for finitely presented modules and their elements:","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"FPModule{T} is the abstract type for finitely presented module parent","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"types","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"FPModuleElem{T} is the abstract type for finitely presented module","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"element types","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Note that the abstract types are parameterised. The type T should usually be the type of elements of the ring the module is over.","category":"page"},{"location":"AbstractAlgebra/module/#Module-functions","page":"Finitely presented modules","title":"Module functions","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"All finitely presented modules over a Euclidean domain implement the following functions.","category":"page"},{"location":"AbstractAlgebra/module/#Basic-functions","page":"Finitely presented modules","title":"Basic functions","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"zero(M::FPModule)","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"iszero(m::FPModuleElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Return true if the given module element is zero.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"ngens(M::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Return the number of generators of the module M in its current representation.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"gen(M::FPModule{T}, i::Int) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Return the i-th generator (indexed from 1) of the module M.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"gens(M::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Return a Julia array of the generators of the module M.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"rels(M::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Return a Julia vector of all the relations between the generators of M. Each relation is given as an AbstractAlgebra row matrix.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"julia> M = FreeModule(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> n = ngens(M)\n2\n\njulia> G = gens(M)\n2-element Vector{AbstractAlgebra.Generic.FreeModuleElem{Rational{BigInt}}}:\n (1//1, 0//1)\n (0//1, 1//1)\n\njulia> R = rels(M)\nAbstractAlgebra.Generic.MatSpaceElem{Rational{BigInt}}[]\n\njulia> g1 = gen(M, 1)\n(1//1, 0//1)\n\njulia> !iszero(g1)\ntrue\n\njulia> M = FreeModule(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> z = zero(M)\n(0//1, 0//1)\n\njulia> iszero(z)\ntrue","category":"page"},{"location":"AbstractAlgebra/module/#Element-constructors","page":"Finitely presented modules","title":"Element constructors","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"We can construct elements of a module M by specifying linear combinations of the generators of M. This is done by passing a vector of ring elements.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"(M::FPModule{T})(v::Vector{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Construct the element of the module M corresponding to sum_i givi where gi are the generators of the module M. The resulting element will lie in the module M.","category":"page"},{"location":"AbstractAlgebra/module/#Coercions","page":"Finitely presented modules","title":"Coercions","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Given a module M and an element n of a module N, it is possible to coerce n into M using the notation M(n) in certain circumstances.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"In particular the element n will be automatically coerced along any canonical injection of a submodule map and along any canonical projection of a quotient map. There must be a path from N to M along such maps.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"F = FreeModule(ZZ, 3)\n\nS1, f = sub(F, [rand(F, -10:10)])\n\nS, g = sub(F, [rand(F, -10:10)])\nQ, h = quo(F, S)\n\nm = rand(S1, -10:10)\nn = Q(m)","category":"page"},{"location":"AbstractAlgebra/module/#Arithmetic-operators","page":"Finitely presented modules","title":"Arithmetic operators","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Elements of a module can be added, subtracted or multiplied by an element of the ring the module is defined over and compared for equality.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"In the case of a noncommutative ring, both left and right scalar multiplication are defined.","category":"page"},{"location":"AbstractAlgebra/module/#Basic-manipulation","page":"Finitely presented modules","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"zero(M::FPModule)","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"julia> M = FreeModule(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> z = zero(M)\n(0//1, 0//1)","category":"page"},{"location":"AbstractAlgebra/module/#Element-indexing","page":"Finitely presented modules","title":"Element indexing","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Base.getindex(m::FPModuleElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/#getindex-Union{Tuple{AbstractAlgebra.FPModuleElem{T}}, Tuple{T}} where T<:RingElement","page":"Finitely presented modules","title":"getindex","text":"getindex(A::SMat, i::Int, j::Int)\n\nGiven a sparse matrix A = (a_ij)_i j, return the entry a_ij.\n\n\n\n\n\ngetindex(A::SMat, i::Int) -> SRow\n\nGiven a sparse matrix A and an index i, return the i-th row of A.\n\n\n\n\n\ngetindex(a::Fac, b) -> Int\n\nIf b is a factor of a, the corresponding exponent is returned. Otherwise an error is thrown.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"julia> F = FreeModule(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> m = F(BigInt[2, -5, 4])\n(2, -5, 4)\n\njulia> m[1]\n2","category":"page"},{"location":"AbstractAlgebra/module/#Module-comparison","page":"Finitely presented modules","title":"Module comparison","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"==(::FPModule{T}, ::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/#==-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}}} where T<:RingElement","page":"Finitely presented modules","title":"==","text":"==(M::FPModule{T}, N::FPModule{T}) where T <: RingElement\n\nReturn true if the modules are (constructed to be) the same module elementwise. This is not object equality and it is not isomorphism. In fact, each method of constructing modules (submodules, quotient modules, products, etc.) must extend this notion of equality to the modules they create.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"julia> M = FreeModule(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> M == M\ntrue\n","category":"page"},{"location":"AbstractAlgebra/module/#Isomorphism","page":"Finitely presented modules","title":"Isomorphism","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"is_isomorphic(::FPModule{T}, ::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/#is_isomorphic-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}}} where T<:RingElement","page":"Finitely presented modules","title":"is_isomorphic","text":"is_isomorphic(M::FPModule{T}, N::FPModule{T}) where T <: RingElement\n\nReturn true if the modules M and N are isomorphic.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"note: Note\nNote that this function relies on the Smith normal form over the base ring of the modules being able to be made unique. This is true for Euclidean domains for which divrem has a fixed choice of quotient and remainder, but it will not in general be true for Euclidean rings that are not domains.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"julia> M = FreeModule(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> m1 = rand(M, -10:10)\n(3, -1, 0)\n\njulia> m2 = rand(M, -10:10)\n(4, 4, -7)\n\njulia> S, f = sub(M, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 3 over integers)\n\njulia> I, g = image(f)\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 3 over integers)\n\njulia> is_isomorphic(S, I)\ntrue\n","category":"page"},{"location":"AbstractAlgebra/module/#Invariant-Factor-Decomposition","page":"Finitely presented modules","title":"Invariant Factor Decomposition","text":"","category":"section"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"For modules over a euclidean domain one can take the invariant factor decomposition to determine the structure of the module. The invariant factors are unique up to multiplication by a unit, and even unique if a canonical_unit is available for the ring that canonicalises elements.","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"snf(::FPModule{T}) where T <: RingElement\ninvariant_factors(::FPModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module/#snf-Union{Tuple{AbstractAlgebra.FPModule{T}}, Tuple{T}} where T<:RingElement","page":"Finitely presented modules","title":"snf","text":"snf(m::FPModule{T}) where T <: RingElement\n\nReturn a pair M, f consisting of the invariant factor decomposition M of the module m and a module homomorphism (isomorphisms) f M to m. The module M is itself a module which can be manipulated as any other module in the system.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module/#invariant_factors-Union{Tuple{AbstractAlgebra.FPModule{T}}, Tuple{T}} where T<:RingElement","page":"Finitely presented modules","title":"invariant_factors","text":"invariant_factors(m::FPModule{T}) where T <: RingElement\n\nReturn a vector of the invariant factors of the module M.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module/","page":"Finitely presented modules","title":"Finitely presented modules","text":"julia> M = FreeModule(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> m1 = rand(M, -10:10)\n(3, -1, 0)\n\njulia> m2 = rand(M, -10:10)\n(4, 4, -7)\n\njulia> S, f = sub(M, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 3 over integers)\n\njulia> Q, g = quo(M, S)\n(Quotient module over Integers with 2 generators and relations:\n[16 -21], Hom: Free module of rank 3 over integers -> Quotient module over Integers with 2 generators and relations:\n[16 -21])\n\njulia> I, f = snf(Q)\n(Invariant factor decomposed module over Integers with invariant factors BigInt[0], Module isomorphism with\nDomain: Invariant factor decomposed module over Integers with invariant factors BigInt[0]\nCodomain: Quotient module over Integers with 2 generators and relations:\n[16 -21])\n\njulia> invs = invariant_factors(Q)\n1-element Vector{BigInt}:\n 0\n","category":"page"},{"location":"Groups/pcgroup/","page":"Polycyclic groups","title":"Polycyclic groups","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/pcgroup/#Polycyclic-groups","page":"Polycyclic groups","title":"Polycyclic groups","text":"","category":"section"},{"location":"Groups/pcgroup/","page":"Polycyclic groups","title":"Polycyclic groups","text":"PcGroup\nPcGroupElem","category":"page"},{"location":"Groups/pcgroup/#PcGroup","page":"Polycyclic groups","title":"PcGroup","text":"PcGroup\n\nPolycyclic group, a group that is defined by a finite presentation of a special kind, a so-called polycyclic presentation. Contrary to arbitrary finitely presented groups (see Finitely presented groups), this presentation allows for efficient computations with the group elements.\n\nExamples\n\ncyclic_group(n::Int): cyclic group of order n\nabelian_group(PcGroup, v::Vector{Int}): direct product of cyclic groups of the orders v[1], v[2], ..., v[length(v)]\n\n\n\n\n\n","category":"type"},{"location":"Groups/pcgroup/#PcGroupElem","page":"Polycyclic groups","title":"PcGroupElem","text":"PcGroupElem\n\nElement of a polycyclic group.\n\nThe generators of a polycyclic group are displayed as f1, f2, f3, etc., and every element of a polycyclic group is displayed as product of the generators.\n\nExamples\n\njulia> G = abelian_group(PcGroup, [2, 4]);\n\njulia> G[1], G[2]\n(f1, f2)\n\njulia> G[2]*G[1]\nf1*f2\n\nNote that this does not define Julia variables named f1, f2, etc.! To get the generators of the group G, use gens(G); for convenience they can also be accessed as G[1], G[2], as shown in Section Elements of groups.\n\n\n\n\n\n","category":"type"},{"location":"Groups/pcgroup/","page":"Polycyclic groups","title":"Polycyclic groups","text":"Julia has the following functions that allow to generate polycyclic groups:","category":"page"},{"location":"Groups/pcgroup/","page":"Polycyclic groups","title":"Polycyclic groups","text":"abelian_group(::Type{T}, v::Vector{Int}) where T <: GAPGroup\ncyclic_group\ndihedral_group\nquaternion_group","category":"page"},{"location":"Groups/pcgroup/#abelian_group-Union{Tuple{T}, Tuple{Type{T}, Vector{Int64}}} where T<:Oscar.GAPGroup","page":"Polycyclic groups","title":"abelian_group","text":"abelian_group(::Type{T}, v::Vector{Int}) where T <: Group -> PcGroup\n\nReturn the direct product of cyclic groups of the orders v[1], v[2], ldots, v[n], as an instance of T. Here, T must be one of PermGroup, FPGroup, or PcGroup.\n\nwarning: Warning\nThe type need to be specified in the input of the function abelian_group, otherwise a group of type GrpAbFinGen is returned, which is not a GAP group type. In future versions of Oscar, this may change.\n\n\n\n\n\n","category":"method"},{"location":"Groups/pcgroup/#cyclic_group","page":"Polycyclic groups","title":"cyclic_group","text":"cyclic_group(::Type{T} = PcGroup, n::IntegerUnion)\ncyclic_group(::Type{T} = PcGroup, n::PosInf)\n\nReturn the cyclic group of order n, as an instance of type T.\n\nExamples\n\njulia> G = cyclic_group(5)\n\n\njulia> G = cyclic_group(PermGroup, 5)\nGroup([ (1,2,3,4,5) ])\n\njulia> G = cyclic_group(PosInf())\nPcp-group with orders [ 0 ]\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/pcgroup/#dihedral_group","page":"Polycyclic groups","title":"dihedral_group","text":"dihedral_group(::Type{T} = PcGroup, n::Union{IntegerUnion,PosInf})\n\nReturn the dihedral group of order n, as an instance of T, where T is in {PcGroup,PermGroup,FPGroup}.\n\nwarning: Warning\nThere are two competing conventions for interpreting the argument n: In the one we use, the returned group has order n, and thus n must always be even. In the other, n indicates that the group describes the symmetry of an n-gon, and thus the group has order 2n.\n\nExamples\n\njulia> dihedral_group(6)\n\n\njulia> dihedral_group(PermGroup, 6)\nGroup([ (1,2,3), (2,3) ])\n\njulia> dihedral_group(PosInf())\nPcp-group with orders [ 2, 0 ]\n\njulia> dihedral_group(7)\nERROR: ArgumentError: n must be a positive even integer or infinity\n\n\n\n\n\n","category":"function"},{"location":"Groups/pcgroup/#quaternion_group","page":"Polycyclic groups","title":"quaternion_group","text":"quaternion_group(::Type{T} = PcGroup, n::IntegerUnion)\n\nReturn the (generalized) quaternion group of order n, as an instance of T, where n is a power of 2 and T is in {PcGroup,PermGroup,FPGroup}.\n\nExamples\n\njulia> g = quaternion_group(8)\n\n\njulia> quaternion_group(PermGroup, 8)\nGroup([ (1,5,3,7)(2,8,4,6), (1,2,3,4)(5,6,7,8) ])\n\njulia> g = quaternion_group(FPGroup, 8)\n\n\njulia> relators(g)\n3-element Vector{FPGroupElem}:\n r^2*s^-2\n s^4\n r^-1*s*r*s\n\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"CurrentModule = Oscar","category":"page"},{"location":"Combinatorics/graphs/#Graphs","page":"Graphs","title":"Graphs","text":"","category":"section"},{"location":"Combinatorics/graphs/#Introduction","page":"Graphs","title":"Introduction","text":"","category":"section"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"Graphs are a fundamental object within all of mathematics and computer science. A graph consists of two sets of data:","category":"page"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"a finite set V = 1ldotsn of vertices; and\na finite set E subseteq Vtimes V of edges.","category":"page"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"There are two types of graphs, directed and undirected. For a directed graph the elements of E are considered to be ordered pairs, for an undirected graph the elements of E are unordered pairs or rather sets with two elements.","category":"page"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"The interface is modeled alongside the Graphs.jl interface to allow for easier integration elsewhere.","category":"page"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"warning: Warning\nThe mechanism for removing a vertex is slightly different in out implementation to the Graphs.jl implementation: In Graphs.jl first the vertex to be removed is swapped with the last vertex, then the last vertex is removed. In our implementation, the vertex is removed and all subsequent vertices have their labels changed. Hence edges can be different in the two implementations after removing a vertex.","category":"page"},{"location":"Combinatorics/graphs/#Construction","page":"Graphs","title":"Construction","text":"","category":"section"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"Graph{T}(nverts::Int64) where {T <: Union{Directed, Undirected}}\ndualgraph(p::Polyhedron)\nedgegraph(p::Polyhedron)\ngraph_from_adjacency_matrix","category":"page"},{"location":"Combinatorics/graphs/#Graph-Union{Tuple{Int64}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"Graph","text":"Graph{T}(nverts::Int64) where {T <: Union{Directed, Undirected}}\n\nConstruct a graph on nverts vertices and no edges. T indicates whether the graph should be Directed or Undirected.\n\nExamples\n\nMake a directed graph with 5 vertices and print the number of nodes and edges.\n\njulia> g = Graph{Directed}(5);\n\njulia> nv(g)\n5\n\njulia> ne(g)\n0\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#dualgraph-Tuple{Polyhedron}","page":"Graphs","title":"dualgraph","text":"dualgraph(p::Polyhedron)\n\nReturn the dual graph of a Polyhedron, vertices of the graph correspond to facets of the polyhedron and there is an edge between two vertices if the corresponding facets are neighboring, meaning their intersection is a codimension 2 face of the polyhedron.\n\nFor bounded polyhedra containing 0 in the interior this is the same as the edge graph the polar dual polyhedron.\n\nExamples\n\nConstruct the dual graph of the cube. This is the same as the edge graph of the octahedron, so it has 6 vertices and 12 edges.\n\njulia> c = cube(3);\n\njulia> g = dualgraph(c);\n\njulia> nv(g)\n6\n\njulia> ne(g)\n12\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#edgegraph-Tuple{Polyhedron}","page":"Graphs","title":"edgegraph","text":"edgegraph(p::Polyhedron)\n\nReturn the edge graph of a Polyhedron, vertices of the graph correspond to vertices of the polyhedron, there is an edge between two vertices if the polyhedron has an edge between the corresponding vertices. The resulting graph is Undirected.\n\nExamples\n\nConstruct the edge graph of the cube. Like the cube it has 8 vertices and 12 edges.\n\njulia> c = cube(3);\n\njulia> g = edgegraph(c);\n\njulia> nv(g)\n8\n\njulia> ne(g)\n12\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#graph_from_adjacency_matrix","page":"Graphs","title":"graph_from_adjacency_matrix","text":"graph_from_adjacency_matrix(::Type{T}, G) where {T <:Union{Directed, Undirected}}\n\nReturn the graph with adjacency matrix G.\n\nThis means that the nodes i j are connected by an edge if and only if G_ij is one. In the undirected case, it is assumed that i j i.e. the upper triangular part of G is ignored.\n\nExamples\n\njulia> G = ZZ[0 0; 1 0]\n[0 0]\n[1 0]\n\njulia> graph_from_adjacency_matrix(Directed, G)\nGraph{Directed}(pm::graph::Graph\n{}\n{0}\n)\n\njulia> graph_from_adjacency_matrix(Undirected, G)\nGraph{Undirected}(pm::graph::Graph\n{1}\n{0}\n)\n\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/graphs/#Modifying-graphs","page":"Graphs","title":"Modifying graphs","text":"","category":"section"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"add_edge!(g::Graph{T}, source::Int64, target::Int64) where {T <: Union{Directed, Undirected}}\nadd_vertices!(g::Graph{T}, n::Int64) where {T <: Union{Directed, Undirected}}\nadd_vertex!(g::Graph{T}) where {T <: Union{Directed, Undirected}}\nrem_edge!(g::Graph{T}, s::Int64, t::Int64) where {T <: Union{Directed, Undirected}}\nrem_vertex!(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}","category":"page"},{"location":"Combinatorics/graphs/#add_edge!-Union{Tuple{T}, Tuple{Graph{T}, Int64, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"add_edge!","text":"add_edge!(g::Graph{T}, s::Int64, t::Int64) where {T <: Union{Directed, Undirected}}\n\nAdd edge (s,t) to the graph g.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> add_edge!(g, 1, 2);\n\njulia> ne(g)\n1\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#add_vertices!-Union{Tuple{T}, Tuple{Graph{T}, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"add_vertices!","text":"add_vertices!(g::Graph{T}, n::Int64) where {T <: Union{Directed, Undirected}}\n\nAdd a n new vertices to the graph g.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> nv(g)\n2\n\njulia> add_vertices!(g, 5);\n\njulia> nv(g)\n7\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#add_vertex!-Union{Tuple{Graph{T}}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"add_vertex!","text":"add_vertex!(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nAdd a vertex to the graph g. The return value is the new vertex.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> nv(g)\n2\n\njulia> add_vertex!(g)\n3\n\njulia> nv(g)\n3\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#rem_edge!-Union{Tuple{T}, Tuple{Graph{T}, Int64, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"rem_edge!","text":"rem_edge!(g::Graph{T}, s::Int64, t::Int64) where {T <: Union{Directed, Undirected}}\n\nRemove edge (s,t) from the graph g.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> add_edge!(g, 1, 2);\n\njulia> ne(g)\n1\n\njulia> rem_edge!(g, 1, 2);\n\njulia> ne(g)\n0\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#rem_vertex!-Union{Tuple{T}, Tuple{Graph{T}, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"rem_vertex!","text":"rem_vertex!(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\n\nRemove the vertex v from the graph g.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> nv(g)\n2\n\njulia> rem_vertex!(g, 1)\n\njulia> nv(g)\n1\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#Auxiliary-functions","page":"Graphs","title":"Auxiliary functions","text":"","category":"section"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"all_neighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\nautomorphism_group_generators(g::Graph{T}) where {T <: Union{Directed, Undirected}}\ncomplete_graph(n::Int64)\ncomplete_bipartite_graph(n::Int64, m::Int64)\nedges(g::Graph{T}) where {T <: Union{Directed, Undirected}}\nhas_edge(g::Graph{T}, source::Int64, target::Int64) where {T <: Union{Directed, Undirected}}\nhas_vertex(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\ninneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\nne(g::Graph{T}) where {T <: Union{Directed, Undirected}}\nneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\nnv(g::Graph{T}) where {T <: Union{Directed, Undirected}}\noutneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\nshortest_path_dijkstra\nis_isomorphic(g1::Graph{T}, g2::Graph{T}) where {T <: Union{Directed, Undirected}}\nis_isomorphic_with_permutation(G1::Graph, G2::Graph)","category":"page"},{"location":"Combinatorics/graphs/#all_neighbors-Union{Tuple{T}, Tuple{Graph{T}, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"all_neighbors","text":"all_neighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\n\nReturn all vertices of a graph g that are connected to the vertex v via an edge, independent of the edge direction.\n\nExamples\n\njulia> g = Graph{Directed}(5);\n\njulia> add_edge!(g, 1, 3);\n\njulia> add_edge!(g, 3, 4);\n\njulia> all_neighbors(g, 3)\n2-element Vector{Int64}:\n 1\n 4\n\njulia> all_neighbors(g, 4)\n1-element Vector{Int64}:\n 3\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#automorphism_group_generators-Union{Tuple{Graph{T}}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"automorphism_group_generators","text":"automorphism_group_generators(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nReturn generators of the automorphism group of the graph g.\n\nExamples\n\njulia> g = complete_graph(4);\n\njulia> automorphism_group_generators(g)\n3-element Vector{PermGroupElem}:\n (3,4)\n (2,3)\n (1,2)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#complete_graph-Tuple{Int64}","page":"Graphs","title":"complete_graph","text":"complete_graph(n::Int64)\n\nAssemble the undirected complete graph on n nodes.\n\nExamples\n\njulia> g = complete_graph(3);\n\njulia> collect(edges(g))\n3-element Vector{Edge}:\n Edge(2, 1)\n Edge(3, 1)\n Edge(3, 2)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#complete_bipartite_graph-Tuple{Int64, Int64}","page":"Graphs","title":"complete_bipartite_graph","text":"complete_bipartite_graph(n::Int64, m::Int64)\n\nAssemble the undirected complete bipartite graph between n and m nodes.\n\nExamples\n\njulia> g = complete_bipartite_graph(2,2);\n\njulia> collect(edges(g))\n4-element Vector{Edge}:\n Edge(3, 1)\n Edge(3, 2)\n Edge(4, 1)\n Edge(4, 2)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#edges-Union{Tuple{Graph{T}}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"edges","text":"edges(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nReturn an iterator over the edges of the graph g.\n\nExamples\n\nA triangle has three edges.\n\njulia> triangle = simplex(2);\n\njulia> g = edgegraph(triangle);\n\njulia> collect(edges(g))\n3-element Vector{Edge}:\n Edge(2, 1)\n Edge(3, 1)\n Edge(3, 2)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#has_edge-Union{Tuple{T}, Tuple{Graph{T}, Int64, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"has_edge","text":"has_edge(g::Graph{T}, source::Int64, target::Int64) where {T <: Union{Directed, Undirected}}\n\nCheck for an edge in a graph.\n\nExamples\n\nCheck for the edge 1to 2 in the edge graph of a triangle.\n\njulia> triangle = simplex(2);\n\njulia> g = edgegraph(triangle);\n\njulia> has_edge(g, 1, 2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#has_vertex-Union{Tuple{T}, Tuple{Graph{T}, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"has_vertex","text":"has_vertex(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\n\nCheck for a vertex in a graph.\n\nExamples\n\nThe edge graph of a triangle only has 3 vertices.\n\njulia> triangle = simplex(2);\n\njulia> g = edgegraph(triangle);\n\njulia> has_vertex(g, 1)\ntrue\n\njulia> has_vertex(g, 4)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#inneighbors-Union{Tuple{T}, Tuple{Graph{T}, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"inneighbors","text":"inneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\n\nReturn the vertices of a graph g that have an edge going towards v. For an undirected graph, all neighboring vertices are returned.\n\nExamples\n\njulia> g = Graph{Directed}(5);\n\njulia> add_edge!(g, 1, 3);\n\njulia> add_edge!(g, 3, 4);\n\njulia> inneighbors(g, 3)\n1-element Vector{Int64}:\n 1\n\njulia> inneighbors(g, 1)\nInt64[]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#ne-Union{Tuple{Graph{T}}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"ne","text":"ne(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nReturn the number of edges of a graph.\n\nExamples\n\nThe edge graph of the cube has 12 edges just like the cube itself.\n\njulia> c = cube(3);\n\njulia> g = edgegraph(c);\n\njulia> ne(g)\n12\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#neighbors-Union{Tuple{T}, Tuple{Graph{T}, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"neighbors","text":"neighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\n\nReturn the neighboring vertices of a vertex v in a graph g. If the graph is directed, the neighbors reachable via outgoing edges are returned.\n\nExamples\n\njulia> g = Graph{Directed}(5);\n\njulia> add_edge!(g, 1, 3);\n\njulia> add_edge!(g, 3, 4);\n\njulia> neighbors(g, 3)\n1-element Vector{Int64}:\n 4\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#nv-Union{Tuple{Graph{T}}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"nv","text":"nv(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nReturn the number of vertices of a graph.\n\nExamples\n\nThe edge graph of the cube has eight vertices, just like the cube itself.\n\njulia> c = cube(3);\n\njulia> g = edgegraph(c);\n\njulia> nv(g)\n8\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#outneighbors-Union{Tuple{T}, Tuple{Graph{T}, Int64}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"outneighbors","text":"outneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\n\nReturn the vertices of a graph g that are target of an edge coming from v. For an undirected graph, all neighboring vertices are returned.\n\nExamples\n\njulia> g = Graph{Directed}(5);\n\njulia> add_edge!(g, 1, 3);\n\njulia> add_edge!(g, 3, 4);\n\njulia> outneighbors(g, 3)\n1-element Vector{Int64}:\n 4\n\njulia> outneighbors(g, 4)\nInt64[]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#shortest_path_dijkstra","page":"Graphs","title":"shortest_path_dijkstra","text":"shortest_path_dijkstra(g::Graph{T}, s::Int64, t::Int64; reverse::Bool=false) where {T <: Union{Directed, Undirected}}\n\nCompute the shortest path between two vertices in a graph using Dijkstra's algorithm. All edges are set to have a length of 1. The optional parameter indicates whether the edges should be considered reversed.\n\nExamples\n\njulia> g = Graph{Directed}(3);\n\njulia> add_edge!(g, 1, 2);\n\njulia> add_edge!(g, 2, 3);\n\njulia> add_edge!(g, 3, 1);\n\njulia> shortest_path_dijkstra(g, 3, 1)\n2-element Vector{Int64}:\n 3\n 1\n\njulia> shortest_path_dijkstra(g, 1, 3)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> shortest_path_dijkstra(g, 3, 1; reverse=true)\n3-element Vector{Int64}:\n 3\n 2\n 1\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/graphs/#is_isomorphic-Union{Tuple{T}, Tuple{Graph{T}, Graph{T}}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"is_isomorphic","text":"is_isomorphic(g1::Graph{T}, g2::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nChecks if the graph g1 is isomorphic to the graph g2.\n\nExamples\n\njulia> is_isomorphic(edgegraph(simplex(3)), dualgraph(simplex(3)))\ntrue\n\njulia> is_isomorphic(edgegraph(cube(3)), dualgraph(cube(3)))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#is_isomorphic_with_permutation-Tuple{Graph, Graph}","page":"Graphs","title":"is_isomorphic_with_permutation","text":"is_isomorphic_with_permutation(G1::Graph, G2::Graph) -> Bool, Vector{Int}\n\nReturn whether G1 is isomorphic to G2 as well as a permutation of the nodes of G1 such that both graphs agree.\n\nExamples\n\njulia> is_isomorphic_with_permutation(edgegraph(simplex(3)), dualgraph(simplex(3)))\n(true, [1, 2, 3, 4])\n\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#Edges","page":"Graphs","title":"Edges","text":"","category":"section"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"dst(e::Edge)\nreverse(e::Edge)\nsrc(e::Edge)","category":"page"},{"location":"Combinatorics/graphs/#dst-Tuple{Edge}","page":"Graphs","title":"dst","text":"dst(e::Edge)\n\nReturn the destination of an edge.\n\nExamples\n\njulia> g = complete_graph(2);\n\njulia> E = collect(edges(g));\n\njulia> e = E[1]\nEdge(2, 1)\n\njulia> dst(e)\n1\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#reverse-Tuple{Edge}","page":"Graphs","title":"reverse","text":"reverse(e::Edge)\n\nReturn the edge in the opposite direction of the edge e.\n\nExamples\n\njulia> g = complete_graph(2);\n\njulia> E = collect(edges(g));\n\njulia> e = E[1]\nEdge(2, 1)\n\njulia> reverse(e)\nEdge(1, 2)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#src-Tuple{Edge}","page":"Graphs","title":"src","text":"src(e::Edge)\n\nReturn the source of an edge.\n\nExamples\n\njulia> g = complete_graph(2);\n\njulia> E = collect(edges(g));\n\njulia> e = E[1]\nEdge(2, 1)\n\njulia> src(e)\n2\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#Saving-and-loading","page":"Graphs","title":"Saving and loading","text":"","category":"section"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"Objects of type Graph can be saved to a file and loaded with the methods load and save. The file is in JSON format and contains the underlying polymake object. In particular, this file can now be read by both polymake and OSCAR.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/#Map-with-inverse","page":"Map with inverse","title":"Map with inverse","text":"","category":"section"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"It is not possible to provide generic functionality to invert a map. However, sometimes one knows an inverse map explicitly and would like to keep track of this.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Recall that as map composition is not commutative, there is a notion of a left inverse and a right inverse for maps.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"To keep track of such inverse maps, AbstractAlgebra provides data types Generic.MapWithRetraction and Generic.MapWithSection.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Given a map f X to Y, a retraction of f is a map g Y to X such that g(f(x)) = x for all x in X.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Given a map f X to Y, a section of f is a map g Y to X such that f(g(x)) = x for all y in Y.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"In AbstractAlgebra, a map with retraction/section is an object containing a pair of maps, the second of which is a retraction/section of the first.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Maps with retraction/section can be composed, and we also define the inverse of such a pair to be the map with the pair swapped. Thus the inverse of a map with retraction is a map with section.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/#Map-with-inverse-constructors","page":"Map with inverse","title":"Map with inverse constructors","text":"","category":"section"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"To construct a map with retraction/section from a pair of maps, we have the following functions:","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"map_with_retraction(m::Map{D, C}, r::Map{C, D}) where {D, C}\nmap_with_section(m::Map{D, C}, s::Map{C, D}) where {D, C}","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Construct the map with retraction/section given a known retraction/section r or s respectively, of m.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"For convenience we allow construction of maps with retraction/section from a pair of Julia functions/closures.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"map_with_retraction_from_func(f::Function, r::Function, R, S)\nmap_with_section_from_func(f::Function, s::Function, R, S)","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Construct the map with retraction/section such that the map is given by the function f and the retraction/section is given by the function r or s respectively. Here R is the parent object representing the domain and S is the parent object representing the codomain of f.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Examples","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"julia> f = map_with_retraction_from_func(x -> x + 1, x -> x - 1, ZZ, ZZ)\nMap with retraction with the following data\n\nDomain:\n=======\nIntegers\n\nCodomain:\n========\nIntegers\n\njulia> a = f(ZZ(1))\n2","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/#Functionality-for-maps-with-inverses","page":"Map with inverse","title":"Functionality for maps with inverses","text":"","category":"section"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"The following functionality is provided for maps with inverses.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"inv(M::Generic.MapWithRetraction)\ninv(M::Generic.MapWithSection)","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Return the map with the two maps contained in M swapped. In the first case, a MapWithSection is returned. In the second case a MapWithRetraction is returned.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"To access the two maps stored in a map with retraction/section, we have the following:","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"image_map(M::Generic.MapWithRetraction)\nimage_map(M::Generic.MapWithSection)\nretraction_map(M::Generic.MapWithRetraction)\nsection_map(M::Generic.MapWithSection)","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"The first two of these functions return the first map in a map with retraction/section, the second two functions return the corresponding second maps.","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"Examples","category":"page"},{"location":"AbstractAlgebra/map_with_inverse/","page":"Map with inverse","title":"Map with inverse","text":"julia> f = map_with_retraction_from_func(x -> x + 1, x -> x - 1, ZZ, ZZ)\nMap with retraction with the following data\n\nDomain:\n=======\nIntegers\n\nCodomain:\n========\nIntegers\n\njulia> g = inv(f)\nMap with section with the following data\n\nDomain:\n=======\nIntegers\n\nCodomain:\n========\nIntegers\n\njulia> h = f*g\nComposite map consisting of the following\n\nIntegers -> Integers\nthen\nIntegers -> Integers\n\njulia> a = h(ZZ(1))\n1\n","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/","page":"Introduction","title":"Introduction","text":"Our focus in this section is on finitely presented modules over rings from the following list:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/","page":"Introduction","title":"Introduction","text":"multivariate polynomial rings (OSCAR type MPolyRing),\nquotients of multivariate polynomial rings (OSCAR type MPolyQuoRing), and\nlocalizations of the above rings (OSCAR types MPolyLocRing, MPolyQuoLocRing).","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/","page":"Introduction","title":"Introduction","text":"Hence, if not mentioned otherwise, the word module refers to a finitely presented module over a ring of one of the above types. Offering a sparse way of implementing free modules, the OSCAR type FreeMod provides the basis for implementing all modules discussed here. More concretely, the general way of implementing a module is to represent it as a subquotient, that is, as a submodule of a quotient of a free module. Note that subquotients form the smallest class of modules which naturally includes both submodules and quotients of free modules.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nMost functions in this section rely on Gröbner (standard) bases techniques. Thus, the functions should not be applied to modules over rings other than those from the list above. See the Linear Algebra chapter for module types which are designed to handle modules over Euclidean domains.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nFor simplicity of the presentation in what follows, functions are often only illustrated by examples with focus on modules over multivariate polynomial rings, but work similarly for modules over a ring of any of the above types.","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Affine/","page":"Affine","title":"Affine","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Affine/","page":"Affine","title":"Affine","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#Affine","page":"Affine","title":"Affine","text":"","category":"section"},{"location":"AlgebraicGeometry/RationalPoints/Affine/","page":"Affine","title":"Affine","text":"AbsAffineRationalPoint\nAffineRationalPoint\ncoordinates(p::AffineRationalPoint)\nideal(P::AbsAffineRationalPoint)\nscheme(P::AbsAffineRationalPoint)\nclosed_embedding(P::AbsAffineRationalPoint)\nis_smooth(P::AbsAffineRationalPoint)\ntangent_space(P::AbsAffineRationalPoint{<:FieldElem})","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#AbsAffineRationalPoint","page":"Affine","title":"AbsAffineRationalPoint","text":"AbsAffineRationalPoint{CoefficientType, ParentType}\n\nA rational point P of an affine scheme X. We refer to X as the parent of P.\n\nLet X subseteq mathbbA^n_k be an algebraic set or more generally a subscheme defined by the ideal I = (f_1 dots f_r) subseteq kx_1dots x_n. A rational point p of X is a tuple p = (p_1 dots p_n) in k^n such that f_1(p) = dots = f_n(p) = 0.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#AffineRationalPoint","page":"Affine","title":"AffineRationalPoint","text":"AffineRationalPoint{CoeffType<:RingElem, ParentType<:RationalPointSet}\n\nA rational point represented in terms of a vector of coordinates.\n\nExamples\n\njulia> A2 = affine_space(GF(2), [:x, :y]);\n\njulia> (x, y) = coordinates(A2);\n\njulia> X = algebraic_set(x*y);\n\njulia> X([1, 0])\nRational point\n of V(x*y)\nwith coordinates (1, 0)\n\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#coordinates-Tuple{Oscar.AffineRationalPoint}","page":"Affine","title":"coordinates","text":"coordinates(p::AffineRationalPoint{S,T}) -> Vector{S}\n\nReturn the coordinates of the rational point p.\n\nThe coordinates are with respect to the ambient space of its ambient scheme.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#ideal-Tuple{AbsAffineRationalPoint}","page":"Affine","title":"ideal","text":"ideal(P::AbsAffineRationalPoint)\n\nReturn the maximal ideal associated to P in the coordinate ring of its ambient space.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#scheme-Tuple{AbsAffineRationalPoint}","page":"Affine","title":"scheme","text":"scheme(P::AbsAffineRationalPoint) -> AbsSpec\n\nReturn the rational point P viewed as a reduced, affine subscheme of its ambient affine space.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#closed_embedding-Tuple{AbsAffineRationalPoint}","page":"Affine","title":"closed_embedding","text":"closed_embedding(P::AbsAffineRationalPoint) -> ClosedEmbedding\n\nReturn the closed embedding of P into its ambient scheme X.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#is_smooth-Tuple{AbsAffineRationalPoint}","page":"Affine","title":"is_smooth","text":"is_smooth(P::AbsAffineRationalPoint)\n\nReturn whether P is a smooth point of its ambient scheme X.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#tangent_space-Tuple{AbsAffineRationalPoint{<:FieldElem}}","page":"Affine","title":"tangent_space","text":"tangent_space(P::AbsAffineRationalPoint{<:FieldElem}) -> AlgebraicSet\n\nReturn the Zariski tangent space of the ambient scheme of P at its point P.\n\nSee also tangent_space(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Affine/","page":"Affine","title":"Affine","text":"Some experimental methods are available too. Note that their interface is likely to change in the future.","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Affine/","page":"Affine","title":"Affine","text":"is_du_val_singularity(P::AbsAffineRationalPoint{<:FieldElem})\ndecide_du_val_singularity(P::AbsAffineRationalPoint{<:FieldElem,<:Any})","category":"page"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#is_du_val_singularity-Tuple{AbsAffineRationalPoint{<:FieldElem}}","page":"Affine","title":"is_du_val_singularity","text":"is_du_val_singularity(P::AbsAffineRationalPoint{<:Field})\n\nReturn whether the ambient scheme of P has at most a Du Val singularity at P.\n\nNote that this includes the case that P is a smooth point.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/RationalPoints/Affine/#decide_du_val_singularity-Tuple{AbsAffineRationalPoint{<:FieldElem}}","page":"Affine","title":"decide_du_val_singularity","text":"decide_du_val_singularity(P::AbsAffineRationalPoint{<:Field})\n\nReturn whether the ambient scheme of P has a Du Val singularity at P.\n\nExamples\n\njulia> A3 = affine_space(QQ, [:x, :y, :z]);\n\njulia> (x, y, z) = ambient_coordinates(A3);\n\njulia> X = subscheme(A3, ideal([x^2+y^2-z^2]));\n\njulia> Oscar.decide_du_val_singularity(X([0,0,0]))\n(true, (:A, 1))\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/elliptic_curves/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend\n","category":"page"},{"location":"Hecke/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"This chapter deals with functionality for elliptic curves, which is available over arbitrary fields, with specific features available for curvers over the rationals and number fields, and finite fields.","category":"page"},{"location":"Hecke/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"An elliptic curve E is the projective closure of the curve given by the Weierstrass equation","category":"page"},{"location":"Hecke/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"y^2 + a_1 x y + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6","category":"page"},{"location":"Hecke/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"specified by the list of coefficients [a1, a2, a3, a4, a6]. If a_1 = a_2 = a_3 = 0, this simplifies to","category":"page"},{"location":"Hecke/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"y^2 = x^3 + a_4 x + a_6","category":"page"},{"location":"Hecke/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"which we refer to as a short Weierstrass equation and which is specified by the two element list [a4, a6].","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Rings/integer/#Integers","page":"Integers","title":"Integers","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"An important design decision in Oscar.jl is to use Julia as the user language by default. This means that integers typed at the REPL are Julia integers. However, for performance reasons, OSCAR has its own integer format.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Julia has a number of different integer types, but the two that are most relevant here are Int and BigInt. All the Julia integer types belong to Integer.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The Int type is for machine integers which are highly efficient, but can only represent integers up to a certain size, and most basic arithmetic operations are performed unchecked, that is, they can silently overflow. The Int type is the type of literal input such as 12, and should be used for loop control flow, array indices, and other situations where the overflow can be provably avoided.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The BigInt type is backed by GMP multiprecision integers and can represent integers whose size is usually only limited by available memory. While the BigInt type avoids overflow problems, it can be relatively slow in the Int range.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"OSCAR currently has the integer type ZZRingElem, which for performance reasons scales internally from machine integers to GMP multiprecision integers.","category":"page"},{"location":"Rings/integer/#The-ring-of-integers","page":"Integers","title":"The ring of integers","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Every object in OSCAR representing a mathematical element has a parent. This is an object encoding information about where that element belongs.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The parent of an OSCAR integer is the ring of integers ZZ.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> ZZ\nInteger Ring\n","category":"page"},{"location":"Rings/integer/#Integer-constructors","page":"Integers","title":"Integer constructors","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"OSCAR integers are created using ZZ:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> ZZ(2)^100\n1267650600228229401496703205376\n\njulia> ZZ(618970019642690137449562111)\n618970019642690137449562111\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"One can also construct the integer 0 with the empty constructor:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> ZZ()\n0\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The following special constructors are also provided:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"zero(ZZ)\none(ZZ)","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> zero(ZZ)\n0\n\njulia> one(ZZ)\n1\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Note that ZZ is not a Julia type, but the above methods of constructing OSCAR integers are similar to the way that Julia integer types can be used to construct Julia integers.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> Int(123)\n123\n\njulia> BigInt(123456343567843598776327698374259876295438725)\n123456343567843598776327698374259876295438725\n\njulia> zero(BigInt)\n0\n\njulia> one(Int)\n1\n","category":"page"},{"location":"Rings/integer/#Limitations","page":"Integers","title":"Limitations","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"OSCAR integers have the same limitations as GMP multiprecision integers, namely that they are limited by the available memory on the machine and in any case to signed integers whose absolute value does not exceed 2^37 bits.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nThe Julia Int type is either a 32 or 64 bit integer, depending on the machine architecture (usually 64 bits on most modern machines). The range of values is machine dependent, but can be found by typing typemin(Int) and typemax(Int) in Julia.","category":"page"},{"location":"Rings/integer/#Julia-integers-in-OSCAR-functions","page":"Integers","title":"Julia integers in OSCAR functions","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"For convenience, all basic arithmetic and exact division functions in OSCAR also accept Julia integers. If all of the arguments to an OSCAR function are julia integers, the resulting integers should be julia integers. However, once at least one of the arguments is an ZZRingElem, the function will generally behave as if all integer arguments were promoted to the type ZZRingElem, and the integers in the return generally should also be of type ZZRingElem. For example:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> divexact(ZZ(234), 2)\n117\n\njulia> typeof(gcd(4, 6))\nInt64\n\njulia> typeof(gcdx(4, 6))\nTuple{Int64, Int64, Int64}\n\njulia> typeof(gcd(4, ZZ(6)))\nZZRingElem\n\njulia> typeof(gcdx(4, ZZ(6)))\nTuple{ZZRingElem, ZZRingElem, ZZRingElem}\n\njulia> typeof(jacobi_symbol(ZZ(2), ZZ(3)))\nInt64\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"In the first example, 2 is a Julia integer but is still valid in the call to the OSCAR function divexact. In the last example, the exceptional function jacobi_symbol returns an Int as this will always be able to hold the three possible return values of -1, 0, or 1.","category":"page"},{"location":"Rings/integer/#Predicates","page":"Integers","title":"Predicates","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"iszero(n::ZZRingElem) -> Bool\nisone(n::ZZRingElem) -> Bool\nis_unit(n::ZZRingElem) -> Bool\nisodd(n::ZZRingElem) -> Bool\niseven(n::ZZRingElem) -> Bool\nis_square(n::ZZRingElem) -> Bool\nis_prime(n::ZZRingElem) -> Bool\nis_probable_prime(n::ZZRingElem) -> Bool","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The is_prime predicate will prove primality, whereas is_probable_prime may declare a composite number to be prime with very low probability.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Negative numbers, 0 and 1 are not considered prime by is_prime and is_probable_prime.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> isone(ZZ(1))\ntrue\n\njulia> is_unit(ZZ(-1))\ntrue\n\njulia> is_square(ZZ(16))\ntrue\n\njulia> is_probable_prime(ZZ(23))\ntrue\n","category":"page"},{"location":"Rings/integer/#Properties","page":"Integers","title":"Properties","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"sign(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the sign of n, i.e. nn if n neq 0, or 0 otherwise.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> sign(ZZ(23))\n1\n\njulia> sign(ZZ(0))\n0\n\njulia> sign(ZZ(-1))\n-1\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"abs(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the absolute value of n, i.e. n if n geq 0 and -n otherwise","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> abs(ZZ(-3))\n3\n","category":"page"},{"location":"Rings/integer/#Basic-arithmetic","page":"Integers","title":"Basic arithmetic","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"OSCAR provides the basic arithmetic operations +, - and * and comparison operators ==, !=, <, <=, >, >=, including mixed operations between Julia and OSCAR integers. It also provides division and powering as described below.","category":"page"},{"location":"Rings/integer/#Division-in-OSCAR","page":"Integers","title":"Division in OSCAR","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"OSCAR distinguishes a number of different kinds of division:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Exact division (divexact)\nEuclidean division (div, rem, divrem and mod)\nConstruction of fractions (a//b)\nFloating point division (a/b)\nDivisibility testing (divides)","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"These choices have been made for maximum parsimony with the Julia language.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nIt is a common error to enter 1/2 for the fraction 'one half' in Julia. This expression is reserved for floating point division. Instead, the double slash operator // should be used for fractions.","category":"page"},{"location":"Rings/integer/#integer_exact_division","page":"Integers","title":"Exact Division","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"divexact(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the quotient of a by b. The result of the exact division of two integers will always be another integer. Exact division raises an exception if the division is not exact, or if division by zero is attempted.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> divexact(ZZ(6), ZZ(3))\n2\n\njulia> divexact(ZZ(6), ZZ(0))\nERROR: DivideError: integer division error\n\njulia> divexact(ZZ(6), ZZ(5))\nERROR: ArgumentError: Not an exact division\n\njulia> divexact(ZZ(6), 2)\n3\n","category":"page"},{"location":"Rings/integer/#Powering","page":"Integers","title":"Powering","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"^(a::ZZRingElem, b::Int) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the result of powering a by b.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> ZZ(37)^37\n10555134955777783414078330085995832946127396083370199442517\n\njulia> ZZ(1)^(-2)\n1\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nAn exception will be raised if an integer other than -1 or 1 is raised to a negative exponent.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nIn Julia 2^-2 is called a literal power. The value returned is a floating point value. To get behaviour that agrees with OSCAR, one can write 2^Int(-2).","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The following is allowed for convenience.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> ZZ(0)^0\n1\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nIn Julia, 2^64 will return zero, as the Julia integer 2 is a machine integer. In OSCAR, the expression ZZ(2)^64 will return the expected result, just as the Julia equivalent BigInt(2)^64 does.","category":"page"},{"location":"Rings/integer/#integer_euclidean_division","page":"Integers","title":"Euclidean division","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The ring of integers is a Euclidean domain and OSCAR provides Euclidean division through the functions divrem, div and rem.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Integer Euclidean division of a by b computes a quotient and remainder such that","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"a = qb + r","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"with r b.","category":"page"},{"location":"Rings/integer/#Division-with-remainder","page":"Integers","title":"Division with remainder","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"divrem(a::ZZRingElem, b::ZZRingElem) -> (ZZRingElem, ZZRingElem) : division with remainder\ndiv(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem : quotient only\nrem(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem : remainder only","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Both rem and divrem compute the remainder r such that when r neq 0 the sign of r is the same as the sign of a.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"All three functions raise an exception if the modulus b is zero.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> divrem(ZZ(5), ZZ(3))\n(1, 2)\n\njulia> div(ZZ(7), ZZ(2))\n3\n\njulia> rem(ZZ(4), ZZ(3))\n1\n\njulia> div(ZZ(2), ZZ(0))\nERROR: DivideError: integer division error\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nThe rem function does not provide a minimal set of representatives, e.g. rem(-2, 3) = -2 but rem(1, 3) = 1.","category":"page"},{"location":"Rings/integer/#Modular-arithmetic","page":"Integers","title":"Modular arithmetic","text":"","category":"section"},{"location":"Rings/integer/#Modular-reduction","page":"Integers","title":"Modular reduction","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"mod(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem : remainder only","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The mod function computes a remainder r such that when r neq 0 the sign of r is the same as the sign of b. Thus, if b 0 then mod(a, b) will be in the range 0 b). An exception is raised if the modulus b is zero. This is summarised in the following table.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"remainder division sign rounding\nrem div/divrem same as dividend towards zero\nmod same as divisor towards -infty","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"There is no function implemented to compute the quotient corresponding to the remainder given by mod.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> mod(ZZ(4), ZZ(3))\n1\n\njulia> mod(ZZ(2), ZZ(0))\nERROR: DivideError: integer division error\n","category":"page"},{"location":"Rings/integer/#integer_divisibility_testing","page":"Integers","title":"Divisibility testing","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"divides(a::ZZRingElem, b::ZZRingElem) -> (Bool, ZZRingElem)","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"In OSCAR, we say that b divides a if there exists c in the same ring such that a = bc.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The call divides(a, b) returns a tuple (flag, q) where flag is either true if b divides a in which case q will be a quotient, or flag is false if b does not divide a in which case q will be an integer whose value is not defined.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> divides(ZZ(6), ZZ(3))\n(true, 2)\n\njulia> divides(ZZ(5), ZZ(2))\n(false, 0)\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Note that for convenience we define:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> divides(ZZ(0), ZZ(0))\n(true, 0)\n","category":"page"},{"location":"Rings/integer/#Greatest-common-divisor","page":"Integers","title":"Greatest common divisor","text":"","category":"section"},{"location":"Rings/integer/#Greatest-common-divisor-2","page":"Integers","title":"Greatest common divisor","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"gcd(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the greatest common divisor of its inputs, which is by definition the largest integer dividing the two inputs, unless both inputs are zero in which case it returns zero. The result will always be non-negative and will only be zero if both inputs are zero.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> gcd(ZZ(34), ZZ(17))\n17\n\njulia> gcd(ZZ(3), ZZ(0))\n3\n","category":"page"},{"location":"Rings/integer/#Extended-GCD","page":"Integers","title":"Extended GCD","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"gcdx(a::ZZRingElem, b::ZZRingElem) -> (ZZRingElem, ZZRingElem, ZZRingElem)","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return a tuple (g s t) such that g is the greatest common divisor of a and b and g = as + bt. Normally s and t are chosen so that s b(2g) and t a(2g), where this uniquely defines s and t. The following cases are handled specially:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"if a = b then t = bb\nif b = 0 or b = 2g then s = aa\nif a = 0 or a = 2g then t = bb","category":"page"},{"location":"Rings/integer/#Least-common-multiple","page":"Integers","title":"Least common multiple","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"lcm(a::ZZRingElem, b::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the least common multiple of a and b. This is the least positive multiple of a and b, unless a = 0 or b = 0 which case we define the least common multiple to be zero.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> lcm(ZZ(6), ZZ(21))\n42\n\njulia> lcm(ZZ(0), ZZ(0))\n0\n","category":"page"},{"location":"Rings/integer/#Roots","page":"Integers","title":"Roots","text":"","category":"section"},{"location":"Rings/integer/#Square-roots","page":"Integers","title":"Square roots","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Julia and OSCAR distinguish two kinds of square root:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Integer square root (isqrt)\nFloating point square root (sqrt)","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"We describe only the first of these here.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"isqrt(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the floor of the square root of its argument, i.e. the largest integer whose square does not exceed its input. An exception is raised if a negative input is passed.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> isqrt(ZZ(16))\n4\n\njulia> isqrt(ZZ(0))\n0\n\njulia> isqrt(ZZ(5))\n2\n\njulia> isqrt(ZZ(-3))\nERROR: DomainError with -3:\nArgument must be non-negative\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"isqrtrem(n::ZZRingElem) -> (ZZRingElem, ZZRingElem)","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the tuple (s, r) such that s is equal to isqrt(n) and n = s^2 + r.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> isqrtrem(ZZ(16))\n(4, 0)\n\njulia> isqrtrem(ZZ(5))\n(2, 1)\n","category":"page"},{"location":"Rings/integer/#General-roots","page":"Integers","title":"General roots","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"root(a::ZZRingElem, n::Int) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return an n-th root of a or throw an error if it does not exist.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"When n is even, the non-negative root is always returned. An exception is raised if n leq 0 or if n is even and a 0.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> root(ZZ(16), 4)\n2\n\njulia> root(ZZ(-5), 2)\nERROR: DomainError with (-5, 2):\nArgument `x` must be positive if exponent `n` is even\n\njulia> root(ZZ(12), -2)\nERROR: DomainError with -2:\nExponent must be positive","category":"page"},{"location":"Rings/integer/#Conversions","page":"Integers","title":"Conversions","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Int(n::ZZRingElem) -> Int\nBigInt(n::ZZRingElem) -> BigInt","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Convert the OSCAR integer to the respective Julia integer.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> n = ZZ(123)\n123\n\njulia> Int(n)\n123\n\njulia> BigInt(n)\n123\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"In the case of Int, if the OSCAR integer is too large to fit, an exception is raised.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> Int(ZZ(12348732648732648763274868732687324))\nERROR: InexactError: convert(Int64, 12348732648732648763274868732687324)\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"fits(::Type{Int}, n::ZZRingElem) -> Bool","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return true if the OSCAR integer will fit in an Int.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> fits(Int, ZZ(123))\ntrue\n\njulia> fits(Int, ZZ(12348732648732648763274868732687324))\nfalse\n","category":"page"},{"location":"Rings/integer/#Factorisation","page":"Integers","title":"Factorisation","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"factor(n::ZZRingElem) -> Fac{ZZRingElem}","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return a factorisation of the given integer. The return value is a special factorisation struct which can be manipulated using the functions below.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> factor(ZZ(-6000361807272228723606))\n-1 * 2 * 229^3 * 43669^3 * 3\n\njulia> factor(ZZ(0))\nERROR: ArgumentError: Argument is not non-zero\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"unit(F::Fac) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> F = factor(ZZ(-12))\n-1 * 2^2 * 3\n\njulia> unit(F)\n-1\n","category":"page"},{"location":"Rings/integer/#Factorisation-are-iterable","page":"Integers","title":"Factorisation are iterable","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Once created, a factorisation is iterable:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> F = factor(ZZ(-60))\n-1 * 5 * 2^2 * 3\n\njulia> for (p, e) in F; println(\"$p^$e\"); end\n5^1\n2^2\n3^1\n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"The pairs (p, e) in a factorisation represent the prime power factors p^e of the non-unit part of the factorisation. They can be placed in an array using collect:","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> F = factor(ZZ(-60))\n-1 * 5 * 2^2 * 3\n\njulia> collect(F)\n3-element Vector{Pair{ZZRingElem, Int64}}:\n 5 => 1\n 2 => 2\n 3 => 1\n","category":"page"},{"location":"Rings/integer/#Accessing-exponents-in-a-factorisation","page":"Integers","title":"Accessing exponents in a factorisation","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"One can also determine whether a given prime is in the non-unit part of a factorisation and if so return its exponent. If the exponent of a prime that is not in a factorisation is requested, an exception is raised.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"For convenience, a Int can be used instead of an OSCAR integer for this functionality.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> F = factor(ZZ(-60))\n-1 * 5 * 2^2 * 3\n\njulia> 5 in F\ntrue\n\njulia> ZZ(3) in F\ntrue\n\njulia> 7 in F\nfalse\n\njulia> F[3]\n1\n\njulia> F[ZZ(7)]\nERROR: 7 is not a factor of -1 * 5 * 2^2 * 3\n","category":"page"},{"location":"Rings/integer/#Combinatorial-functions","page":"Integers","title":"Combinatorial functions","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nThe functions in this section that take Int arguments will return an Int, which may overflow or throw an error. Use the ZZRingElem versions if this is not the desired behaviour.","category":"page"},{"location":"Rings/integer/#Factorial","page":"Integers","title":"Factorial","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"factorial(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the factorial of n, i.e. n. An exception is raised if n 0. We define 0 = 1.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"rising_factorial(x::Int, n::Int) -> Int\nrising_factorial(x::ZZRingElem, n::Int) -> ZZRingElem\nrising_factorial(x::ZZRingElem, n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return x(x + 1)(x + 2)ldots(x + n - 1). An exception is raised if n 0. We define rising_factorial(x, 0) to be 1.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> factorial(ZZ(30))\n265252859812191058636308480000000\n\njulia> rising_factorial(ZZ(-30), 3)\n-24360\n","category":"page"},{"location":"Rings/integer/#Primorial","page":"Integers","title":"Primorial","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"primorial(n::Int) -> Int\nprimorial(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the primorial P(n), i.e. the product of all primes less than or equal to n. An exception is raised if n 0. We define P(0) = P(1) = 1.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> primorial(ZZ(100))\n2305567963945518424753102147331756070\n","category":"page"},{"location":"Rings/integer/#Bell-numbers","page":"Integers","title":"Bell numbers","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"bell(n::Int) -> Int\nbell(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the n-th Bell number B(n), i.e. the number of ways of partitioning a set of n elements. An exception is raised if n 0.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> bell(ZZ(20))\n51724158235372\n","category":"page"},{"location":"Rings/integer/#Binomial-coefficients","page":"Integers","title":"Binomial coefficients","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"binomial(n::ZZRingElem, k::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the binomial coefficient fracn (n-1) cdots (n-k+1)k for k ge 0 and returns 0 for k < 0.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nJulia already defines the binomial function for Int, which throws an error on overflow.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> binomial(ZZ(72), ZZ(15))\n1155454041309504\n","category":"page"},{"location":"Rings/integer/#Integer-partitions","page":"Integers","title":"Integer partitions","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"number_of_partitions(n::Int) -> Int\nnumber_of_partitions(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the number of integer partitions p(n) of n, i.e. the number of distinct ways to write n as a sum of positive integers. Note that p(0) = 1, as the empty sum is counted. For n 0 we return zero.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> number_of_partitions(ZZ(10^6))\n1471684986358223398631004760609895943484030484439142125334612747351666117418918618276330148873983597555842015374130600288095929387347128232270327849578001932784396072064228659048713020170971840761025676479860846908142829356706929785991290519899445490672219997823452874982974022288229850136767566294781887494687879003824699988197729200632068668735996662273816798266213482417208446631027428001918132198177180646511234542595026728424452592296781193448139994664730105742564359154794989181485285351370551399476719981691459022015599101959601417474075715430750022184895815209339012481734469448319323280150665384042994054179587751761294916248142479998802936507195257074485047571662771763903391442495113823298195263008336489826045837712202455304996382144601028531832004519046591968302787537418118486000612016852593542741980215046267245473237321845833427512524227465399130174076941280847400831542217999286071108336303316298289102444649696805395416791875480010852636774022023128467646919775022348562520747741843343657801534130704761975530375169707999287040285677841619347472368171772154046664303121315630003467104673818\n","category":"page"},{"location":"Rings/integer/#Fibonacci-sequence","page":"Integers","title":"Fibonacci sequence","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"fibonacci(n::Int) -> Int\nfibonacci(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the n-th Fibonacci number F(n), defined by the recurrence relation F(1) = 1, F(2) = 1 and F(n) = F(n - 1) + F(n - 2) for n geq 3. We define F(0) = 0 and for n 0 we have F(-n) = (-1)^n+1F(n).","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> fibonacci(ZZ(100))\n354224848179261915075\n\njulia> fibonacci(-2)\n-1\n","category":"page"},{"location":"Rings/integer/#Number-theoretic-functionality","page":"Integers","title":"Number theoretic functionality","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"note: Note\nThe functions in this section that take Int arguments will return a Int, which may overflow or throw an error. Use the ZZRingElem versions if this is not the desired behaviour.","category":"page"},{"location":"Rings/integer/#Moebius-mu-function","page":"Integers","title":"Moebius mu function","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"moebius_mu(n::Int) -> Int\nmoebius_mu(n::ZZRingElem) -> Int ","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the Moebius function mu(n), which is defined to be 0 if n is not squarefree and otherwise is defined to be +1 or -1 if n has an even or odd number of prime factors, respectively. Alternatively, mu(n) can be defined to be the sum of the primitive n-th roots of unity. An exception is raised if n leq 0.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> moebius_mu(30)\n-1\n","category":"page"},{"location":"Rings/integer/#Jacobi-symbols","page":"Integers","title":"Jacobi symbols","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"jacobi_symbol(m::Int, n::Int) -> Int\njacobi_symbol(m::ZZRingElem, n::ZZRingElem) -> Int","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the Jacobi symbol left(fracmnright), which is defined for integers m and odd, positive integers n. If the factorisation of n is n = p_1^i_1p_2^i_2ldots p_r^i_r then we define","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"left(fracmnright) = left(fracmp_1right)^i_1left(fracmp_2right)^i_2ldots left(fracmp_rright)^i_r","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"where left(fracmpright) on the right hand side is the Legendre symbol, which is defined for an odd prime number p to be 0 if p divides m and otherwise +1 or -1 depending on whether m is a square modulo p or not. An exception is raised if n is even or if n leq 0.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> jacobi_symbol(3, 37)\n1\n","category":"page"},{"location":"Rings/integer/#Sigma-function","page":"Integers","title":"Sigma function","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"divisor_sigma(m::Int, n::Int) -> Int\ndivisor_sigma(m::ZZRingElem, n::Int) -> ZZRingElem\ndivisor_sigma(m::ZZRingElem, n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the sum of the n-th powers of the divisors of m","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"sigma(m n) = sum_dm d^n","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"If m leq 0 or n 0 we raise an exception.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> divisor_sigma(60, 5)\n806220408\n","category":"page"},{"location":"Rings/integer/#Euler-totient-function","page":"Integers","title":"Euler totient function","text":"","category":"section"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"euler_phi(n::Int) -> Int\neuler_phi(n::ZZRingElem) -> ZZRingElem","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"Return the Euler totient function varphi(n), i.e. the number of positive integers 1 leq x leq n which are coprime to n. Note that varphi(1) = 1. We raise an exception if n leq 0.","category":"page"},{"location":"Rings/integer/","page":"Integers","title":"Integers","text":"julia> euler_phi(200)\n80\n","category":"page"},{"location":"Groups/fpgroup/","page":"Finitely presented groups","title":"Finitely presented groups","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/fpgroup/#Finitely-presented-groups","page":"Finitely presented groups","title":"Finitely presented groups","text":"","category":"section"},{"location":"Groups/fpgroup/","page":"Finitely presented groups","title":"Finitely presented groups","text":"FPGroup\nFPGroupElem\nfree_group(n::Int)\nis_full_fp_group(G::FPGroup)\nrelators(G::FPGroup)\nlength(g::FPGroupElem)\nmap_word","category":"page"},{"location":"Groups/fpgroup/#FPGroup","page":"Finitely presented groups","title":"FPGroup","text":"FPGroup\n\nFinitely presented group. Such groups can be constructed a factors of free groups, see free_group.\n\n\n\n\n\n","category":"type"},{"location":"Groups/fpgroup/#FPGroupElem","page":"Finitely presented groups","title":"FPGroupElem","text":"TODO: document this\n\n\n\n\n\n","category":"type"},{"location":"Groups/fpgroup/#free_group-Tuple{Int64}","page":"Finitely presented groups","title":"free_group","text":"free_group(n::Int, s::VarName = :f; eltype::Symbol = :letter) -> FPGroup\nfree_group(L::Vector{<:VarName}) -> FPGroup\nfree_group(L::VarName...) -> FPGroup\n\nThe first form returns the free group of rank n, where the generators are printed as s1, s2, ..., the default being f1, f2, ... If eltype has the value :syllable then each element in the free group is internally represented by a vector of syllables, whereas a representation by a vector of integers is chosen in the default case of eltype == :letter.\n\nThe second form, if L has length n, returns the free group of rank n, where the i-th generator is printed as L[i].\n\nThe third form, if there are n arguments L..., returns the free group of rank n, where the i-th generator is printed as L[i].\n\nwarning: Note\nVariables named like the group generators are not created by this function.\n\n\n\n\n\n","category":"method"},{"location":"Groups/fpgroup/#is_full_fp_group-Tuple{FPGroup}","page":"Finitely presented groups","title":"is_full_fp_group","text":"is_full_fp_group(G::FPGroup)\n\nReturn true if G has been constructed as a free group or a quotient of a free group, and false otherwise.\n\nNote that also subgroups of groups of type FPGroup have the type FPGroup, and functions such as relators do not make sense for proper subgroups.\n\nExamples\n\njulia> f = free_group(2); is_full_fp_group(f)\ntrue\n\njulia> s = sub(f, gens(f))[1]; is_full_fp_group(s)\nfalse\n\njulia> q = quo(f, [gen(f,1)^2])[1]; is_full_fp_group(q)\ntrue\n\njulia> u = sub(q, gens(q))[1]; is_full_fp_group(u)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/fpgroup/#relators-Tuple{FPGroup}","page":"Finitely presented groups","title":"relators","text":"relators(G::FPGroup)\n\nReturn a vector of relators for the full finitely presented group G, i.e., elements x_1 x_2 ldots x_n in F = free_group(ngens(G)) such that G is isomorphic with Fx_1 x_2 ldots x_n.\n\nAn exception is thrown if G has been constructed only as a subgroup of a full finitely presented group, see is_full_fp_group.\n\nExamples\n\njulia> f = free_group(2); (x, y) = gens(f);\n\njulia> q = quo(f, [x^2, y^2, comm(x, y)])[1]; relators(q)\n3-element Vector{FPGroupElem}:\n f1^2\n f2^2\n f1^-1*f2^-1*f1*f2\n\n\n\n\n\n","category":"method"},{"location":"Groups/fpgroup/#length-Tuple{FPGroupElem}","page":"Finitely presented groups","title":"length","text":"length(g::FPGroupElem)\n\nReturn the length of g as a word in terms of the generators of its group if g is an element of a free group, otherwise a exception is thrown.\n\nExamples\n\njulia> F = free_group(2); F1 = gen(F, 1); F2 = gen(F, 2);\n\njulia> length(F1*F2^-2)\n3\n\njulia> length(one(F))\n0\n\njulia> length(one(quo(F, [F1])[1]))\nERROR: ArgumentError: the element does not lie in a free group\n\n\n\n\n\n","category":"method"},{"location":"Groups/fpgroup/#map_word","page":"Finitely presented groups","title":"map_word","text":"map_word(g::FPGroupElem, genimgs::Vector; genimgs_inv::Vector = Vector(undef, length(genimgs)), init = nothing)\nmap_word(v::Vector{Union{Int, Pair{Int, Int}}}, genimgs::Vector; genimgs_inv::Vector = Vector(undef, length(genimgs)), init = nothing)\n\nReturn the product R_1 R_2 cdots R_n that is described by g or v, respectively.\n\nIf g is an element of a free group G, say, then the rank of G must be equal to the length of genimgs, g is a product of the form g_i_1^e_i g_i_2^e_2 cdots g_i_n^e_n where g_i is the i-th generator of G and the e_i are nonzero integers, and R_j = imgsij^{ej}$.\n\nIf g is an element of a finitely presented group then the result is defined as map_word applied to a representing element of the underlying free group.\n\nIf the first argument is a vector v of integers k_i or pairs k_i => e_i, respectively, then the absolute values of the k_i must be at most the length of genimgs, and R_j = imgs|ki|^{\\epsiloni}$ where epsilon_i is the sign of k_i (times e_i).\n\nIf a vector genimgs_inv is given then its assigned entries are expected to be the inverses of the corresponding entries in genimgs, and the function will use (and set) these entries in order to avoid calling inv (more than once) for entries of genimgs.\n\nIf v has length zero then init is returned if also genimgs has length zero, otherwise one(genimgs[1]) is returned. In all other cases, init is ignored.\n\nExamples\n\njulia> F = free_group(2); F1 = gen(F, 1); F2 = gen(F, 2);\n\njulia> imgs = gens(symmetric_group(4))\n2-element Vector{PermGroupElem}:\n (1,2,3,4)\n (1,2)\n\njulia> map_word(F1^2, imgs)\n(1,3)(2,4)\n\njulia> map_word(F2, imgs)\n(1,2)\n\njulia> map_word(one(F), imgs)\n()\n\njulia> invs = Vector(undef, 2);\n\njulia> map_word(F1^-2*F2, imgs, genimgs_inv = invs)\n(1,3,2,4)\n\njulia> invs\n2-element Vector{Any}:\n (1,4,3,2)\n #undef\n\n\n\n\n\n\n","category":"function"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/LieAlgebras/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"This project aims to provide functionality for Lie algebras and their representations. It aims to provide the computational tools to work with the concepts defined in James E. Humphreys (1972).","category":"page"},{"location":"Experimental/LieAlgebras/introduction/#Status","page":"Introduction","title":"Status","text":"","category":"section"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"This part of OSCAR is in an experimental state; please see Adding new projects to experimental for what this means.","category":"page"},{"location":"Experimental/LieAlgebras/introduction/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"Lars Göttgens","category":"page"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"CurrentModule = Oscar","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#Free-Associative-Algebras","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#Two-sided-ideals","page":"Free Associative Algebras","title":"Two-sided ideals","text":"","category":"section"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#Types","page":"Free Associative Algebras","title":"Types","text":"","category":"section"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"The OSCAR type for two-sided ideals in a free associative algebra is FreeAssAlgIdeal{T}, where T is the element type of the algebra.","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#Constructors","page":"Free Associative Algebras","title":"Constructors","text":"","category":"section"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"ideal(R::FreeAssAlgebra, g::Vector{T}) where T <: FreeAssAlgElem\nideal(g::Vector{T}) where T <: FreeAssAlgElem","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#Ideal-Membership","page":"Free Associative Algebras","title":"Ideal Membership","text":"","category":"section"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int)","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#ideal_membership-Tuple{FreeAssAlgElem, Oscar.FreeAssAlgIdeal, Int64}","page":"Free Associative Algebras","title":"ideal_membership","text":"ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int)\n\nReturn true if calucations with intermediate degrees bounded by deg_bound prove that a is in I. Otherwise, a return of false indicates an inconclusive answer, but larger deg_bounds give more confidence in a negative answer.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#Projective-schemes","page":"Projective schemes","title":"Projective schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"Let A be a commutative noetherian base ring and S = Ax_0dots x_n the standard graded polynomial ring over A. Then X = mathrmProj(S) = mathbb P^n_A is a (relative) projective scheme over mathrmSpec(A). Similarly, for a homogeneous ideal I subset S we have X = mathrmProj(SI) subset mathbb P^n_A a (relative) projective scheme over mathrmSpec(A) which is a closed subscheme of mathbb P^n_A in a natural way. The majority of applications will be in the setting where A = mathbb k is a field, but be aware that we also support different base rings such as the usual four MPolyRing, MPolyQuoRing, MPolyLocRing, and MPolyQuoLocRing.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#Abstract-types-and-basic-interface","page":"Projective schemes","title":"Abstract types and basic interface","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"The abstract type for such projective schemes is ","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" AbsProjectiveScheme{CoeffRingType, RingType} where {CoeffRingType<:Ring}","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"where, in the above notation, CoeffRingType denotes the type of A and RingType the type of either S or S/I, respectively. The abstract type comes with the following interface:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" base_ring(X::AbsProjectiveScheme)\n base_scheme(X::AbsProjectiveScheme)\n homogeneous_coordinate_ring(P::AbsProjectiveScheme)\n relative_ambient_dimension(X::AbsProjectiveScheme)\n ambient_coordinate_ring(P::AbsProjectiveScheme)\n ambient_space(P::AbsProjectiveScheme)\n defining_ideal(X::AbsProjectiveScheme)\n affine_cone(X::AbsProjectiveScheme)\n homogeneous_coordinates_on_affine_cone(X::AbsProjectiveScheme)\n covered_scheme(P::AbsProjectiveScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#base_ring-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"base_ring","text":"base_ring(X::AbsProjectiveScheme)\n\nOn X ℙʳ_A this returns A.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#base_scheme-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"base_scheme","text":"base_scheme(X::AbsProjectiveScheme)\n\nReturn the base scheme Y for X ℙʳₖ Y Y with Y defined over a field 𝕜.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#homogeneous_coordinate_ring-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"homogeneous_coordinate_ring","text":"homogeneous_coordinate_ring(P::AbsProjectiveScheme)\n\nOn a projective scheme P = Proj(S) for a standard graded finitely generated algebra S this returns S.\n\nExample\n\njulia> S, _ = grade(QQ[\"x\", \"y\", \"z\"][1]);\n\njulia> I = ideal(S, S[1] + S[2]);\n\njulia> X = ProjectiveScheme(S, I)\nProjective scheme\n over rational field\ndefined by ideal(x + y)\n\njulia> homogeneous_coordinate_ring(X)\nQuotient\n of graded multivariate polynomial ring in 3 variables over QQ\n by ideal(x + y)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#relative_ambient_dimension-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"relative_ambient_dimension","text":"relative_ambient_dimension(X::AbsProjectiveScheme)\n\nOn X ℙʳ_A this returns r.\n\nExample\n\njulia> S, _ = grade(QQ[\"x\", \"y\", \"z\"][1]);\n\njulia> I = ideal(S, S[1] + S[2])\nideal(x + y)\n\njulia> X = ProjectiveScheme(S, I)\nProjective scheme\n over rational field\ndefined by ideal(x + y)\n\njulia> relative_ambient_dimension(X)\n2\n\njulia> dim(X)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#ambient_coordinate_ring-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"ambient_coordinate_ring","text":"ambient_coordinate_ring(P::AbsProjectiveScheme)\n\nOn a projective scheme P = Proj(S) with S = PI for a standard graded polynomial ring P and a homogeneous ideal I this returns P.\n\nExample\n\njulia> S, _ = grade(QQ[\"x\", \"y\", \"z\"][1])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> I = ideal(S, S[1] + S[2])\nideal(x + y)\n\njulia> X = ProjectiveScheme(S, I)\nProjective scheme\n over rational field\ndefined by ideal(x + y)\n\njulia> homogeneous_coordinate_ring(X)\nQuotient\n of graded multivariate polynomial ring in 3 variables over QQ\n by ideal(x + y)\n\njulia> ambient_coordinate_ring(X) === S\ntrue\n\njulia> ambient_coordinate_ring(X) === homogeneous_coordinate_ring(X)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#ambient_space-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"ambient_space","text":"ambient_space(X::AbsProjectiveScheme)\n\nOn X ℙʳ_A this returns ℙʳ_A.\n\nExample\n\njulia> S, _ = grade(QQ[\"x\", \"y\", \"z\"][1]);\n\njulia> I = ideal(S, S[1] + S[2]);\n\njulia> X = ProjectiveScheme(S, I)\nProjective scheme\n over rational field\ndefined by ideal(x + y)\n\njulia> P = ambient_space(X)\nProjective space of dimension 2\n over rational field\nwith homogeneous coordinates [x, y, z]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#defining_ideal-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"defining_ideal","text":"defining_ideal(X::AbsProjectiveScheme)\n\nOn X ℙʳ_A this returns the homogeneous ideal I As₀sᵣ defining X.\n\nExample\n\njulia> R, (u, v) = QQ[\"u\", \"v\"];\n\njulia> Q, _ = quo(R, ideal(R, u^2 + v^2));\n\njulia> S, _ = grade(Q[\"x\", \"y\", \"z\"][1]);\n\njulia> P = projective_scheme(S)\nProjective space of dimension 2\n over quotient of multivariate polynomial ring by ideal with 1 generator\nwith homogeneous coordinates [x, y, z]\n\njulia> defining_ideal(P)\nideal()\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#affine_cone-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"affine_cone","text":"affine_cone(X::AbsProjectiveScheme)\n\nOn X = Proj(S) ℙʳ_𝕜 this returns a pair (C, f) where C = C(X) 𝕜ʳ¹ is the affine cone of X and f S 𝒪(C) is the morphism of rings from the homogeneous_coordinate_ring to the coordinate_ring of the affine cone.\n\nNote that if the base scheme is not affine, then the affine cone is not affine.\n\nExample\n\njulia> R, (u, v) = QQ[\"u\", \"v\"];\n\njulia> Q, _ = quo(R, ideal(R, u^2 + v^2));\n\njulia> S, _ = grade(Q[\"x\", \"y\", \"z\"][1]);\n\njulia> P = projective_scheme(S)\nProjective space of dimension 2\n over quotient of multivariate polynomial ring by ideal with 1 generator\nwith homogeneous coordinates [x, y, z]\n\njulia> affine_cone(P)\n(Spec of quotient of multivariate polynomial ring, Map with following data\nDomain:\n=======\nS\nCodomain:\n=========\nQuotient of multivariate polynomial ring by ideal with 1 generator)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#homogeneous_coordinates_on_affine_cone-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"homogeneous_coordinates_on_affine_cone","text":"homogeneous_coordinates_on_affine_cone(X::AbsProjectiveScheme)\n\nOn X ℙʳ_A this returns a vector with the homogeneous coordinates s₀sᵣ as entries where each one of the sᵢ is a function on the affine cone of X.\n\nExample\n\njulia> R, (u, v) = QQ[\"u\", \"v\"];\n\njulia> Q, _ = quo(R, ideal(R, u^2 + v^2));\n\njulia> S, _ = grade(Q[\"x\", \"y\", \"z\"][1]);\n\njulia> P = projective_scheme(S)\nProjective space of dimension 2\n over quotient of multivariate polynomial ring by ideal with 1 generator\nwith homogeneous coordinates [x, y, z]\n\njulia> homogeneous_coordinates_on_affine_cone(P)\n3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x\n y\n z\n\njulia> gens(OO(affine_cone(P)[1])) # all coordinates on the affine cone\n5-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x\n y\n z\n u\n v\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#covered_scheme-Tuple{AbsProjectiveScheme}","page":"Projective schemes","title":"covered_scheme","text":"covered_scheme(P::AbsProjectiveScheme)\n\nReturn a CoveredScheme X isomorphic to P with standard affine charts given by dehomogenization.\n\nUse dehomogenization_map with U one of the affine_charts of X to obtain the dehomogenization map from the homogeneous_coordinate_ring of P to the coordinate_ring of U.\n\nExamples\n\njulia> P = projective_space(QQ, 2);\n\njulia> Pcov = covered_scheme(P)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n 3: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [(s1//s0), (s2//s0)]\n 2: [(s0//s1), (s2//s1)]\n 3: [(s0//s2), (s1//s2)]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"The minimal concrete type realizing this interface is ","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" ProjectiveScheme{CoeffRingType, RingType} <: AbsProjectiveScheme{CoeffRingType, RingType}","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#Constructors","page":"Projective schemes","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"Besides ProjectiveScheme(S) for some graded polynomial ring or a graded affine algebra S, we provide the following constructors:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" projective_scheme(S::MPolyDecRing)\n projective_scheme(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem}\n projective_scheme(I::MPolyIdeal{<:MPolyDecRingElem})\n projective_scheme(Q::MPolyQuoRing{MPolyDecRingElem{T, PT}}) where {T, PT<:MPolyRingElem{T}} = ProjectiveScheme(Q)","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"Subschemes defined by homogeneous ideals, ring elements, or lists of elements can be created via the respective methods of the subscheme(P::AbsProjectiveScheme, ...) function. Special constructors are provided for projective space itself via the function projective_space and its various methods.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" projective_space(A::Ring, var_symb::Vector{VarName})\n projective_space(A::Ring, r::Int; var_name::VarName=:s)","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#projective_space-Tuple{Ring, Vector{Union{Char, AbstractString, Symbol}}}","page":"Projective schemes","title":"projective_space","text":"projective_space(A::Ring, var_symb::Vector{VarName})\n\nCreate the (relative) projective space Proj(A[x₀,…,xₙ]) over A where x₀,…,xₙ is a list of variable names.\n\nExamples\n\njulia> projective_space(QQ, [:x, :PPP, :?])\nProjective space of dimension 2\n over rational field\nwith homogeneous coordinates [x, PPP, ?]\n\njulia> homogeneous_coordinate_ring(ans)\nMultivariate polynomial ring in 3 variables over QQ graded by\n x -> [1]\n PPP -> [1]\n ? -> [1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#projective_space-Tuple{Ring, Int64}","page":"Projective schemes","title":"projective_space","text":"projective_space(A::Ring, r::Int; var_name::VarName=:s)\n\nCreate the (relative) projective space Proj(A[s₀,…,sᵣ]) over A where s is a string for the variable names. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#Attributes","page":"Projective schemes","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"Besides those attributes already covered by the above general interface we have the following (self-explanatory) ones for projective schemes over a field.","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" dim(P::AbsProjectiveScheme{<:Field})\n hilbert_polynomial(P::AbsProjectiveScheme{<:Field})\n degree(P::AbsProjectiveScheme{<:Field})\n arithmetic_genus(P::AbsProjectiveScheme{<:Field})","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#Methods","page":"Projective schemes","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"To facilitate the interplay between an AbsProjectiveScheme and the affine charts of its covered_scheme we provide the following methods:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec)\n dehomogenization_map(X::AbsProjectiveScheme, i::Int)\n homogenization_map(P::AbsProjectiveScheme, U::AbsSpec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#dehomogenization_map-Tuple{AbsProjectiveScheme, AbsSpec}","page":"Projective schemes","title":"dehomogenization_map","text":"dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec)\n\nReturn the restriction morphism from the graded coordinate ring of X to 𝒪(U).\n\nExamples\n\njulia> P = projective_space(QQ, [\"x0\", \"x1\", \"x2\"])\nProjective space of dimension 2\n over rational field\nwith homogeneous coordinates [x0, x1, x2]\n\njulia> X = covered_scheme(P);\n\njulia> U = first(affine_charts(X))\nSpectrum\n of multivariate polynomial ring in 2 variables (x1//x0), (x2//x0)\n over rational field\n\njulia> phi = dehomogenization_map(P, U);\n\njulia> S = homogeneous_coordinate_ring(P);\n\njulia> phi(S[2])\n(x1//x0)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#dehomogenization_map-Tuple{AbsProjectiveScheme, Int64}","page":"Projective schemes","title":"dehomogenization_map","text":"dehomogenization_map(X::AbsProjectiveScheme, i::Int)\n\nReturn the restriction morphism from the graded coordinate ring of X to 𝒪(Uᵢ). Where Uᵢ is the i-th affine chart of X.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#homogenization_map-Tuple{AbsProjectiveScheme, AbsSpec}","page":"Projective schemes","title":"homogenization_map","text":"homogenization_map(P::AbsProjectiveScheme, U::AbsSpec)\n\nGiven an affine chart U P of an AbsProjectiveScheme P, return a method h for the homogenization of elements a 𝒪(U).\n\nThis means that h(a) returns a pair (p q) representing a fraction pq S of the ambient_coordinate_ring of P such that a is the dehomogenization of pq.\n\nNote: For the time being, this only works for affine charts which are of the standard form sᵢ 0 for sᵢ S one of the homogeneous coordinates of P.\n\nNote: Since this map returns representatives only, it is not a mathematical morphism and, hence, in particular not an instance of Hecke.Map.\n\nExamples\n\njulia> A, _ = QQ[\"u\", \"v\"];\n\njulia> P = projective_space(A, [\"x0\", \"x1\", \"x2\"])\nProjective space of dimension 2\n over multivariate polynomial ring in 2 variables over QQ\nwith homogeneous coordinates [x0, x1, x2]\n\njulia> X = covered_scheme(P)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n 3: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [(x1//x0), (x2//x0), u, v]\n 2: [(x0//x1), (x2//x1), u, v]\n 3: [(x0//x2), (x1//x2), u, v]\n\njulia> U = first(affine_charts(X))\nSpectrum\n of multivariate polynomial ring in 4 variables (x1//x0), (x2//x0), u, v\n over rational field\n\njulia> phi = homogenization_map(P, U);\n\njulia> R = OO(U);\n\njulia> phi.(gens(R))\n4-element Vector{Tuple{MPolyDecRingElem{QQMPolyRingElem, AbstractAlgebra.Generic.MPoly{QQMPolyRingElem}}, MPolyDecRingElem{QQMPolyRingElem, AbstractAlgebra.Generic.MPoly{QQMPolyRingElem}}}}:\n (x1, x0)\n (x2, x0)\n (u, 1)\n (v, 1)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#Properties","page":"Projective schemes","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"Further properties of projective schemes (all self-explanatory):","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":" is_empty(P::AbsProjectiveScheme{<:Field})\n is_smooth(P::AbsProjectiveScheme)\n is_irreducible(P::AbsProjectiveScheme)\n is_reduced(P::AbsProjectiveScheme)\n is_geometrically_reduced(P::AbsProjectiveScheme{<:Field})\n is_geometrically_irreducible(P::AbsProjectiveScheme{<:Field})\n is_integral(X::AbsProjectiveScheme{<:Field})\n is_geometrically_integral(X::AbsProjectiveScheme{<:Field})","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/#Affine-Toric-Schemes","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"","category":"section"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/#Constructors","page":"Affine Toric Schemes","title":"Constructors","text":"","category":"section"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"We provide the following constructors for affine toric schemes:","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"toric_spec(antv::AffineNormalToricVariety)","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/#toric_spec-Tuple{AffineNormalToricVariety}","page":"Affine Toric Schemes","title":"toric_spec","text":"toric_spec(antv::AffineNormalToricVariety)\n\nConstructs the affine toric scheme (i.e. Spec of a ring) associated to an affine toric variety.\n\nExamples\n\njulia> C = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> antv = affine_normal_toric_variety(C)\nNormal, affine toric variety\n\njulia> toric_spec(antv)\nSpec of an affine toric variety\n\n\n\n\n\n","category":"method"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/#Attributes","page":"Affine Toric Schemes","title":"Attributes","text":"","category":"section"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"An affine toric scheme has all attributes of a normal toric scheme. In addition, there are the following special attributes, that we overload from the corresponding affine toric variety:","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"cone(XToricSpec),\ndual_cone(XToricSpec),\nhilbert_basis(XToricSpec),\ntoric_ideal(RMPolyRing XToricSpec),\ntoric_ideal(XToricSpec).","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/#Properties","page":"Affine Toric Schemes","title":"Properties","text":"","category":"section"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"For an affine toric scheme, all properties of normal toric schemes are supported.","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/#A-note-on-the-torus-inclusion-and-the-torus-action","page":"Affine Toric Schemes","title":"A note on the torus inclusion and the torus action","text":"","category":"section"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"Note that the torus_inclusions(X::ToricSpec) is not yet supported. For an affine toric scheme X, we envision that this function should return a list l containing the inclusions Tʳⁱ X of the different tori. ","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"Similarly, torus_action(X::ToricSpec) is not yet supported. For an affine toric scheme X with a dense open torus T this method should returns a quintuple of morphisms (pT, pX, incX, mult) consisting of the following:","category":"page"},{"location":"Experimental/ToricSchemes/affine_toric_schemes/","page":"Affine Toric Schemes","title":"Affine Toric Schemes","text":"the projection T X T of the product with the torus T to T,\nthe projection T X X,\nthe inclusion X T X taking x to (1 x),\nthe group action T X X.","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/#Generic-Laurent-polynomials","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"Laurent polynomials are similar to polynomials but can have terms of negative degrees, and form a ring denoted by Rx x^-1 where R is the coefficient ring.","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/#Generic-Laurent-polynomial-types","page":"Generic Laurent polynomials","title":"Generic Laurent polynomial types","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"AbstractAlgebra.jl provides a generic implementation of Laurent polynomials, built in terms of regular polynomials in the file src/generic/LaurentPoly.jl.","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"The type LaurentPolyWrap{T, ...} <: LaurentPolyRingElem{T} implements generic Laurent polynomials by wrapping regular polynomials: a Laurent polynomial l wraps a polynomial p and an integer n such that l = x^-n * p.","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"The corresponding parent type is LaurentPolyWrapRing{T, ...} <: LaurentPolynomialRing{T}.","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/#Abstract-types","page":"Generic Laurent polynomials","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"Two abstract types LaurentPolyRingElem{T} and LaurentPolynomialRing{T} are defined to represent Laurent polynomials and rings thereof, parameterized on a base ring T.","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/#Laurent-polynomials-ring-constructor","page":"Generic Laurent polynomials","title":"Laurent polynomials ring constructor","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"In order to instantiate Laurent polynomials, one must first construct the parent ring:","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"LaurentPolynomialRing","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/#LaurentPolynomialRing","page":"Generic Laurent polynomials","title":"LaurentPolynomialRing","text":"LaurentPolynomialRing(R::Ring, s::VarName)\n\nGiven a base ring R and string s specifying how the generator (variable) should be printed, return a tuple S, x representing the new Laurent polynomial ring S = Rx 1x and the generator x of the ring.\n\nExamples\n\njulia> R, x = LaurentPolynomialRing(ZZ, \"x\")\n(Univariate Laurent Polynomial Ring in x over Integers, x)\n\njulia> 2x^-3 + x^2\nx^2 + 2*x^-3\n\njulia> rand(R, -3:3, -9:9)\n-3*x^2 - 8*x + 4 + 3*x^-1 - 6*x^-2 + 9*x^-3\n\n\n\n\n\nLaurentPolynomialRing(R::AbstractAlgebra.Ring, s::Vector{T}; cached::Bool = true) where T <: VarName\n\nGiven a base ring R and an array of strings s specifying how the generators (variables) should be printed, return a tuple T, (x1, x2, ...) representing the new ring T = Rx1 1x1 x2 1x2 and the generators x1 x2 of the ring. By default the parent object T will depend only on R and x1, x2, ... and will be cached. Setting the optional argument cached to false will prevent the parent object T from being cached.\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/laurent_polynomial/#Basic-functionality","page":"Generic Laurent polynomials","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"Laurent polynomials implement the ring interface, and some methods from the polynomial interface, for example:","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/","page":"Generic Laurent polynomials","title":"Generic Laurent polynomials","text":"julia> R, x = LaurentPolynomialRing(ZZ, \"x\")\n(Univariate Laurent polynomial ring in x over integers, x)\n\njulia> var(R)\n:x\n\njulia> symbols(R)\n1-element Vector{Symbol}:\n :x\n\njulia> nvars(R)\n1\n\njulia> f = x^-2 + 2x\n2*x + x^-2\n\njulia> coeff.(f, -2:2)\n5-element Vector{BigInt}:\n 1\n 0\n 0\n 2\n 0\n\njulia> set_coefficient!(f, 3, ZZ(5))\n5*x^3 + 2*x + x^-2\n\njulia> is_gen(f)\nfalse\n\njulia> shift_left(f,2)\n5*x^5 + 2*x^3 + 1\n\njulia> map_coefficients(x->2x, f)\n10*x^3 + 4*x + 2*x^-2\n\njulia> change_base_ring(RealField, f)\n5.0*x^3 + 2.0*x + x^-2\n\njulia> leading_coefficient(f), trailing_coefficient(f)\n(5, 1)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/acb/#Fixed-precisioncomplex-balls","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Arbitrary precision complex ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Complex numbers are represented in rectangular form a+bi where ab are arb balls.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"The Arb complex field is constructed using the AcbField constructor. This constructs the parent object for the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"The types of complex boxes in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Library Field Element type Parent type\nArb mathbbC (boxes) acb AcbField","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"All the complex field types belong to the Field abstract type and the types of elements in this field, i.e. complex boxes in this case, belong to the FieldElem abstract type.","category":"page"},{"location":"Nemo/acb/#Complex-ball-functionality","page":"Fixed precisioncomplex balls","title":"Complex ball functionality","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"The complex balls in Nemo provide all the field functionality defined by AbstractAlgebra:.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Below, we document the additional functionality provided for complex balls.","category":"page"},{"location":"Nemo/acb/#Complex-field-constructors","page":"Fixed precisioncomplex balls","title":"Complex field constructors","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"In order to construct complex boxes in Nemo, one must first construct the Arb complex field itself. This is accomplished with the following constructor.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"AcbField(prec::Int)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Return the Arb complex field with precision in bits prec used for operations on interval midpoints. The precision used for interval radii is a fixed implementation-defined constant (30 bits).","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Here is an example of creating an Arb complex field and using the resulting parent object to coerce values into the resulting field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> a = CC(\"0.25\")\n0.25000000000000000000\n\njulia> b = CC(\"0.1\")\n[0.100000000000000000 +/- 1.22e-20]\n\njulia> c = CC(0.5)\n0.50000000000000000000\n\njulia> d = CC(12)\n12.000000000000000000","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Note that whilst one can coerce double precision floating point values into an Arb complex field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.","category":"page"},{"location":"Nemo/acb/#Constructors","page":"Fixed precisioncomplex balls","title":"Constructors","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"onei(::AcbField)","category":"page"},{"location":"Nemo/acb/#onei-Tuple{AcbField}","page":"Fixed precisioncomplex balls","title":"onei","text":"onei(r::AcbField)\n\nReturn exact one times i in the given Arb complex field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> c = onei(CC)\n1.0000000000000000000*im","category":"page"},{"location":"Nemo/acb/#Basic-functionality","page":"Fixed precisioncomplex balls","title":"Basic functionality","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"The following basic functionality is provided by the default Arb complex field implementation in Nemo, to support construction of generic rings over complex fields. Any custom complex field implementation in Nemo should provide analogues of these functions along with the usual arithmetic operations.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"parent_type(::Type{acb})","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Gives the type of the parent object of an Arb complex field element.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"elem_type(R::AcbField)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Given the parent object for an Arb complex field, return the type of elements of the field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"mul!(c::acb, a::acb, b::acb)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Multiply a by b and set the existing Arb complex field element c to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"addeq!(c::acb, a::acb)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"In-place addition adds a to c and sets c to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"deepcopy(a::acb)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Return a copy of the Arb complex field element a, recursively copying the internal data. Arb complex field elements are mutable in Nemo so a shallow copy is not sufficient.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Given the parent object R for an Arb complex field, the following coercion functions are provided to coerce various elements into the Arb complex field. Developers provide these by overloading the call operator for the complex field parent objects.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"R()","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Coerce zero into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"R(n::Integer)\nR(f::ZZRingElem)\nR(q::QQFieldElem)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Coerce an integer or rational value into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"R(f::Float64)\nR(f::BigFloat)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Coerce the given floating point number into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"R(f::AbstractString)\nR(f::AbstractString, g::AbstractString)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Coerce the decimal number, given as a string, into the Arb complex field. In each case f is the real part and g is the imaginary part.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"R(f::arb)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Coerce the given Arb real ball into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"R(f::acb)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Take an Arb complex field element that is already in an Arb field and simply return it. A copy of the original is not made.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Here are some examples of coercing elements into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\n\njulia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> a = CC(3)\n3.0000000000000000000\n\njulia> b = CC(QQ(2,3))\n[0.6666666666666666666 +/- 8.48e-20]\n\njulia> c = CC(\"3 +/- 0.0001\")\n[3.000 +/- 1.01e-4]\n\njulia> d = CC(\"-1.24e+12345\")\n[-1.240000000000000000e+12345 +/- 1.16e+12326]\n\njulia> f = CC(\"nan +/- inf\")\nnan\n\njulia> g = CC(RR(3))\n3.0000000000000000000","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"In addition to the above, developers of custom complex field types must ensure that they provide the equivalent of the function base_ring(R::AcbField) which should return Union{}. In addition to this they should ensure that each complex field element contains a field parent specifying the parent object of the complex field element, or at least supply the equivalent of the function parent(a::acb) to return the parent object of a complex field element.","category":"page"},{"location":"Nemo/acb/#Basic-manipulation","page":"Fixed precisioncomplex balls","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"isfinite(::acb)","category":"page"},{"location":"Nemo/acb/#isfinite-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"isfinite","text":"isfinite(x::acb)\n\nReturn true if x is finite, i.e. its real and imaginary parts have finite midpoint and radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"is_exact(::acb)","category":"page"},{"location":"Nemo/acb/#is_exact-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"is_exact","text":"is_exact(x::acb)\n\nReturn true if x is exact, i.e. has its real and imaginary parts have zero radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"isinteger(::acb)","category":"page"},{"location":"Nemo/acb/#isinteger-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"isinteger","text":"isinteger(x::acb)\n\nReturn true if x is an exact integer, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"accuracy_bits(::acb)","category":"page"},{"location":"Nemo/acb/#accuracy_bits-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"accuracy_bits","text":"accuracy_bits(x::acb)\n\nReturn the relative accuracy of x measured in bits, capped between typemax(Int) and -typemax(Int).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> a = CC(\"1.2 +/- 0.001\")\n[1.20 +/- 1.01e-3]\n\njulia> b = CC(3)\n3.0000000000000000000\n\njulia> isreal(a)\ntrue\n\njulia> isfinite(b)\ntrue\n\njulia> isinteger(b)\ntrue\n\njulia> c = real(a)\n[1.20 +/- 1.01e-3]\n\njulia> d = imag(b)\n0\n\njulia> f = accuracy_bits(a)\n9\n","category":"page"},{"location":"Nemo/acb/#Containment","page":"Fixed precisioncomplex balls","title":"Containment","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"It is often necessary to determine whether a given exact value or box is contained in a given complex box or whether two boxes overlap. The following functions are provided for this purpose.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"overlaps(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#overlaps-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"overlaps","text":"overlaps(x::acb, y::acb)\n\nReturns true if any part of the box x overlaps any part of the box y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"contains(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#contains-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"contains","text":"contains(x::acb, y::acb)\n\nReturns true if the box x contains the box y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"contains(::acb, ::Integer)\ncontains(::acb, ::ZZRingElem)\ncontains(::acb, ::QQFieldElem)","category":"page"},{"location":"Nemo/acb/#contains-Tuple{acb, Integer}","page":"Fixed precisioncomplex balls","title":"contains","text":"contains(x::acb, y::Integer)\n\nReturns true if the box x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/#contains-Tuple{acb, ZZRingElem}","page":"Fixed precisioncomplex balls","title":"contains","text":"contains(x::acb, y::ZZRingElem)\n\nReturns true if the box x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/#contains-Tuple{acb, QQFieldElem}","page":"Fixed precisioncomplex balls","title":"contains","text":"contains(x::acb, y::QQFieldElem)\n\nReturns true if the box x contains the given rational value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"The following functions are also provided for determining if a box intersects a certain part of the complex number plane.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"contains_zero(::acb)","category":"page"},{"location":"Nemo/acb/#contains_zero-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"contains_zero","text":"contains_zero(x::acb)\n\nReturns true if the box x contains zero, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> x = CC(\"1 +/- 0.001\")\n[1.00 +/- 1.01e-3]\n\njulia> y = CC(\"3\")\n3.0000000000000000000\n\njulia> overlaps(x, y)\nfalse\n\njulia> contains(x, y)\nfalse\n\njulia> contains(y, 3)\ntrue\n\njulia> contains(x, ZZ(1)//2)\nfalse\n\njulia> contains_zero(x)\nfalse","category":"page"},{"location":"Nemo/acb/#Comparison","page":"Fixed precisioncomplex balls","title":"Comparison","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Nemo provides a full range of comparison operations for Arb complex boxes. ","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"In addition to the standard comparisons, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"isequal(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#isequal-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"isequal","text":"isequal(x::acb, y::acb)\n\nReturn true if the boxes x and y are precisely equal, i.e. their real and imaginary parts have the same midpoints and radii.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"A full range of ad hoc comparison operators is provided. These are implemented directly in Julia, but we document them as though only == were provided.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Function\n==(x::acb, y::Integer)\n==(x::Integer, y::acb)\n==(x::acb, y::ZZRingElem)\n==(x::ZZRingElem, y::acb)\n==(x::arb, y::ZZRingElem)\n==(x::ZZRingElem, y::arb)\n==(x::acb, y::Float64)\n==(x::Float64, y::acb)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> x = CC(\"1 +/- 0.001\")\n[1.00 +/- 1.01e-3]\n\njulia> y = CC(\"3\")\n3.0000000000000000000\n\njulia> z = CC(\"4\")\n4.0000000000000000000\n\njulia> isequal(x, deepcopy(x))\ntrue\n\njulia> x == 3\nfalse\n\njulia> ZZ(3) == z\nfalse\n\njulia> x != 1.23\ntrue","category":"page"},{"location":"Nemo/acb/#Absolute-value","page":"Fixed precisioncomplex balls","title":"Absolute value","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> x = CC(\"-1 +/- 0.001\")\n[-1.00 +/- 1.01e-3]\n\njulia> a = abs(x)\n[1.00 +/- 1.01e-3]","category":"page"},{"location":"Nemo/acb/#Shifting","page":"Fixed precisioncomplex balls","title":"Shifting","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> x = CC(\"-3 +/- 0.001\")\n[-3.00 +/- 1.01e-3]\n\njulia> a = ldexp(x, 23)\n[-2.52e+7 +/- 4.26e+4]\n\njulia> b = ldexp(x, -ZZ(15))\n[-9.16e-5 +/- 7.78e-8]","category":"page"},{"location":"Nemo/acb/#Miscellaneous-operations","page":"Fixed precisioncomplex balls","title":"Miscellaneous operations","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"trim(::acb)","category":"page"},{"location":"Nemo/acb/#trim-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"trim","text":"trim(x::acb)\n\nReturn an acb box containing x but which may be more economical, by rounding off insignificant bits from midpoints.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"unique_integer(::acb)","category":"page"},{"location":"Nemo/acb/#unique_integer-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"unique_integer","text":"unique_integer(x::acb)\n\nReturn a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the box x contains a unique integer. If this is the case, the second return value is set to this unique integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> x = CC(\"-3 +/- 0.001\", \"0.1\")\n[-3.00 +/- 1.01e-3] + [0.100000000000000000 +/- 1.22e-20]*im\n\njulia> a = trim(x)\n[-3.00 +/- 1.01e-3] + [0.100000000000000000 +/- 1.22e-20]*im\n\njulia> b, c = unique_integer(x)\n(false, 0)\n\njulia> d = conj(x)\n[-3.00 +/- 1.01e-3] + [-0.100000000000000000 +/- 1.22e-20]*im\n\njulia> f = angle(x)\n[3.1083 +/- 3.95e-5]","category":"page"},{"location":"Nemo/acb/#Constants","page":"Fixed precisioncomplex balls","title":"Constants","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"const_pi(::AcbField)","category":"page"},{"location":"Nemo/acb/#const_pi-Tuple{AcbField}","page":"Fixed precisioncomplex balls","title":"const_pi","text":"const_pi(r::AcbField)\n\nReturn pi = 314159ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(200)\nComplex Field with 200 bits of precision and error bounds\n\njulia> a = const_pi(CC)\n[3.14159265358979323846264338327950288419716939937510582097494 +/- 5.73e-60]","category":"page"},{"location":"Nemo/acb/#Mathematical-and-special-functions","page":"Fixed precisioncomplex balls","title":"Mathematical and special functions","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"rsqrt(::acb)","category":"page"},{"location":"Nemo/acb/#rsqrt-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"rsqrt","text":"rsqrt(x::acb)\n\nReturn the reciprocal of the square root of x, i.e. 1sqrtx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"cispi(::acb)","category":"page"},{"location":"Nemo/acb/#cispi-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"cispi","text":"cispi(x::acb)\n\nReturn the exponential of pi i x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"root_of_unity(::AcbField, k::Int)","category":"page"},{"location":"Nemo/acb/#root_of_unity-Tuple{AcbField, Int64}","page":"Fixed precisioncomplex balls","title":"root_of_unity","text":"root_of_unity(C::AcbField, k::Int)\n\nReturn exp(2pi ik).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"log_sinpi(::acb)","category":"page"},{"location":"Nemo/acb/#log_sinpi-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"log_sinpi","text":"log_sinpi(x::acb)\n\nReturn logsin(pi x), constructed without branch cuts off the real line.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"gamma(::acb)","category":"page"},{"location":"Nemo/acb/#gamma-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"gamma","text":"gamma(x::acb)\n\nReturn the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"lgamma(::acb)","category":"page"},{"location":"Nemo/acb/#lgamma-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"lgamma","text":"lgamma(x::acb)\n\nReturn the logarithm of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"rgamma(::acb)","category":"page"},{"location":"Nemo/acb/#rgamma-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"rgamma","text":"rgamma(x::acb)\n\nReturn the reciprocal of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"digamma(::acb)","category":"page"},{"location":"Nemo/acb/#digamma-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"digamma","text":"digamma(x::acb)\n\nReturn the logarithmic derivative of the gamma function evaluated at x, i.e. psi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"zeta(::acb)","category":"page"},{"location":"Nemo/acb/#zeta-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"zeta","text":"zeta(x::acb)\n\nReturn the Riemann zeta function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"barnes_g(::acb)","category":"page"},{"location":"Nemo/acb/#barnes_g-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"barnes_g","text":"barnes_g(x::acb)\n\nReturn the Barnes G-function, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"log_barnes_g(::acb)","category":"page"},{"location":"Nemo/acb/#log_barnes_g-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"log_barnes_g","text":"log_barnes_g(x::acb)\n\nReturn the logarithm of the Barnes G-function, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"erf(::acb)","category":"page"},{"location":"Nemo/acb/#erf-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"erf","text":"erf(x::acb)\n\nReturn the error function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"erfi(::acb)","category":"page"},{"location":"Nemo/acb/#erfi-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"erfi","text":"erfi(x::acb)\n\nReturn the imaginary error function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"exp_integral_ei(::acb)","category":"page"},{"location":"Nemo/acb/#exp_integral_ei-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"exp_integral_ei","text":"exp_integral_ei(x::acb)\n\nReturn the exponential integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"sin_integral(::acb)","category":"page"},{"location":"Nemo/acb/#sin_integral-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"sin_integral","text":"sin_integral(x::acb)\n\nReturn the sine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"cos_integral(::acb)","category":"page"},{"location":"Nemo/acb/#cos_integral-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"cos_integral","text":"cos_integral(x::acb)\n\nReturn the exponential cosine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"sinh_integral(::acb)","category":"page"},{"location":"Nemo/acb/#sinh_integral-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"sinh_integral","text":"sinh_integral(x::acb)\n\nReturn the hyperbolic sine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"cosh_integral(::acb)","category":"page"},{"location":"Nemo/acb/#cosh_integral-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"cosh_integral","text":"cosh_integral(x::acb)\n\nReturn the hyperbolic cosine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"dedekind_eta(::acb)","category":"page"},{"location":"Nemo/acb/#dedekind_eta-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"dedekind_eta","text":"dedekind_eta(x::acb)\n\nReturn the Dedekind eta function eta(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"modular_weber_f(::acb)","category":"page"},{"location":"Nemo/acb/#modular_weber_f-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"modular_weber_f","text":"modular_weber_f(x::acb)\n\nReturn the modular Weber function mathfrakf(tau) = fraceta^2(tau)eta(tau2)eta(2tau) at x in the complex upper half plane.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"modular_weber_f1(::acb)","category":"page"},{"location":"Nemo/acb/#modular_weber_f1-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"modular_weber_f1","text":"modular_weber_f1(x::acb)\n\nReturn the modular Weber function mathfrakf_1(tau) = fraceta(tau2)eta(tau) at x in the complex upper half plane.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"modular_weber_f2(::acb)","category":"page"},{"location":"Nemo/acb/#modular_weber_f2-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"modular_weber_f2","text":"modular_weber_f2(x::acb)\n\nReturn the modular Weber function mathfrakf_2(tau) = fracsqrt2eta(2tau)eta(tau) at x in the complex upper half plane.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"j_invariant(::acb)","category":"page"},{"location":"Nemo/acb/#j_invariant-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"j_invariant","text":"j_invariant(x::acb)\n\nReturn the j-invariant j(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"modular_lambda(::acb)","category":"page"},{"location":"Nemo/acb/#modular_lambda-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"modular_lambda","text":"modular_lambda(x::acb)\n\nReturn the modular lambda function lambda(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"modular_delta(::acb)","category":"page"},{"location":"Nemo/acb/#modular_delta-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"modular_delta","text":"modular_delta(x::acb)\n\nReturn the modular delta function Delta(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"eisenstein_g(::Int, ::acb)","category":"page"},{"location":"Nemo/acb/#eisenstein_g-Tuple{Int64, acb}","page":"Fixed precisioncomplex balls","title":"eisenstein_g","text":"eisenstein_g(k::Int, x::acb)\n\nReturn the non-normalized Eisenstein series G_k(tau) of mathrmSL_2(mathbbZ). Also defined for tau = i infty.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"elliptic_k(::acb)","category":"page"},{"location":"Nemo/acb/#elliptic_k-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"elliptic_k","text":"elliptic_k(x::acb)\n\nReturn the complete elliptic integral K(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"elliptic_e(::acb)","category":"page"},{"location":"Nemo/acb/#elliptic_e-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"elliptic_e","text":"elliptic_e(x::acb)\n\nReturn the complete elliptic integral E(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"agm(::acb)\nagm(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#agm-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"agm","text":"agm(x::acb)\n\nReturn the arithmetic-geometric mean of 1 and x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/#agm-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"agm","text":"agm(x::acb, y::acb)\n\nReturn the arithmetic-geometric mean of x and y.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"polygamma(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#polygamma-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"polygamma","text":"polygamma(s::acb, a::acb)\n\nReturn the generalised polygamma function psi(sz).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"zeta(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#zeta-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"zeta","text":"zeta(s::acb, a::acb)\n\nReturn the Hurwitz zeta function zeta(sa).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"rising_factorial(::acb, ::Int)","category":"page"},{"location":"Nemo/acb/#rising_factorial-Tuple{acb, Int64}","page":"Fixed precisioncomplex balls","title":"rising_factorial","text":"rising_factorial(x::acb, n::Int)\n\nReturn the rising factorial x(x + 1)ldots (x + n - 1) as an Acb.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"rising_factorial2(::acb, ::Int)","category":"page"},{"location":"Nemo/acb/#rising_factorial2-Tuple{acb, Int64}","page":"Fixed precisioncomplex balls","title":"rising_factorial2","text":"rising_factorial2(x::acb, n::Int)\n\nReturn a tuple containing the rising factorial x(x + 1)ldots (x + n - 1) and its derivative.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"polylog(::Union{acb,Int}, ::acb)","category":"page"},{"location":"Nemo/acb/#polylog-Tuple{Union{Int64, acb}, acb}","page":"Fixed precisioncomplex balls","title":"polylog","text":"polylog(s::Union{acb,Int}, a::acb)\n\nReturn the polylogarithm Li_s(a).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"log_integral(::acb)","category":"page"},{"location":"Nemo/acb/#log_integral-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"log_integral","text":"log_integral(x::acb)\n\nReturn the logarithmic integral, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"log_integral_offset(::acb)","category":"page"},{"location":"Nemo/acb/#log_integral_offset-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"log_integral_offset","text":"log_integral_offset(x::acb)\n\nReturn the offset logarithmic integral, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"exp_integral_e(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#exp_integral_e-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"exp_integral_e","text":"exp_integral_e(s::acb, x::acb)\n\nReturn the generalised exponential integral E_s(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"gamma(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#gamma-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"gamma","text":"gamma(s::acb, x::acb)\n\nReturn the upper incomplete gamma function Gamma(sx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"gamma_regularized(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#gamma_regularized-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"gamma_regularized","text":"gamma_regularized(s::acb, x::acb)\n\nReturn the regularized upper incomplete gamma function Gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"gamma_lower(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#gamma_lower-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"gamma_lower","text":"gamma_lower(s::acb, x::acb)\n\nReturn the lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"gamma_lower_regularized(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#gamma_lower_regularized-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"gamma_lower_regularized","text":"gamma_lower_regularized(s::acb, x::acb)\n\nReturn the regularized lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"airy_ai(::acb)","category":"page"},{"location":"Nemo/acb/#airy_ai-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"airy_ai","text":"airy_ai(x::acb)\n\nReturn the Airy function operatornameAi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"airy_ai_prime(::acb)","category":"page"},{"location":"Nemo/acb/#airy_ai_prime-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"airy_ai_prime","text":"airy_ai_prime(x::acb)\n\nReturn the derivative of the Airy function operatornameAi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"airy_bi(::acb)","category":"page"},{"location":"Nemo/acb/#airy_bi-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"airy_bi","text":"airy_bi(x::acb)\n\nReturn the Airy function operatornameBi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"airy_bi_prime(::acb)","category":"page"},{"location":"Nemo/acb/#airy_bi_prime-Tuple{acb}","page":"Fixed precisioncomplex balls","title":"airy_bi_prime","text":"airy_bi_prime(x::acb)\n\nReturn the derivative of the Airy function operatornameBi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"bessel_j(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#bessel_j-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"bessel_j","text":"bessel_j(nu::acb, x::acb)\n\nReturn the Bessel function J_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"bessel_y(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#bessel_y-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"bessel_y","text":"bessel_y(nu::acb, x::acb)\n\nReturn the Bessel function Y_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"bessel_i(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#bessel_i-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"bessel_i","text":"bessel_i(nu::acb, x::acb)\n\nReturn the Bessel function I_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"bessel_k(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#bessel_k-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"bessel_k","text":"bessel_k(nu::acb, x::acb)\n\nReturn the Bessel function K_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"hypergeometric_1f1(::acb, ::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#hypergeometric_1f1-Tuple{acb, acb, acb}","page":"Fixed precisioncomplex balls","title":"hypergeometric_1f1","text":"hypergeometric_1f1(a::acb, b::acb, x::acb)\n\nReturn the confluent hypergeometric function _1F_1(abx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"hypergeometric_1f1_regularized(::acb, ::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#hypergeometric_1f1_regularized-Tuple{acb, acb, acb}","page":"Fixed precisioncomplex balls","title":"hypergeometric_1f1_regularized","text":"hypergeometric_1f1_regularized(a::acb, b::acb, x::acb)\n\nReturn the regularized confluent hypergeometric function _1F_1(abx) Gamma(b).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"hypergeometric_u(::acb, ::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#hypergeometric_u-Tuple{acb, acb, acb}","page":"Fixed precisioncomplex balls","title":"hypergeometric_u","text":"hypergeometric_u(a::acb, b::acb, x::acb)\n\nReturn the confluent hypergeometric function U(abx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"hypergeometric_2f1(::acb, ::acb, ::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#hypergeometric_2f1-NTuple{4, acb}","page":"Fixed precisioncomplex balls","title":"hypergeometric_2f1","text":"hypergeometric_2f1(a::acb, b::acb, c::acb, x::acb; flags=0)\n\nReturn the Gauss hypergeometric function _2F_1(abcx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"jacobi_theta(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#jacobi_theta-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"jacobi_theta","text":"jacobi_theta(z::acb, tau::acb)\n\nReturn a tuple of four elements containing the Jacobi theta function values theta_1 theta_2 theta_3 theta_4 evaluated at z tau.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"weierstrass_p(::acb, ::acb)","category":"page"},{"location":"Nemo/acb/#weierstrass_p-Tuple{acb, acb}","page":"Fixed precisioncomplex balls","title":"weierstrass_p","text":"weierstrass_p(z::acb, tau::acb)\n\nReturn the Weierstrass elliptic function wp(ztau).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"julia> CC = AcbField(64)\nComplex Field with 64 bits of precision and error bounds\n\njulia> s = CC(1, 2)\n1.0000000000000000000 + 2.0000000000000000000*im\n\njulia> z = CC(\"1.23\", \"3.45\")\n[1.230000000000000000 +/- 2.00e-19] + [3.450000000000000000 +/- 3.91e-19]*im\n\njulia> a = sin(z)^2 + cos(z)^2\n[1.000000000000000 +/- 4.92e-16] + [+/- 4.12e-16]*im\n\njulia> b = zeta(z)\n[0.685803329024164062 +/- 6.30e-19] + [-0.038574782404586856 +/- 7.54e-19]*im\n\njulia> c = bessel_j(s, z)\n[0.63189634741402481 +/- 4.85e-18] + [0.00970090757446076 +/- 4.66e-18]*im\n\njulia> d = hypergeometric_1f1(s, s+1, z)\n[-1.3355297330012291 +/- 5.83e-17] + [-0.1715020340928697 +/- 4.97e-17]*im","category":"page"},{"location":"Nemo/acb/#Linear-dependence","page":"Fixed precisioncomplex balls","title":"Linear dependence","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"lindep(::Vector{acb}, n::Int)","category":"page"},{"location":"Nemo/acb/#lindep-Tuple{Vector{acb}, Int64}","page":"Fixed precisioncomplex balls","title":"lindep","text":"lindep(A::Vector{acb}, bits::Int)\n\nFind a small linear combination of the entries of the array A that is small (using LLL). The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find linear dependence between a list of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"lindep(A::Matrix{acb}, bits::Int)","category":"page"},{"location":"Nemo/acb/#lindep-Tuple{Matrix{acb}, Int64}","page":"Fixed precisioncomplex balls","title":"lindep","text":"lindep(A::Matrix{acb}, bits::Int)\n\nFind a (common) small linear combination of the entries in each row of the array A, that is small (using LLL). It is assumed that the complex numbers in each row of the array share the same linear combination. The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find a common linear dependence shared across a number of lists of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the common linear combination.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precisioncomplex balls","title":"Fixed precisioncomplex balls","text":"CC = AcbField(128)\n\n# These are two of the roots of x^5 + 3x + 1\na = CC(1.0050669478588622428791051888364775253, - 0.93725915669289182697903585868761513585)\nb = CC(-0.33198902958450931620250069492231652319)\n\n# We recover the polynomial from one root....\nV1 = [CC(1), a, a^2, a^3, a^4, a^5];\nW = lindep(V1, 20)\n\n# ...or from two\nV2 = [CC(1), b, b^2, b^3, b^4, b^5];\nVs = [V1 V2]\nX = lindep(Vs, 20)","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/direct_sum/#Direct-Sums","page":"Direct Sums","title":"Direct Sums","text":"","category":"section"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"AbstractAlgebra allows the construction of the external direct sum of any nonempty vector of finitely presented modules.","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Note that external direct sums are considered equal iff they are the same object.","category":"page"},{"location":"AbstractAlgebra/direct_sum/#Generic-direct-sum-type","page":"Direct Sums","title":"Generic direct sum type","text":"","category":"section"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"AbstractAlgebra provides a generic direct sum type Generic.DirectSumModule{T} where T is the element type of the base ring. The implementation is in src/generic/DirectSum.jl","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Elements of direct sum modules have type Generic.DirectSumModuleElem{T}.","category":"page"},{"location":"AbstractAlgebra/direct_sum/#Abstract-types","page":"Direct Sums","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Direct sum module types belong to the abstract type FPModule{T} and their elements to FPModuleElem{T}.","category":"page"},{"location":"AbstractAlgebra/direct_sum/#Constructors","page":"Direct Sums","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"direct_sum","category":"page"},{"location":"AbstractAlgebra/direct_sum/#direct_sum","page":"Direct Sums","title":"direct_sum","text":"direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T\n\nGiven modules M_1dots M_n, say, return the direct sum bigoplus_i=1^n M_i. \n\nAdditionally, return \n\na vector containing the canonical injections M_itobigoplus_i=1^n M_i if task = :sum (default),\na vector containing the canonical projections bigoplus_i=1^n M_ito M_i if task = :prod,\ntwo vectors containing the canonical injections and projections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_sum(M::Matroid, N::Matroid)\n\nThe direct sum of the matroids M and N. Optionally one can also pass a vector of matroids.\n\nSee Section 4.2 of James Oxley (2011).\n\nTo obtain the direct sum of the Fano and a uniform matroid type:\n\nExamples\n\njulia> direct_sum(fano_matroid(), uniform_matroid(2,4))\nMatroid of rank 5 on 11 elements\n\nTo take the sum of three uniform matroids use:\n\nExamples\n\njulia> matroids = Vector([uniform_matroid(2,4), uniform_matroid(1,3), uniform_matroid(3,4)]);\n\njulia> M = direct_sum(matroids)\nMatroid of rank 6 on 11 elements\n\n\n\n\n\ndirect_sum(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}\ndirect_sum(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic spaces with isometries (V_1 f_1) ldots (V_n f_n), return the quadratic space with isometry (V f) together with the injections V_i to V, where V is the direct sum V = V_1 oplus ldots oplus V_n and f is the isometry of V induced by the diagonal actions of the f_i's.\n\nFor objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (V f) as a direct product with the projections V to V_i, one should call direct_product(x). If one wants to obtain (V f) as a biproduct with the injections V_i to V and the projections V to V_i, one should call biproduct(x).\n\nExamples\n\njulia> V1 = quadratic_space(QQ, QQ[2 5;\n 5 6])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[2 5]\n[5 6]\n\njulia> Vf1 = quadratic_space_with_isometry(V1, neg=true)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [-1 0]\n [ 0 -1]\n\njulia> V2 = quadratic_space(QQ, QQ[ 2 -1;\n -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> f = matrix(QQ, 2, 2, [1 1;\n 0 -1])\n[1 1]\n[0 -1]\n\njulia> Vf2 = quadratic_space_with_isometry(V2, f)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\njulia> Vf3, inj = direct_sum(Vf1, Vf2)\n(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 2\nCodomain:\n=========\nQuadratic space of dimension 4, Map with following data\nDomain:\n=======\nQuadratic space of dimension 2\nCodomain:\n=========\nQuadratic space of dimension 4])\n\njulia> Vf3\nQuadratic space of dimension 4\n with isometry of finite order 2\n given by\n [-1 0 0 0]\n [ 0 -1 0 0]\n [ 0 0 1 1]\n [ 0 0 0 -1]\n\njulia> space(Vf3)\nQuadratic space of dimension 4\n over rational field\nwith gram matrix\n[2 5 0 0]\n[5 6 0 0]\n[0 0 2 -1]\n[0 0 -1 2]\n\n\n\n\n\ndirect_sum(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor}\ndirect_sum(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor}\n\nGiven a collection of lattices with isometries (L_1 f_1) ldots (L_n f_n), return the lattice with isometry (L f) together with the injections L_i to L, where L is the direct sum L = L_1 oplus ldots oplus L_n and f is the isometry of L induced by the diagonal actions of the f_i's.\n\nFor objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (L f) as a direct product with the projections L to L_i, one should call direct_product(x). If one wants to obtain (L f) as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> g = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lg = integer_lattice_with_isometry(L, g)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 5\n given by\n [1 1 1 1 1]\n [0 -1 -1 -1 -1]\n [0 1 0 0 0]\n [0 0 1 0 0]\n [0 0 0 1 0]\n\njulia> Lh, inj = direct_sum(Lf, Lg)\n(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 5\nCodomain:\n=========\nQuadratic space of dimension 10, Map with following data\nDomain:\n=======\nQuadratic space of dimension 5\nCodomain:\n=========\nQuadratic space of dimension 10])\n\njulia> Lh\nInteger lattice of rank 10 and degree 10\n with isometry of finite order 10\n given by\n [ 1 0 0 0 0 0 0 0 0 0]\n [-1 -1 -1 -1 -1 0 0 0 0 0]\n [ 0 0 0 0 1 0 0 0 0 0]\n [ 0 0 0 1 0 0 0 0 0 0]\n [ 0 0 1 0 0 0 0 0 0 0]\n [ 0 0 0 0 0 1 1 1 1 1]\n [ 0 0 0 0 0 0 -1 -1 -1 -1]\n [ 0 0 0 0 0 0 1 0 0 0]\n [ 0 0 0 0 0 0 0 1 0 0]\n [ 0 0 0 0 0 0 0 0 1 0]\n\n\n\n\n\ndirect_sum(G::GrpAbFinGen, H::GrpAbFinGen, V::Vector{<:Map{GrpAbFinGen, GrpAbFinGen}})\n\nFor groups G = prod G_i and H = prod H_i as well as maps V_i: G_i -> H_i, build the induced map from G -> H.\n\n\n\n\n\ndirect_sum(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}\n⊕(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}\n\nConstruct the direct sum of the modules V....\n\n\n\n\n\ndirect_sum(G::GrpAbFinGen...) -> GrpAbFinGen, Vector{GrpAbFinGenMap}\n\nReturn the direct sum D of the (finitely many) abelian groups G_i, together with the injections G_i to D.\n\nFor finite abelian groups, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain D as a direct product together with the projections $ D \\to Gi$, one should call `directproduct(G...). If one wants to obtain $D$ as a biproduct together with the projections and the injections, one should callbiproduct(G...)`.\n\nOtherwise, one could also call canonical_injections(D) or canonical_projections(D) later on.\n\n\n\n\n\ndirect_sum(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}\ndirect_sum(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian spaces V_1 ldots V_n, return their direct sum V = V_1 oplus ldots oplus V_n, together with the injections V_i to V.\n\nFor objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct product with the projections V to V_i, one should call direct_product(x). If one wants to obtain V as a biproduct with the injections V_i to V and the projections V to V_i, one should call biproduct(x).\n\n\n\n\n\ndirect_sum(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}\ndirect_sum(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian lattices L_1 ldots L_n, return their direct sum L = L_1 oplus ldots oplus L_n, together with the injections L_i to L (seen as maps between the corresponding ambient spaces).\n\nFor objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections L to L_i, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\n\n\n\n\ndirect_sum(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}\ndirect_sum(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMor}\n\nGiven a collection of torsion quadratic modules T_1 ldots T_n, return their direct sum T = T_1oplus ldots oplus T_n, together with the injections T_i to T.\n\nFor objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct product with the projections T to T_i, one should call direct_product(x). If one wants to obtain T as a biproduct with the injections T_i to T and the projections T to T_i, one should call biproduct(x).\n\n\n\n\n\ndirect_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls\n\nReturn the isometry class of the direct sum of two representatives.\n\n\n\n\n\ndirect_sum(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}\ndirect_sum(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}\n\nGiven a collection of mathbb Z-lattices L_1 ldots L_n, return their direct sum L = L_1 oplus ldots oplus L_n, together with the injections L_i to L. (seen as maps between the corresponding ambient spaces).\n\nFor objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections L to L_i, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\n\n\n\n\ndirect_sum(S1::ZZLocalGenus, S2::ZZLocalGenus) -> ZZLocalGenus\n\nReturn the local genus of the direct sum of two representatives.\n\n\n\n\n\ndirect_sum(G1::ZZGenus, G2::ZZGenus) -> ZZGenus\n\nReturn the genus of the direct sum of G1 and G2.\n\nThe direct sum is defined via representatives.\n\n\n\n\n\ndirect_sum(g1::HermLocalGenus, g2::HermLocalGenus) -> HermLocalGenus\n\nGiven two local genus symbols g1 and g2 for hermitian lattices over EK at the same prime ideal mathfrak p of mathcal O_K, return their direct sum. It corresponds to the local genus symbol of the mathfrak p-adic completion of the direct sum of respective representatives of g1 and g2.\n\n\n\n\n\ndirect_sum(G1::HermGenus, G2::HermGenus) -> HermGenus\n\nGiven two global genus symbols G1 and G2 for hermitian lattices over EK, return their direct sum. It corresponds to the global genus symbol of the direct sum of respective representatives of G1 and G2.\n\n\n\n\n\ndirect_sum(m::Vector{<:FPModule{T}}) where T <: RingElement\ndirect_sum(vals::FPModule{T}...) where T <: RingElement\n\nReturn a tuple M f g consisting of M the direct sum of the modules m (supplied as a vector of modules), a vector f of the injections of the mi into M and a vector g of the projections from M onto the mi.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Examples","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"julia> F = FreeModule(ZZ, 5)\nFree module of rank 5 over integers\n\njulia> m1 = F(BigInt[4, 7, 8, 2, 6])\n(4, 7, 8, 2, 6)\n\njulia> m2 = F(BigInt[9, 7, -2, 2, -4])\n(9, 7, -2, 2, -4)\n\njulia> S1, f1 = sub(F, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)\n\njulia> m1 = F(BigInt[3, 1, 7, 7, -7])\n(3, 1, 7, 7, -7)\n\njulia> m2 = F(BigInt[-8, 6, 10, -1, 1])\n(-8, 6, 10, -1, 1)\n\njulia> S2, f2 = sub(F, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)\n\njulia> m1 = F(BigInt[2, 4, 2, -3, -10])\n(2, 4, 2, -3, -10)\n\njulia> m2 = F(BigInt[5, 7, -6, 9, -5])\n(5, 7, -6, 9, -5)\n\njulia> S3, f3 = sub(F, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)\n\njulia> D, f = direct_sum(S1, S2, S3)\n(DirectSumModule over integers, AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule], AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations])","category":"page"},{"location":"AbstractAlgebra/direct_sum/#Functionality-for-direct-sums","page":"Direct Sums","title":"Functionality for direct sums","text":"","category":"section"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"In addition to the Module interface, AbstractAlgebra direct sums implement the following functionality.","category":"page"},{"location":"AbstractAlgebra/direct_sum/#Basic-manipulation","page":"Direct Sums","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"summands(::Generic.DirectSumModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/direct_sum/#summands-Union{Tuple{AbstractAlgebra.Generic.DirectSumModule{T}}, Tuple{T}} where T<:RingElement","page":"Direct Sums","title":"summands","text":"summands(M::DirectSumModule{T}) where T <: RingElement\n\nReturn the modules that this module is a direct sum of.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Examples","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"julia> F = FreeModule(ZZ, 5)\nFree module of rank 5 over integers\n\njulia> m1 = F(BigInt[4, 7, 8, 2, 6])\n(4, 7, 8, 2, 6)\n\njulia> m2 = F(BigInt[9, 7, -2, 2, -4])\n(9, 7, -2, 2, -4)\n\njulia> S1, f1 = sub(F, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)\n\njulia> m1 = F(BigInt[3, 1, 7, 7, -7])\n(3, 1, 7, 7, -7)\n\njulia> m2 = F(BigInt[-8, 6, 10, -1, 1])\n(-8, 6, 10, -1, 1)\n\njulia> S2, f2 = sub(F, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)\n\njulia> m1 = F(BigInt[2, 4, 2, -3, -10])\n(2, 4, 2, -3, -10)\n\njulia> m2 = F(BigInt[5, 7, -6, 9, -5])\n(5, 7, -6, 9, -5)\n\njulia> S3, f3 = sub(F, [m1, m2])\n(Submodule over Integers with 2 generators and no relations, Hom: Submodule over Integers with 2 generators and no relations -> Free module of rank 5 over integers)\n\njulia> D, f = direct_sum(S1, S2, S3)\n(DirectSumModule over integers, AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule, Hom: Submodule over Integers with 2 generators and no relations -> DirectSumModule], AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations, Hom: DirectSumModule -> Submodule over Integers with 2 generators and no relations])\n\njulia> summands(D)\n3-element Vector{AbstractAlgebra.Generic.Submodule{BigInt}}:\n Submodule over Integers with 2 generators and no relations\n Submodule over Integers with 2 generators and no relations\n Submodule over Integers with 2 generators and no relations","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":" (D::DirectSumModule{T}(::Vector{<:FPModuleElem{T}}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Given a vector (or 1-dim array) of module elements, where the i-th entry has to be an element of the i-summand of D, create the corresponding element in D.","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Examples","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"julia> N = FreeModule(QQ, 1);\n\njulia> M = FreeModule(QQ, 2);\n\njulia> D, _ = direct_sum(M, N, M);\n\njulia> D([gen(M, 1), gen(N, 1), gen(M, 2)])\n(1//1, 0//1, 1//1, 0//1, 1//1)","category":"page"},{"location":"AbstractAlgebra/direct_sum/#Special-Homomorphisms","page":"Direct Sums","title":"Special Homomorphisms","text":"","category":"section"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Due to the special structure as direct sums, homomorphisms can be created by specifying homomorphisms for all summands. In case of the codmain being a direct sum as well, any homomorphism may be thought of as a matrix containing maps from the i-th source summand to the j-th target module:","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"ModuleHomomorphism(D::DirectSumModule{T}, S::DirectSumModule{T}, m::Matrix{Any}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Given a matrix m such that the (ij)-th entry is either 0 (Int(0)) or a ModuleHomomorphism from the i-th summand of D to the j-th summand of S, construct the corresponding homomorphism.","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"ModuleHomomorphism(D::DirectSumModule{T}, S::FPModuleElem{T}, m::Vector{ModuleHomomorphism})","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Given an array a of ModuleHomomorphism such that a_i, the i-th entry of a is a ModuleHomomorphism from the i-th summand of D into S, construct the direct sum of the components.","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Given a matrix m such that the (ij)-th entry is either 0 (Int(0)) or a ModuleHomomorphism from the i-th summand of D to the j-th summand of S, construct the corresponding homomorphism.","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"Examples","category":"page"},{"location":"AbstractAlgebra/direct_sum/","page":"Direct Sums","title":"Direct Sums","text":"julia> N = FreeModule(QQ, 2);\n\njulia> D, _ = direct_sum(N, N);\n\njulia> p = ModuleHomomorphism(N, N, [3,4] .* basis(N));\n\njulia> q = ModuleHomomorphism(N, N, [5,7] .* basis(N));\n\njulia> phi = ModuleHomomorphism(D, D, [p 0; 0 q])\nModule homomorphism\n from DirectSumModule over rationals\n to DirectSumModule over rationals\n\njulia> r = ModuleHomomorphism(N, D, [2,3] .* gens(D)[1:2])\nModule homomorphism\n from vector space of dimension 2 over rationals\n to DirectSumModule over rationals\n\njulia> psi = ModuleHomomorphism(D, D, [r, r])\nModule homomorphism\n from DirectSumModule over rationals\n to DirectSumModule over rationals","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Binomial-Primary-Decomposition","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Introduction","page":"Binomial Primary Decomposition","title":"Introduction","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"A binomial is a polynomial consisting of at most two terms. A binomial ideal is an ideal which can be generated by binomials. A binomial primary decomposition is a primary decomposition of a binomial ideal into primary ideals which are binomial as well. In this section, focusing on polynomial rings over fields, we discuss functionality for computing such decompositions.","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"We begin by recalling that a proper ideal I of a polynomial ring Kx_1 dots x_n over a field K is called cellular if each variable x_i is either a nonzerodivisor or nilpotent modulo I. In this case, we refer to the nonzerodivisors among the variables as the cell variables with respect to I. A cellular decomposition of a proper binomial ideal I of Kx_1 dots x_n is a decomposition of I into cellular binomial ideals. Using Noetherian induction, it is not too difficult to show that such decompositions exist. ","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"With this notation, the algorithms for computing binomial primary decompositions proceed in two main steps:","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"First, compute a cellular decomposition of the given binomial ideal.\nThen, decompose each cellular component into primary binomial ideals.","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"While the first step can be performed over any ground field for which Gröbner bases are implemented, the second step may require a field extension: From a theoretical point of view, the existence of binomial primary decompositions is only guaranteed if the ground field is algebraically closed.","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"note: Note\nA pure difference binomial is a binomial which is the difference of two monomials. A unital binomial ideal is an ideal which can be generated by pure difference binomials and monomials. Note that cellular components of unital binomial ideals are unital as well. For unital binomial ideals in mathbb Qx_1 dots x_n, binomial primary decompositions exist already over cyclotomic extensions of mathbb Q. In particular, any such ideal can be decomposed over the abelian closure mathbb Q^textab of mathbb Q. While OSCAR offers functionality for doing this, computing binomial primary decompositions in other cases is not yet supported. See the number theory chapter for how to deal with mathbb Q^textab.","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"note: Note\nBinomial primary decompositions computed with OSCAR are not necessarily minimal.","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"Papers offering details on theory and algorithms as well as examples include:","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"David Eisenbud, Bernd Sturmfels (1996)\nIgnacio Ojeda Martínez de Castilla, Ramón Peidra Sánchez (2000)\nThomas Kahle (2010)\nZekiye Sahin Eser, Laura Felicia Matusevich (2016)\nZekiye Sahin Eser, Laura Felicia Matusevich (2019)","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Basic-Tests","page":"Binomial Primary Decomposition","title":"Basic Tests","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Binomiality-Test","page":"Binomial Primary Decomposition","title":"Binomiality Test","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"is_binomial(f::MPolyRingElem)\nis_binomial(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#is_binomial-Tuple{MPolyRingElem}","page":"Binomial Primary Decomposition","title":"is_binomial","text":"is_binomial(f::MPolyRingElem)\n\nReturn true if f consists of at most 2 terms, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#is_binomial-Tuple{MPolyIdeal}","page":"Binomial Primary Decomposition","title":"is_binomial","text":"is_binomial(I::MPolyIdeal)\n\nReturn true if I can be generated by polynomials consisting of at most 2 terms, false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> f = 2*x+y\n2*x + y\n\njulia> is_binomial(f)\ntrue\n\njulia> J = ideal(R, [x^2-y^3, z^2])\nideal(x^2 - y^3, z^2)\n\njulia> is_binomial(J)\ntrue\n","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Cellularity-Test","page":"Binomial Primary Decomposition","title":"Cellularity Test","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"is_cellular(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#is_cellular-Tuple{MPolyIdeal}","page":"Binomial Primary Decomposition","title":"is_cellular","text":"is_cellular(I::MPolyIdeal)\n\nGiven a binomial ideal I, return true together with the indices of the cell variables if I is cellular. Return false together with the index of a variable which is a zerodivisor but not nilpotent modulo I, otherwise (return (false, [-1]) if I is not proper).\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:6)\n(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])\n\njulia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])\nideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])\n\njulia> is_cellular(I)\n(true, [1, 2, 3, 4])\n\njulia> R, (x,y,z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x-y,x^3-1,z*y^2-z])\nideal(x - y, x^3 - 1, y^2*z - z)\n\njulia> is_cellular(I)\n(false, [3])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Unitality-Test","page":"Binomial Primary Decomposition","title":"Unitality Test","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"is_unital(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#is_unital-Tuple{MPolyIdeal}","page":"Binomial Primary Decomposition","title":"is_unital","text":"is_unital(I::MPolyIdeal)\n\nGiven a binomial ideal I, return true if I can be generated by differences of monomials and monomials.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x+y])\nideal(x + y)\n\njulia> is_unital(I)\nfalse\n\njulia> J = ideal(R, [x^2-y^3, z^2])\nideal(x^2 - y^3, z^2)\n\njulia> is_unital(J)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Cellular-Decomposition","page":"Binomial Primary Decomposition","title":"Cellular Decomposition","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"cellular_decomposition(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#cellular_decomposition-Tuple{MPolyIdeal}","page":"Binomial Primary Decomposition","title":"cellular_decomposition","text":"cellular_decomposition(I::MPolyIdeal)\n\nGiven a binomial ideal I, return a cellular decomposition of I.\n\nExamples\n\njulia> R, (x,y,z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x-y,x^3-1,z*y^2-z])\nideal(x - y, x^3 - 1, y^2*z - z)\n\njulia> cellular_decomposition(I)\n2-element Vector{MPolyIdeal{QQMPolyRingElem}}:\n ideal(y - 1, x - 1)\n ideal(x - y, x^3 - 1, y^2*z - z, z)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Primary-Decomposition-of-Cellular-Ideals","page":"Binomial Primary Decomposition","title":"Primary Decomposition of Cellular Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"cellular_hull(I::MPolyIdeal{QQMPolyRingElem})\ncellular_associated_primes(I::MPolyIdeal{QQMPolyRingElem})\ncellular_minimal_associated_primes(I::MPolyIdeal{QQMPolyRingElem})\ncellular_primary_decomposition(I::MPolyIdeal{QQMPolyRingElem})","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#cellular_hull-Tuple{MPolyIdeal{QQMPolyRingElem}}","page":"Binomial Primary Decomposition","title":"cellular_hull","text":"cellular_hull(I::MPolyIdeal{QQMPolyRingElem})\n\nGiven a cellular binomial ideal I, return the intersection of the minimal primary components of I.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:6)\n(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])\n\njulia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])\nideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])\n\njulia> is_cellular(I)\n(true, [1, 2, 3, 4])\n\njulia> cellular_hull(I)\nideal(x[6], x[5])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#cellular_associated_primes-Tuple{MPolyIdeal{QQMPolyRingElem}}","page":"Binomial Primary Decomposition","title":"cellular_associated_primes","text":"cellular_associated_primes(I::MPolyIdeal{QQMPolyRingElem})\n\nGiven a cellular binomial ideal I, return the associated primes of I.\n\nThe result is defined over the abelian closure of mathbb Q. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:6)\n(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])\n\njulia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])\nideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])\n\njulia> cellular_associated_primes(I)\n5-element Vector{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}:\n ideal(x[5], x[6])\n ideal(x[1] - x[2], x[5], x[6])\n ideal(x[1] - zeta(3)*x[2], x[5], x[6])\n ideal(x[1] + (zeta(3) + 1)*x[2], x[5], x[6])\n ideal(x[3] - x[4], x[5], x[6])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#cellular_minimal_associated_primes-Tuple{MPolyIdeal{QQMPolyRingElem}}","page":"Binomial Primary Decomposition","title":"cellular_minimal_associated_primes","text":"cellular_minimal_associated_primes(I::MPolyIdeal{QQMPolyRingElem})\n\nGiven a cellular binomial ideal I, return the minimal associated primes of I.\n\nThe result is defined over the abelian closure of mathbb Q. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:6)\n(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])\n\njulia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])\nideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])\n\njulia> cellular_minimal_associated_primes(I::MPolyIdeal{QQMPolyRingElem})\n1-element Vector{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}:\n ideal(x[5], x[6])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#cellular_primary_decomposition-Tuple{MPolyIdeal{QQMPolyRingElem}}","page":"Binomial Primary Decomposition","title":"cellular_primary_decomposition","text":"cellular_primary_decomposition(I::MPolyIdeal{QQMPolyRingElem})\n\nGiven a cellular binomial ideal I, return a binomial primary decomposition of I.\n\nThe result is defined over the abelian closure of mathbb Q. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\" => 1:6)\n(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x[1], x[2], x[3], x[4], x[5], x[6]])\n\njulia> I = ideal(R, [x[5]*(x[1]^3-x[2]^3), x[6]*(x[3]-x[4]), x[5]^2, x[6]^2, x[5]*x[6]])\nideal(x[1]^3*x[5] - x[2]^3*x[5], x[3]*x[6] - x[4]*x[6], x[5]^2, x[6]^2, x[5]*x[6])\n\njulia> cellular_primary_decomposition(I)\n5-element Vector{Tuple{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}}:\n (ideal(x[6], x[5]), ideal(x[5], x[6]))\n (ideal(x[6], x[1] - x[2], x[5]^2), ideal(x[1] - x[2], x[5], x[6]))\n (ideal(x[6], x[1] - zeta(3)*x[2], x[5]^2), ideal(x[1] - zeta(3)*x[2], x[5], x[6]))\n (ideal(x[6], x[1] + (zeta(3) + 1)*x[2], x[5]^2), ideal(x[1] + (zeta(3) + 1)*x[2], x[5], x[6]))\n (ideal(x[5], x[3] - x[4], x[6]^2), ideal(x[3] - x[4], x[5], x[6]))\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#Primary-Decomposition-of-Binomial-Ideals","page":"Binomial Primary Decomposition","title":"Primary Decomposition of Binomial Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/","page":"Binomial Primary Decomposition","title":"Binomial Primary Decomposition","text":"binomial_primary_decomposition(I::MPolyIdeal{QQMPolyRingElem})","category":"page"},{"location":"CommutativeAlgebra/Miscellaneous/binomial_ideals/#binomial_primary_decomposition-Tuple{MPolyIdeal{QQMPolyRingElem}}","page":"Binomial Primary Decomposition","title":"binomial_primary_decomposition","text":"binomial_primary_decomposition(I::MPolyIdeal{QQMPolyRingElem})\n\nGiven a binomial ideal I, return a binomial primary decomposition of I.\n\nThe result is defined over the abelian closure of mathbb Q. In the output, if needed, the generator for roots of unities is denoted by zeta. So zeta(3), for example, stands for a primitive third root of unity.\n\nExamples\n\njulia> R, (x,y,z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x-y,x^3-1,z*y^2-z])\nideal(x - y, x^3 - 1, y^2*z - z)\n\njulia> binomial_primary_decomposition(I)\n3-element Vector{Tuple{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbElem{nf_elem}}}}}:\n (ideal(z, y - zeta(3), x - zeta(3)), ideal(y - zeta(3), x - zeta(3), z))\n (ideal(z, y + zeta(3) + 1, x + zeta(3) + 1), ideal(y + zeta(3) + 1, x + zeta(3) + 1, z))\n (ideal(y - 1, x - 1), ideal(y - 1, x - 1, x*y - 1))\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/perm/#Permutations-and-Symmetric-groups","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"AbstractAlgebra.jl provides rudimentary native support for permutation groups (implemented in src/generic/PermGroups.jl). All functionality of permutations is accessible in the Generic submodule.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Permutations are represented internally via vector of integers, wrapped in type Perm{T}, where T<:Integer carries the information on the type of elements of a permutation. Symmetric groups are singleton parent objects of type SymmetricGroup{T} and are used mostly to store the length of a permutation, since it is not included in the permutation type.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Symmetric groups are created using the SymmetricGroup (inner) constructor.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Both SymmetricGroup and Perm and can be parametrized by any type T<:Integer . By default the parameter is the Int-type native to the systems architecture. However, if you are sure that your permutations are small enough to fit into smaller integer type (such as Int32, UInt16, or even Int8), you may choose to change the parametrizing type accordingly. In practice this may result in decreased memory footprint (when storing multiple permutations) and noticeable faster performance, if your workload is heavy in operations on permutations, which e.g. does not fit into cache of your cpu.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"All the permutation group types belong to the Group abstract type and the corresponding permutation element types belong to the GroupElem abstract type.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Generic.setpermstyle","category":"page"},{"location":"AbstractAlgebra/perm/#setpermstyle","page":"Permutations and Symmetric groups","title":"setpermstyle","text":"setpermstyle(format::Symbol)\n\nSelect the style in which permutations are displayed (in the REPL or in general as strings). This can be either\n\n:array - as vector of integers whose n-th position represents the value at n), or\n:cycles - as, more familiar for mathematicians, decomposition into disjoint cycles, where the value at n is represented by the entry immediately following n in a cycle (the default).\n\nThe difference is purely esthetical.\n\nExamples\n\njulia> setpermstyle(:array)\n:array\n\njulia> Perm([2,3,1,5,4])\n[2, 3, 1, 5, 4]\n\njulia> setpermstyle(:cycles)\n:cycles\n\njulia> Perm([2,3,1,5,4])\n(1,2,3)(4,5)\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/perm/#Permutations-constructors","page":"Permutations and Symmetric groups","title":"Permutations constructors","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"There are several methods to construct permutations in AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"The easiest way is to directly call to the Perm (inner) constructor:","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Generic.Perm","category":"page"},{"location":"AbstractAlgebra/perm/#Perm","page":"Permutations and Symmetric groups","title":"Perm","text":"Perm{T<:Integer}\n\nThe type of permutations. Fieldnames:\n\nd::Vector{T} - vector representing the permutation\nmodified::Bool - bit to check the validity of cycle decomposition\ncycles::CycleDec{T} - (cached) cycle decomposition\n\nA permutation p consists of a vector (p.d) of n integers from 1 to n. If the i-th entry of the vector is j, this corresponds to p sending i to j. The cycle decomposition (p.cycles) is computed on demand and should never be accessed directly. Use cycles(p) instead.\n\nThere are two inner constructors of Perm:\n\nPerm(n::T) constructs the trivial Perm{T}-permutation of length n.\nPerm(v::AbstractVector{<:Integer} [,check=true]) constructs a permutation represented by v. By default Perm constructor checks if the vector constitutes a valid permutation. To skip the check call Perm(v, false).\n\nExamples\n\njulia> Perm([1,2,3])\n()\n \njulia> g = Perm(Int32[2,3,1])\n(1,2,3)\n\njulia> typeof(g)\nPerm{Int32}\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Since the parent object can be reconstructed from the permutation itself, you can work with permutations without explicitly constructing the parent object.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"The other way is to first construct the permutation group they belong to. This is accomplished with the inner constructor SymmetricGroup(n::Integer) which constructs the permutation group on n symbols and returns the parent object representing the group.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Generic.SymmetricGroup","category":"page"},{"location":"AbstractAlgebra/perm/#SymmetricGroup","page":"Permutations and Symmetric groups","title":"SymmetricGroup","text":"SymmetricGroup{T<:Integer}\n\nThe full symmetric group singleton type. SymmetricGroup(n) constructs the full symmetric group S_n on n-symbols. The type of elements of the group is inferred from the type of n.\n\nExamples\n\njulia> G = SymmetricGroup(5)\nFull symmetric group over 5 elements\n\njulia> elem_type(G)\nPerm{Int64}\n\njulia> H = SymmetricGroup(UInt16(5))\nFull symmetric group over 5 elements\n\njulia> elem_type(H)\nPerm{UInt16}\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"A vector of integers can be then coerced to a permutation by calling a parent permutation group on it. The advantage is that the vector is automatically converted to the integer type fixed at the creation of the parent object.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Examples:","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"julia> G = SymmetricGroup(BigInt(5)); p = G([2,3,1,5,4])\n(1,2,3)(4,5)\n\njulia> typeof(p)\nPerm{BigInt}\n\njulia> H = SymmetricGroup(UInt16(5)); r = H([2,3,1,5,4])\n(1,2,3)(4,5)\n\njulia> typeof(r)\nPerm{UInt16}\n\njulia> one(H)\n()","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"By default the coercion checks for non-unique values in the vector, but this can be switched off with G([2,3,1,5,4], false).","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Finally there is a perm\"...\" string macro to construct a permutation from a string input.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"@perm_str","category":"page"},{"location":"AbstractAlgebra/perm/#@perm_str","page":"Permutations and Symmetric groups","title":"@perm_str","text":"perm\"...\"\n\nString macro to parse disjoint cycles into Perm{Int}.\n\nStrings for the output of GAP could be copied directly into perm\"...\". Cycles of length 1 are not necessary, but can be included. A permutation of the minimal support is constructed, i.e. the maximal n in the decomposition determines the parent group S_n.\n\nExamples\n\njulia> p = perm\"(1,3)(2,4)\"\n(1,3)(2,4)\n\njulia> typeof(p)\nPerm{Int64}\n\njulia> parent(p) == SymmetricGroup(4)\ntrue\n\njulia> p = perm\"(1,3)(2,4)(10)\"\n(1,3)(2,4)\n\njulia> parent(p) == SymmetricGroup(10)\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"AbstractAlgebra/perm/#Permutation-interface","page":"Permutations and Symmetric groups","title":"Permutation interface","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"The following basic functionality is provided by the default permutation group implementation in AbstractAlgebra.jl, to support construction of other generic constructions over permutation groups. Any custom permutation group implementation in AbstractAlgebra.jl should provide the group element arithmetic and comparison.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"A custom implementation also needs to implement hash(::Perm, ::UInt) and (possibly) deepcopy_internal(::Perm, ::IdDict).","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"note: Note\nPermutation group elements are mutable and so returning shallow copies is not sufficient.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"getindex(a::Perm, n::Integer)","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Allow access to entry n of the given permutation via the syntax a[n]. Note that entries are 1-indexed.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"setindex!(a::Perm, d::Integer, n::Integer)","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Set the n-th entry of the given permutation to d. This allows Julia to provide the syntax a[n] = d for setting entries of a permutation. Entries are 1-indexed.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"note: Note\nUsing setindex! invalidates the cycle decomposition cached in a permutation, which will be computed the next time it is needed.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Given the parent object G for a permutation group, the following coercion functions are provided to coerce various arguments into the permutation group. Developers provide these by overloading the permutation group parent objects.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"one(G)","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Return the identity permutation.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"G(A::Vector{<:Integer})","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Return the permutation whose entries are given by the elements of the supplied vector.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"G(p::Perm)","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Take a permutation that is already in the permutation group and simply return it. A copy of the original is not made if not necessary.","category":"page"},{"location":"AbstractAlgebra/perm/#Basic-manipulation","page":"Permutations and Symmetric groups","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Numerous functions are provided to manipulate permutation group elements.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"cycles(::Perm)","category":"page"},{"location":"AbstractAlgebra/perm/#cycles-Tuple{Perm}","page":"Permutations and Symmetric groups","title":"cycles","text":"cycles(g::Perm)\n\nDecompose permutation g into disjoint cycles.\n\nReturn a CycleDec object which iterates over disjoint cycles of g. The ordering of cycles is not guaranteed, and the order within each cycle is computed up to a cyclic permutation. The cycle decomposition is cached in g and used in future computation of permtype, parity, sign, order and ^ (powering).\n\nExamples\n\njulia> g = Perm([3,4,5,2,1,6])\n(1,3,5)(2,4)\n\njulia> collect(cycles(g))\n3-element Vector{Vector{Int64}}:\n [1, 3, 5]\n [2, 4]\n [6]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Cycle structure is cached in a permutation, since once available, it provides a convenient shortcut in many other algorithms.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"parity(::Perm)\nsign(::Perm)\npermtype(::Perm)","category":"page"},{"location":"AbstractAlgebra/perm/#parity-Tuple{Perm}","page":"Permutations and Symmetric groups","title":"parity","text":"parity(g::Perm)\n\nReturn the parity of the given permutation, i.e. the parity of the number of transpositions in any decomposition of g into transpositions.\n\nparity returns 1 if the number is odd and 0 otherwise. parity uses cycle decomposition of g if already available, but will not compute it on demand. Since cycle structure is cached in g you may call cycles(g) before calling parity.\n\nExamples\n\njulia> g = Perm([3,4,1,2,5])\n(1,3)(2,4)\n\njulia> parity(g)\n0\n\njulia> g = Perm([3,4,5,2,1,6])\n(1,3,5)(2,4)\n\njulia> parity(g)\n1\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#sign-Tuple{Perm}","page":"Permutations and Symmetric groups","title":"sign","text":"sign(g::Perm)\n\nReturn the sign of a permutation.\n\nsign returns 1 if g is even and -1 if g is odd. sign represents the homomorphism from the permutation group to the unit group of mathbbZ whose kernel is the alternating group.\n\nExamples\n\njulia> g = Perm([3,4,1,2,5])\n(1,3)(2,4)\n\njulia> sign(g)\n1\n\njulia> g = Perm([3,4,5,2,1,6])\n(1,3,5)(2,4)\n\njulia> sign(g)\n-1\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#permtype-Tuple{Perm}","page":"Permutations and Symmetric groups","title":"permtype","text":"permtype(g::Perm)\n\nReturn the type of permutation g, i.e. lengths of disjoint cycles in cycle decomposition of g.\n\nThe lengths are sorted in decreasing order by default. permtype(g) fully determines the conjugacy class of g.\n\nExamples\n\njulia> g = Perm([3,4,5,2,1,6])\n(1,3,5)(2,4)\n\njulia> permtype(g)\n3-element Vector{Int64}:\n 3\n 2\n 1\n\njulia> e = one(g)\n()\n\njulia> permtype(e)\n6-element Vector{Int64}:\n 1\n 1\n 1\n 1\n 1\n 1\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Additionally GroupsCore.jl package provides more functionality, notably functions gens and order. You may consult its documentation. Note that even an Int64 can be easily overflowed when computing with symmetric groups. Thus, by default, order returns (always correct) BigInts. If you are sure that the computation will not overflow, you may use order(::Type{T}, ...) to perform computations with machine integers. Julia's standard promotion rules apply for the returned value.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Since SymmetricGroup implements the iterator protocol, you may iterate over all permutations via a simple loop:","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"for p in SymmetricGroup(n)\n ...\nend","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Iteration over all permutations in reasonable time, (i.e. in terms of minutes) is possible when n 13.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"You may also use the non-allocating Generic.elements! function for n 14 (or even 15 if you are patient enough), which is an order of magnitude faster.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Generic.elements!(::Generic.SymmetricGroup)","category":"page"},{"location":"AbstractAlgebra/perm/#elements!-Tuple{AbstractAlgebra.Generic.SymmetricGroup}","page":"Permutations and Symmetric groups","title":"elements!","text":"Generic.elements!(G::SymmetricGroup)\n\nReturn an unsafe iterator over all permutations in G. Only one permutation is allocated and then modified in-place using the non-recursive Heaps algorithm.\n\nNote: you need to explicitly copy permutations intended to be stored or modified.\n\nExamples\n\njulia> elts = Generic.elements!(SymmetricGroup(5));\n\n\njulia> length(elts)\n120\n\njulia> for p in Generic.elements!(SymmetricGroup(3))\n println(p)\n end\n()\n(1,2)\n(1,3,2)\n(2,3)\n(1,2,3)\n(1,3)\n\njulia> A = collect(Generic.elements!(SymmetricGroup(3))); A\n6-element Vector{Perm{Int64}}:\n (1,3)\n (1,3)\n (1,3)\n (1,3)\n (1,3)\n (1,3)\n\njulia> unique(A)\n1-element Vector{Perm{Int64}}:\n (1,3)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"However, since all permutations yielded by elements! are aliased (modified \"in-place\"), collect(Generic.elements!(SymmetricGroup(n))) returns a vector of identical permutations.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"note: Note\nIf you intend to use or store elements yielded by elements! you need to deepcopy them explicitly.","category":"page"},{"location":"AbstractAlgebra/perm/#Arithmetic-operators","page":"Permutations and Symmetric groups","title":"Arithmetic operators","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"*(::Perm{T}, ::Perm{T}) where T\n^(::Perm, n::Integer)\nBase.inv(::Perm)","category":"page"},{"location":"AbstractAlgebra/perm/#*-Union{Tuple{T}, Tuple{Perm{T}, Perm{T}}} where T","page":"Permutations and Symmetric groups","title":"*","text":"*(g::Perm, h::Perm)\n\nReturn the composition h g of two permutations.\n\nThis corresponds to the action of permutation group on the set [1..n] on the right and follows the convention of GAP.\n\nIf g and h are parametrized by different types, the result is promoted accordingly.\n\nExamples\n\njulia> Perm([2,3,1,4])*Perm([1,3,4,2]) # (1,2,3)*(2,3,4)\n(1,3)(2,4)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#^-Tuple{Perm, Integer}","page":"Permutations and Symmetric groups","title":"^","text":"^(g::Perm, n::Integer)\n\nReturn the n-th power of a permutation g.\n\nBy default g^n is computed by cycle decomposition of g if n > 3. Generic.power_by_squaring provides a different method for powering which may or may not be faster, depending on the particular case. Due to caching of the cycle structure, repeated powering of g will be faster with the default method.\n\nExamples\n\njulia> g = Perm([2,3,4,5,1])\n(1,2,3,4,5)\n\njulia> g^3\n(1,4,2,5,3)\n\njulia> g^5\n()\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#inv-Tuple{Perm}","page":"Permutations and Symmetric groups","title":"inv","text":"Base.inv(g::Perm)\n\nReturn the inverse of the given permutation, i.e. the permutation g^-1 such that g g^-1 = g^-1 g is the identity permutation.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Permutations parametrized by different types can be multiplied, and follow the standard julia integer promotion rules:","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"g = rand(SymmetricGroup(Int8(5)));\nh = rand(SymmetricGroup(UInt32(5)));\ntypeof(g*h)\n\n# output\nPerm{UInt32}","category":"page"},{"location":"AbstractAlgebra/perm/#Coercion","page":"Permutations and Symmetric groups","title":"Coercion","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"The following coercions are available for G::SymmetricGroup parent objects. Each of the methods perform basic sanity checks on the input which can be switched off by the second argument.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Examples","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"(G::SymmetricGroup)(::AbstractVector{<:Integer}[, check=true])","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Turn a vector of integers into a permutation (performing conversion, if necessary).","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"(G::SymmetricGroup)(::Perm[, check=true])","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Coerce a permutation p into group G (performing the conversion, if necessary). If p is already an element of G no copy is performed.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"(G::SymmetricGroup)(::String[, check=true])","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Parse the string input e.g. copied from the output of GAP. The method uses the same logic as the perm\"...\" macro. The string is sanitized and checked for disjoint cycles. Both string(p::Perm) (if setpermstyle(:cycles)) and string(cycles(p::Perm)) are valid input for this method.","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"(G::SymmetricGroup{T})(::CycleDec{T}[, check=true]) where T","category":"page"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"Turn a cycle decomposition object into a permutation.","category":"page"},{"location":"AbstractAlgebra/perm/#Comparison","page":"Permutations and Symmetric groups","title":"Comparison","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"==(::Perm, ::Perm)\n==(::Generic.SymmetricGroup, ::Generic.SymmetricGroup)","category":"page"},{"location":"AbstractAlgebra/perm/#==-Tuple{Perm, Perm}","page":"Permutations and Symmetric groups","title":"==","text":"==(g::Perm, h::Perm)\n\nReturn true if permutations are equal, otherwise return false.\n\nPermutations parametrized by different integer types are considered equal if they define the same permutation in the abstract permutation group.\n\nExamples\n\njulia> g = Perm(Int8[2,3,1])\n(1,2,3)\n\njulia> h = perm\"(3,1,2)\"\n(1,2,3)\n\njulia> g == h\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#==-Tuple{AbstractAlgebra.Generic.SymmetricGroup, AbstractAlgebra.Generic.SymmetricGroup}","page":"Permutations and Symmetric groups","title":"==","text":"==(G::SymmetricGroup, H::SymmetricGroup)\n\nReturn true if permutation groups are equal, otherwise return false.\n\nPermutation groups on the same number of letters, but parametrized by different integer types are considered different.\n\nExamples\n\njulia> G = SymmetricGroup(UInt(5))\nPermutation group over 5 elements\n\njulia> H = SymmetricGroup(5)\nPermutation group over 5 elements\n\njulia> G == H\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#Misc","page":"Permutations and Symmetric groups","title":"Misc","text":"","category":"section"},{"location":"AbstractAlgebra/perm/","page":"Permutations and Symmetric groups","title":"Permutations and Symmetric groups","text":"rand(::Generic.SymmetricGroup)\nGeneric.matrix_repr(::Perm)\nGeneric.emb(::Generic.SymmetricGroup, ::Vector{Int}, ::Bool)\nGeneric.emb!(::Perm, ::Perm, V)","category":"page"},{"location":"AbstractAlgebra/perm/#rand-Tuple{AbstractAlgebra.Generic.SymmetricGroup}","page":"Permutations and Symmetric groups","title":"rand","text":"rand([rng=GLOBAL_RNG,] G::SymmetricGroup)\n\nReturn a random permutation from G.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#matrix_repr-Tuple{Perm}","page":"Permutations and Symmetric groups","title":"matrix_repr","text":"matrix_repr(a::Perm)\n\nReturn the permutation matrix as a sparse matrix representing a via natural embedding of the permutation group into the general linear group over mathbbZ.\n\nExamples\n\njulia> p = Perm([2,3,1])\n(1,2,3)\n\njulia> matrix_repr(p)\n3×3 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n ⋅ 1 ⋅\n ⋅ ⋅ 1\n 1 ⋅ ⋅\n\njulia> Array(ans)\n3×3 Matrix{Int64}:\n 0 1 0\n 0 0 1\n 1 0 0\n\n\n\n\n\nmatrix_repr(Y::YoungTableau)\n\nConstruct sparse integer matrix representing the tableau.\n\nExamples\n\njulia> y = YoungTableau([4,3,1]);\n\n\njulia> matrix_repr(y)\n3×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 8 stored entries:\n 1 2 3 4\n 5 6 7 ⋅\n 8 ⋅ ⋅ ⋅\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#emb-Tuple{AbstractAlgebra.Generic.SymmetricGroup, Vector{Int64}, Bool}","page":"Permutations and Symmetric groups","title":"emb","text":"emb(G::SymmetricGroup, V::Vector{Int}, check::Bool=true)\n\nReturn the natural embedding of a permutation group into G as the subgroup permuting points indexed by V.\n\nExamples\n\njulia> p = Perm([2,3,1])\n(1,2,3)\n\njulia> f = Generic.emb(SymmetricGroup(5), [3,2,5]);\n\n\njulia> f(p)\n(2,5,3)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/perm/#emb!-Tuple{Perm, Perm, Any}","page":"Permutations and Symmetric groups","title":"emb!","text":"emb!(result::Perm, p::Perm, V)\n\nEmbed permutation p into permutation result on the indices given by V.\n\nThis corresponds to the natural embedding of S_k into S_n as the subgroup permuting points indexed by V.\n\nExamples\n\njulia> p = Perm([2,1,4,3])\n(1,2)(3,4)\n\njulia> Generic.emb!(Perm(collect(1:5)), p, [3,1,4,5])\n(1,3)(4,5)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#Projective-Algebraic-Sets","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"For finitely many homogeneous polynomials f_1dots f_r in kx_0dots x_n, and I=(f_1dots f_n) leq kx_0dots x_n the homogeneous ideal they generate, we denote by X = V(I) subseteq mathbbP^n the projective algebraic set defined by I and call k its base field.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"Let mathbbP^n(k)=(k^n+1setminus0)k^* be the set of k-points of projective space of dimension n. If k subseteq K is any field extension, we denote the set of K-points of X by","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"beginalignedX(K) = P in mathbbP^n(K) mid f_1(P)=dots = f_n(P)=0\n=P in mathbbP^n(K) mid forall fin I f(P)=0endaligned","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"Most properties of the projective variety X refer to X(K) where K is an algebraically closed field. Just like for affine schemes there are a few exceptions to this rule, for instance, whether X is irreducible or not depends on its base field. See is_irreducible(X::AbsProjectiveScheme) for details. Further exceptions are documented in the individual methods.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#Relation-to-schemes","page":"Projective Algebraic Sets","title":"Relation to schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"One can view a projective algebraic set as a scheme. See Projective schemes.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"More formally we define a projective algebraic set as follows:","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"AbsProjectiveAlgebraicSet","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#AbsProjectiveAlgebraicSet","page":"Projective Algebraic Sets","title":"AbsProjectiveAlgebraicSet","text":"AbsProjectiveAlgebraicSet <: AbsProjectiveScheme\n\nA projective, geometrically reduced scheme of finite type over a field.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#Constructors","page":"Projective Algebraic Sets","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"Projective algebraic sets can be created from homogeneous polynomials and homogeneous ideals in standard graded rings.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"algebraic_set(I::MPolyIdeal{<:MPolyDecRingElem}; check::Bool=true)\nalgebraic_set(p::MPolyDecRingElem; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#algebraic_set-Tuple{MPolyIdeal{<:MPolyDecRingElem}}","page":"Projective Algebraic Sets","title":"algebraic_set","text":"algebraic_set(I::MPolyIdeal{MPolyDecRingElem})\n\nReturn the projrective algebraic set defined by the homogeneous ideal I.\n\njulia> P,(x0,x1) = graded_polynomial_ring(QQ,[:x0,:x1]);\n\njulia> algebraic_set(ideal([x0,x1]))\nAlgebraic set\n in projective 1-space over QQ with coordinates [x0, x1]\ndefined by ideal(x1, x0)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#algebraic_set-Tuple{MPolyDecRingElem}","page":"Projective Algebraic Sets","title":"algebraic_set","text":"algebraic_set(p::MPolyDecRingElem; check::Bool=true)\n\nReturn the projective algebraic set defined by the homogeneous polynomial p.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"Algebraic sets can also be constructed from projective schemes.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"algebraic_set(X::AbsProjectiveScheme; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#algebraic_set-Tuple{AbsProjectiveScheme}","page":"Projective Algebraic Sets","title":"algebraic_set","text":"algebraic_set(X::AbsProjectiveScheme; is_reduced::Bool=false, check::Bool=true) -> ProjectiveAlgebraicSet\n\nConvert X to a ProjectiveAlgebraicSet by considering its underlying reduced scheme.\n\nIf is_reduced is true assume that X is already reduced.\n\njulia> P, (x0, x1, x2) = graded_polynomial_ring(QQ,[:x0,:x1,:x2]);\n\njulia> X = projective_scheme(ideal([x0*x1^2, x2]))\nProjective scheme\n over rational field\ndefined by ideal(x0*x1^2, x2)\n\njulia> Y = algebraic_set(X)\nAlgebraic set\n in projective 2-space over QQ with coordinates [x0, x1, x2]\ndefined by ideal(x2, x0*x1)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"set_theoretic_intersection(X::AbsProjectiveAlgebraicSet, Y::AbsProjectiveAlgebraicSet)\nirreducible_components(X::AbsProjectiveAlgebraicSet)\ngeometric_irreducible_components(X::AbsProjectiveAlgebraicSet)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#set_theoretic_intersection-Tuple{AbsProjectiveAlgebraicSet, AbsProjectiveAlgebraicSet}","page":"Projective Algebraic Sets","title":"set_theoretic_intersection","text":"set_theoretic_intersection(X::AbsProjectiveAlgebraicSet, Y::AbsProjectiveAlgebraicSet) -> AbsProjectiveAlgebraicSet\n\nReturn the set theoretic intersection of X and Y as as algebraic sets in projective space.\n\nThis is the reduced subscheme of the scheme theoretic intersection.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#irreducible_components-Tuple{AbsProjectiveAlgebraicSet}","page":"Projective Algebraic Sets","title":"irreducible_components","text":"irreducible_components(X::AbsProjectiveAlgebraicSet) -> Vector{ProjectiveVariety}\n\nReturn the irreducible components of X defined over the base field of X.\n\nNote that even if X is irreducible, there may be several geometrically irreducible components.\n\njulia> P1 = projective_space(QQ,1)\nProjective space of dimension 1\n over rational field\nwith homogeneous coordinates [s0, s1]\n\njulia> (s0,s1) = homogeneous_coordinates(P1);\n\njulia> X = algebraic_set((s0^2+s1^2)*s1)\nAlgebraic set\n in projective 1-space over QQ with coordinates [s0, s1]\ndefined by ideal(s0^2*s1 + s1^3)\n\njulia> (X1,X2) = irreducible_components(X)\n2-element Vector{ProjectiveAlgebraicSet{QQField, MPolyQuoRing{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}}:\n V(s0^2 + s1^2)\n V(s1)\n\njulia> X1 # irreducible but not geometrically irreducible\nAlgebraic set\n in projective 1-space over QQ with coordinates [s0, s1]\ndefined by ideal(s0^2 + s1^2)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#geometric_irreducible_components-Tuple{AbsProjectiveAlgebraicSet}","page":"Projective Algebraic Sets","title":"geometric_irreducible_components","text":"geometric_irreducible_components(X::AbsProjectiveAlgebraicSet) -> Vector{ProjectiveVariety}\n\nReturn the geometrically irreducible components of X.\n\nThey are the irreducible components of X seen over an algebraically closed field.\n\nThis is expensive and involves taking field extensions.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#Attributes","page":"Projective Algebraic Sets","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"In addition to the attributes inherited from Projective schemes the following are available.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"vanishing_ideal(X::AbsProjectiveAlgebraicSet)\nfat_ideal(X::AbsProjectiveAlgebraicSet)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#vanishing_ideal-Tuple{AbsProjectiveAlgebraicSet}","page":"Projective Algebraic Sets","title":"vanishing_ideal","text":"vanishing_ideal(X::AbsProjectiveAlgebraicSet) -> Ideal\n\nReturn the ideal of all homogeneous polynomials vanishing in X.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#fat_ideal-Tuple{AbsProjectiveAlgebraicSet}","page":"Projective Algebraic Sets","title":"fat_ideal","text":"fat_ideal(X::AbsProjectiveAlgebraicSet) -> Ideal\n\nReturn a homogenous ideal whose radical is the vanishing ideal of X.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#Methods","page":"Projective Algebraic Sets","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"Inherited from Projective schemes","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/#Properties","page":"Projective Algebraic Sets","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/","page":"Projective Algebraic Sets","title":"Projective Algebraic Sets","text":"Inherited from Projective schemes","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/residue/#Residue-rings","page":"Residue rings","title":"Residue rings","text":"","category":"section"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"Nemo allows the creation of residue rings of the form R(a) for an element a of a ring R.","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"We don't require (a) to be a prime or maximal ideal. Instead, we allow the creation of the residue ring R(a) for any nonzero a and simply raise an exception if an impossible inverse is encountered during computations involving elements of R(a). Of course, a GCD function must be available for the base ring R.","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"There is a generic implementation of residue rings of this form in AbstractAlgebra.jl, which accepts any ring R as base ring.","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"The associated types of parent object and elements for each kind of residue rings in Nemo are given in the following table.","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl Generic.ResidueRingElem{T} Generic.ResidueRing{T}\nmathbbZ (Int modulus) Flint zzModRingElem zzModRing\nmathbbZ (ZZ modulus) Flint ZZModRingElem ZZModRing","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"The modulus a of a residue ring is stored in its parent object.","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"All residue element types belong to the abstract type ResElem and all the residue ring parent object types belong to the abstract type ResidueRing. This enables one to write generic functions that accept any Nemo residue type.","category":"page"},{"location":"Nemo/residue/#Residue-functionality","page":"Residue rings","title":"Residue functionality","text":"","category":"section"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"All the residue rings in Nemo provide the functionality described in AbstractAlgebra for residue rings:","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/residue","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"In addition, generic residue rings are available.","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"We describe Nemo specific residue ring functionality below.","category":"page"},{"location":"Nemo/residue/#GCD","page":"Residue rings","title":"GCD","text":"","category":"section"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"gcdx(::zzModRingElem, ::zzModRingElem)\ngcdx(::ZZModRingElem, ::ZZModRingElem)","category":"page"},{"location":"Nemo/residue/#gcdx-Tuple{zzModRingElem, zzModRingElem}","page":"Residue rings","title":"gcdx","text":"gcdx(a::zzModRingElem, b::zzModRingElem)\n\nCompute the extended gcd with the Euclidean structure inherited from mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/residue/#gcdx-Tuple{ZZModRingElem, ZZModRingElem}","page":"Residue rings","title":"gcdx","text":"gcdx(a::ZZModRingElem, b::ZZModRingElem)\n\nCompute the extended gcd with the Euclidean structure inherited from mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"Examples","category":"page"},{"location":"Nemo/residue/","page":"Residue rings","title":"Residue rings","text":"julia> R = residue_ring(ZZ, 123456789012345678949)\nIntegers modulo 123456789012345678949\n\njulia> g, s, t = gcdx(R(123), R(456))\n(1, 123456789012345678928, 41152263004115226322)","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/rand/#Random-interface","page":"Random interface","title":"Random interface","text":"","category":"section"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"AbstractAlgebra makes use of the Julia Random interface for random generation.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"In addition we make use of an experimental package RandomExtensions.jl for extending the random interface in Julia.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"The latter is required because some of our types require more than one argument to specify how to randomise them.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"The usual way of generating random values that Julia and these extensions provide would look as follows:","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"julia> using AbstractAlgebra\n\njulia> using Random\n\njulia> using RandomExtensions\n\njulia> S, x = polynomial_ring(ZZ, \"x\")\n(Univariate Polynomial Ring in x over Integers, x)\n\njulia> rand(Random.GLOBAL_RNG, make(S, 1:3, -10:10))\n-5*x + 4","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"This example generates a polynomial over the integers with degree in the range 1 to 3 and with coefficients in the range -10 to 10.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"In addition we implement shortened versions for ease of use which don't require creating a make instance or passing in the standard RNG.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"julia> using AbstractAlgebra\n\njulia> S, x = polynomial_ring(ZZ, \"x\")\n(Univariate Polynomial Ring in x over Integers, x)\n\njulia> rand(S, 1:3, -10:10)\n-5*x + 4","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"Because rings can be constructed over other rings in a tower, all of this is supported by defining RandomExtensions.make instances that break the various levels of the ring down into separate make instances.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"For example, here is the implementation of make for polynomial rings such as the above:","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"function RandomExtensions.make(S::PolyRing, deg_range::UnitRange{Int}, vs...)\n R = base_ring(S)\n if length(vs) == 1 && elem_type(R) == Random.gentype(vs[1])\n Make(S, deg_range, vs[1]) # forward to default Make constructor\n else\n make(S, deg_range, make(R, vs...))\n end\nend","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"As you can see, it has two cases. The first is where this invocation of make is already at the bottom of the tower of rings, in which case it just forwards to the default Make constructor.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"The second case expects that we are higher up in the tower of rings and that make needs to be broken up (recursively) into the part that deals with the ring level we are at and the level that deals with the base ring.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"To help make we tell it the type of object we are hoping to randomly generate.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"RandomExtensions.maketype(S::PolyRing, dr::UnitRange{Int}, _) = elem_type(S)","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"Finally we implement the actual random generation itself.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"# define rand for make(S, deg_range, v)\nfunction rand(rng::AbstractRNG, sp::SamplerTrivial{<:Make3{<:RingElement,<:PolyRing,UnitRange{Int}}})\n S, deg_range, v = sp[][1:end]\n R = base_ring(S)\n f = S()\n x = gen(S)\n # degree -1 is zero polynomial\n deg = rand(rng, deg_range)\n if deg == -1\n return f\n end\n for i = 0:deg - 1\n f += rand(rng, v)*x^i\n end\n # ensure leading coefficient is nonzero\n c = R()\n while iszero(c)\n c = rand(rng, v)\n end\n f += c*x^deg\n return f\nend","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"Note that when generating random elements of the base ring for example, one should use the random number generator rng that is passed in.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"As mentioned above, we define a simplified random generator that saves the user having to create make instances.","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"rand(rng::AbstractRNG, S::PolyRing, deg_range::UnitRange{Int}, v...) =\n rand(rng, make(S, deg_range, v...))\n\nrand(S::PolyRing, degs, v...) = rand(Random.GLOBAL_RNG, S, degs, v...)","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"To test whether a random generator is working properly, the test_rand function exists in the AbstractAlgebra test submodule in the file test/runtests.jl. For example, in AbstractAlgebra test code:","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"using Test\n\nR, x = polynomial_ring(ZZ, \"x\")\n\ntest_rand(R, -1:10, -10:10)","category":"page"},{"location":"AbstractAlgebra/rand/","page":"Random interface","title":"Random interface","text":"In general, we try to use UnitRange's to specify how 'big' we want the random instance to be, e.g. the range of degrees a polynomial could take, the range random integers could lie in, etc. The objective is to make it easy for the user to control the 'size' of random values in test code.","category":"page"},{"location":"StraightLinePrograms/abstractalgebra/#AbstractAlgebra's-polynomial-interface","page":"AbstractAlgebra's polynomial interface","title":"AbstractAlgebra's polynomial interface","text":"","category":"section"},{"location":"StraightLinePrograms/abstractalgebra/","page":"AbstractAlgebra's polynomial interface","title":"AbstractAlgebra's polynomial interface","text":"This is the initial API of SLPs which hasn't been updated in a while and might not work as-is with the current state of the package.","category":"page"},{"location":"StraightLinePrograms/abstractalgebra/","page":"AbstractAlgebra's polynomial interface","title":"AbstractAlgebra's polynomial interface","text":"Currently, SLPs have a polynomial interface (SLPoly).","category":"page"},{"location":"StraightLinePrograms/abstractalgebra/#Examples","page":"AbstractAlgebra's polynomial interface","title":"Examples","text":"","category":"section"},{"location":"StraightLinePrograms/abstractalgebra/","page":"AbstractAlgebra's polynomial interface","title":"AbstractAlgebra's polynomial interface","text":"julia> using AbstractAlgebra, StraightLinePrograms, BenchmarkTools;\n\njulia> S = SLPolyRing(zz, [:x, :y]); x, y = gens(S)\n2-element Vector{SLPoly{Int64,SLPolyRing{Int64,AbstractAlgebra.Integers{Int64}}}}:\n x\n y\n\njulia> p = 3 + 2x * y^2 # each line of the SLP is shown with current value\n #1 = * 2 x ==> (2x)\n #2 = ^ y 2 ==> y^2\n #3 = * #1 #2 ==> (2xy^2)\n #4 = + 3 #3 ==> (3 + (2xy^2))\n\njulia> p.cs # constants used in the program\n2-element Vector{Int64}:\n 3\n 2\n\njulia> p.lines # each line is a UInt64 encoding an opcode and 2 arguments\n Line(0x0500000028000001)\n Line(0x8780000020000002)\n Line(0x0500000030000004)\n Line(0x0300000010000005)\n\njulia> SLP.evaluate(p, [2, 3])\n39\n\njulia> p2 = (p*(x*y))^6\n#1 = * 2 x ==> (2x)\n#2 = ^ y 2 ==> y^2\n#3 = * #1 #2 ==> (2xy^2)\n#4 = + 3 #3 ==> (3 + (2xy^2))\n#5 = * x y ==> (xy)\n#6 = * #4 #5 ==> ((3 + (2xy^2))xy)\n#7 = ^ #6 6 ==> ((3 + (2xy^2))xy)^6\n\njulia> R, (x1, y1) = polynomial_ring(zz, [\"x\", \"y\"]); R\nMultivariate Polynomial Ring in x, y over Integers\n\njulia> q = convert(R, p2)\n64*x^12*y^18+576*x^11*y^16+2160*x^10*y^14+4320*x^9*y^12+4860*x^8*y^10+2916*x^7*y^8+729*x^6*y^6\n\njulia> v = [3, 5]; @btime SLP.evaluate($q, $v)\n 32.101 μs (634 allocations: 45.45 KiB)\n-1458502820125772303\n\njulia> @btime SLP.evaluate($p2, $v)\n 270.341 ns (4 allocations: 352 bytes)\n-1458502820125772303\n\njulia> res = Int[]; @btime StraightLinePrograms.evaluate!($res, $p2, $v)\n 171.013 ns (0 allocations: 0 bytes)\n-1458502820125772303\n\njulia> res # intermediate computations (first 2 elements are constants)\n9-element Vector{Int64}:\n 3\n 2\n 6\n 25\n 150\n 153\n 15\n 2295\n -1458502820125772303\n\njulia> f2 = StraightLinePrograms.compile!(p2) # compile to machine code\n#3 (generic function with 1 method)\n\njulia> @btime SLP.evaluate($p2, $v)\n 31.153 ns (1 allocation: 16 bytes)\n-1458502820125772303\n\njulia> @btime $f2($v) # use a function barrier for last bit of efficiency\n 7.980 ns (0 allocations: 0 bytes)\n-1458502820125772303\n\njulia> q\n64*x^12*y^18+576*x^11*y^16+2160*x^10*y^14+4320*x^9*y^12+4860*x^8*y^10+2916*x^7*y^8+729*x^6*y^6\n\njulia> p3 = convert(S, q) # convert back q::Mpoly to an SLPoly\n #1 = ^ x 6 ==> x^6\n #2 = ^ x 7 ==> x^7\n #3 = ^ x 8 ==> x^8\n #4 = ^ x 9 ==> x^9\n #5 = ^ x 10 ==> x^10\n #6 = ^ x 11 ==> x^11\n #7 = ^ x 12 ==> x^12\n #8 = ^ y 6 ==> y^6\n #9 = ^ y 8 ==> y^8\n#10 = ^ y 10 ==> y^10\n#11 = ^ y 12 ==> y^12\n#12 = ^ y 14 ==> y^14\n#13 = ^ y 16 ==> y^16\n#14 = ^ y 18 ==> y^18\n#15 = * 64 #7 ==> (64x^12)\n#16 = * #15 #14 ==> (64x^12y^18)\n#17 = * 576 #6 ==> (576x^11)\n#18 = * #17 #13 ==> (576x^11y^16)\n#19 = + #16 #18 ==> ((64x^12y^18) + (576x^11y^16))\n#20 = * 2160 #5 ==> (2160x^10)\n#21 = * #20 #12 ==> (2160x^10y^14)\n#22 = + #19 #21 ==> ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14))\n#23 = * 4320 #4 ==> (4320x^9)\n#24 = * #23 #11 ==> (4320x^9y^12)\n#25 = + #22 #24 ==> ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12))\n#26 = * 4860 #3 ==> (4860x^8)\n#27 = * #26 #10 ==> (4860x^8y^10)\n#28 = + #25 #27 ==> ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12) + (4860x^8y^10))\n#29 = * 2916 #2 ==> (2916x^7)\n#30 = * #29 #9 ==> (2916x^7y^8)\n#31 = + #28 #30 ==> ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12) + (4860x^8y^10) + (2916x^7y^8))\n#32 = * 729 #1 ==> (729x^6)\n#33 = * #32 #8 ==> (729x^6y^6)\n#34 = + #31 #33 ==> ((64x^12y^18) + (576x^11y^16) + (2160x^10y^14) + (4320x^9y^12) + (4860x^8y^10) + (2916x^7y^8) + (729x^6y^6))\n\njulia> @btime SLP.evaluate($p3, $v)\n 699.465 ns (5 allocations: 1008 bytes)\n-1458502820125772303\n\njulia> @time f3 = StraightLinePrograms.compile!(p3);\n 0.002830 seconds (1.40 k allocations: 90.930 KiB)\n\njulia> @btime $f3($v)\n 80.229 ns (0 allocations: 0 bytes)\n-1458502820125772303\n\njulia> p4 = convert(S, q, limit_exp=true); # use different encoding\n\njulia> @btime SLP.evaluate($p4, $v)\n 766.864 ns (5 allocations: 1008 bytes)\n-1458502820125772303\n\njulia> @time f4 = StraightLinePrograms.compile!(p4);\n 0.002731 seconds (1.74 k allocations: 108.676 KiB)\n\njulia> @btime $f4($v)\n 11.781 ns (0 allocations: 0 bytes)\n-1458502820125772303","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/arb/#Fixed-precision-real-balls","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Fixed precision real ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Real numbers are represented in mid-rad interval form m pm r = m-r m+r.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"The Arb real field is constructed using the ArbField constructor. This constructs the parent object for the Arb real field.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"The types of real balls in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Library Field Element type Parent type\nArb mathbbR (balls) arb ArbField","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"All the real field types belong to the Field abstract type and the types of elements in this field, i.e. balls in this case, belong to the FieldElem abstract type.","category":"page"},{"location":"Nemo/arb/#Real-ball-functionality","page":"Fixed precision real balls","title":"Real ball functionality","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Real balls in Nemo provide all the field functionality described in AbstractAlgebra:","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Below, we document the additional functionality provided for real balls.","category":"page"},{"location":"Nemo/arb/#Constructors","page":"Fixed precision real balls","title":"Constructors","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"In order to construct real balls in Nemo, one must first construct the Arb real field itself. This is accomplished with the following constructor.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"ArbField(prec::Int)","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Return the Arb field with precision in bits prec used for operations on interval midpoints. The precision used for interval radii is a fixed implementation-defined constant (30 bits).","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Here is an example of creating an Arb real field and using the resulting parent object to coerce values into the resulting field.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\n\na = RR(\"0.25\")\nb = RR(\"0.1 +/- 0.001\")\nc = RR(0.5)\nd = RR(12)","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Note that whilst one can coerce double precision floating point values into an Arb real field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb field.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.","category":"page"},{"location":"Nemo/arb/#Real-ball-constructors","page":"Fixed precision real balls","title":"Real ball constructors","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"ball(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#ball-Tuple{arb, arb}","page":"Fixed precision real balls","title":"ball","text":"ball(x::arb, y::arb)\n\nConstructs an Arb ball enclosing x_m pm (x_r + y_m + y_r), given the pair (x y) = (x_m pm x_r y_m pm y_r).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\n\nc = ball(RR(3), RR(\"0.0001\"))","category":"page"},{"location":"Nemo/arb/#Conversions","page":"Fixed precision real balls","title":"Conversions","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\n\nconvert(Float64, RR(1//3))","category":"page"},{"location":"Nemo/arb/#Basic-manipulation","page":"Fixed precision real balls","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"is_nonzero(::arb)","category":"page"},{"location":"Nemo/arb/#is_nonzero-Tuple{arb}","page":"Fixed precision real balls","title":"is_nonzero","text":"is_nonzero(x::arb)\n\nReturn true if x is certainly not equal to zero, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"isfinite(::arb)","category":"page"},{"location":"Nemo/arb/#isfinite-Tuple{arb}","page":"Fixed precision real balls","title":"isfinite","text":"isfinite(x::arb)\n\nReturn true if x is finite, i.e. having finite midpoint and radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"is_exact(::arb)","category":"page"},{"location":"Nemo/arb/#is_exact-Tuple{arb}","page":"Fixed precision real balls","title":"is_exact","text":"is_exact(x::arb)\n\nReturn true if x is exact, i.e. has zero radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"isinteger(::arb)","category":"page"},{"location":"Nemo/arb/#isinteger-Tuple{arb}","page":"Fixed precision real balls","title":"isinteger","text":"isinteger(x::arb)\n\nReturn true if x is an exact integer, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"is_positive(::arb)","category":"page"},{"location":"Nemo/arb/#is_positive-Tuple{arb}","page":"Fixed precision real balls","title":"is_positive","text":"is_positive(x::arb)\n\nReturn true if x is certainly positive, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"is_nonnegative(::arb)","category":"page"},{"location":"Nemo/arb/#is_nonnegative-Tuple{arb}","page":"Fixed precision real balls","title":"is_nonnegative","text":"is_nonnegative(x::arb)\n\nReturn true if x is certainly nonnegative, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"is_negative(::arb)","category":"page"},{"location":"Nemo/arb/#is_negative-Tuple{arb}","page":"Fixed precision real balls","title":"is_negative","text":"is_negative(x::arb)\n\nReturn true if x is certainly negative, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"is_nonpositive(::arb)","category":"page"},{"location":"Nemo/arb/#is_nonpositive-Tuple{arb}","page":"Fixed precision real balls","title":"is_nonpositive","text":"is_nonpositive(x::arb)\n\nReturn true if x is certainly nonpositive, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"midpoint(::arb)","category":"page"},{"location":"Nemo/arb/#midpoint-Tuple{arb}","page":"Fixed precision real balls","title":"midpoint","text":"midpoint(x::arb)\n\nReturn the midpoint of the ball x as an Arb ball.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"radius(::arb)","category":"page"},{"location":"Nemo/arb/#radius-Tuple{arb}","page":"Fixed precision real balls","title":"radius","text":"radius(x::arb)\n\nReturn the radius of the ball x as an Arb ball.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"accuracy_bits(::arb)","category":"page"},{"location":"Nemo/arb/#accuracy_bits-Tuple{arb}","page":"Fixed precision real balls","title":"accuracy_bits","text":"accuracy_bits(x::arb)\n\nReturn the relative accuracy of x measured in bits, capped between typemax(Int) and -typemax(Int).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\n\na = RR(\"1.2 +/- 0.001\")\nb = RR(3)\n\nis_positive(a)\nisfinite(b)\nisinteger(b)\nis_negative(a)\nc = radius(a)\nd = midpoint(b)\nf = accuracy_bits(a)","category":"page"},{"location":"Nemo/arb/#Printing","page":"Fixed precision real balls","title":"Printing","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Printing real balls can at first sight be confusing. Lets look at the following example:","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\n\na = RR(1)\nb = RR(2)\nc = RR(12)\n\nx = ball(a, b)\ny = ball(c, b)\n\nmid = midpoint(x)\nrad = radius(x)\n\nprint(x, \"\\n\", y, \"\\n\", mid, \"\\n\", rad)","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"which generates","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"[+/- 3.01]\n[1e+1 +/- 4.01]\n1.0000000000000000000\n[2.0000000037252902985 +/- 3.81e-20]","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"The first reason that c is not printed as [1 +/- 2] is that the midpoint does not have a greater exponent than the radius in its scientific notation. For similar reasons y is not printed as [12 +/- 2].","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"The second reason is that we get an additional error term after our addition. As we see, radius(c) is not equal to 2, which when printed rounds it up to a reasonable decimal place. This is because real balls keep track of rounding errors of basic arithmetic.","category":"page"},{"location":"Nemo/arb/#Containment","page":"Fixed precision real balls","title":"Containment","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"It is often necessary to determine whether a given exact value or ball is contained in a given real ball or whether two balls overlap. The following functions are provided for this purpose.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"overlaps(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#overlaps-Tuple{arb, arb}","page":"Fixed precision real balls","title":"overlaps","text":"overlaps(x::arb, y::arb)\n\nReturns true if any part of the ball x overlaps any part of the ball y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"contains(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#contains-Tuple{arb, arb}","page":"Fixed precision real balls","title":"contains","text":"contains(x::arb, y::arb)\n\nReturns true if the ball x contains the ball y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"contains(::arb, ::Integer)\ncontains(::arb, ::ZZRingElem)\ncontains(::arb, ::QQFieldElem)\ncontains{T <: Integer}(::arb, ::Rational{T})\ncontains(::arb, ::BigFloat)","category":"page"},{"location":"Nemo/arb/#contains-Tuple{arb, Integer}","page":"Fixed precision real balls","title":"contains","text":"contains(x::arb, y::Integer)\n\nReturns true if the ball x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/#contains-Tuple{arb, ZZRingElem}","page":"Fixed precision real balls","title":"contains","text":"contains(x::arb, y::ZZRingElem)\n\nReturns true if the ball x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/#contains-Tuple{arb, QQFieldElem}","page":"Fixed precision real balls","title":"contains","text":"contains(x::arb, y::QQFieldElem)\n\nReturns true if the ball x contains the given rational value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/#contains-Union{Tuple{T}, Tuple{arb, Rational{T}}} where T<:Integer","page":"Fixed precision real balls","title":"contains","text":"contains(x::arb, y::Rational{T}) where {T <: Integer}\n\nReturns true if the ball x contains the given rational value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/#contains-Tuple{arb, BigFloat}","page":"Fixed precision real balls","title":"contains","text":"contains(x::arb, y::BigFloat)\n\nReturns true if the ball x contains the given floating point value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"The following functions are also provided for determining if a ball intersects a certain part of the real number line.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"contains_zero(::arb)","category":"page"},{"location":"Nemo/arb/#contains_zero-Tuple{arb}","page":"Fixed precision real balls","title":"contains_zero","text":"contains_zero(x::arb)\n\nReturns true if the ball x contains zero, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"contains_negative(::arb)","category":"page"},{"location":"Nemo/arb/#contains_negative-Tuple{arb}","page":"Fixed precision real balls","title":"contains_negative","text":"contains_negative(x::arb)\n\nReturns true if the ball x contains any negative value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"contains_positive(::arb)","category":"page"},{"location":"Nemo/arb/#contains_positive-Tuple{arb}","page":"Fixed precision real balls","title":"contains_positive","text":"contains_positive(x::arb)\n\nReturns true if the ball x contains any positive value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"contains_nonnegative(::arb)","category":"page"},{"location":"Nemo/arb/#contains_nonnegative-Tuple{arb}","page":"Fixed precision real balls","title":"contains_nonnegative","text":"contains_nonnegative(x::arb)\n\nReturns true if the ball x contains any nonnegative value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"contains_nonpositive(::arb)","category":"page"},{"location":"Nemo/arb/#contains_nonpositive-Tuple{arb}","page":"Fixed precision real balls","title":"contains_nonpositive","text":"contains_nonpositive(x::arb)\n\nReturns true if the ball x contains any nonpositive value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\nx = RR(\"1 +/- 0.001\")\ny = RR(\"3\")\n\noverlaps(x, y)\ncontains(x, y)\ncontains(y, 3)\ncontains(x, ZZ(1)//2)\ncontains_zero(x)\ncontains_positive(y)","category":"page"},{"location":"Nemo/arb/#Comparison","page":"Fixed precision real balls","title":"Comparison","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Nemo provides a full range of comparison operations for Arb balls. Note that a ball is considered less than another ball if every value in the first ball is less than every value in the second ball, etc.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"In addition to the standard comparison operators, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"isequal(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#isequal-Tuple{arb, arb}","page":"Fixed precision real balls","title":"isequal","text":"isequal(x::arb, y::arb)\n\nReturn true if the balls x and y are precisely equal, i.e. have the same midpoints and radii.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"We also provide a full range of ad hoc comparison operators. These are implemented directly in Julia, but we document them as though isless and == were provided.","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Function\n==(x::arb, y::Integer)\n==(x::Integer, y::arb)\n==(x::arb, y::ZZRingElem)\n==(x::ZZRingElem, y::arb)\n==(x::arb, y::Float64)\n==(x::Float64, y::arb)\nisless(x::arb, y::Integer)\nisless(x::Integer, y::arb)\nisless(x::arb, y::ZZRingElem)\nisless(x::ZZRingElem, y::arb)\nisless(x::arb, y::Float64)\nisless(x::Float64, y::arb)\nisless(x::arb, y::BigFloat)\nisless(x::BigFloat, y::arb)\nisless(x::arb, y::QQFieldElem)\nisless(x::QQFieldElem, y::arb)","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\nx = RR(\"1 +/- 0.001\")\ny = RR(\"3\")\nz = RR(\"4\")\n\nisequal(x, deepcopy(x))\nx == 3\nZZ(3) < z\nx != 1.23","category":"page"},{"location":"Nemo/arb/#Absolute-value","page":"Fixed precision real balls","title":"Absolute value","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\nx = RR(\"-1 +/- 0.001\")\n\na = abs(x)","category":"page"},{"location":"Nemo/arb/#Shifting","page":"Fixed precision real balls","title":"Shifting","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\nx = RR(\"-3 +/- 0.001\")\n\na = ldexp(x, 23)\nb = ldexp(x, -ZZ(15))","category":"page"},{"location":"Nemo/arb/#Miscellaneous-operations","page":"Fixed precision real balls","title":"Miscellaneous operations","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"add_error!(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#add_error!-Tuple{arb, arb}","page":"Fixed precision real balls","title":"add_error!","text":"add_error!(x::arb, y::arb)\n\nAdds the absolute values of the midpoint and radius of y to the radius of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"trim(::arb)","category":"page"},{"location":"Nemo/arb/#trim-Tuple{arb}","page":"Fixed precision real balls","title":"trim","text":"trim(x::arb)\n\nReturn an arb interval containing x but which may be more economical, by rounding off insignificant bits from the midpoint.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"unique_integer(::arb)","category":"page"},{"location":"Nemo/arb/#unique_integer-Tuple{arb}","page":"Fixed precision real balls","title":"unique_integer","text":"unique_integer(x::arb)\n\nReturn a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the interval x contains a unique integer. If this is the case, the second return value is set to this unique integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"setunion(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#setunion-Tuple{arb, arb}","page":"Fixed precision real balls","title":"setunion","text":"setunion(x::arb, y::arb)\n\nReturn an arb containing the union of the intervals represented by x and y.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\nx = RR(\"-3 +/- 0.001\")\ny = RR(\"2 +/- 0.5\")\n\na = trim(x)\nb, c = unique_integer(x)\nd = setunion(x, y)","category":"page"},{"location":"Nemo/arb/#Constants","page":"Fixed precision real balls","title":"Constants","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_pi(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_pi-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_pi","text":"const_pi(r::ArbField)\n\nReturn pi = 314159ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_e(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_e-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_e","text":"const_e(r::ArbField)\n\nReturn e = 271828ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_log2(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_log2-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_log2","text":"const_log2(r::ArbField)\n\nReturn log(2) = 069314ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_log10(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_log10-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_log10","text":"const_log10(r::ArbField)\n\nReturn log(10) = 2302585ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_euler(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_euler-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_euler","text":"const_euler(r::ArbField)\n\nReturn Euler's constant gamma = 0577215ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_catalan(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_catalan-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_catalan","text":"const_catalan(r::ArbField)\n\nReturn Catalan's constant C = 0915965ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_khinchin(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_khinchin-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_khinchin","text":"const_khinchin(r::ArbField)\n\nReturn Khinchin's constant K = 2685452ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"const_glaisher(::ArbField)","category":"page"},{"location":"Nemo/arb/#const_glaisher-Tuple{ArbField}","page":"Fixed precision real balls","title":"const_glaisher","text":"const_glaisher(r::ArbField)\n\nReturn Glaisher's constant A = 1282427ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(200)\n\na = const_pi(RR)\nb = const_e(RR)\nc = const_euler(RR)\nd = const_glaisher(RR)","category":"page"},{"location":"Nemo/arb/#Mathematical-and-special-functions","page":"Fixed precision real balls","title":"Mathematical and special functions","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"rsqrt(::arb)","category":"page"},{"location":"Nemo/arb/#rsqrt-Tuple{arb}","page":"Fixed precision real balls","title":"rsqrt","text":"rsqrt(x::arb)\n\nReturn the reciprocal of the square root of x, i.e. 1sqrtx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"sqrt1pm1(::arb)","category":"page"},{"location":"Nemo/arb/#sqrt1pm1-Tuple{arb}","page":"Fixed precision real balls","title":"sqrt1pm1","text":"sqrt1pm1(x::arb)\n\nReturn sqrt1+x-1, evaluated accurately for small x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"sqrtpos(::arb)","category":"page"},{"location":"Nemo/arb/#sqrtpos-Tuple{arb}","page":"Fixed precision real balls","title":"sqrtpos","text":"sqrtpos(x::arb)\n\nReturn the sqrt root of x, assuming that x represents a nonnegative number. Thus any negative number in the input interval is discarded.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"gamma(::arb)","category":"page"},{"location":"Nemo/arb/#gamma-Tuple{arb}","page":"Fixed precision real balls","title":"gamma","text":"gamma(x::arb)\n\nReturn the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"lgamma(::arb)","category":"page"},{"location":"Nemo/arb/#lgamma-Tuple{arb}","page":"Fixed precision real balls","title":"lgamma","text":"lgamma(x::arb)\n\nReturn the logarithm of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"rgamma(::arb)","category":"page"},{"location":"Nemo/arb/#rgamma-Tuple{arb}","page":"Fixed precision real balls","title":"rgamma","text":"rgamma(x::arb)\n\nReturn the reciprocal of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"digamma(::arb)","category":"page"},{"location":"Nemo/arb/#digamma-Tuple{arb}","page":"Fixed precision real balls","title":"digamma","text":"digamma(x::arb)\n\nReturn the logarithmic derivative of the gamma function evaluated at x, i.e. psi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"gamma(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#gamma-Tuple{arb, arb}","page":"Fixed precision real balls","title":"gamma","text":"gamma(s::arb, x::arb)\n\nReturn the upper incomplete gamma function Gamma(sx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"gamma_regularized(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#gamma_regularized-Tuple{arb, arb}","page":"Fixed precision real balls","title":"gamma_regularized","text":"gamma_regularized(s::arb, x::arb)\n\nReturn the regularized upper incomplete gamma function Gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"gamma_lower(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#gamma_lower-Tuple{arb, arb}","page":"Fixed precision real balls","title":"gamma_lower","text":"gamma_lower(s::arb, x::arb)\n\nReturn the lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"gamma_lower_regularized(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#gamma_lower_regularized-Tuple{arb, arb}","page":"Fixed precision real balls","title":"gamma_lower_regularized","text":"gamma_lower_regularized(s::arb, x::arb)\n\nReturn the regularized lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"zeta(::arb)","category":"page"},{"location":"Nemo/arb/#zeta-Tuple{arb}","page":"Fixed precision real balls","title":"zeta","text":"zeta(x::arb)\n\nReturn the Riemann zeta function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"atan2(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#atan2-Tuple{arb, arb}","page":"Fixed precision real balls","title":"atan2","text":"atan2(y::arb, x::arb)\n\nReturn operatornameatan2(yx) = arg(x+yi). Same as atan(y, x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"agm(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#agm-Tuple{arb, arb}","page":"Fixed precision real balls","title":"agm","text":"agm(x::arb, y::arb)\n\nReturn the arithmetic-geometric mean of x and y\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"zeta(::arb, ::arb)","category":"page"},{"location":"Nemo/arb/#zeta-Tuple{arb, arb}","page":"Fixed precision real balls","title":"zeta","text":"zeta(s::arb, a::arb)\n\nReturn the Hurwitz zeta function zeta(sa).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"root(::arb, ::Int)","category":"page"},{"location":"Nemo/arb/#root-Tuple{arb, Int64}","page":"Fixed precision real balls","title":"root","text":"root(x::arb, n::Int)\n\nReturn the n-th root of x. We require x geq 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"factorial(::arb)","category":"page"},{"location":"Nemo/arb/#factorial-Tuple{arb}","page":"Fixed precision real balls","title":"factorial","text":"factorial(x::arb)\n\nReturn the factorial of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"factorial(::Int, ::ArbField)","category":"page"},{"location":"Nemo/arb/#factorial-Tuple{Int64, ArbField}","page":"Fixed precision real balls","title":"factorial","text":"factorial(n::Int, r::ArbField)\n\nReturn the factorial of n in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"binomial(::arb, ::UInt)","category":"page"},{"location":"Nemo/arb/#binomial-Tuple{arb, UInt64}","page":"Fixed precision real balls","title":"binomial","text":"binomial(x::arb, n::UInt)\n\nReturn the binomial coefficient x choose n.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"binomial(::UInt, ::UInt, ::ArbField)","category":"page"},{"location":"Nemo/arb/#binomial-Tuple{UInt64, UInt64, ArbField}","page":"Fixed precision real balls","title":"binomial","text":"binomial(n::UInt, k::UInt, r::ArbField)\n\nReturn the binomial coefficient n choose k in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"fibonacci(::ZZRingElem, ::ArbField)","category":"page"},{"location":"Nemo/arb/#fibonacci-Tuple{ZZRingElem, ArbField}","page":"Fixed precision real balls","title":"fibonacci","text":"fibonacci(n::ZZRingElem, r::ArbField)\n\nReturn the n-th Fibonacci number in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"fibonacci(::Int, ::ArbField)","category":"page"},{"location":"Nemo/arb/#fibonacci-Tuple{Int64, ArbField}","page":"Fixed precision real balls","title":"fibonacci","text":"fibonacci(n::Int, r::ArbField)\n\nReturn the n-th Fibonacci number in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"gamma(::ZZRingElem, ::ArbField)","category":"page"},{"location":"Nemo/arb/#gamma-Tuple{ZZRingElem, ArbField}","page":"Fixed precision real balls","title":"gamma","text":"gamma(x::ZZRingElem, r::ArbField)\n\nReturn the Gamma function evaluated at x in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"gamma(::QQFieldElem, ::ArbField)","category":"page"},{"location":"Nemo/arb/#gamma-Tuple{QQFieldElem, ArbField}","page":"Fixed precision real balls","title":"gamma","text":"gamma(x::QQFieldElem, r::ArbField)\n\nReturn the Gamma function evaluated at x in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"zeta(::Int, ::ArbField)","category":"page"},{"location":"Nemo/arb/#zeta-Tuple{Int64, ArbField}","page":"Fixed precision real balls","title":"zeta","text":"zeta(n::Int, r::ArbField)\n\nReturn the Riemann zeta function zeta(n) as an element of the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"bernoulli(::Int, ::ArbField)","category":"page"},{"location":"Nemo/arb/#bernoulli-Tuple{Int64, ArbField}","page":"Fixed precision real balls","title":"bernoulli","text":"bernoulli(n::Int, r::ArbField)\n\nReturn the n-th Bernoulli number as an element of the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"rising_factorial(::arb, ::Int)","category":"page"},{"location":"Nemo/arb/#rising_factorial-Tuple{arb, Int64}","page":"Fixed precision real balls","title":"rising_factorial","text":"rising_factorial(x::arb, n::Int)\n\nReturn the rising factorial x(x + 1)ldots (x + n - 1) as an Arb.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"rising_factorial(::QQFieldElem, ::Int, ::ArbField)","category":"page"},{"location":"Nemo/arb/#rising_factorial-Tuple{QQFieldElem, Int64, ArbField}","page":"Fixed precision real balls","title":"rising_factorial","text":"rising_factorial(x::QQFieldElem, n::Int, r::ArbField)\n\nReturn the rising factorial x(x + 1)ldots (x + n - 1) as an element of the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"rising_factorial2(::arb, ::Int)","category":"page"},{"location":"Nemo/arb/#rising_factorial2-Tuple{arb, Int64}","page":"Fixed precision real balls","title":"rising_factorial2","text":"rising_factorial2(x::arb, n::Int)\n\nReturn a tuple containing the rising factorial x(x + 1)ldots (x + n - 1) and its derivative.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"polylog(::Union{arb,Int}, ::arb)","category":"page"},{"location":"Nemo/arb/#polylog-Tuple{Union{Int64, arb}, arb}","page":"Fixed precision real balls","title":"polylog","text":"polylog(s::Union{arb,Int}, a::arb)\n\nReturn the polylogarithm Li_s(a).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"chebyshev_t(::Int, ::arb)","category":"page"},{"location":"Nemo/arb/#chebyshev_t-Tuple{Int64, arb}","page":"Fixed precision real balls","title":"chebyshev_t","text":"chebyshev_t(n::Int, x::arb)\n\nReturn the value of the Chebyshev polynomial T_n(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"chebyshev_u(::Int, ::arb)","category":"page"},{"location":"Nemo/arb/#chebyshev_u-Tuple{Int64, arb}","page":"Fixed precision real balls","title":"chebyshev_u","text":"chebyshev_u(n::Int, x::arb)\n\nReturn the value of the Chebyshev polynomial U_n(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"chebyshev_t2(::Int, ::arb)","category":"page"},{"location":"Nemo/arb/#chebyshev_t2-Tuple{Int64, arb}","page":"Fixed precision real balls","title":"chebyshev_t2","text":"chebyshev_t2(n::Int, x::arb)\n\nReturn the tuple (T_n(x) T_n-1(x)).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"chebyshev_u2(::Int, ::arb)","category":"page"},{"location":"Nemo/arb/#chebyshev_u2-Tuple{Int64, arb}","page":"Fixed precision real balls","title":"chebyshev_u2","text":"chebyshev_u2(n::Int, x::arb)\n\nReturn the tuple (U_n(x) U_n-1(x))\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"bell(::ZZRingElem, ::ArbField)","category":"page"},{"location":"Nemo/arb/#bell-Tuple{ZZRingElem, ArbField}","page":"Fixed precision real balls","title":"bell","text":"bell(n::ZZRingElem, r::ArbField)\n\nReturn the Bell number B_n as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"bell(::Int, ::ArbField)","category":"page"},{"location":"Nemo/arb/#bell-Tuple{Int64, ArbField}","page":"Fixed precision real balls","title":"bell","text":"bell(n::Int, r::ArbField)\n\nReturn the Bell number B_n as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"numpart(::ZZRingElem, ::ArbField)","category":"page"},{"location":"Nemo/arb/#numpart-Tuple{ZZRingElem, ArbField}","page":"Fixed precision real balls","title":"numpart","text":"numpart(n::ZZRingElem, r::ArbField)\n\nReturn the number of partitions p(n) as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"numpart(::Int, ::ArbField)","category":"page"},{"location":"Nemo/arb/#numpart-Tuple{Int64, ArbField}","page":"Fixed precision real balls","title":"numpart","text":"numpart(n::Int, r::ArbField)\n\nReturn the number of partitions p(n) as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"airy_ai(::arb)","category":"page"},{"location":"Nemo/arb/#airy_ai-Tuple{arb}","page":"Fixed precision real balls","title":"airy_ai","text":"airy_ai(x::arb)\n\nReturn the Airy function operatornameAi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"airy_ai_prime(::arb)","category":"page"},{"location":"Nemo/arb/#airy_ai_prime-Tuple{arb}","page":"Fixed precision real balls","title":"airy_ai_prime","text":"airy_ai_prime(x::arb)\n\nReturn the derivative of the Airy function operatornameAi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"airy_bi(::arb)","category":"page"},{"location":"Nemo/arb/#airy_bi-Tuple{arb}","page":"Fixed precision real balls","title":"airy_bi","text":"airy_bi(x::arb)\n\nReturn the Airy function operatornameBi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"airy_bi_prime(::arb)","category":"page"},{"location":"Nemo/arb/#airy_bi_prime-Tuple{arb}","page":"Fixed precision real balls","title":"airy_bi_prime","text":"airy_bi_prime(x::arb)\n\nReturn the derivative of the Airy function operatornameBi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\n\na = floor(exp(RR(1)))\nb = sinpi(QQ(5,6), RR)\nc = gamma(QQ(1,3), ArbField(256))\nd = bernoulli(1000, ArbField(53))\nf = polylog(3, RR(-10))","category":"page"},{"location":"Nemo/arb/#Linear-dependence","page":"Fixed precision real balls","title":"Linear dependence","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"lindep(::Vector{arb}, n::Int)","category":"page"},{"location":"Nemo/arb/#lindep-Tuple{Vector{arb}, Int64}","page":"Fixed precision real balls","title":"lindep","text":"lindep(A::Vector{arb}, bits::Int)\n\nFind a small linear combination of the entries of the array A that is small (using LLL). The entries are first scaled by the given number of bits before truncating to integers for use in LLL. This function can be used to find linear dependence between a list of real numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.\n\nExamples\n\njulia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\n\njulia> a = RR(-0.33198902958450931620250069492231652319)\n[-0.33198902958450932088 +/- 4.15e-22]\n\njulia> V = [RR(1), a, a^2, a^3, a^4, a^5]\n6-element Vector{arb}:\n 1.0000000000000000000\n [-0.33198902958450932088 +/- 4.15e-22]\n [0.11021671576446420510 +/- 7.87e-21]\n [-0.03659074051063616184 +/- 4.17e-21]\n [0.012147724433904692427 +/- 4.99e-22]\n [-0.004032911246472051677 +/- 6.25e-22]\n\njulia> W = lindep(V, 20)\n6-element Vector{ZZRingElem}:\n 1\n 3\n 0\n 0\n 0\n 1\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(128)\n\na = RR(-0.33198902958450931620250069492231652319)\n\nV = [RR(1), a, a^2, a^3, a^4, a^5]\nW = lindep(V, 20)","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"simplest_rational_inside(::arb)","category":"page"},{"location":"Nemo/arb/#simplest_rational_inside-Tuple{arb}","page":"Fixed precision real balls","title":"simplest_rational_inside","text":" simplest_rational_inside(x::arb)\n\nReturn the simplest fraction inside the ball x. A canonical fraction a_1b_1 is defined to be simpler than a_2b_2 iff b_1 b_2 or b_1 = b_2 and a_1 a_2.\n\nExamples\n\njulia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\n\njulia> simplest_rational_inside(const_pi(RR))\n8717442233//2774848045\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(64)\nsimplest_rational_inside(const_pi(RR))","category":"page"},{"location":"Nemo/arb/#Random-generation","page":"Fixed precision real balls","title":"Random generation","text":"","category":"section"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"rand(::ArbField)","category":"page"},{"location":"Nemo/arb/#rand-Tuple{ArbField}","page":"Fixed precision real balls","title":"rand","text":"rand(r::ArbField; randtype::Symbol=:urandom)\n\nReturn a random element in given Arb field.\n\nThe randtype default is :urandom which return an arb contained in 01.\n\nThe rest of the methods return non-uniformly distributed values in order to exercise corner cases. The option :randtest will return a finite number, and :randtest_exact the same but with a zero radius. The option :randtest_precise return an arb with a radius around 2^-mathrmprec the magnitude of the midpoint, while :randtest_wide return a radius that might be big relative to its midpoint. The :randtest_special-option might return a midpoint and radius whose values are NaN or inf.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"Examples","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"RR = ArbField(100)\n\na = rand(RR)\nb = rand(RR; randtype = :null_exact)\nc = rand(RR; randtype = :exact)\nd = rand(RR; randtype = :special)","category":"page"},{"location":"Nemo/factor/","page":"Factorisation","title":"Factorisation","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/factor/#Factorisation","page":"Factorisation","title":"Factorisation","text":"","category":"section"},{"location":"Nemo/factor/","page":"Factorisation","title":"Factorisation","text":"Nemo provides a unified interface to handle factorisations using the Fact objects. These can only be constructed using the factor function for the respective ring elements. This is best illustrated by an example.","category":"page"},{"location":"Nemo/factor/","page":"Factorisation","title":"Factorisation","text":"julia> fac = factor(ZZ(-6000361807272228723606))\n-1 * 2 * 229^3 * 43669^3 * 3\n\njulia> unit(fac)\n-1\n\njulia> -6000361807272228723606 == unit(fac) * prod([ p^e for (p, e) in fac])\ntrue\n\njulia> for (p, e) in fac; println(\"$p $e\"); end\n2 1\n229 3\n43669 3\n3 1\n\njulia> 229 in fac\ntrue\n\njulia> fac[229]\n3","category":"page"},{"location":"Nemo/factor/#Basic-functionality","page":"Factorisation","title":"Basic functionality","text":"","category":"section"},{"location":"Nemo/factor/","page":"Factorisation","title":"Factorisation","text":"Objects of type Fac are iterable, that is, if a is an object of type Fac, then for (p, e) in a will iterate through all pairs (p, e), where p is a factor and e the corresponding exponent.","category":"page"},{"location":"Nemo/factor/","page":"Factorisation","title":"Factorisation","text":"in(::ZZRingElem, ::Fac{ZZRingElem})\ngetindex(::Fac{ZZRingElem}, ::ZZRingElem)\nlength(::Fac{ZZRingElem})\nunit(::Fac{ZZRingElem})","category":"page"},{"location":"Nemo/factor/#in-Tuple{ZZRingElem, Fac{ZZRingElem}}","page":"Factorisation","title":"in","text":"in(a, b::Fac)\n\nTest whether a is a factor of b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/factor/#getindex-Tuple{Fac{ZZRingElem}, ZZRingElem}","page":"Factorisation","title":"getindex","text":"getindex(a::Fac, b) -> Int\n\nIf b is a factor of a, the corresponding exponent is returned. Otherwise an error is thrown.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/factor/#length-Tuple{Fac{ZZRingElem}}","page":"Factorisation","title":"length","text":"length(a::Fac) -> Int\n\nReturn the number of factors of a, not including the unit.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/factor/#unit-Tuple{Fac{ZZRingElem}}","page":"Factorisation","title":"unit","text":"unit(a::Fac{T}) -> T\n\nReturn the unit of the factorization.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Homological-Algebra","page":"Homological Algebra","title":"Homological Algebra","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"Some OSCAR functions which are fundamental to homological algebra such as the kernel function and basic functions for handling chain and cochain complexes have already been discussed in previous sections. Building on these functions, we now introduce further OSCAR functionality supporting computations in homological algebra.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Presentations","page":"Homological Algebra","title":"Presentations","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"presentation(M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#presentation-Tuple{ModuleFP}","page":"Homological Algebra","title":"presentation","text":"presentation(M::ModuleFP)\n\nReturn a free presentation of M.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A = R[x; y];\n\njulia> B = R[x^2; y^3; z^4];\n\njulia> M = SubquoModule(A, B);\n\njulia> P = presentation(M)\n0 <---- M <---- R^2 <---- R^5\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, [1,2,2]);\n\njulia> p = presentation(F)\n0 <---- F <---- F <---- 0\n\njulia> p[-2]\nGraded free module Rg^0 of rank 0 over Rg\n\njulia> p[-1]\nGraded free module Rg^1([-1]) + Rg^2([-2]) of rank 3 over Rg\n\njulia> p[0]\nGraded free module Rg^1([-1]) + Rg^2([-2]) of rank 3 over Rg\n\njulia> p[1]\nGraded free module Rg^0 of rank 0 over Rg\n\njulia> map(p,-1)\nF -> 0\ne[1] -> 0\ne[2] -> 0\ne[3] -> 0\nHomogeneous module homomorphism\n\njulia> map(p,0)\nF -> F\ne[1] -> e[1]\ne[2] -> e[2]\ne[3] -> e[3]\nHomogeneous module homomorphism\n\njulia> map(p,1)\n0 -> F\nHomogeneous module homomorphism\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> P = presentation(M)\n0 <---- M <---- Rg^2 <---- Rg^5\n\njulia> P[-2]\nGraded free module Rg^0 of rank 0 over Rg\n\njulia> P[-1]\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> P[0]\nGraded free module Rg^2([-1]) of rank 2 over Rg\n\njulia> P[1]\nGraded free module Rg^2([-2]) + Rg^1([-3]) + Rg^2([-5]) of rank 5 over Rg\n\njulia> map(P,-1)\nM -> 0\nx*e[1] -> 0\ny*e[1] -> 0\nHomogeneous module homomorphism\n\njulia> map(P,0)\nRg^2 -> M\ne[1] -> x*e[1]\ne[2] -> y*e[1]\nHomogeneous module homomorphism\n\njulia> map(P,1)\nRg^5 -> Rg^2\ne[1] -> x*e[1]\ne[2] -> -y*e[1] + x*e[2]\ne[3] -> y^2*e[2]\ne[4] -> z^4*e[1]\ne[5] -> z^4*e[2]\nHomogeneous module homomorphism\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Representation-as-Cokernel","page":"Homological Algebra","title":"Representation as Cokernel","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"present_as_cokernel(M::SubquoModule, task::Symbol = :none)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#present_as_cokernel","page":"Homological Algebra","title":"present_as_cokernel","text":"present_as_cokernel(M::SubquoModule, task::Symbol = :none)\n\nReturn a subquotient C which is isomorphic to M, and whose generators are the standard unit vectors of its ambient free module.\n\nAdditionally,\n\nreturn an isomorphism M to C if task = :with_morphism,\nreturn and cache an isomorphism M to C if task = :cache_morphism,\ndo none of the above if task = :none (default).\n\nIf task = :only_morphism, return only an isomorphism.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A = R[x; y];\n\njulia> B = R[x^2; y^3; z^4];\n\njulia> M = SubquoModule(A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> C = present_as_cokernel(M)\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 5 generators\n1 -> x*e[1]\n2 -> -y*e[1] + x*e[2]\n3 -> y^2*e[2]\n4 -> z^4*e[1]\n5 -> z^4*e[2]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> present_as_cokernel(M, :with_morphism)\n(Graded subquotient of submodule of Rg^2 generated by\n1 -> e[1]\n2 -> e[2]\nby submodule of Rg^2 generated by\n1 -> x*e[1]\n2 -> -y*e[1] + x*e[2]\n3 -> y^2*e[2]\n4 -> z^4*e[1]\n5 -> z^4*e[2], Graded subquotient of submodule of Rg^2 generated by\n1 -> e[1]\n2 -> e[2]\nby submodule of Rg^2 generated by\n1 -> x*e[1]\n2 -> -y*e[1] + x*e[2]\n3 -> y^2*e[2]\n4 -> z^4*e[1]\n5 -> z^4*e[2] -> M\ne[1] -> x*e[1]\ne[2] -> y*e[1]\nHomogeneous module homomorphism)\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Syzygies-and-Free-Resolutions","page":"Homological Algebra","title":"Syzygies and Free Resolutions","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"free_resolution(M::SubquoModule{<:MPolyRingElem}; \n ordering::ModuleOrdering = default_ordering(M),\n length::Int=0, algorithm::Symbol=:fres\n )","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#free_resolution-Tuple{SubquoModule{<:MPolyRingElem}}","page":"Homological Algebra","title":"free_resolution","text":"free_resolution(M::SubquoModule{<:MPolyRingElem}; \n ordering::ModuleOrdering = default_ordering(M),\n length::Int=0, algorithm::Symbol=:fres\n )\n\nReturn a free resolution of M.\n\nIf length != 0, the free resolution is only computed up to the length-th free module. At the moment, algorithm only allows the option :fres.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; x*y; y^2; z^4]\n[x^2]\n[x*y]\n[y^2]\n[z^4]\n\njulia> M = SubquoModule(A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 4 generators\n1 -> x^2*e[1]\n2 -> x*y*e[1]\n3 -> y^2*e[1]\n4 -> z^4*e[1]\n\njulia> fr = free_resolution(M, length=1)\nFree resolution of M\nR^2 <---- R^6\n0 1\n\njulia> is_complete(fr)\nfalse\n\njulia> fr[4]\nFree module of rank 0 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> fr\nC_-2 <---- C_-1 <---- C_0 <---- C_1 <---- C_2 <---- C_3 <---- C_4\n\njulia> is_complete(fr)\ntrue\n\njulia> fr = free_resolution(M, algorithm=:fres)\nFree resolution of M\nR^2 <---- R^6 <---- R^6 <---- R^2 <---- 0\n0 1 2 3 4\n\nNote: Over rings other than polynomial rings, the method will default to a lazy, iterative kernel computation.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Betti-Diagrams","page":"Homological Algebra","title":"Betti Diagrams","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"cm_regularity(M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#cm_regularity-Tuple{ModuleFP}","page":"Homological Algebra","title":"cm_regularity","text":"cm_regularity(M::ModuleFP)\n\nGiven a finitely presented graded module M over a standard mathbb Z-graded multivariate polynomial ring, return the Castelnuovo-Mumford regularity of M.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = graded_free_module(R, 1);\n\njulia> M, _ = quo(F, [x^2*F[1], y^2*F[1], z^2*F[1]])\n(Graded subquotient of submodule of F generated by\n1 -> e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^2*e[1]\n3 -> z^2*e[1], F -> M\ne[1] -> e[1]\nHomogeneous module homomorphism)\n\njulia> cm_regularity(M)\n3\n\njulia> minimal_betti_table(M);\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Homology","page":"Homological Algebra","title":"Homology","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"homology(C::ComplexOfMorphisms{<:ModuleFP})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#homology-Tuple{ComplexOfMorphisms{<:ModuleFP}}","page":"Homological Algebra","title":"homology","text":"homology(C::ComplexOfMorphisms{<:ModuleFP})\n\nReturn the homology of C.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A, _ = quo(F, [x^4*F[1]]);\n\njulia> B, _ = quo(F, [x^3*F[1]]);\n\njulia> a = hom(A, B, [x^2*B[1]]);\n\njulia> b = hom(B, B, [x^2*B[1]]);\n\njulia> C = ComplexOfMorphisms(ModuleFP, [a, b]);\n\njulia> H = homology(C)\n3-element Vector{SubquoModule{QQMPolyRingElem}}:\n Subquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 1 generator\n1 -> x^4*e[1]\n Subquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 2 generators\n1 -> x^3*e[1]\n2 -> x^2*e[1]\n Subquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 2 generators\n1 -> x^3*e[1]\n2 -> x^2*e[1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"homology(C::ComplexOfMorphisms{<:ModuleFP}, i::Int)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#homology-Tuple{ComplexOfMorphisms{<:ModuleFP}, Int64}","page":"Homological Algebra","title":"homology","text":"homology(C::ComplexOfMorphisms{<:ModuleFP}, i::Int)\n\nReturn the i-th homology module of C.\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A, _ = quo(F, [x^4*F[1]]);\n\njulia> B, _ = quo(F, [x^3*F[1]]);\n\njulia> a = hom(A, B, [x^2*B[1]]);\n\njulia> b = hom(B, B, [x^2*B[1]]);\n\njulia> C = ComplexOfMorphisms(ModuleFP, [a, b]);\n\njulia> H = homology(C, 1)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 2 generators\n1 -> x^3*e[1]\n2 -> x^2*e[1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Hom-and-Ext","page":"Homological Algebra","title":"Hom and Ext","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"hom(M::ModuleFP, N::ModuleFP, algorithm::Symbol=:maps)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#hom","page":"Homological Algebra","title":"hom","text":"hom(M::ModuleFP, N::ModuleFP)\n\nReturn the module Hom(M,N) as an object of type SubquoModule.\n\nAdditionally, if H is that object, return the map which sends an element of H to the corresponding homomorphism M to N.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = FreeMod(R, 2);\n\njulia> V = [x*F[1], y^2*F[2]];\n\njulia> M = quo(F, V)[1]\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 2 generators\n1 -> x*e[1]\n2 -> y^2*e[2]\n\njulia> H = hom(M, M)[1]\nhom of (M, M)\n\njulia> gens(H)\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n (e[1] -> e[1])\n (e[2] -> e[2])\n\njulia> relations(H)\n4-element Vector{FreeModElem{QQMPolyRingElem}}:\n x*(e[1] -> e[1])\n y^2*(e[1] -> e[2])\n x*(e[2] -> e[1])\n y^2*(e[2] -> e[2])\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"element_to_homomorphism(f::ModuleFPElem)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#element_to_homomorphism-Tuple{ModuleFPElem}","page":"Homological Algebra","title":"element_to_homomorphism","text":"element_to_homomorphism(f::ModuleFPElem)\n\nIf f is an element of a module created via hom(M,N), for some modules M and N, return the homomorphism M to N corresponding to f.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = FreeMod(R, 2);\n\njulia> V = [x*F[1], y^2*F[2]];\n\njulia> M = quo(F, V)[1]\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 2 generators\n1 -> x*e[1]\n2 -> y^2*e[2]\n\njulia> H = hom(M, M)[1];\n\njulia> gens(H)\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n (e[1] -> e[1])\n (e[2] -> e[2])\n\njulia> relations(H)\n4-element Vector{FreeModElem{QQMPolyRingElem}}:\n x*(e[1] -> e[1])\n y^2*(e[1] -> e[2])\n x*(e[2] -> e[1])\n y^2*(e[2] -> e[2])\n\njulia> a = element_to_homomorphism(H[1]+y*H[2])\nMap with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 2 generators\n1 -> x*e[1]\n2 -> y^2*e[2]\nCodomain:\n=========\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 2 generators\n1 -> x*e[1]\n2 -> y^2*e[2]\n\njulia> matrix(a)\n[1 0]\n[0 y]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"homomorphism_to_element(H::ModuleFP, phi::ModuleFPHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#homomorphism_to_element-Tuple{ModuleFP, ModuleFPHom}","page":"Homological Algebra","title":"homomorphism_to_element","text":"homomorphism_to_element(H::ModuleFP, a::ModuleFPHom)\n\nIf the module H is created via hom(M,N), for some modules M and N, and a: M to N is a homomorphism, then return the element of H corresponding to a.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = FreeMod(R, 2);\n\njulia> V = [x*F[1], y^2*F[2]];\n\njulia> M = quo(F, V)[1]\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 2 generators\n1 -> x*e[1]\n2 -> y^2*e[2]\n\njulia> H = hom(M, M)[1];\n\njulia> gens(H)\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n (e[1] -> e[1])\n (e[2] -> e[2])\n\njulia> relations(H)\n4-element Vector{FreeModElem{QQMPolyRingElem}}:\n x*(e[1] -> e[1])\n y^2*(e[1] -> e[2])\n x*(e[2] -> e[1])\n y^2*(e[2] -> e[2])\n\njulia> W = [M[1], y*M[2]];\n\njulia> a = hom(M, M, W);\n\njulia> iswelldefined(a)\ntrue\n\njulia> matrix(a)\n[1 0]\n[0 y]\n\njulia> m = homomorphism_to_element(H, a)\n(e[1] -> e[1]) + y*(e[2] -> e[2])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"ext(M::ModuleFP, N::ModuleFP, i::Int)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#ext-Tuple{ModuleFP, ModuleFP, Int64}","page":"Homological Algebra","title":"ext","text":"ext(M::ModuleFP, N::ModuleFP, i::Int)\n\nReturn textExt^i(MN).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = FreeMod(R, 1);\n\njulia> V = [x*F[1], y*F[1]];\n\njulia> M = quo(F, V)[1]\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\n\njulia> ext(M, M, 0)\nSubquotient of Submodule with 1 generator\n1 -> (e[1] -> e[1])\nby Submodule with 2 generators\n1 -> x*(e[1] -> e[1])\n2 -> y*(e[1] -> e[1])\n\njulia> ext(M, M, 1)\nSubquotient of Submodule with 2 generators\n1 -> (e[2] -> e[1])\n2 -> (e[1] -> e[1])\nby Submodule with 4 generators\n1 -> x*(e[1] -> e[1])\n2 -> y*(e[1] -> e[1])\n3 -> x*(e[2] -> e[1])\n4 -> y*(e[2] -> e[1])\n\njulia> ext(M, M, 2)\nSubquotient of Submodule with 1 generator\n1 -> (e[1] -> e[1])\nby Submodule with 3 generators\n1 -> x*(e[1] -> e[1])\n2 -> y*(e[1] -> e[1])\n3 -> -x*(e[1] -> e[1])\n\njulia> ext(M, M, 3)\nSubmodule with 0 generators\nrepresented as subquotient with no relations.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Tensorproduct-and-Tor","page":"Homological Algebra","title":"Tensorproduct and Tor","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"tensor_product(G::ModuleFP...; task::Symbol = :none)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#tensor_product-Tuple{Vararg{ModuleFP}}","page":"Homological Algebra","title":"tensor_product","text":"tensor_product(M::ModuleFP...; task::Symbol = :none)\n\nGiven a collection of modules, say, M_1 dots M_n over a ring R, return M_1otimes_R cdots otimes_R M_n.\n\nIf task = :map, additionally return the map which sends a tuple (m_1dots m_n) of elements m_iin M_i to the pure tensor m_1otimesdotsotimes m_n.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A = R[x; y];\n\njulia> B = R[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> gens(M)\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x*e[1]\n y*e[1]\n\njulia> T, t = tensor_product(M, M; task = :map);\n\njulia> gens(T)\n4-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x^2*e[1] \\otimes e[1]\n x*y*e[1] \\otimes e[1]\n x*y*e[1] \\otimes e[1]\n y^2*e[1] \\otimes e[1]\n\njulia> domain(t)\nparent of tuples of type Tuple{SubquoModuleElem{QQMPolyRingElem}, SubquoModuleElem{QQMPolyRingElem}}\n\njulia> t((M[1], M[2]))\nx*y*e[1] \\otimes e[1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"tor(M::ModuleFP, N::ModuleFP, i::Int)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#tor-Tuple{ModuleFP, ModuleFP, Int64}","page":"Homological Algebra","title":"tor","text":"tor(M::ModuleFP, N::ModuleFP, i::Int)\n\nReturn textTor_i(MN).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> A = R[x; y];\n\njulia> B = R[x^2; y^3; z^4];\n\njulia> M = SubquoModule(A, B);\n\njulia> F = free_module(R, 1);\n\njulia> Q, _ = quo(F, [x*F[1]]);\n\njulia> T0 = tor(Q, M, 0)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1] \\otimes e[1]\n2 -> y*e[1] \\otimes e[1]\nby Submodule with 4 generators\n1 -> x^2*e[1] \\otimes e[1]\n2 -> y^3*e[1] \\otimes e[1]\n3 -> z^4*e[1] \\otimes e[1]\n4 -> x*y*e[1] \\otimes e[1]\n\njulia> T1 = tor(Q, M, 1)\nSubquotient of Submodule with 1 generator\n1 -> -x*e[1] \\otimes e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1] \\otimes e[1]\n2 -> y^3*e[1] \\otimes e[1]\n3 -> z^4*e[1] \\otimes e[1]\n\njulia> T2 = tor(Q, M, 2)\nSubmodule with 0 generators\nrepresented as subquotient with no relations.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Fitting-Ideals","page":"Homological Algebra","title":"Fitting Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"fitting_ideal(M::ModuleFP{T}, i::Int) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#fitting_ideal-Union{Tuple{T}, Tuple{ModuleFP{T}, Int64}} where T<:MPolyRingElem","page":"Homological Algebra","title":"fitting_ideal","text":" fitting_ideal(M::ModuleFP{T}, i::Int) where T <: MPolyRingElem\n\nReturn the i-th Fitting ideal of M.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = free_module(R, 2);\n\njulia> o = zero(R)\n0\n\njulia> U = matrix([x^3-y^2 o; o x^3-y^2; -x^2 y; -y x])\n[x^3 - y^2 0]\n[ 0 x^3 - y^2]\n[ -x^2 y]\n[ -y x]\n\njulia> M = quo(F,U)[1]\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 4 generators\n1 -> (x^3 - y^2)*e[1]\n2 -> (x^3 - y^2)*e[2]\n3 -> -x^2*e[1] + y*e[2]\n4 -> -y*e[1] + x*e[2]\n\njulia> fitting_ideal(M, -1)\nideal(0)\n\njulia> fitting_ideal(M, 0)\nideal(x^3 - y^2)\n\njulia> fitting_ideal(M, 1)\nideal(y, x)\n\njulia> fitting_ideal(M, 2)\nideal(1)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Flatness","page":"Homological Algebra","title":"Flatness","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"Checking flatness in OSCAR relies on characterizing flatness in terms of Fitting ideals.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"is_flat(M::ModuleFP{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#is_flat-Union{Tuple{ModuleFP{T}}, Tuple{T}} where T<:MPolyRingElem","page":"Homological Algebra","title":"is_flat","text":" is_flat(M::ModuleFP{T}) where T <: MPolyRingElem\n\nReturn true if M is flat, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = free_module(R, 2);\n\njulia> o = zero(R)\n0\n\njulia> U = matrix([x^3-y^2 o; o x^3-y^2; -x^2 y; -y x])\n[x^3 - y^2 0]\n[ 0 x^3 - y^2]\n[ -x^2 y]\n[ -y x]\n\njulia> M = quo(F,U)[1]\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 4 generators\n1 -> (x^3 - y^2)*e[1]\n2 -> (x^3 - y^2)*e[2]\n3 -> -x^2*e[1] + y*e[2]\n4 -> -y*e[1] + x*e[2]\n\njulia> is_flat(M)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"non_flat_locus(M::ModuleFP{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#non_flat_locus-Union{Tuple{ModuleFP{T}}, Tuple{T}} where T<:MPolyRingElem","page":"Homological Algebra","title":"non_flat_locus","text":" non_flat_locus(M::ModuleFP{T}) where T <: MPolyRingElem\n\nReturn an ideal of base_ring(M) which defines the non-flat-locus of M in the sense that the localization of M at a prime ideal of base_ring(M) is non-flat iff the prime ideal contains the returned ideal.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> F = free_module(R, 2);\n\njulia> o = zero(R)\n0\n\njulia> U = matrix([x^3-y^2 o; o x^3-y^2; -x^2 y; -y x])\n[x^3 - y^2 0]\n[ 0 x^3 - y^2]\n[ -x^2 y]\n[ -y x]\n\njulia> M = quo(F,U)[1]\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 4 generators\n1 -> (x^3 - y^2)*e[1]\n2 -> (x^3 - y^2)*e[2]\n3 -> -x^2*e[1] + y*e[2]\n4 -> -y*e[1] + x*e[2]\n\njulia> non_flat_locus(M)\nideal(x^3 - y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Regular-Sequence-Test","page":"Homological Algebra","title":"Regular Sequence Test","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"is_regular_sequence(V::Vector{T}, M::ModuleFP{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#is_regular_sequence-Union{Tuple{T}, Tuple{Vector{T}, ModuleFP{T}}} where T<:MPolyRingElem","page":"Homological Algebra","title":"is_regular_sequence","text":" is_regular_sequence(V::Vector{T}, M::ModuleFP{T}) where T <: MPolyRingElem\n\nReturn true if the elements of V form, in the given order, a regular sequence on M. Return false, otherwise.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> V = [x*z-z, x*y-y, x]\n3-element Vector{QQMPolyRingElem}:\n x*z - z\n x*y - y\n x\n\njulia> is_regular_sequence(V, F)\nfalse\n\njulia> W = [x*z-z, x, x*y-y]\n3-element Vector{QQMPolyRingElem}:\n x*z - z\n x\n x*y - y\n\njulia> is_regular_sequence(W, F)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Koszul-Complex","page":"Homological Algebra","title":"Koszul Complex","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"koszul_matrix(V::Vector{T}, i::Int) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#koszul_matrix-Union{Tuple{T}, Tuple{Vector{T}, Int64}} where T<:MPolyRingElem","page":"Homological Algebra","title":"koszul_matrix","text":" koszul_matrix(V::Vector{T}, p::Int) where T <: MPolyRingElem\n\nIf f_1 dots f_r are the entries of V in the given order, return the matrix representing the p-th map of the Koszul complex K(f_1 dots f_r).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> V = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x\n y\n z\n\njulia> koszul_matrix(V, 3)\n[z -y x]\n\njulia> koszul_matrix(V, 2)\n[-y x 0]\n[-z 0 x]\n[ 0 -z y]\n\njulia> koszul_matrix(V, 1)\n[x]\n[y]\n[z]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"koszul_complex(V::Vector{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#koszul_complex-Union{Tuple{Vector{T}}, Tuple{T}} where T<:MPolyRingElem","page":"Homological Algebra","title":"koszul_complex","text":" koszul_complex(V::Vector{T}) where T <: MPolyRingElem\n\nIf f_1 dots f_r are the entries of V in the given order, return the Koszul complex K(f_1 dots f_r).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> V = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x\n y\n z\n\njulia> K = koszul_complex(V);\n\njulia> matrix(map(K, 2))\n[-y x 0]\n[-z 0 x]\n[ 0 -z y]\n\njulia> Kd = hom(K, free_module(R, 1));\n\njulia> matrix(map(Kd, 1))\n[-y -z 0]\n[ x 0 -z]\n[ 0 x y]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Koszul-Homology","page":"Homological Algebra","title":"Koszul Homology","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"koszul_homology(V::Vector{T}, M::ModuleFP{T}, p::Int) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#koszul_homology-Union{Tuple{T}, Tuple{Vector{T}, ModuleFP{T}, Int64}} where T<:MPolyRingElem","page":"Homological Algebra","title":"koszul_homology","text":" koszul_homology(V::Vector{T}, M::ModuleFP{T}, p::Int) where T <: MPolyRingElem\n\nIf f_1 dots f_r are the entries of V in the given order, return the p-th homology module of the complex K(f_1 dots f_r)otimes_R M, where K(f_1 dots f_r) is the Koszul complex defined by f_1 dots f_r.\n\nnote: Note\nSee Gert-Martin Greuel, Gerhard Pfister (2008) or Wolfram Decker, Christoph Lossen (2006) for the definition of the Koszul complex.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> V = [x*y, x*z, y*z]\n3-element Vector{QQMPolyRingElem}:\n x*y\n x*z\n y*z\n\njulia> koszul_homology(V, F, 0)\nSubmodule with 3 generators\n1 -> y*z*e[1]\n2 -> x*z*e[1]\n3 -> x*y*e[1]\nrepresented as subquotient with no relations.\n\njulia> koszul_homology(V, F, 1)\nSubmodule with 3 generators\n1 -> -z*e[1] + z*e[2]\n2 -> y*e[2]\n3 -> x*e[1]\nrepresented as subquotient with no relations.\n\njulia> koszul_homology(V, F, 2)\nSubmodule with 1 generator\n1 -> 0\nrepresented as subquotient with no relations.\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> TC = ideal(R, [x*z-y^2, w*z-x*y, w*y-x^2]);\n\njulia> F = free_module(R, 1);\n\njulia> koszul_homology(gens(TC), F, 0)\nSubmodule with 3 generators\n1 -> (-x*z + y^2)*e[1]\n2 -> (-w*z + x*y)*e[1]\n3 -> (-w*y + x^2)*e[1]\nrepresented as subquotient with no relations.\n\njulia> koszul_homology(gens(TC), F, 1)\nSubmodule with 3 generators\n1 -> y*e[1] - z*e[2]\n2 -> x*e[1] - y*e[2]\n3 -> w*e[1] - x*e[2]\nrepresented as subquotient with no relations.\n\njulia> koszul_homology(gens(TC), F, 2)\nSubmodule with 1 generator\n1 -> 0\nrepresented as subquotient with no relations.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#Depth","page":"Homological Algebra","title":"Depth","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"The computation of depth in OSCAR relies on expressing depth in terms of Koszul cohomology. ","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"depth(I::MPolyIdeal{T}, M::ModuleFP{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/homological_algebra/#depth-Union{Tuple{T}, Tuple{MPolyIdeal{T}, ModuleFP{T}}} where T<:MPolyRingElem","page":"Homological Algebra","title":"depth","text":" depth(I::MPolyIdeal{T}, M::ModuleFP{T}) where T <: MPolyRingElem\n\nReturn the depth of I on M.\n\nExamples\n\njulia> R, (w, x, y, z) = polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> TC = ideal(R, [x*z-y^2, w*z-x*y, w*y-x^2]);\n\njulia> dim(TC)\n2\n\njulia> F = free_module(R, 1);\n\njulia> U = collect(gen(TC, i)*F[1] for i in 1:ngens(TC));\n\njulia> M, _ = quo(F, U);\n\njulia> I = ideal(R, gens(R))\nideal(w, x, y, z)\n\njulia> depth(I, M)\n2\n\njulia> S, x, y = polynomial_ring(QQ, \"x\" => 1:3, \"y\" => 1:5);\n\njulia> W = [y[1]-x[1]^2, y[2]-x[2]^2, y[3]-x[3]^2, y[4]-x[2]*(x[1]-x[3]), y[5]-(x[1]-x[2])*x[3]];\n\njulia> J = eliminate(ideal(S, W), x);\n\njulia> R, y = polynomial_ring(QQ, \"y\" => 1:5);\n\njulia> W = append!(repeat([zero(R)], 3), gens(R))\n8-element Vector{QQMPolyRingElem}:\n 0\n 0\n 0\n y[1]\n y[2]\n y[3]\n y[4]\n y[5]\n\njulia> P = hom(S, R, W);\n\njulia> VP4 = P(J);\n\njulia> dim(VP4)\n3\n\njulia> F = free_module(R, 1);\n\njulia> U = collect(gen(VP4, i)*F[1] for i in 1:ngens(VP4));\n\njulia> M, _ = quo(F, U);\n\njulia> I = ideal(R, gens(R))\nideal(y[1], y[2], y[3], y[4], y[5])\n\njulia> depth(I, M)\n1\n\n\n\n\n\n","category":"method"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/developer/introduction/#Introduction-to-Nemo-development","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"","category":"section"},{"location":"Nemo/developer/introduction/#Relationship-to-AbstractAlgebra.jl","page":"Introduction to Nemo development","title":"Relationship to AbstractAlgebra.jl","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Some time in the past, Nemo was split into two packages called Nemo.jl and AbstractAlgebra.jl. The purpose was to provide a Julia only package which did some subset of what Nemo could do, albeit slower. This was requested by people in the Julia community.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Unfortunately this hasn't been terribly successful. Most Julia developers expect that AbstractAlgebra and Nemo functionality will work for Julia matrices over AbstractAlgebra/Nemo rings. This would be possible for functions that do not conflict with Base or LinearAlgebra at least when working with non-empty matrices. However, for reasons that we explain in both the Appendix to the AbstractAlgebra package and in the parent object section of the developer documentation, this is not possible even in theory for functions that would conflict with Julia's standard library or for empty matrices (except in a limited number of special cases).","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Unfortunately the Julia standard library functions do not work with matrices of Nemo objects and there is little we can do about this. Moreover, some Julia functionality isn't supported by the underlying C libraries in Nemo and would be difficult or impossible to provide on the C side.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Nowadays we see AbstractAlgebra to provide three things to Nemo:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"An abstract type hierarchy\nGeneric ring constructions, e.g. generic polynomials and matrices\nGeneric implementations that should work for any ring implementing the required interfaces. These interfaces are documented in the AbstractAlgebra documentation.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Nemo itself is now more or less just a wrapper of four C libraries:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Flint : polynomials and matrices over Z, Q, Z/nZ, Qp, Fq\nArb : polynomials, matrices and special functions over balls over R and C\nAntic : algebraic number field element arithmetic\nCalcium : exact real and complex numbers, including algebraic numbers","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Each ring implemented in those C libraries is wrapped in such a way as to implement the interfaces described by AbstractAlgebra.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Most of the time an AbstractAlgebra implementation will work just as well using Nemo, but the latter will usually be faster, due to the extremely performant C code (around half a million lines of it).","category":"page"},{"location":"Nemo/developer/introduction/#Layout-of-files","page":"Introduction to Nemo development","title":"Layout of files","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"In the src directory of Nemo are four directories flint, arb, antic and calcium, each containing the wrappers for the relevant C libraries. The test directory is similarly organised.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Within each of these directories is a set of files, one per module within the C libraries, e.g. the fmpz.jl file wraps the Flint fmpz module for multiple precision integers. The fmpz_poly.jl file wraps the Flint univariate polynomials over fmpz integers, and so on.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The QQFieldElem prefix is for Flint rationals, FqPolyRepFieldElem for Flint finite fields with multiprecision characteristic, fqPolyRepFieldElem is the same but for single word characteristic. The padic prefix is for the field of p-adic numbers for a given p. The zzModRingElem prefix is for Z/nZ for a given n. The gfp prefix is the same as Z/nZ but where n is prime, so that we are dealing with a field.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The FlintTypes.jl file contains the implementation of all the Flint types.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"In the antic directory, nf_elem is for elements of a number field.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The AnticTypes.jl file contains the Antic types.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"In the arb directory the arb prefix is for arbitrary precision ball arithmetic over the reals. The acb prefix is similar but for complex numbers.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The ArbTypes.jl file contains the Arb types.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"In the calcium directory the ca prefix is for Calcium's type. There is also a qqbar file for the field of algebraic numbers.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"In the AbstractAlgebra.jl package the src directory contains a directory called generic. This is where the implementations of generic types, such as matrices, polynomials, series, etc. reside. Each file such as Matrix.jl corresponds to a generic group/ring/field or other algebraic construction (typically over a base ring). The files in this directory exist inside a submodule of AbstractAlgebra called Generic.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The file GenericTypes.jl is where all the generic types are implemented.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"At the top level of the src directory is a file Generic.jl which is where the Generic submodule of AbstractAlgebra begins and where imports are made from AbstractAlgebra into Generic.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"In the src directory we have implementations that work for every type belonging to a given abstract type, e.g. Matrix.jl has implementations that will work for any matrix type, whether from AbstractAlgebra's Generic module or even matrix types from Nemo, and so on. So long as they are implemented to provide the Matrix interface all the functions there will work for them. The same applies for Poly.jl for polynomial types, AbsSeries.jl for absolute series types, RelSeries.jl for relative series types, etc.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"In the src directory is AbstractTypes.jl where all the AbstractAlgebra abstract types are defined.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Also in the src directory is a subdirectory called Julia. This is where we give our own implementations of functionality for Julia Integers and Rationals and various other basic rings implemented in terms of Julia types. These are provided so that the package will work as a pure Julia package, replacing many of the rings and fields that would be available in Flint and the other C libraries with Julia equivalents.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Note that some of the implementations we give there would conflict with Base and so are only available inside AbstractAlgebra and are not exported!","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"We try to keep the test directory at the top level of the source tree organised in the same manner as the other directories just discussed, though there is currently no split between tests for Generic and for the implementations in src. All tests are currently combined in test/generic..","category":"page"},{"location":"Nemo/developer/introduction/#Git,-GitHub-and-project-workflows","page":"Introduction to Nemo development","title":"Git, GitHub and project workflows","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The official repositories for AbstractAlgebra and Nemo are:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"https://github.com/Nemocas/AbstractAlgebra.jl","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"https://github.com/Nemocas/Nemo.jl","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"If you wish to contribute to these projects, the first step is to fork them on GitHub. The button for this is in the upper right of the main project page. You will need to sign up for a free GitHub account to do this.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Once you have your own GitHub copy of our repository you can push changes to it from your local machine and this will make them visible to the world.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Before sinking a huge amount of time into a contribution, please open a ticket on the official project page on GitHub explaining what you intend to do and discussing it with the other developers.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The easiest way to get going with development on your local machine is to dev AbstractAlgebra and/or Nemo. To do this, press the ] key in Julia to enter the special package mode and type:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"dev Nemo","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Now you will find a local copy on your machine of the Nemo repository in","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":".julia/dev/Nemo","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"However, this will be set up to push to the official repository instead of your own, so you will need to change this. For example, if your GitHub account name is myname, edit the .git/config file in your local Nemo directory to say:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":" url = https://github.com/Nemocas/Nemo.jl.git\n pushurl = https://github.com/myname/Nemo.jl","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"instead of just the first line which will already be there.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"It is highly recommended that you do not work in the master branch, but create a new branch for each thing you want to contribute to Nemo.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"git checkout -b mynewbranch","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"If your contribution is small and does not take a long time to implement, everything will likely be fine if you simply commit the changes locally, then push them to your GitHub account online:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"git commit -a\ngit push --all","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"However, if you are working on a much larger project it is highly recommended that you frequently pull from the official master branch and rebase your new branch on top of any changes that have been made there:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"git checkout master\ngit pull\ngit checkout mynewbranch\ngit rebase master","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Note that rebasing will try to rewrite each of your commits over the top of the branch you are rebasing on (master in this case). This process will have many steps if there are many commits and lots of conflicts. Simply follow the instructions until the process is finished.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"The longer you leave it before rebasing on master the longer the rebase process will take. It can eventually become overwhelming as it is not replaying the latest state of your repository over master, but each commit that you made in order. You may have completely forgotten what those older commits were about, so this can become very difficult if not done regularly.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Once you have pushed your changes to your GitHub account, go to the official project GitHub page and you should see your branch mentioned near the top of the page. Open a pull request.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Someone will review your code and suggest changes they'd like made. Simply add more commits to your branch and push again. They will automatically get added to your pull request.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Note that we don't accept code without tests and documentation. We use Documenter.jl for our documentation, in Markdown format. See our existing code for examples of docstrings above functions in the source code and look in the docs/src directory to see how these docstrings are merged into our online documentation.","category":"page"},{"location":"Nemo/developer/introduction/#Development-list","page":"Introduction to Nemo development","title":"Development list","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"All developers of AbstractAlgebra and Nemo are welcome to write to our development list to ask questions and discuss development:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"https://groups.google.com/g/nemo-devel","category":"page"},{"location":"Nemo/developer/introduction/#Reporting-bugs","page":"Introduction to Nemo development","title":"Reporting bugs","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Bugs should be reported by opening an issue (ticket) on the official GitHub page for the relevant project. Please state the Julia version being used, the machine you are using and the version of AbstractAlgebra/Nemo you are using. The version can be found in the Project.toml file at the top level of the source tree.","category":"page"},{"location":"Nemo/developer/introduction/#Development-roadmap","page":"Introduction to Nemo development","title":"Development roadmap","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"AbstractAlgebra has a special roadmap ticket which lists the most important tickets that have been opened. If you want to contribute something high value this is the place to start:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"https://github.com/Nemocas/AbstractAlgebra.jl/issues/492","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"This ticket is updated every so often.","category":"page"},{"location":"Nemo/developer/introduction/#Binaries","page":"Introduction to Nemo development","title":"Binaries","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Binaries of C libraries for Nemo are currently made in a separate repository:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"https://github.com/JuliaPackaging/Yggdrasil","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"If code is added to any of the C libraries used by Nemo, this jll package must be updated first and the version updated in Nemo.jl before the new functionality can be used. Ask the core developers for help with this as various other tasks must be completed at the same time.","category":"page"},{"location":"Nemo/developer/introduction/#Relationship-to-Oscar","page":"Introduction to Nemo development","title":"Relationship to Oscar","text":"","category":"section"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Nemo and AbstractAlgebra are heavily used by the Oscar computer algebra system being developed in Germany by a number of universities involved in a large project known as TRR 195, funded by the DFG.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"Oscar is the number one customer for Nemo. Many bugs in Nemo are found and fixed by Oscar developers and most of the key Nemo developers are part of the Oscar project.","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"See the Oscar website for further details:","category":"page"},{"location":"Nemo/developer/introduction/","page":"Introduction to Nemo development","title":"Introduction to Nemo development","text":"https://www.oscar-system.org/","category":"page"},{"location":"Hecke/abelian/maps/","page":"-","title":"-","text":"Maps between abelian groups are mainly of type GrpAbFinGenMap. They allow normal map operations such as image, preimage, domain, codomain and can be created in a variety of situations.","category":"page"},{"location":"Hecke/abelian/maps/#Maps","page":"-","title":"Maps","text":"","category":"section"},{"location":"Hecke/abelian/maps/","page":"-","title":"-","text":"Maps between abelian groups can be constructed via","category":"page"},{"location":"Hecke/abelian/maps/","page":"-","title":"-","text":"images of the generators\npairs of elements\nvia composition\nand isomorphism/ inclusion testing","category":"page"},{"location":"Hecke/abelian/maps/","page":"-","title":"-","text":"hom(G::GrpAbFinGen, H::GrpAbFinGen, A::Matrix{ <: Map{GrpAbFinGen, GrpAbFinGen}})\nis_isomorphic(G::GrpAbFinGen, H::GrpAbFinGen)","category":"page"},{"location":"Hecke/abelian/maps/#hom-Tuple{GrpAbFinGen, GrpAbFinGen, Matrix{<:Map{GrpAbFinGen, GrpAbFinGen}}}","page":"-","title":"hom","text":"hom(G::GrpAbFinGen, H::GrpAbFinGen, A::Matrix{ <: Map{GrpAbFinGen, GrpAbFinGen}}) -> Map\n\nGiven groups G and H that are created as direct products as well as a matrix A containing maps Aij G_i to H_j, return the induced homomorphism.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/maps/#is_isomorphic-Tuple{GrpAbFinGen, GrpAbFinGen}","page":"-","title":"is_isomorphic","text":"is_isomorphic(G::GrpAbFinGen, H::GrpAbFinGen) -> Bool\n\nReturn whether G and H are isomorphic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/maps/","page":"-","title":"-","text":"using Hecke # hide\nG = free_abelian_group(2)\nh = hom(G, G, [gen(G, 2), 3*gen(G, 1)])\nh(gen(G, 1))\nh(gen(G, 2))","category":"page"},{"location":"Hecke/abelian/maps/","page":"-","title":"-","text":"Homomorphisms also allow addition and subtraction corresponding to the pointwise operation:","category":"page"},{"location":"Hecke/abelian/maps/","page":"-","title":"-","text":"using Hecke # hide\nG = free_abelian_group(2)\nh = hom(G, G, [2*gen(G, 2), 3*gen(G, 1)])\n(h+h)(gen(G, 1))","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/real/#Arbitrary-precision-real-balls","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Arbitrary precision real ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Real numbers are represented in mid-rad interval form m pm r = m-r m+r.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"The types of real balls in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Library Field Element type Parent type\nArb mathbbR (balls) RealFieldElem RealField","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"The real field types belong to the Field abstract type and the types of elements in this field, i.e. balls in this case, belong to the FieldElem abstract type.","category":"page"},{"location":"Nemo/real/#Real-ball-functionality","page":"Arbitrary precision real balls","title":"Real ball functionality","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Real balls in Nemo provide all the field functionality described in AbstractAlgebra:","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Below, we document the additional functionality provided for real balls.","category":"page"},{"location":"Nemo/real/#precision_management","page":"Arbitrary precision real balls","title":"Precision management","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Precision for ball arithmetic and creation of elements can be controlled using the functions:","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"precision(::Type{Balls})\nset_precision!(::Type{Balls}, n::Int)\nset_precision!(f::Any, ::Type{Balls}, n::Int)","category":"page"},{"location":"Nemo/real/#precision-Tuple{Type{Balls}}","page":"Arbitrary precision real balls","title":"precision","text":"precision(::Type{Balls})\n\nReturn the precision for ball arithmetic.\n\nExamples\n\njulia> set_precision!(Balls, 200); precision(Balls)\n200\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/#set_precision!-Tuple{Type{Balls}, Int64}","page":"Arbitrary precision real balls","title":"set_precision!","text":"set_precision!(::Type{Balls}, n::Int)\n\nSet the precision for all ball arithmetic to be n.\n\nExamples\n\njulia> const_pi(RealField())\n[3.141592653589793239 +/- 5.96e-19]\n\njulia> set_precision!(Balls, 200); const_pi(RealField())\n[3.14159265358979323846264338327950288419716939937510582097494 +/- 5.73e-60]\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/#set_precision!-Tuple{Any, Type{Balls}, Int64}","page":"Arbitrary precision real balls","title":"set_precision!","text":"set_precision!(f, ::Type{Balls}, n::Int)\n\nChange ball arithmetic precision to n for the duration of f..\n\nExamples\n\njulia> set_precision!(Balls, 4) do\n const_pi(RealField())\n end\n[3e+0 +/- 0.376]\n\njulia> set_precision!(Balls, 200) do\n const_pi(RealField())\n end\n[3.1415926535897932385 +/- 3.74e-20]\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"info: Info\nThis functions are not thread-safe.","category":"page"},{"location":"Nemo/real/#Constructors","page":"Arbitrary precision real balls","title":"Constructors","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"In order to construct real balls in Nemo, one must first construct the Arb real field itself. This is accomplished with the following constructor.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"RealField()","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Here is an example of creating the real field and using the resulting parent object to coerce values into the resulting field.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> a = RR(\"0.25\")\n0.25000000000000000000\n\njulia> b = RR(\"0.1 +/- 0.001\")\n[0.1 +/- 1.01e-3]\n\njulia> c = RR(0.5)\n0.50000000000000000000\n\njulia> d = RR(12)\n12.000000000000000000","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Note that whilst one can coerce double precision floating point values into an Arb real field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb field.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.","category":"page"},{"location":"Nemo/real/#Real-ball-constructors","page":"Arbitrary precision real balls","title":"Real ball constructors","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Using coercion into the real field, new elements can be created.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> c = RR(1)\n1.0000000000000000000\n\njulia> d = RR(1//2)\n0.50000000000000000000","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Note that for the construction, also the precision can be supplied:","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"RR = RealField()\n\nc = RR(1, precision = 100)\nd = RR(1//2, precision = 4)","category":"page"},{"location":"Nemo/real/#Conversions","page":"Arbitrary precision real balls","title":"Conversions","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> convert(Float64, RR(1//3))\n0.3333333333333333","category":"page"},{"location":"Nemo/real/#Basic-manipulation","page":"Arbitrary precision real balls","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"is_nonzero(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#is_nonzero-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"is_nonzero","text":"is_nonzero(x::RealFieldElem)\n\nReturn true if x is certainly not equal to zero, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"isfinite(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#isfinite-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"isfinite","text":"isfinite(x::RealFieldElem)\n\nReturn true if x is finite, i.e. having finite midpoint and radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"is_exact(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#is_exact-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"is_exact","text":"is_exact(x::RealFieldElem)\n\nReturn true if x is exact, i.e. has zero radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"isinteger(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#isinteger-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"isinteger","text":"isinteger(x::RealFieldElem)\n\nReturn true if x is an exact integer, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"is_positive(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#is_positive-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"is_positive","text":"is_positive(x::RealFieldElem)\n\nReturn true if x is certainly positive, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"is_nonnegative(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#is_nonnegative-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"is_nonnegative","text":"is_nonnegative(x::RealFieldElem)\n\nReturn true if x is certainly nonnegative, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"is_negative(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#is_negative-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"is_negative","text":"is_negative(x::RealFieldElem)\n\nReturn true if x is certainly negative, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"is_nonpositive(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#is_nonpositive-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"is_nonpositive","text":"is_nonpositive(x::RealFieldElem)\n\nReturn true if x is certainly nonpositive, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"midpoint(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#midpoint-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"midpoint","text":"midpoint(x::RealFieldElem)\n\nReturn the midpoint of the ball x as an Arb ball.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"radius(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#radius-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"radius","text":"radius(x::RealFieldElem)\n\nReturn the radius of the ball x as an Arb ball.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"accuracy_bits(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#accuracy_bits-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"accuracy_bits","text":"accuracy_bits(x::RealFieldElem)\n\nReturn the relative accuracy of x measured in bits, capped between typemax(Int) and -typemax(Int).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> a = RR(\"1.2 +/- 0.001\")\n[1.20 +/- 1.01e-3]\n\njulia> b = RR(3)\n3.0000000000000000000\n\njulia> is_positive(a)\ntrue\n\njulia> isfinite(b)\ntrue\n\njulia> isinteger(b)\ntrue\n\njulia> is_negative(a)\nfalse\n\njulia> c = radius(a)\n[0.0010000000038417056203 +/- 1.12e-23]\n\njulia> d = midpoint(b)\n3.0000000000000000000\n\njulia> f = accuracy_bits(a)\n9","category":"page"},{"location":"Nemo/real/#Printing","page":"Arbitrary precision real balls","title":"Printing","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Printing real balls can at first sight be confusing. Lets look at the following example:","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"RR = RealField()\n\na = RR(1)\nb = RR(2)\nc = RR(12)\n\nx = ball(a, b)\ny = ball(c, b)\n\nmid = midpoint(x)\nrad = radius(x)\n\nprint(x, \"\\n\", y, \"\\n\", mid, \"\\n\", rad)","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"which generates","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"[+/- 3.01]\n[1e+1 +/- 4.01]\n1.0000000000000000000\n[2.0000000037252902985 +/- 3.81e-20]","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"The first reason that c is not printed as [1 +/- 2] is that the midpoint does not have a greater exponent than the radius in its scientific notation. For similar reasons y is not printed as [12 +/- 2].","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"The second reason is that we get an additional error term after our addition. As we see, radius(c) is not equal to 2, which when printed rounds it up to a reasonable decimal place. This is because real balls keep track of rounding errors of basic arithmetic.","category":"page"},{"location":"Nemo/real/#Containment","page":"Arbitrary precision real balls","title":"Containment","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"It is often necessary to determine whether a given exact value or ball is contained in a given real ball or whether two balls overlap. The following functions are provided for this purpose.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"overlaps(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#overlaps-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"overlaps","text":"overlaps(x::RealFieldElem, y::RealFieldElem)\n\nReturns true if any part of the ball x overlaps any part of the ball y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"contains(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#contains-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"contains","text":"contains(x::RealFieldElem, y::RealFieldElem)\n\nReturns true if the ball x contains the ball y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"contains(::RealFieldElem, ::Integer)\ncontains(::RealFieldElem, ::ZZRingElem)\ncontains(::RealFieldElem, ::QQFieldElem)\ncontains{T <: Integer}(::RealFieldElem, ::Rational{T})\ncontains(::RealFieldElem, ::BigFloat)","category":"page"},{"location":"Nemo/real/#contains-Tuple{RealFieldElem, Integer}","page":"Arbitrary precision real balls","title":"contains","text":"contains(x::RealFieldElem, y::Integer)\n\nReturns true if the ball x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/#contains-Tuple{RealFieldElem, ZZRingElem}","page":"Arbitrary precision real balls","title":"contains","text":"contains(x::RealFieldElem, y::ZZRingElem)\n\nReturns true if the ball x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/#contains-Tuple{RealFieldElem, QQFieldElem}","page":"Arbitrary precision real balls","title":"contains","text":"contains(x::RealFieldElem, y::QQFieldElem)\n\nReturns true if the ball x contains the given rational value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/#contains-Union{Tuple{T}, Tuple{RealFieldElem, Rational{T}}} where T<:Integer","page":"Arbitrary precision real balls","title":"contains","text":"contains(x::RealFieldElem, y::Rational{T}) where {T <: Integer}\n\nReturns true if the ball x contains the given rational value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/#contains-Tuple{RealFieldElem, BigFloat}","page":"Arbitrary precision real balls","title":"contains","text":"contains(x::RealFieldElem, y::BigFloat)\n\nReturns true if the ball x contains the given floating point value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"The following functions are also provided for determining if a ball intersects a certain part of the real number line.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"contains_zero(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#contains_zero-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"contains_zero","text":"contains_zero(x::RealFieldElem)\n\nReturns true if the ball x contains zero, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"contains_negative(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#contains_negative-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"contains_negative","text":"contains_negative(x::RealFieldElem)\n\nReturns true if the ball x contains any negative value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"contains_positive(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#contains_positive-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"contains_positive","text":"contains_positive(x::RealFieldElem)\n\nReturns true if the ball x contains any positive value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"contains_nonnegative(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#contains_nonnegative-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"contains_nonnegative","text":"contains_nonnegative(x::RealFieldElem)\n\nReturns true if the ball x contains any nonnegative value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"contains_nonpositive(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#contains_nonpositive-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"contains_nonpositive","text":"contains_nonpositive(x::RealFieldElem)\n\nReturns true if the ball x contains any nonpositive value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> x = RR(\"1 +/- 0.001\")\n[1.00 +/- 1.01e-3]\n\njulia> y = RR(\"3\")\n3.0000000000000000000\n\njulia> overlaps(x, y)\nfalse\n\njulia> contains(x, y)\nfalse\n\njulia> contains(y, 3)\ntrue\n\njulia> contains(x, ZZ(1)//2)\nfalse\n\njulia> contains_zero(x)\nfalse\n\njulia> contains_positive(y)\ntrue","category":"page"},{"location":"Nemo/real/#Comparison","page":"Arbitrary precision real balls","title":"Comparison","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Nemo provides a full range of comparison operations for Arb balls. Note that a ball is considered less than another ball if every value in the first ball is less than every value in the second ball, etc.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"In addition to the standard comparison operators, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"isequal(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#isequal-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"isequal","text":"isequal(x::RealFieldElem, y::RealFieldElem)\n\nReturn true if the balls x and y are precisely equal, i.e. have the same midpoints and radii.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"We also provide a full range of ad hoc comparison operators. These are implemented directly in Julia, but we document them as though isless and == were provided.","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Function\n==(x::RealFieldElem, y::Integer)\n==(x::Integer, y::RealFieldElem)\n==(x::RealFieldElem, y::ZZRingElem)\n==(x::ZZRingElem, y::RealFieldElem)\n==(x::RealFieldElem, y::Float64)\n==(x::Float64, y::RealFieldElem)\nisless(x::RealFieldElem, y::Integer)\nisless(x::Integer, y::RealFieldElem)\nisless(x::RealFieldElem, y::ZZRingElem)\nisless(x::ZZRingElem, y::RealFieldElem)\nisless(x::RealFieldElem, y::Float64)\nisless(x::Float64, y::RealFieldElem)\nisless(x::RealFieldElem, y::BigFloat)\nisless(x::BigFloat, y::RealFieldElem)\nisless(x::RealFieldElem, y::QQFieldElem)\nisless(x::QQFieldElem, y::RealFieldElem)","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> x = RR(\"1 +/- 0.001\")\n[1.00 +/- 1.01e-3]\n\njulia> y = RR(\"3\")\n3.0000000000000000000\n\njulia> z = RR(\"4\")\n4.0000000000000000000\n\njulia> isequal(x, deepcopy(x))\ntrue\n\njulia> x == 3\nfalse\n\njulia> ZZ(3) < z\ntrue\n\njulia> x != 1.23\ntrue","category":"page"},{"location":"Nemo/real/#Absolute-value","page":"Arbitrary precision real balls","title":"Absolute value","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> x = RR(\"-1 +/- 0.001\")\n[-1.00 +/- 1.01e-3]\n\njulia> a = abs(x)\n[1.00 +/- 1.01e-3]","category":"page"},{"location":"Nemo/real/#Shifting","page":"Arbitrary precision real balls","title":"Shifting","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> x = RR(\"-3 +/- 0.001\")\n[-3.00 +/- 1.01e-3]\n\njulia> a = ldexp(x, 23)\n[-2.52e+7 +/- 4.26e+4]\n\njulia> b = ldexp(x, -ZZ(15))\n[-9.16e-5 +/- 7.78e-8]","category":"page"},{"location":"Nemo/real/#Miscellaneous-operations","page":"Arbitrary precision real balls","title":"Miscellaneous operations","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"add_error!(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#add_error!-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"add_error!","text":"add_error!(x::RealFieldElem, y::RealFieldElem)\n\nAdds the absolute values of the midpoint and radius of y to the radius of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"trim(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#trim-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"trim","text":"trim(x::RealFieldElem)\n\nReturn an arb interval containing x but which may be more economical, by rounding off insignificant bits from the midpoint.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"unique_integer(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#unique_integer-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"unique_integer","text":"unique_integer(x::RealFieldElem)\n\nReturn a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the interval x contains a unique integer. If this is the case, the second return value is set to this unique integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"setunion(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#setunion-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"setunion","text":"setunion(x::RealFieldElem, y::RealFieldElem)\n\nReturn an arb containing the union of the intervals represented by x and y.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> x = RR(\"-3 +/- 0.001\")\n[-3.00 +/- 1.01e-3]\n\njulia> y = RR(\"2 +/- 0.5\")\n[2e+0 +/- 0.501]\n\njulia> a = trim(x)\n[-3.00 +/- 1.01e-3]\n\njulia> b, c = unique_integer(x)\n(true, -3)\n\njulia> d = setunion(x, y)\n[+/- 3.01]","category":"page"},{"location":"Nemo/real/#Constants","page":"Arbitrary precision real balls","title":"Constants","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_pi(::RealField)","category":"page"},{"location":"Nemo/real/#const_pi-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_pi","text":"const_pi(r::RealField)\n\nReturn pi = 314159ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_e(::RealField)","category":"page"},{"location":"Nemo/real/#const_e-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_e","text":"const_e(r::RealField)\n\nReturn e = 271828ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_log2(::RealField)","category":"page"},{"location":"Nemo/real/#const_log2-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_log2","text":"const_log2(r::RealField)\n\nReturn log(2) = 069314ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_log10(::RealField)","category":"page"},{"location":"Nemo/real/#const_log10-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_log10","text":"const_log10(r::RealField)\n\nReturn log(10) = 2302585ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_euler(::RealField)","category":"page"},{"location":"Nemo/real/#const_euler-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_euler","text":"const_euler(r::RealField)\n\nReturn Euler's constant gamma = 0577215ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_catalan(::RealField)","category":"page"},{"location":"Nemo/real/#const_catalan-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_catalan","text":"const_catalan(r::RealField)\n\nReturn Catalan's constant C = 0915965ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_khinchin(::RealField)","category":"page"},{"location":"Nemo/real/#const_khinchin-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_khinchin","text":"const_khinchin(r::RealField)\n\nReturn Khinchin's constant K = 2685452ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"const_glaisher(::RealField)","category":"page"},{"location":"Nemo/real/#const_glaisher-Tuple{RealField}","page":"Arbitrary precision real balls","title":"const_glaisher","text":"const_glaisher(r::RealField)\n\nReturn Glaisher's constant A = 1282427ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> a = const_pi(RR)\n[3.141592653589793239 +/- 5.96e-19]\n\njulia> b = const_e(RR)\n[2.718281828459045235 +/- 4.29e-19]\n\njulia> c = const_euler(RR)\n[0.5772156649015328606 +/- 4.35e-20]\n\njulia> d = const_glaisher(RR)\n[1.282427129100622637 +/- 3.01e-19]","category":"page"},{"location":"Nemo/real/#Mathematical-and-special-functions","page":"Arbitrary precision real balls","title":"Mathematical and special functions","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"rsqrt(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#rsqrt-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"rsqrt","text":"rsqrt(x::RealFieldElem)\n\nReturn the reciprocal of the square root of x, i.e. 1sqrtx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"sqrt1pm1(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#sqrt1pm1-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"sqrt1pm1","text":"sqrt1pm1(x::RealFieldElem)\n\nReturn sqrt1+x-1, evaluated accurately for small x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"sqrtpos(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#sqrtpos-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"sqrtpos","text":"sqrtpos(x::RealFieldElem)\n\nReturn the sqrt root of x, assuming that x represents a nonnegative number. Thus any negative number in the input interval is discarded.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"gamma(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#gamma-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"gamma","text":"gamma(x::RealFieldElem)\n\nReturn the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"lgamma(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#lgamma-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"lgamma","text":"lgamma(x::RealFieldElem)\n\nReturn the logarithm of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"rgamma(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#rgamma-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"rgamma","text":"rgamma(x::RealFieldElem)\n\nReturn the reciprocal of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"digamma(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#digamma-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"digamma","text":"digamma(x::RealFieldElem)\n\nReturn the logarithmic derivative of the gamma function evaluated at x, i.e. psi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"gamma(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#gamma-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"gamma","text":"gamma(s::RealFieldElem, x::RealFieldElem)\n\nReturn the upper incomplete gamma function Gamma(sx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"gamma_regularized(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#gamma_regularized-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"gamma_regularized","text":"gamma_regularized(s::RealFieldElem, x::RealFieldElem)\n\nReturn the regularized upper incomplete gamma function Gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"gamma_lower(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#gamma_lower-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"gamma_lower","text":"gamma_lower(s::RealFieldElem, x::RealFieldElem)\n\nReturn the lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"gamma_lower_regularized(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#gamma_lower_regularized-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"gamma_lower_regularized","text":"gamma_lower_regularized(s::RealFieldElem, x::RealFieldElem)\n\nReturn the regularized lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"zeta(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#zeta-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"zeta","text":"zeta(x::RealFieldElem)\n\nReturn the Riemann zeta function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"atan2(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#atan2-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"atan2","text":"atan2(y::RealFieldElem, x::RealFieldElem)\n\nReturn operatornameatan2(yx) = arg(x+yi). Same as atan(y, x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"agm(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#agm-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"agm","text":"agm(x::RealFieldElem, y::RealFieldElem)\n\nReturn the arithmetic-geometric mean of x and y\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"zeta(::RealFieldElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#zeta-Tuple{RealFieldElem, RealFieldElem}","page":"Arbitrary precision real balls","title":"zeta","text":"zeta(s::RealFieldElem, a::RealFieldElem)\n\nReturn the Hurwitz zeta function zeta(sa).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"root(::RealFieldElem, ::Int)","category":"page"},{"location":"Nemo/real/#root-Tuple{RealFieldElem, Int64}","page":"Arbitrary precision real balls","title":"root","text":"root(x::RealFieldElem, n::Int)\n\nReturn the n-th root of x. We require x geq 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"factorial(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#factorial-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"factorial","text":"factorial(x::RealFieldElem)\n\nReturn the factorial of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"factorial(::Int, ::RealField)","category":"page"},{"location":"Nemo/real/#factorial-Tuple{Int64, RealField}","page":"Arbitrary precision real balls","title":"factorial","text":"factorial(n::Int, r::RealField)\n\nReturn the factorial of n in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"binomial(::RealFieldElem, ::UInt)","category":"page"},{"location":"Nemo/real/#binomial-Tuple{RealFieldElem, UInt64}","page":"Arbitrary precision real balls","title":"binomial","text":"binomial(x::RealFieldElem, n::UInt)\n\nReturn the binomial coefficient x choose n.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"binomial(::UInt, ::UInt, ::RealField)","category":"page"},{"location":"Nemo/real/#binomial-Tuple{UInt64, UInt64, RealField}","page":"Arbitrary precision real balls","title":"binomial","text":"binomial(n::UInt, k::UInt, r::RealField)\n\nReturn the binomial coefficient n choose k in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"fibonacci(::ZZRingElem, ::RealField)","category":"page"},{"location":"Nemo/real/#fibonacci-Tuple{ZZRingElem, RealField}","page":"Arbitrary precision real balls","title":"fibonacci","text":"fibonacci(n::ZZRingElem, r::RealField)\n\nReturn the n-th Fibonacci number in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"fibonacci(::Int, ::RealField)","category":"page"},{"location":"Nemo/real/#fibonacci-Tuple{Int64, RealField}","page":"Arbitrary precision real balls","title":"fibonacci","text":"fibonacci(n::Int, r::RealField)\n\nReturn the n-th Fibonacci number in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"gamma(::ZZRingElem, ::RealField)","category":"page"},{"location":"Nemo/real/#gamma-Tuple{ZZRingElem, RealField}","page":"Arbitrary precision real balls","title":"gamma","text":"gamma(x::ZZRingElem, r::RealField)\n\nReturn the Gamma function evaluated at x in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"gamma(::QQFieldElem, ::RealField)","category":"page"},{"location":"Nemo/real/#gamma-Tuple{QQFieldElem, RealField}","page":"Arbitrary precision real balls","title":"gamma","text":"gamma(x::QQFieldElem, r::RealField)\n\nReturn the Gamma function evaluated at x in the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"zeta(::Int, ::RealField)","category":"page"},{"location":"Nemo/real/#zeta-Tuple{Int64, RealField}","page":"Arbitrary precision real balls","title":"zeta","text":"zeta(n::Int, r::RealField)\n\nReturn the Riemann zeta function zeta(n) as an element of the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"bernoulli(::Int, ::RealField)","category":"page"},{"location":"Nemo/real/#bernoulli-Tuple{Int64, RealField}","page":"Arbitrary precision real balls","title":"bernoulli","text":"bernoulli(n::Int, r::RealField)\n\nReturn the n-th Bernoulli number as an element of the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"rising_factorial(::RealFieldElem, ::Int)","category":"page"},{"location":"Nemo/real/#rising_factorial-Tuple{RealFieldElem, Int64}","page":"Arbitrary precision real balls","title":"rising_factorial","text":"rising_factorial(x::RealFieldElem, n::Int)\n\nReturn the rising factorial x(x + 1)ldots (x + n - 1) as an Arb.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"rising_factorial(::QQFieldElem, ::Int, ::RealField)","category":"page"},{"location":"Nemo/real/#rising_factorial-Tuple{QQFieldElem, Int64, RealField}","page":"Arbitrary precision real balls","title":"rising_factorial","text":"rising_factorial(x::QQFieldElem, n::Int, r::RealField)\n\nReturn the rising factorial x(x + 1)ldots (x + n - 1) as an element of the given Arb field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"rising_factorial2(::RealFieldElem, ::Int)","category":"page"},{"location":"Nemo/real/#rising_factorial2-Tuple{RealFieldElem, Int64}","page":"Arbitrary precision real balls","title":"rising_factorial2","text":"rising_factorial2(x::RealFieldElem, n::Int)\n\nReturn a tuple containing the rising factorial x(x + 1)ldots (x + n - 1) and its derivative.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"polylog(::Union{RealFieldElem,Int}, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#polylog-Tuple{Union{Int64, RealFieldElem}, RealFieldElem}","page":"Arbitrary precision real balls","title":"polylog","text":"polylog(s::Union{RealFieldElem,Int}, a::RealFieldElem)\n\nReturn the polylogarithm Li_s(a).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"chebyshev_t(::Int, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#chebyshev_t-Tuple{Int64, RealFieldElem}","page":"Arbitrary precision real balls","title":"chebyshev_t","text":"chebyshev_t(n::Int, x::RealFieldElem)\n\nReturn the value of the Chebyshev polynomial T_n(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"chebyshev_u(::Int, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#chebyshev_u-Tuple{Int64, RealFieldElem}","page":"Arbitrary precision real balls","title":"chebyshev_u","text":"chebyshev_u(n::Int, x::RealFieldElem)\n\nReturn the value of the Chebyshev polynomial U_n(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"chebyshev_t2(::Int, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#chebyshev_t2-Tuple{Int64, RealFieldElem}","page":"Arbitrary precision real balls","title":"chebyshev_t2","text":"chebyshev_t2(n::Int, x::RealFieldElem)\n\nReturn the tuple (T_n(x) T_n-1(x)).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"chebyshev_u2(::Int, ::RealFieldElem)","category":"page"},{"location":"Nemo/real/#chebyshev_u2-Tuple{Int64, RealFieldElem}","page":"Arbitrary precision real balls","title":"chebyshev_u2","text":"chebyshev_u2(n::Int, x::RealFieldElem)\n\nReturn the tuple (U_n(x) U_n-1(x))\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"bell(::ZZRingElem, ::RealField)","category":"page"},{"location":"Nemo/real/#bell-Tuple{ZZRingElem, RealField}","page":"Arbitrary precision real balls","title":"bell","text":"bell(n::ZZRingElem, r::RealField)\n\nReturn the Bell number B_n as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"bell(::Int, ::RealField)","category":"page"},{"location":"Nemo/real/#bell-Tuple{Int64, RealField}","page":"Arbitrary precision real balls","title":"bell","text":"bell(n::Int, r::RealField)\n\nReturn the Bell number B_n as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"numpart(::ZZRingElem, ::RealField)","category":"page"},{"location":"Nemo/real/#numpart-Tuple{ZZRingElem, RealField}","page":"Arbitrary precision real balls","title":"numpart","text":"numpart(n::ZZRingElem, r::RealField)\n\nReturn the number of partitions p(n) as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"numpart(::Int, ::RealField)","category":"page"},{"location":"Nemo/real/#numpart-Tuple{Int64, RealField}","page":"Arbitrary precision real balls","title":"numpart","text":"numpart(n::Int, r::RealField)\n\nReturn the number of partitions p(n) as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"airy_ai(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#airy_ai-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"airy_ai","text":"airy_ai(x::RealFieldElem)\n\nReturn the Airy function operatornameAi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"airy_ai_prime(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#airy_ai_prime-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"airy_ai_prime","text":"airy_ai_prime(x::RealFieldElem)\n\nReturn the derivative of the Airy function operatornameAi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"airy_bi(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#airy_bi-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"airy_bi","text":"airy_bi(x::RealFieldElem)\n\nReturn the Airy function operatornameBi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"airy_bi_prime(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#airy_bi_prime-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"airy_bi_prime","text":"airy_bi_prime(x::RealFieldElem)\n\nReturn the derivative of the Airy function operatornameBi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"julia> RR = RealField()\nReal field\n\njulia> a = floor(exp(RR(1)))\n2.0000000000000000000\n\njulia> b = sinpi(QQ(5,6), RR)\n0.50000000000000000000\n\njulia> c = gamma(QQ(1,3), RR)\n[2.678938534707747634 +/- 7.13e-19]\n\njulia> d = bernoulli(1000, RR)\n[-5.318704469415522036e+1769 +/- 6.61e+1750]\n\njulia> f = polylog(3, RR(-10))\n[-5.92106480375697 +/- 6.68e-15]","category":"page"},{"location":"Nemo/real/#Linear-dependence","page":"Arbitrary precision real balls","title":"Linear dependence","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"lindep(::Vector{RealFieldElem}, n::Int)","category":"page"},{"location":"Nemo/real/#lindep-Tuple{Vector{RealFieldElem}, Int64}","page":"Arbitrary precision real balls","title":"lindep","text":"lindep(A::Vector{RealFieldElem}, bits::Int)\n\nFind a small linear combination of the entries of the array A that is small (using LLL). The entries are first scaled by the given number of bits before truncating to integers for use in LLL. This function can be used to find linear dependence between a list of real numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.\n\nExamples\n\njulia> RR = RealField()\nReal field\n\njulia> a = RR(-0.33198902958450931620250069492231652319)\n[-0.33198902958450932088 +/- 4.15e-22]\n\njulia> V = [RR(1), a, a^2, a^3, a^4, a^5]\n6-element Vector{RealFieldElem}:\n 1.0000000000000000000\n [-0.33198902958450932088 +/- 4.15e-22]\n [0.11021671576446420510 +/- 7.87e-21]\n [-0.03659074051063616184 +/- 4.17e-21]\n [0.012147724433904692427 +/- 4.99e-22]\n [-0.004032911246472051677 +/- 6.25e-22]\n\njulia> W = lindep(V, 20)\n6-element Vector{ZZRingElem}:\n 1\n 3\n 0\n 0\n 0\n 1\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"simplest_rational_inside(::RealFieldElem)","category":"page"},{"location":"Nemo/real/#simplest_rational_inside-Tuple{RealFieldElem}","page":"Arbitrary precision real balls","title":"simplest_rational_inside","text":" simplest_rational_inside(x::RealFieldElem)\n\nReturn the simplest fraction inside the ball x. A canonical fraction a_1b_1 is defined to be simpler than a_2b_2 iff b_1 b_2 or b_1 = b_2 and a_1 a_2.\n\nExamples\n\njulia> RR = RealField()\nReal field\n\njulia> simplest_rational_inside(const_pi(RR))\n8717442233//2774848045\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/#Random-generation","page":"Arbitrary precision real balls","title":"Random generation","text":"","category":"section"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"rand(::RealField)","category":"page"},{"location":"Nemo/real/#rand-Tuple{RealField}","page":"Arbitrary precision real balls","title":"rand","text":"rand(r::RealField; randtype::Symbol=:urandom)\n\nReturn a random element in given Arb field.\n\nThe randtype default is :urandom which return an arb contained in 01.\n\nThe rest of the methods return non-uniformly distributed values in order to exercise corner cases. The option :randtest will return a finite number, and :randtest_exact the same but with a zero radius. The option :randtest_precise return an arb with a radius around 2^-mathrmprec the magnitude of the midpoint, while :randtest_wide return a radius that might be big relative to its midpoint. The :randtest_special-option might return a midpoint and radius whose values are NaN or inf.\n\n\n\n\n\nrand([rng=GLOBAL_RNG,] G::SymmetricGroup)\n\nReturn a random permutation from G.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"Examples","category":"page"},{"location":"Nemo/real/","page":"Arbitrary precision real balls","title":"Arbitrary precision real balls","text":"RR = RealField()\n\na = rand(RR)\nb = rand(RR; randtype = :null_exact)\nc = rand(RR; randtype = :exact)\nd = rand(RR; randtype = :special)","category":"page"},{"location":"Combinatorics/schur_polynomials/#Schur-polynomials","page":"Schur polynomials","title":"Schur polynomials","text":"","category":"section"},{"location":"Combinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"schur_polynomial(lambda::Partition{T}, n::Int=sum(lambda)) where T<:Integer","category":"page"},{"location":"Combinatorics/schur_polynomials/#schur_polynomial-Union{Tuple{Partition{T}}, Tuple{T}, Tuple{Partition{T}, Int64}} where T<:Integer","page":"Schur polynomials","title":"schur_polynomial","text":"schur_polynomial(lambda::Partition{T}, n::Int=length(lambda)) where T<:Integer\nschur_polynomial(R::ZZMPolyRing, lambda::Partition{T}, n::Int=length(lambda)) where T<:Integer\n\nReturn the Schur polynomial s_λ(x_1x_2x_n) in n variables.\n\nIf R is not given, the Schur polynomial will be over polynomial_ring(ZZ,n).\n\nExamples\n\njulia> R,x = polynomial_ring(ZZ, [\"a\",\"b\",\"c\"]);\n\njulia> schur_polynomial(R, partition([2,1]))\na^2*b + a*b^2\n\njulia> schur_polynomial(R, partition([2,1]), 3)\na^2*b + a^2*c + a*b^2 + 2*a*b*c + a*c^2 + b^2*c + b*c^2\n\njulia> schur_polynomial(partition([2]))\nx1^2\n\nAlgorithm\n\nWe use two different Algorithms, depending on the size of the input. The Combinatorial Algorithm is used for Partitions of small integers, or if n 10. In the other cases we use Cauchy's bialternant formula.\n\nCombinatorial Algorithm\n\ns_λ=_T x_1^m_1x_n^m_n\n\nwhere the sum is taken over all semistandard tableaux T of shape λ, and m_i gives the weight of i in T.\n\nCauchy's bialternant formula\n\ns_lambda(x_1dotsx_n) = prod_1leq i j leq n (x_i-x_j)^-1\nbeginvmatrix\nx_1^λ_1+n-1 x_2^λ_1+n-1 x_n^λ_1+n-1 \nx_1^λ_2+n-2 x_2^λ_2+n-2 x_n^λ_2+n-2 \n \nx_1^λ_n x_2^λ_n x_n^λ_n\nendvmatrix\n\n\n\n\n\n","category":"method"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/developer/typesystem/#The-type-system","page":"The type system","title":"The type system","text":"","category":"section"},{"location":"Nemo/developer/typesystem/#Use-of-Julia-types-in-Nemo","page":"The type system","title":"Use of Julia types in Nemo","text":"","category":"section"},{"location":"Nemo/developer/typesystem/#Concrete-and-abstract-types","page":"The type system","title":"Concrete and abstract types","text":"","category":"section"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Julia does not provide a traditional class/inheritance approach to programming. Instead, the basic unit of its object oriented approach is the type definition (struct and mutable struct) and inheritance exists only on the function side of the language rather than data side. Julia provides a rich system of abstract types and unions on the data side and multimethods on the function side to effect this.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"For example Julia's Number type is an abstract type containing all concrete types that behave like numbers, e.g. Int64, Float64, and so on.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Abstract types can also belong to other abstract types, forming a tree of abstract types.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"In Nemo the most important abstract types are Ring and Field, with the latter belonging to the former so that all fields are rings, and the abstract types RingElem and FieldElem for the objects that represent elements of rings and fields, again with the latter abstract type belonging to the former.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Because this hierarchy of abstract types must form a tree, Julia is strictly speaking single inheritance, as each concrete and abstract type can belong to at most one other abstract type. For example, one could not have a diamond of abstract types with ExactField belonging to both Field and ExactRing.","category":"page"},{"location":"Nemo/developer/typesystem/#Recovering-aspects-of-multiple-inheritance-in-Nemo","page":"The type system","title":"Recovering aspects of multiple inheritance in Nemo","text":"","category":"section"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Various possibilities exist to get around the limitation that abstract types must form a 'tree' in Nemo and AbstractAlgebra.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"One such possibility is union types. If a function should accept one of a number of concrete or abstract types that can't all be made to belong to a single abstract type due to this limitation then one can use a union type.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"For example, Nemo defines RingElement to be a union of RingElem and all the Julia standard types which behave like ring elements, e.g. all Integer types and types of rationals with Integer components.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Other union types are defined in src/AbstractAlgebra.jl in AbstractAlgebra.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"A second feature we make use of in Nemo is parameterised types. Each concrete and abstract type can take one or more parameters. These parameter can be any other type, either concrete or abstract. For example, in Julia Rational{T} is for rationals with numerator and denominator of type T.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"A great deal of control over parameterised types is possible, e.g. one can restrict the type parameter T using a where clause, e.g. to write a function that accepts all rational types with integer components of the same type one can use the type Rational{T} where T <: Integer.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Nemo makes use of such parameterised types for generic ring constructions such as generic polynomial rings and matrices over a given base ring. The type of the elements of the base ring is substituted for the parameter T in any concrete instantiation of the types Poly{T} and Mat{T}, which are defined in AbstractAlgebra in src/generic/GenericTypes.jl.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The totality of all univariate polynomial types, including those of generic Poly{T} types and those coming from C libraries (such as ZZPolyRingElem), is represented by the abstract type PolyRingElem{T} which in turn belongs to RingElem, both defined in AbstractAlgebra in src/AbstractTypes.jl.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Similarly, the totality of all matrix types, including explicit C types like ZZMatrix and the generic Mat{T} types is given by the abstract type MatElem{T}, again defined in AbstractAlgebra in src/AbstractTypes.jl.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"This hierarchy of types allows one to write functions at any level, e.g. for all univariate polynomial types, just those with a given base type T, or for a specific concrete type corresponding to just one kind of univariate polynomial.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"A third possibility to get around the single inheritance limitation of Julia is type traits. There is currently no explicit compiler/language support for traits, however various implementations exist that make use of type parameters in tricky ways. This allows one to add 'traits' to types, so long as those traits can be expressed as types. In this way, types can have multiple 'properties' at the same time, instead of belonging to just a single abstract type.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Nemo does not currently use type traits, though the map types in Nemo do make use of a custom analogue of this.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Note that unlike class based systems that dispatch on the type of a (sometimes implicit) this or self parameter, Julia methods dispatch on the type of all arguments. This is a natural fit for mathematics where all sorts of ad hoc left and right operations may be required.","category":"page"},{"location":"Nemo/developer/typesystem/#Encapsulation,-maps-and-runtime-flags","page":"The type system","title":"Encapsulation, maps and runtime flags","text":"","category":"section"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"One limitation of the Julia approach is that the type of an object cannot be changed at runtime. For example one might like to insist that a given ring is in fact a field. There are three standard ways to handle this in Julia.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The first approach is to encapsulate the object in another object which does have the desired type. The second approach is to map the object to a different one of the required type (e.g. by applying a morphism). The third approach is to introduce data fields in the original type which can be changed at runtime, unlike its type. All three approaches come with downsides. ","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Encapsulation can be time consuming for the developer as methods which applied to the original object do not automatically apply to the encapsulated object. One can write methods which do, but this is not automatic.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Application of a map may come with a performance penalty and may be difficult for the user to navigate. Moreover, mutation of the resulting object does not result in mutation of the original object.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The third option of adding runtime data fields essentially takes one back to writing a (possibly bug ridden) interpreter. It relies on the developer implementing outer methods that make use of hand written control statements to determine which of a range of inner methods should be applied to the object. This misses the benefits of one of the main defining features of Julia, namely its multimethod system and can also make introspection more difficult.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Nemo does not apply any of these three approaches widely at present, though information which can only be known at runtime such as whether a ring is Euclidean will eventually have to be encoded using one of these three methods.","category":"page"},{"location":"Nemo/developer/typesystem/#Nemo's-custom-map-types","page":"The type system","title":"Nemo's custom map types","text":"","category":"section"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"It makes sense that map types in Nemo should be parameterised by the element types of both the domain and codomain of the map, and of course all maps in the system should somehow belong to an abstract type Map.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"This leads one to consider a two parameter system of types Map{D, C} where D and C are the domain and codomain types respectively.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"One may also wish to implement various types of map, e.g. linear maps (where the map contains a matrix representing the map) or functional maps (where the map is implemented by a Julia function) and so on. Notionally one imagines doing this with a hierarchy of two parameter abstract types all ultimately belonging to Map{D, C} as the root of the tree.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"This approach begins to break down when constructions from homological algebra begin to be applied to maps. In such cases, the maps themselves are the object of study and functions may be applied to maps to produce other maps.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The simplest such function is composition. In a system where composition of maps always results in a map of the same type, no problem arises with the straightforward approach outlined above.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"However, for various reasons (including performance) it may not be desirable or even possible to construct a composition of two given maps using the same representation as the original maps. This means that the result of composing two maps of the same type may be a map of a different type, e.g. in the worst case a general composition type.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"This problem makes many homological and category theoretic operations on maps difficult or impossible to implement.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Other operations which may be desirable to implement are caching of maps (e.g. where the map is extremely time consuming to compute, such as discrete logarithms) and attaching category theoretic information to maps. Such operations can be effected by encapsulating existing maps in objects containing the extra information, e.g. a cache or a category. However all the methods that applied to the original map objects now no longer apply to the encapsulated objects.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"To work around these limitations Nemo implements a four parameter Map type, Map{D, C, T, U}.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The first two parameters are the domain and codomain types as discussed above.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The parameter T is a \"map class\" which is itself an abstract type existing in a hierarchy of abstract types. This parameter is best thought of as a trait, independent of the hierarchy of abstract types belonging to Map, giving additional flexibility to the map types in the system.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"For example, T may be set to LinearMap or FunctionalMap. This may be useful if one wishes to distinguish maps in other ways, e.g. whether they are homomorphisms, isomorphisms, maps with section or retraction etc. As usual, offering traits partially gets around the single inheritance problem.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The final parameter U is used to allow maps of a given type U to be composed and still result in a map of type U, even though the concrete type of the composition is different to that of the original maps. Methods can be written for all maps of type U by matching this parameter, rather than matching on the concrete type U of the original maps.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"For example, two maps with concrete type MyRingHomomorphism would belong to Map{D, C, T, MyRingHomomorphism} as would any composition of such maps, even if the concrete type of the composition was not a MyRingHomomorphism.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Naturally four parameter types are rather unwieldy and so various helper functions are provided to compute four parameter map types. In the first instance one still has the type Map{D, C} which will give the union of all map types whose first two parameters are D and C, and where the remaining two parameters are arbitrary.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"However one can also pass a map class or a concrete type U to a Map function to compute the class of all maps of the given map class or type.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"For example, to write a function which accepts all maps of \"type\" MyRingHomomorphism, including all compositions of such maps, one inserts Map(MyRingHomomorphism) in place of the type, e.g.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"function myfun(f::Map(MyRingHomomorphism))","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Note the parentheses here, rather than curly braces; it's a function to compute a type! Now the function myfun will accept any map type whose fourth parameter U is set to MyRingHomomorphism.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"This four parameter system is flexible, but may need to be expanded in the future. For example it may be useful to have more than one trait T. This could be achieved either by making T a tuple of traits or by introducing a parameterised MapTrait type which can be placed at that location. Naturally the Map functions for computing the four parameter types will have to be similarly expanded to make it easier for the user.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The map type system is currently considered experimental and our observation so far is that it is not intuitive for developers.","category":"page"},{"location":"Nemo/developer/typesystem/#Type-hierarchy-diagram","page":"The type system","title":"Type hierarchy diagram","text":"","category":"section"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"The most important abstract types in the system are the element types. Their hierarchy is shown in the following diagram.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"(Image: alt text)","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"Most of the element types have a corresponding parent abstract type. These are shown in the following diagram.","category":"page"},{"location":"Nemo/developer/typesystem/","page":"The type system","title":"The type system","text":"(Image: alt text)","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/rational/#Rational-field","page":"Rational field","title":"Rational field","text":"","category":"section"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"AbstractAlgebra.jl provides a module, implemented in src/julia/Rational.jl for making Julia Rational{BigInt}s conform to the AbstractAlgebra.jl Field interface.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"In addition to providing a parent object QQ for Julia Rational{BigInt}s, we implement any additional functionality required by AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"Because Rational{BigInt} cannot be directly included in the AbstractAlgebra.jl abstract type hierarchy, we achieve integration of Julia Rational{BigInt}s by introducing a type union, called FieldElement, which is a union of FieldElem and a number of Julia types, including Rational{BigInt}. Everywhere that FieldElem is notionally used in AbstractAlgebra.jl, we are in fact using FieldElement, with additional care being taken to avoid ambiguities.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"The details of how this is done are technical, and we refer the reader to the implementation for details. For most intents and purposes, one can think of the Julia Rational{BigInt} type as belonging to FieldElem.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"One other technicality is that Julia defines certain functions for Rational{BigInt}, such as sqrt and exp differently to what AbstractAlgebra.jl requires. To get around this, we redefine these functions internally to AbstractAlgebra.jl, without redefining them for users of AbstractAlgebra.jl. This allows the internals of AbstractAlgebra.jl to function correctly, without broadcasting pirate definitions of already defined Julia functions to the world.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"To access the internal definitions, one can use AbstractAlgebra.sqrt and AbstractAlgebra.exp, etc.","category":"page"},{"location":"AbstractAlgebra/rational/#Types-and-parent-objects","page":"Rational field","title":"Types and parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"Rationals have type Rational{BigInt}, as in Julia itself. We simply supplement the functionality for this type as required for computer algebra.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"The parent objects of such integers has type Rationals{BigInt}.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"For convenience, we also make Rational{Int} a part of the AbstractAlgebra.jl type hierarchy and its parent object (accessible as qq) has type Rationals{Int}. But we caution that this type is not particularly useful as a model of the rationals and may not function as expected within AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/rational/#Rational-constructors","page":"Rational field","title":"Rational constructors","text":"","category":"section"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"In order to construct rationals in AbstractAlgebra.jl, one can first construct the rational field itself. This is accomplished using either of the following constructors.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"fraction_field(R::Integers{BigInt})","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"Rationals{BigInt}()","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"This gives the unique object of type Rationals{BigInt} representing the field of rationals in AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"In practice, one simply uses QQ which is assigned to be the return value of the above constructor. There is no need to call the constructor in practice.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"Here are some examples of creating the rational field and making use of the resulting parent object to coerce various elements into the field.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"Examples","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"julia> f = QQ()\n0//1\n\njulia> g = QQ(123)\n123//1\n\njulia> h = QQ(BigInt(1234))\n1234//1\n\njulia> k = QQ(BigInt(12), BigInt(7))\n12//7\n\njulia> QQ == fraction_field(ZZ)\ntrue\n","category":"page"},{"location":"AbstractAlgebra/rational/#Basic-field-functionality","page":"Rational field","title":"Basic field functionality","text":"","category":"section"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"The rational field in AbstractAlgebra.jl implements the full Field and Fraction Field interfaces.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"We give some examples of such functionality.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"Examples","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"julia> f = QQ(12, 7)\n12//7\n\njulia> h = zero(QQ)\n0//1\n\njulia> k = one(QQ)\n1//1\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> U = base_ring(QQ)\nIntegers\n\njulia> V = base_ring(f)\nIntegers\n\njulia> T = parent(f)\nRationals\n\njulia> f == deepcopy(f)\ntrue\n\njulia> g = f + 12\n96//7\n\njulia> r = ZZ(12)//ZZ(7)\n12//7\n\njulia> n = numerator(r)\n12\n","category":"page"},{"location":"AbstractAlgebra/rational/#Rational-functionality-provided-by-AbstractAlgebra.jl","page":"Rational field","title":"Rational functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"The functionality below supplements that provided by Julia itself for its Rational{BigInt} type.","category":"page"},{"location":"AbstractAlgebra/rational/#Square-and-n-th-root","page":"Rational field","title":"Square and n-th root","text":"","category":"section"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"The functions sqrt, is_square, is_square_with_sqrt are all provided, as are root, is_power and is_power_with_root.","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"Examples","category":"page"},{"location":"AbstractAlgebra/rational/","page":"Rational field","title":"Rational field","text":"julia> d = AbstractAlgebra.sqrt(ZZ(36)//ZZ(25))\n6//5\n\njulia> is_square(ZZ(9)//ZZ(16))\ntrue\n\njulia> root(ZZ(27)//64, 3)\n3//4","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/series/#Power-series","page":"Power series","title":"Power series","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"AbstractAlgebra.jl allows the creation of capped relative and absolute power series over any computable commutative ring R.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Capped relative power series are power series of the form a_jx^j + a_j+1x^j+1 + cdots + a_k-1x^k-1 + O(x^k) where a_j in R and the relative precision k - j is at most equal to some specified precision n.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Capped absolute power series are power series of the form a_jx^j + a_j+1x^j+1 + cdots + a_n-1x^n-1 + O(x^n) where j geq 0, a_j in R and the precision n is fixed.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"There are two implementations of relative series: relative power series, implemented in src/RelSeries.jl for which j 0 in the above description, and Laurent series where j can be negative, implemented in src/Laurent.jl. Note that there are two implementations for Laurent series, one over rings and one over fields, though in practice most of the implementation uses the same code in both cases.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"There is a single implementation of absolute series: absolute power series, implemented in src/AbsSeries.jl.","category":"page"},{"location":"AbstractAlgebra/series/#Generic-power-series-types","page":"Power series","title":"Generic power series types","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"AbstractAlgebra.jl provides generic series types implemented in src/generic/AbsSeries.jl, src/generic/RelSeries.jl and src/generic/LaurentSeries.jl which implement the Series interface.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"These generic series have types Generic.RelSeries{T}, Generic.AbsSeries{T}, Generic.LaurentSeriesRingElem{T} and Generic.LaurentSeriesFieldElem{T}. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"The parent objects have types Generic.AbsPowerSeriesRing{T} and Generic.RelPowerSeriesRing{T} and Generic.LaurentSeriesRing{T} respectively.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"The default precision, string representation of the variable and base ring R of a generic power series are stored in its parent object.","category":"page"},{"location":"AbstractAlgebra/series/#Abstract-types","page":"Power series","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Relative power series elements belong to the abstract type RelPowerSeriesRingElem.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Laurent series elements belong directly to either RingElem or FieldElem since it is more useful to be able to distinguish whether they belong to a ring or field than it is to distinguish that they are relative series.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Absolute power series elements belong to AbsPowerSeriesRingElem.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"The parent types for relative and absolute power series, Generic.RelPowerSeriesRing{T} and Generic.AbsPowerSeriesRing{T} respectively, belong to SeriesRing{T}.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"The parent types of Laurent series belong directly to Ring and Field respectively.","category":"page"},{"location":"AbstractAlgebra/series/#Series-ring-constructors","page":"Power series","title":"Series ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"In order to construct series in AbstractAlgebra.jl, one must first construct the ring itself. This is accomplished with any of the following constructors.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"power_series_ring(R::Ring, prec_max::Int, s::VarName; cached::Bool = true, model=:capped_relative)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"laurent_series_ring(R::Ring, prec_max::Int, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"laurent_series_ring(R::Field, prec_max::Int, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Given a base ring R, a maximum precision (relative or absolute, depending on the model) and a string s specifying how the generator (variable) should be printed, return a tuple S, x representing the series ring and its generator.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"By default, S will depend only on S, x and the maximum precision and will be cached. Setting the optional argument cached to false will prevent this.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"In the case of power series, the optional argument model can be set to either :capped_absolute or capped_relative, depending on which power series model is required.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"It is also possible to construct absolute and relative power series with a default variable. These are lightweight constructors and should be used in generic algorithms wherever possible when creating series rings where the symbol does not matter.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"AbsPowerSeriesRing(R::Ring, prec::Int)\nRelPowerSeriesRing(R::Ring, prec::Int)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Return the absolute or relative power series ring over the given base ring R and with precision cap given by prec. Note that a tuple is not returned, only the power series ring itself, not a generator.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Here are some examples of constructing various kinds of series rings and coercing various elements into those rings.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, x = power_series_ring(ZZ, 10, \"x\")\n(Univariate power series ring over integers, x + O(x^11))\n\njulia> S, y = power_series_ring(ZZ, 10, \"y\"; model=:capped_absolute)\n(Univariate power series ring over integers, y + O(y^10))\n\njulia> T, z = laurent_series_ring(ZZ, 10, \"z\")\n(Laurent series ring in z over integers, z + O(z^11))\n\njulia> U, w = laurent_series_field(QQ, 10, \"w\")\n(Laurent series field in w over rationals, w + O(w^11))\n\njulia> f = R()\nO(x^10)\n\njulia> g = S(123)\n123 + O(y^10)\n\njulia> h = U(BigInt(1234))\n1234 + O(w^10)\n\njulia> k = T(z + 1)\n1 + z + O(z^10)\n\njulia> V = AbsPowerSeriesRing(ZZ, 10)\nUnivariate power series ring in x with precision 10\n over integers","category":"page"},{"location":"AbstractAlgebra/series/#Power-series-constructors","page":"Power series","title":"Power series constructors","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Series can be constructed using arithmetic operators using the generator of the series. Also see the big-oh notation below for specifying the precision.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"All of the standard ring constructors can also be used to construct power series.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"(R::SeriesRing)() # constructs zero\n(R::SeriesRing)(c::Integer)\n(R::SeriesRing)(c::elem_type(R))\n(R::SeriesRing{T})(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"In addition, the following constructors that are specific to power series are provided. They take an array of coefficients, a length, precision and valuation. Coefficients will be coerced into the coefficient ring if they are not already in that ring.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"For relative series we have:","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"(S::SeriesRing{T})(A::Vector{T}, len::Int, prec::Int, val::Int) where T <: RingElem\n(S::SeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: RingElem}\n(S::SeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: Integer}","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"And for absolute series:","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"(S::SeriesRing{T})(A::Vector{T}, len::Int, prec::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"It is also possible to create series directly without having to create the corresponding series ring.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"abs_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T\nrel_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, val::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T\nlaurent_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, val::Int, scale::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> S, x = power_series_ring(QQ, 10, \"x\"; model=:capped_absolute)\n(Univariate power series ring over rationals, x + O(x^10))\n\njulia> f = S(Rational{BigInt}[0, 2, 3, 1], 4, 6)\n2*x + 3*x^2 + x^3 + O(x^6)\n\njulia> f = abs_series(ZZ, [1, 2, 3], 3, 5, \"y\")\n1 + 2*y + 3*y^2 + O(y^5)\n\njulia> g = rel_series(ZZ, [1, 2, 3], 3, 7, 4)\nx^4 + 2*x^5 + 3*x^6 + O(x^7)\n\njulia> k = abs_series(ZZ, [1, 2, 3], 1, 6, cached=false)\n1 + O(x^6)\n\njulia> p = rel_series(ZZ, BigInt[], 0, 3, 1)\nO(x^3)\n\njulia> q = abs_series(ZZ, [], 0, 6)\nO(x^6)\n\njulia> s = abs_series(ZZ, [1, 2, 3], 3, 5; max_precision=10)\n1 + 2*x + 3*x^2 + O(x^5)\n\njulia> s = laurent_series(ZZ, [1, 2, 3], 3, 5, 0, 2; max_precision=10)\n1 + 2*x^2 + 3*x^4 + O(x^5)","category":"page"},{"location":"AbstractAlgebra/series/#Big-oh-notation","page":"Power series","title":"Big-oh notation","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Series elements can be given a precision using the big-oh notation. This is provided by a function of the following form, (or something equivalent for Laurent series):","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"O(x::SeriesElem)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, x = power_series_ring(ZZ, 10, \"x\")\n(Univariate power series ring over integers, x + O(x^11))\n\njulia> S, y = laurent_series_ring(ZZ, 10, \"y\")\n(Laurent series ring in y over integers, y + O(y^11))\n\njulia> f = 1 + 2x + O(x^5)\n1 + 2*x + O(x^5)\n\njulia> g = 2y + 7y^2 + O(y^7)\n2*y + 7*y^2 + O(y^7)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"What is happening here in practice is that O(x^n) is creating the series 0 + O(x^n) and the rules for addition of series dictate that if this is added to a series of greater precision, then the lower of the two precisions must be used.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Of course it may be that the precision of the series that O(x^n) is added to is already lower than n, in which case adding O(x^n) has no effect. This is the case if the default precision is too low, since x on its own has the default precision.","category":"page"},{"location":"AbstractAlgebra/series/#Power-series-models","page":"Power series","title":"Power series models","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Capped relative power series have their maximum relative precision capped at some value prec_max. This means that if the leading term of a nonzero power series element is c_ax^a and the precision is b then the power series is of the form c_ax^a + c_a+1x^a+1 + ldots + O(x^a + b).","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"The zero power series is simply taken to be 0 + O(x^b).","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"The capped relative model has the advantage that power series are stable multiplicatively. In other words, for nonzero power series f and g we have that divexact(f*g), g) == f.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"However, capped relative power series are not additively stable, i.e. we do not always have (f + g) - g = f.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Similar comments apply to Laurent series.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"On the other hand, capped absolute power series have their absolute precision capped. This means that if the leading term of a nonzero power series element is c_ax^a and the precision is b then the power series is of the form c_ax^a + c_a+1x^a+1 + ldots + O(x^b).","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Capped absolute series are additively stable, but not necessarily multiplicatively stable.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"For all models, the maximum precision is also used as a default precision in the case of coercing coefficients into the ring and for any computation where the result could mathematically be given to infinite precision.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"In all models we say that two power series are equal if they agree up to the minimum absolute precision of the two power series.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Thus, for example, x^5 + O(x^10) == 0 + O(x^5), since the minimum absolute precision is 5.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"During computations, it is possible for power series to lose relative precision due to cancellation. For example if f = x^3 + x^5 + O(x^8) and g = x^3 + x^6 + O(x^8) then f - g = x^5 - x^6 + O(x^8) which now has relative precision 3 instead of relative precision 5.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Amongst other things, this means that equality is not transitive. For example x^6 + O(x^11) == 0 + O(x^5) and x^7 + O(x^12) == 0 + O(x^5) but x^6 + O(x^11) neq x^7 + O(x^12).","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Sometimes it is necessary to compare power series not just for arithmetic equality, as above, but to see if they have precisely the same precision and terms. For this purpose we introduce the isequal function.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"For example, if f = x^2 + O(x^7) and g = x^2 + O(x^8) and h = 0 + O(x^2) then f == g, f == h and g == h, but isequal(f, g), isequal(f, h) and isequal(g, h) would all return false. However, if k = x^2 + O(x^7) then isequal(f, k) would return true.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"There are further difficulties if we construct polynomial over power series. For example, consider the polynomial in y over the power series ring in x over the rationals. Normalisation of such polynomials is problematic. For instance, what is the leading coefficient of (0 + O(x^10))y + (1 + O(x^10))?","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"If one takes it to be (0 + O(x^10)) then some functions may not terminate due to the fact that algorithms may require the degree of polynomials to decrease with each iteration. Instead, the degree may remain constant and simply accumulate leading terms which are arithmetically zero but not identically zero.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"On the other hand, when constructing power series over other power series, if we simply throw away terms which are arithmetically equal to zero, our computations may have different output depending on the order in which the power series are added!","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"One should be aware of these difficulties when working with power series. Power series, as represented on a computer, simply don't satisfy the axioms of a ring. They must be used with care in order to approximate operations in a mathematical power series ring.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Simply increasing the precision will not necessarily give a \"more correct\" answer and some computations may not even terminate due to the presence of arithmetic zeroes!","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"An absolute power series ring over a ring R with precision p behaves very much like the quotient Rx(x^p) of the polynomial ring over R. Therefore one can often treat absolute power series rings as though they were rings. However, this depends on all series being given a precision equal to the specified maximum precision and not a lower precision.","category":"page"},{"location":"AbstractAlgebra/series/#Functions-for-types-and-parents-of-series-rings","page":"Power series","title":"Functions for types and parents of series rings","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"base_ring(R::SeriesRing)\nbase_ring(a::SeriesElem)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Return the coefficient ring of the given series ring or series.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"parent(a::SeriesElem)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Return the parent of the given series.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"characteristic(R::SeriesRing)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Return the characteristic of the given series ring. If the characteristic is not known, an exception is raised.","category":"page"},{"location":"AbstractAlgebra/series/#Series-functions","page":"Power series","title":"Series functions","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Unless otherwise noted, the functions below are available for all series models, including Laurent series. We denote this by using the abstract type RelPowerSeriesRingElem, even though absolute series and Laurent series types do not belong to this abstract type.","category":"page"},{"location":"AbstractAlgebra/series/#Basic-functionality","page":"Power series","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Series implement the Ring Interface","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"zero(R::SeriesRing)\none(R::SeriesRing)\niszero(a::SeriesElem)\nisone(a::SeriesElem)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"divexact(a::T, b::T) where T <: SeriesElem\ninv(a::SeriesElem) ","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Series also implement the Series Interface, the most important basic functions being the following.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"var(S::SeriesRing)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Return a symbol for the variable of the given series ring.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"max_precision(S::SeriesRing)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Return the precision cap of the given series ring.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"precision(f::SeriesElem)\nvaluation(f::SeriesElem)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"gen(R::SeriesRing)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"The following functions are also provided for all series.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"coeff(a::SeriesElem, n::Int)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Return the degree n coefficient of the given power series. Note coefficients are numbered from n = 0 for the constant coefficient. If n exceeds the current precision of the power series, the function returns a zero coefficient.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"For power series types, n must be non-negative. Laurent series do not have this restriction.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"modulus{T <: ResElem}(::SeriesElem{T})","category":"page"},{"location":"AbstractAlgebra/series/#modulus-Union{Tuple{SeriesElem{T}}, Tuple{T}} where T<:ResElem","page":"Power series","title":"modulus","text":"modulus(a::SeriesElem{T}) where {T <: ResElem}\n\nReturn the modulus of the coefficients of the given power series.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"is_gen(::RelPowerSeriesRingElem)","category":"page"},{"location":"AbstractAlgebra/series/#is_gen-Tuple{RelPowerSeriesRingElem}","page":"Power series","title":"is_gen","text":"is_gen(a::RelPowerSeriesRingElem)\n\nReturn true if the given power series is arithmetically equal to the generator of its power series ring to its current precision, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> S, x = power_series_ring(ZZ, 10, \"x\")\n(Univariate power series ring over integers, x + O(x^11))\n\njulia> f = 1 + 3x + x^3 + O(x^10)\n1 + 3*x + x^3 + O(x^10)\n\njulia> g = 1 + 2x + x^2 + O(x^10)\n1 + 2*x + x^2 + O(x^10)\n\njulia> h = zero(S)\nO(x^10)\n\njulia> k = one(S)\n1 + O(x^10)\n\njulia> isone(k)\ntrue\n\njulia> iszero(f)\nfalse\n\njulia> n = pol_length(f)\n4\n\njulia> c = polcoeff(f, 3)\n1\n\njulia> U = base_ring(S)\nIntegers\n\njulia> v = var(S)\n:x\n\njulia> max_precision(S) == 10\ntrue\n\njulia> T = parent(x + 1)\nUnivariate power series ring in x with precision 10\n over integers\n\njulia> g == deepcopy(g)\ntrue\n\njulia> t = divexact(2g, 2)\n1 + 2*x + x^2 + O(x^10)\n\njulia> p = precision(f)\n10\n\njulia> R, t = power_series_ring(QQ, 10, \"t\")\n(Univariate power series ring over rationals, t + O(t^11))\n\njulia> S, x = power_series_ring(R, 30, \"x\")\n(Univariate power series ring over univariate power series ring, x + O(x^31))\n\njulia> a = O(x^4)\nO(x^4)\n\njulia> b = (t + 3)*x + (t^2 + 1)*x^2 + O(x^4)\n(3 + t + O(t^10))*x + (1 + t^2 + O(t^10))*x^2 + O(x^4)\n\njulia> k = is_gen(gen(R))\ntrue\n\njulia> m = is_unit(-1 + x + 2x^2)\ntrue\n\njulia> n = valuation(a)\n4\n\njulia> p = valuation(b)\n1\n\njulia> c = coeff(b, 2)\n1 + t^2 + O(t^10)\n\njulia> S, x = power_series_ring(ZZ, 10, \"x\")\n(Univariate power series ring over integers, x + O(x^11))\n\njulia> f = 1 + 3x + x^3 + O(x^5)\n1 + 3*x + x^3 + O(x^5)\n\njulia> g = S(BigInt[1, 2, 0, 1, 0, 0, 0], 4, 10, 3);\n\njulia> set_length!(g, 3)\nx^3 + 2*x^4 + O(x^10)\n\njulia> g = setcoeff!(g, 2, BigInt(11))\nx^3 + 2*x^4 + 11*x^5 + O(x^10)\n\njulia> fit!(g, 8)\n\njulia> g = setcoeff!(g, 7, BigInt(4))\nx^3 + 2*x^4 + 11*x^5 + O(x^10)","category":"page"},{"location":"AbstractAlgebra/series/#Change-base-ring","page":"Power series","title":"Change base ring","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"map_coefficients(::Any, ::AbsPowerSeriesRingElem{<:RingElem})\nchange_base_ring(::Ring, ::AbsPowerSeriesRingElem{<:RingElem})","category":"page"},{"location":"AbstractAlgebra/series/#map_coefficients-Tuple{Any, AbsPowerSeriesRingElem{<:RingElem}}","page":"Power series","title":"map_coefficients","text":"map_coefficients(f, p::SeriesElem{<: RingElement}; cached::Bool=true, parent::PolyRing)\n\nTransform the series p by applying f on each non-zero coefficient.\n\nIf the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/#change_base_ring-Tuple{Ring, AbsPowerSeriesRingElem{<:RingElem}}","page":"Power series","title":"change_base_ring","text":"change_base_ring(R::Ring, p::SeriesElem{<: RingElement}; parent::PolyRing)\n\nReturn the series obtained by coercing the non-zero coefficients of p into R.\n\nIf the optional parent keyword is provided, the series will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, x = power_series_ring(ZZ, 10, \"x\")\n(Univariate power series ring over integers, x + O(x^11))\n\njulia> f = 4*x^6 + x^7 + 9*x^8 + 16*x^9 + 25*x^10 + O(x^11)\n4*x^6 + x^7 + 9*x^8 + 16*x^9 + 25*x^10 + O(x^11)\n\njulia> map_coefficients(AbstractAlgebra.sqrt, f)\n2*x^6 + x^7 + 3*x^8 + 4*x^9 + 5*x^10 + O(x^11)\n\njulia> change_base_ring(QQ, f)\n4*x^6 + x^7 + 9*x^8 + 16*x^9 + 25*x^10 + O(x^11)","category":"page"},{"location":"AbstractAlgebra/series/#Shifting","page":"Power series","title":"Shifting","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"shift_left{T <: RingElem}(::RelPowerSeriesRingElem{T}, ::Int)","category":"page"},{"location":"AbstractAlgebra/series/#shift_left-Union{Tuple{T}, Tuple{RelPowerSeriesRingElem{T}, Int64}} where T<:RingElem","page":"Power series","title":"shift_left","text":"shift_left(x::RelPowerSeriesRingElem{T}, n::Int) where T <: RingElement\n\nReturn the power series x shifted left by n terms, i.e. multiplied by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"shift_right{T <: RingElem}(::RelPowerSeriesRingElem{T}, ::Int)","category":"page"},{"location":"AbstractAlgebra/series/#shift_right-Union{Tuple{T}, Tuple{RelPowerSeriesRingElem{T}, Int64}} where T<:RingElem","page":"Power series","title":"shift_right","text":"shift_right(x::RelPowerSeriesRingElem{T}, n::Int) where T <: RingElement\n\nReturn the power series x shifted right by n terms, i.e. divided by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S, x = power_series_ring(R, 30, \"x\")\n(Univariate power series ring over univariate polynomial ring, x + O(x^31))\n\njulia> a = 2x + x^3\n2*x + x^3 + O(x^31)\n\njulia> b = O(x^4)\nO(x^4)\n\njulia> c = 1 + x + 2x^2 + O(x^5)\n1 + x + 2*x^2 + O(x^5)\n\njulia> d = 2x + x^3 + O(x^4)\n2*x + x^3 + O(x^4)\n\njulia> f = shift_left(a, 2)\n2*x^3 + x^5 + O(x^33)\n\njulia> g = shift_left(b, 2)\nO(x^6)\n\njulia> h = shift_right(c, 1)\n1 + 2*x + O(x^4)\n\njulia> k = shift_right(d, 3)\n1 + O(x^1)\n","category":"page"},{"location":"AbstractAlgebra/series/#Truncation","page":"Power series","title":"Truncation","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"truncate{T <: RingElem}(::RelPowerSeriesRingElem{T}, ::Int)","category":"page"},{"location":"AbstractAlgebra/series/#truncate-Union{Tuple{T}, Tuple{RelPowerSeriesRingElem{T}, Int64}} where T<:RingElem","page":"Power series","title":"truncate","text":"truncate(a::RelPowerSeriesRingElem{T}, n::Int) where T <: RingElement\n\nReturn a truncated to (absolute) precision n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S, x = power_series_ring(R, 30, \"x\")\n(Univariate power series ring over univariate polynomial ring, x + O(x^31))\n\njulia> a = 2x + x^3\n2*x + x^3 + O(x^31)\n\njulia> b = O(x^4)\nO(x^4)\n\njulia> c = 1 + x + 2x^2 + O(x^5)\n1 + x + 2*x^2 + O(x^5)\n\njulia> d = 2x + x^3 + O(x^4)\n2*x + x^3 + O(x^4)\n\njulia> f = truncate(a, 3)\n2*x + O(x^3)\n\njulia> g = truncate(b, 2)\nO(x^2)\n\njulia> h = truncate(c, 7)\n1 + x + 2*x^2 + O(x^5)\n\njulia> k = truncate(d, 5)\n2*x + x^3 + O(x^4)\n","category":"page"},{"location":"AbstractAlgebra/series/#Division","page":"Power series","title":"Division","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Base.inv(::RelPowerSeriesRingElem)","category":"page"},{"location":"AbstractAlgebra/series/#inv-Tuple{RelPowerSeriesRingElem}","page":"Power series","title":"inv","text":"Base.inv(a::RelPowerSeriesRingElem)\n\nReturn the inverse of the power series a, i.e. 1a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S, x = power_series_ring(R, 30, \"x\")\n(Univariate power series ring over univariate polynomial ring, x + O(x^31))\n\njulia> a = 1 + x + 2x^2 + O(x^5)\n1 + x + 2*x^2 + O(x^5)\n\njulia> b = S(-1)\n-1 + O(x^30)\n\njulia> c = inv(a)\n1 - x - x^2 + 3*x^3 - x^4 + O(x^5)\n\njulia> d = inv(b)\n-1 + O(x^30)\n","category":"page"},{"location":"AbstractAlgebra/series/#Composition","page":"Power series","title":"Composition","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"compose(a::RelPowerSeriesRingElem, b::RelPowerSeriesRingElem)","category":"page"},{"location":"AbstractAlgebra/series/#compose-Tuple{RelPowerSeriesRingElem, RelPowerSeriesRingElem}","page":"Power series","title":"compose","text":"compose(a::RelPowerSeriesRingElem, b::RelPowerSeriesRingElem)\n\nCompose the series a with the series b and return the result, i.e. return acirc b. The two series do not need to be in the same ring, however the series b must have positive valuation or an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Note that subst can be used instead of compose, however the provided functionality is the same. General series substitution is not well-defined.","category":"page"},{"location":"AbstractAlgebra/series/#Derivative-and-integral","page":"Power series","title":"Derivative and integral","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"derivative(a::RelPowerSeriesRingElem)","category":"page"},{"location":"AbstractAlgebra/series/#derivative-Tuple{RelPowerSeriesRingElem}","page":"Power series","title":"derivative","text":"derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the derivative of the given Puiseux series a.\n\n\n\n\n\nderivative(f::AbsPowerSeriesRingElem{T})\n\nReturn the derivative of the power series f.\n\n\n\n\n\nderivative(f::RelPowerSeriesRingElem{T})\n\nReturn the derivative of the power series f.\n\njulia> R, x = power_series_ring(QQ, 10, \"x\")\n(Univariate power series ring in x over Rationals, x + O(x^11))\n\njulia> f = 2 + x + 3x^3\n2 + x + 3*x^3 + O(x^10)\n\njulia> derivative(f)\n1 + 9*x^2 + O(x^9)\n\n\n\n\n\nderivative(f::AbstractAlgebra.MPolyRingElem{T}, j::Int) where {T <: RingElement}\n\nReturn the partial derivative of f with respect to j-th variable of the polynomial ring.\n\n\n\n\n\nderivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.\n\n\n\n\n\nderivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem\n\nReturn the derivative of x with respect to the variable of index n.\n\n\n\n\n\nderivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem\n\nReturn the derivative of x with respect to the variable v.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"integral(a::RelPowerSeriesRingElem)","category":"page"},{"location":"AbstractAlgebra/series/#integral-Tuple{RelPowerSeriesRingElem}","page":"Power series","title":"integral","text":"integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the integral of the given Puiseux series a.\n\n\n\n\n\nintegral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(f::AbsPowerSeriesRingElem{T})\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(f::RelPowerSeriesRingElem{T})\n\nReturn the integral of the power series f.\n\njulia> R, x = power_series_ring(QQ, 10, \"x\")\n(Univariate power series ring in x over Rationals, x + O(x^11))\n\njulia> f = 2 + x + 3x^3\n2 + x + 3*x^3 + O(x^10)\n\njulia> integral(f)\n2*x + 1//2*x^2 + 3//4*x^4 + O(x^11)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/#Special-functions","page":"Power series","title":"Special functions","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Base.log(a::SeriesElem{T}) where T <: FieldElem","category":"page"},{"location":"AbstractAlgebra/series/#log-Union{Tuple{SeriesElem{T}}, Tuple{T}} where T<:FieldElem","page":"Power series","title":"log","text":"log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the logarithm of the given Puiseux series a.\n\n\n\n\n\nlog(a::SeriesElem{T}) where T <: FieldElement\n\nReturn the logarithm of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Base.exp(a::RelPowerSeriesRingElem)","category":"page"},{"location":"AbstractAlgebra/series/#exp-Tuple{RelPowerSeriesRingElem}","page":"Power series","title":"exp","text":"exp(a::Generic.LaurentSeriesElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the exponential of the given Puiseux series a.\n\n\n\n\n\nexp(a::AbsPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::RelPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Base.sqrt(a::RelPowerSeriesRingElem)","category":"page"},{"location":"AbstractAlgebra/series/#sqrt-Tuple{RelPowerSeriesRingElem}","page":"Power series","title":"sqrt","text":"sqrt(a::RelPowerSeriesRingElem)\n\nReturn the square root of the power series a. By default the function raises an exception if the input is not a square. If check=false this check is omitted.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S, x = power_series_ring(R, 30, \"x\")\n(Univariate power series ring over univariate polynomial ring, x + O(x^31))\n\njulia> T, z = power_series_ring(QQ, 30, \"z\")\n(Univariate power series ring over rationals, z + O(z^31))\n\njulia> a = 1 + z + 3z^2 + O(z^5)\n1 + z + 3*z^2 + O(z^5)\n\njulia> b = z + 2z^2 + 5z^3 + O(z^5)\nz + 2*z^2 + 5*z^3 + O(z^5)\n\njulia> c = exp(x + O(x^40))\n1 + x + 1//2*x^2 + 1//6*x^3 + 1//24*x^4 + 1//120*x^5 + 1//720*x^6 + 1//5040*x^7 + 1//40320*x^8 + 1//362880*x^9 + 1//3628800*x^10 + 1//39916800*x^11 + 1//479001600*x^12 + 1//6227020800*x^13 + 1//87178291200*x^14 + 1//1307674368000*x^15 + 1//20922789888000*x^16 + 1//355687428096000*x^17 + 1//6402373705728000*x^18 + 1//121645100408832000*x^19 + 1//2432902008176640000*x^20 + 1//51090942171709440000*x^21 + 1//1124000727777607680000*x^22 + 1//25852016738884976640000*x^23 + 1//620448401733239439360000*x^24 + 1//15511210043330985984000000*x^25 + 1//403291461126605635584000000*x^26 + 1//10888869450418352160768000000*x^27 + 1//304888344611713860501504000000*x^28 + 1//8841761993739701954543616000000*x^29 + 1//265252859812191058636308480000000*x^30 + O(x^31)\n\njulia> d = divexact(x, exp(x + O(x^40)) - 1)\n1 - 1//2*x + 1//12*x^2 - 1//720*x^4 + 1//30240*x^6 - 1//1209600*x^8 + 1//47900160*x^10 - 691//1307674368000*x^12 + 1//74724249600*x^14 - 3617//10670622842880000*x^16 + 43867//5109094217170944000*x^18 - 174611//802857662698291200000*x^20 + 77683//14101100039391805440000*x^22 - 236364091//1693824136731743669452800000*x^24 + 657931//186134520519971831808000000*x^26 - 3392780147//37893265687455865519472640000000*x^28 + O(x^29)\n\njulia> f = exp(b)\n1 + z + 5//2*z^2 + 43//6*z^3 + 193//24*z^4 + O(z^5)\n\njulia> log(exp(b)) == b\ntrue\n\njulia> h = sqrt(a)\n1 + 1//2*z + 11//8*z^2 - 11//16*z^3 - 77//128*z^4 + O(z^5)\n","category":"page"},{"location":"AbstractAlgebra/series/#Random-generation","page":"Power series","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Random series can be constructed using the rand function. A range of possible valuations is provided. The maximum precision of the ring is used as a bound on the precision. Other parameters are used to construct random coefficients.","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"rand(R::SeriesRing, val_range::UnitRange{Int}, v...)","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"Examples","category":"page"},{"location":"AbstractAlgebra/series/","page":"Power series","title":"Power series","text":"julia> R, x = power_series_ring(ZZ, 10, \"x\")\n(Univariate power series ring over integers, x + O(x^11))\n\njulia> f = rand(R, 3:5, -10:10)\n3*x^4 - x^5 + 4*x^7 + 4*x^8 - 7*x^9 + 2*x^10 + 4*x^11 - x^12 - 4*x^13 + O(x^14)","category":"page"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/ff_embedding/#Finite-field-embeddings","page":"Finite field embeddings","title":"Finite field embeddings","text":"","category":"section"},{"location":"Nemo/ff_embedding/#Introduction","page":"Finite field embeddings","title":"Introduction","text":"","category":"section"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"Nemo allows the construction of finite field embeddings making use of the algorithm of Bosma, Cannon and Steel behind the scenes to ensure compatibility. Critical routines (e.g. polynomial factorization, matrix computations) are provided by the C library Flint, whereas high level tasks are written directly in Nemo.","category":"page"},{"location":"Nemo/ff_embedding/#Embedding-functionality","page":"Finite field embeddings","title":"Embedding functionality","text":"","category":"section"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"It is possible to explicitly call the embedding embed function to create an embedding, but it is also possible to directly ask for the conversion of a finite field element x in some other finite field k via calling k(x). The resulting embedding is of type FinFieldMorphism. It is also possible to compute the preimage map of an embedding via the preimage_map function, applied to an embedding or directly to the finite fields (this actually first computes the embedding), or via conversion. An error is thrown if the element you want to compute the preimage of is not in the image of the embedding.","category":"page"},{"location":"Nemo/ff_embedding/#Computing-an-embedding","page":"Finite field embeddings","title":"Computing an embedding","text":"","category":"section"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"embed(::fqPolyRepField, ::fqPolyRepField)","category":"page"},{"location":"Nemo/ff_embedding/#embed-Tuple{fqPolyRepField, fqPolyRepField}","page":"Finite field embeddings","title":"embed","text":"embed(k::T, K::T) where T <: FinField\n\nEmbed k in K, with some additional computations in order to satisfy compatibility conditions with previous and future embeddings.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"Examples","category":"page"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"julia> k2, x2 = FiniteField(19, 2, \"x2\")\n(Finite field of degree 2 over GF(19), x2)\n\njulia> k4, x4 = FiniteField(19, 4, \"x4\")\n(Finite field of degree 4 over GF(19), x4)\n\njulia> f = embed(k2, k4)\nMorphism of finite fields from\n from finite field of degree 2 over gF(19)\n to finite field of degree 4 over gF(19)\n\njulia> y = f(x2)\n6*x4^3 + 5*x4^2 + 9*x4 + 17\n\njulia> z = k4(x2)\n6*x4^3 + 5*x4^2 + 9*x4 + 17","category":"page"},{"location":"Nemo/ff_embedding/#Computing-the-preimage-of-an-embedding","page":"Finite field embeddings","title":"Computing the preimage of an embedding","text":"","category":"section"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"preimage_map(::fqPolyRepField, ::fqPolyRepField)\npreimage_map(::FinFieldMorphism)","category":"page"},{"location":"Nemo/ff_embedding/#preimage_map-Tuple{fqPolyRepField, fqPolyRepField}","page":"Finite field embeddings","title":"preimage_map","text":"preimage_map(k::T, k::T) where T <: FinField\n\nComputes the preimage map corresponding to the embedding of k into K.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/ff_embedding/#preimage_map-Tuple{Nemo.FinFieldMorphism}","page":"Finite field embeddings","title":"preimage_map","text":"preimage_map(f::FinFieldMorphism)\n\nCompute the preimage map corresponding to the embedding f.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"Examples","category":"page"},{"location":"Nemo/ff_embedding/","page":"Finite field embeddings","title":"Finite field embeddings","text":"julia> k7, x7 = FiniteField(13, 7, \"x7\")\n(Finite field of degree 7 over GF(13), x7)\n\njulia> k21, x21 = FiniteField(13, 21, \"x21\")\n(Finite field of degree 21 over GF(13), x21)\n\njulia> s = preimage_map(k7, k21)\nPreimage of the morphism from Finite field of degree 7 over GF(13) to Finite field of degree 21 over GF(13)\n\njulia> y = k21(x7);\n\njulia> z = s(y)\nx7\n\njulia> t = k7(y)\nx7","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Subquotients","page":"Subquotients","title":"Subquotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"A subquotient is a submodule of a quotient of a free module. In this section, the expression subquotient refers to a subquotient over a ring of type MPolyRing, MPolyQuoRing, MPolyLocRing, or MPolyQuoLocRing. That is, given a ring R of one of these types, a subquotient M over R is a module of type","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"M = (textim a + textim b)textim b","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"where","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"aR^s R^p text and bR^t R^p","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"are two homomorphisms of free R-modules with the same codomain. We then refer to","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"the module M as the subquotient defined by a and b,\nthe codomain R^p as the ambient free module of M,\nthe images of the canonical basis vectors of R^s in R^p as the ambient representatives of the generators of M, and\nthe images of the canonical basis vectors of R^t in R^p as the relations of M.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"Alternatively, we speak of the subquotient of textim a by textim b or the subquotient defined by A and B, where A and B are the matrices representing a and b, respectively.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"Finally, we refer to","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"the quotient of R^p by the submodule generated by the relations of M as the ambient module of M,","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"and regard M as a submodule of that ambient module, embedded in the natural way.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"note: Note\nRecall from the section on free modules that by a free R-module we mean a free module of type R^p , where we think of R^p as a free module with a given basis, namely the basis of standard unit vectors. Accordingly, elements of free modules are represented by coordinate vectors, and homomorphisms between free modules by matrices. Here, by convention, vectors are row vectors, and matrices operate by multiplication on the right.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"note: Note\nOver a graded ring R, we work with graded free modules R^s, R^p, R^t and graded homomorphisms a, b. As a consequence, every module involved in the construction of the subquotient defined by a and b carries an induced grading. In particular, the subquotient itself carries an induced grading.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Types","page":"Subquotients","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"All OSCAR types for the finitely presented modules considered here belong to the abstract type ModuleFP{T}, where T is the element type of the underlying ring. Graded or not, the subquotients belong to the abstract subtype AbstractSubQuo{T} <: ModuleFP{T}, they are modelled as objects of the concrete type SubquoModule{T} <: AbstractSubQuo{T}.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"note: Note\nCanonical maps such us the canonical projection onto a quotient module arise in many constructions in commutative algebra. The SubquoModule type is designed so that it allows for the caching of such maps when executing functions. The tensor_product function discussed in this section provides an example.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Constructors","page":"Subquotients","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"subquotient(a::FreeModuleHom, b::FreeModuleHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#subquotient-Tuple{FreeModuleHom, FreeModuleHom}","page":"Subquotients","title":"subquotient","text":"subquotient(a::FreeModuleHom, b::FreeModuleHom)\n\nGiven homomorphisms a and b between free modules such that codomain(a) === codomain(b), return (textim a + textim b)textim b.\n\nsubquotient(F::FreeMod{T}, A::MatElem{T}, B::MatElem{T}) where T\n\nGiven matrices A and B with rank F columns, return (textim a + textim b)textim b, where a and b are free module homomorphisms with codomain F represented by A and B.\n\nsubquotient(A::MatElem{T}, B::MatElem{T}) where T\n\nGiven matrices A and B with the same number of columns, create a free module F whose rank is that number, and return (textim a + textim b)textim b, where a and b are free module homomorphisms with codomain F represented by A and B.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> FR = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AR = R[x; y]\n[x]\n[y]\n\njulia> BR = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> MR = SubquoModule(FR, AR, BR)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> P = ideal(R, [x, y, z]);\n\njulia> U = complement_of_prime_ideal(P);\n\njulia> RL, _ = Localization(R, U);\n\njulia> FRL = free_module(RL, 1)\nFree module of rank 1 over Localization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal\n\njulia> ARL = RL[x; y]\n[x]\n[y]\n\njulia> BRL = RL[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> MRL = SubquoModule(FRL, ARL, BRL)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> RQ, _ = quo(R, ideal(R, [2*x^2-y^3, 2*x^2-y^5]));\n\njulia> FRQ = free_module(RQ, 1)\nFree module of rank 1 over RQ\n\njulia> ARQ = RQ[x; y]\n[x]\n[y]\n\njulia> BRQ = RQ[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> MRQ = SubquoModule(FRQ, ARQ, BRQ)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> 2*x^2*e[1]\n3 -> z^4*e[1]\n\njulia> RQL, _ = Localization(RQ, U);\n\njulia> FRQL = free_module(RQL, 1)\nFree module of rank 1 over Localization of quotient of multivariate polynomial ring at complement of prime ideal\n\njulia> ARQL = RQL[x; y]\n[x]\n[y]\n\njulia> BRQL = RQL[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> MRQL = SubquoModule(FRQL, ARQL, BRQL)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> 0\n2 -> 0\n3 -> z^4*e[1]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F1 = graded_free_module(Rg, [2,2,2]);\n\njulia> F2 = graded_free_module(Rg, [2]);\n\njulia> G = graded_free_module(Rg, [1,1]);\n\njulia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]]\n3-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n (x + y)*e[1] + y*e[2]\n z*e[2]\n\njulia> V2 = [z*G[2]+y*G[1]]\n1-element Vector{FreeModElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1] + z*e[2]\n\njulia> a1 = hom(F1, G, V1)\nF1 -> G\ne[1] -> y*e[1]\ne[2] -> (x + y)*e[1] + y*e[2]\ne[3] -> z*e[2]\nHomogeneous module homomorphism\n\njulia> a2 = hom(F2, G, V2)\nF2 -> G\ne[1] -> y*e[1] + z*e[2]\nHomogeneous module homomorphism\n\njulia> V = subquotient(a1,a2)\nGraded subquotient of submodule of G generated by\n1 -> y*e[1]\n2 -> (x + y)*e[1] + y*e[2]\n3 -> z*e[2]\nby submodule of G generated by\n1 -> y*e[1] + z*e[2]\n\njulia> A1 = Rg[x y; 2*x^2 3*y^2]\n[ x y]\n[2*x^2 3*y^2]\n\njulia> A2 = Rg[x^3 x^2*y; (2*x^2+x*y)*x (2*y^3+y*x^2)]\n[ x^3 x^2*y]\n[2*x^3 + x^2*y x^2*y + 2*y^3]\n\njulia> B = Rg[4*x*y^3 (2*x+y)^4]\n[4*x*y^3 16*x^4 + 32*x^3*y + 24*x^2*y^2 + 8*x*y^3 + y^4]\n\njulia> F2 = graded_free_module(Rg,[0,0])\nGraded free module Rg^2([0]) of rank 2 over Rg\n\njulia> M1 = SubQuo(F2, A1, B)\nGraded subquotient of submodule of F2 generated by\n1 -> x*e[1] + y*e[2]\n2 -> 2*x^2*e[1] + 3*y^2*e[2]\nby submodule of F2 generated by\n1 -> 4*x*y^3*e[1] + (16*x^4 + 32*x^3*y + 24*x^2*y^2 + 8*x*y^3 + y^4)*e[2]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Data-Associated-to-Subqotients","page":"Subquotients","title":"Data Associated to Subqotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"If M is a subquotient with ambient free R-module F, then","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"base_ring(M) refers to R,\nambient_free_module(M) to F,\ngens(M) to the generators of M, \nngens(M) to the number of these generators, \nM[i], gen(M, i) to the ith such generator,\nambient_representatives_generators(M) to the ambient representatives of the generators of M in F,\nrelations(M) to the relations of M, and\nambient_module(M) to the ambient module of M.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Examples","page":"Subquotients","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> base_ring(M)\nMultivariate polynomial ring in 3 variables x, y, z\n over rational field\n\njulia> F === ambient_free_module(M)\ntrue\n\njulia> gens(M)\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x*e[1]\n y*e[1]\n\njulia> ngens(M)\n2\n\njulia> gen(M, 2)\ny*e[1]\n\njulia> ambient_representatives_generators(M)\n2-element Vector{FreeModElem{QQMPolyRingElem}}:\n x*e[1]\n y*e[1]\n\njulia> relations(M)\n3-element Vector{FreeModElem{QQMPolyRingElem}}:\n x^2*e[1]\n y^3*e[1]\n z^4*e[1]\n\njulia> ambient_module(M)\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"In the graded case, we also have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":" grading_group(M::SubquoModule)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#grading_group-Tuple{SubquoModule}","page":"Subquotients","title":"grading_group","text":"grading_group(M::SubquoModule)\n\nReturn the grading group of base_ring(M).\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F1 = graded_free_module(Rg, [2,2,2]);\n\njulia> F2 = graded_free_module(Rg, [2]);\n\njulia> G = graded_free_module(Rg, [1,1]);\n\njulia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];\n\njulia> V2 = [z*G[2]+y*G[1]];\n\njulia> a1 = hom(F1, G, V1);\n\njulia> a2 = hom(F2, G, V2);\n\njulia> M = subquotient(a1,a2);\n\njulia> grading_group(M)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"degrees_of_generators(M::SubquoModule)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#degrees_of_generators-Tuple{SubquoModule}","page":"Subquotients","title":"degrees_of_generators","text":"degrees_of_generators(M::SubquoModule)\n\nReturn the degrees of the generators of M.\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F1 = graded_free_module(Rg, [2,2,2]);\n\njulia> F2 = graded_free_module(Rg, [2]);\n\njulia> G = graded_free_module(Rg, [1,1]);\n\njulia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];\n\njulia> V2 = [z*G[2]+y*G[1]];\n\njulia> a1 = hom(F1, G, V1);\n\njulia> a2 = hom(F2, G, V2);\n\njulia> M = subquotient(a1,a2);\n\njulia> degrees_of_generators(M)\n3-element Vector{GrpAbFinGenElem}:\n Element of Z with components [2]\n Element of Z with components [2]\n Element of Z with components [2]\n\njulia> gens(M)\n3-element Vector{SubquoModuleElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n y*e[1]\n (x + y)*e[1] + y*e[2]\n z*e[2]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Elements-of-Subqotients","page":"Subquotients","title":"Elements of Subqotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"All OSCAR types for elements of finitely presented modules considered here belong to the abstract type ModuleElemFP{T}, where T is the element type of the polynomial ring. For elements of subquotients, there are the abstract subtype AbstractSubQuoElem{T} <: ModuleFPElem{T} and its concrete descendant SubquoModuleElem{T} which implements an element m of a subquotient M over a ring R as a sparse row, that is, as an object of type SRow{T}. This object specifies the coefficients of an R-linear combination of the generators of M giving m. To create an element, enter the coefficients as a sparse row or a vector: ","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"(M::SubquoModule{T})(c::SRow{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"(M::SubquoModule{T})(c::Vector{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"Alternatively, directly write the element as an R-linear combination of generators of M.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Examples-2","page":"Subquotients","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> m = M(sparse_row(R, [(1,z),(2,one(R))]))\n(x*z + y)*e[1]\n\njulia> n = M([z, one(R)])\n(x*z + y)*e[1]\n\njulia> o = z*M[1] + M[2]\n(x*z + y)*e[1]\n\njulia> m == n == o\ntrue\n","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"Given an element m of a subquotient M over a ring R with element type T,","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"parent(m) refers to M, \ncoordinates(m) to an object of type SRow{T} specifying the coefficients of an R-linear combination of the generators of M which gives m, and\nambient_representative(m) to an element of the ambient free module of M which represents m.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"Given an element f of the ambient free module of a subquotient M such that f represents an element of M, the function below creates the represented element:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"(M::SubquoModule{T})(f::FreeModElem{T}; check::Bool = true) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"By default (check = true), it is tested whether f indeed represents an element of M. If this is already clear, it may be convenient to omit the test (check = false).","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Examples-3","page":"Subquotients","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"julia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> m = z*M[1] + M[2]\n(x*z + y)*e[1]\n\njulia> parent(m)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> coordinates(m)\nSparse row with positions [1, 2] and values QQMPolyRingElem[z, 1]\n\njulia> fm = ambient_representative(m)\n(x*z + y)*e[1]\n\njulia> typeof(m)\nSubquoModuleElem{QQMPolyRingElem}\n\njulia> typeof(fm)\nFreeModElem{QQMPolyRingElem}\n\njulia> parent(fm) === ambient_free_module(M)\ntrue\n\njulia> F = ambient_free_module(M)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> f = x*F[1]\nx*e[1]\n\njulia> M(f)\nx*e[1]\n\njulia> typeof(f)\nFreeModElem{QQMPolyRingElem}\n\njulia> typeof(M(f))\nSubquoModuleElem{QQMPolyRingElem}\n","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"The zero element of a subquotient is obtained as follows:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"zero(M::SubquoModule)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#zero-Tuple{SubquoModule}","page":"Subquotients","title":"zero","text":"zero(M::SubquoModule)\n\nReturn the zero element of M.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"Whether a given element of a subquotient is zero can be tested as follows:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"is_zero(m::SubquoModuleElem)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#is_zero-Tuple{SubquoModuleElem}","page":"Subquotients","title":"is_zero","text":"is_zero(m::SubquoModuleElem)\n\nReturn true if m is zero, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> is_zero(M[1])\nfalse\n\njulia> is_zero(x*M[1])\ntrue\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1)\nGraded free module Rg^1([0]) of rank 1 over Rg\n\njulia> A = Rg[x; y]\n[x]\n[y]\n\njulia> B = Rg[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> is_zero(M[1])\nfalse\n\njulia> is_zero(x*M[1])\ntrue\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"is_homogeneous(m::SubquoModuleElem)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#is_homogeneous-Tuple{SubquoModuleElem}","page":"Subquotients","title":"is_homogeneous","text":"is_homogeneous(m::SubquoModuleElem)\n\nReturn true if m is homogeneous, false otherwise.\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F1 = graded_free_module(Rg, [2,2,2]);\n\njulia> F2 = graded_free_module(Rg, [2]);\n\njulia> G = graded_free_module(Rg, [1,1]);\n\njulia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];\n\njulia> V2 = [z*G[2]+y*G[1]];\n\njulia> a1 = hom(F1, G, V1);\n\njulia> a2 = hom(F2, G, V2);\n\njulia> M = subquotient(a1,a2);\n\njulia> m1 = x*M[1]+y*M[2]+z*M[3]\n(2*x*y + y^2)*e[1] + (y^2 + z^2)*e[2]\n\njulia> is_homogeneous(m1)\ntrue\n\njulia> is_homogeneous(zero(M))\ntrue\n\njulia> m2 = M[1]+x*M[2]\n(x^2 + x*y + y)*e[1] + x*y*e[2]\n\njulia> is_homogeneous(m2)\nfalse\n\njulia> m3 = x*M[1]+M[2]+x*M[3]\n(x*y + x + y)*e[1] + (x*z + y)*e[2]\n\njulia> is_homogeneous(m3)\ntrue\n\njulia> simplify(m3)\nx*e[1] + (y - z)*e[2]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"degree(m::SubquoModuleElem)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#degree-Tuple{SubquoModuleElem}","page":"Subquotients","title":"degree","text":"degree(m::SubquoModuleElem)\n\nGiven a homogeneous element m of a graded subquotient, return the degree of m.\n\ndegree(::Type{Vector{Int}}, m::SubquoModuleElem)\n\nGiven a homogeneous element m of a mathbb Z^m-graded subquotient, return the degree of m, converted to a vector of integer numbers.\n\ndegree(::Type{Int}, m::SubquoModuleElem)\n\nGiven a homogeneous element m of a mathbb Z-graded subquotient, return the degree of m, converted to an integer number.\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F1 = graded_free_module(Rg, [2,2,2]);\n\njulia> F2 = graded_free_module(Rg, [2]);\n\njulia> G = graded_free_module(Rg, [1,1]);\n\njulia> V1 = [y*G[1], (x+y)*G[1]+y*G[2], z*G[2]];\n\njulia> V2 = [z*G[2]+y*G[1]];\n\njulia> a1 = hom(F1, G, V1);\n\njulia> a2 = hom(F2, G, V2);\n\njulia> M = subquotient(a1,a2);\n\njulia> m = x*y*z*M[1]\nx*y^2*z*e[1]\n\njulia> degree(m)\nElement of Z with components [5]\n\njulia> degree(Int, m)\n5\n\njulia> m3 = x*M[1]+M[2]+x*M[3]\n(x*y + x + y)*e[1] + (x*z + y)*e[2]\n\njulia> degree(m3)\nElement of Z with components [2]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Tests-on-Subqotients","page":"Subquotients","title":"Tests on Subqotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"The functions is_graded, is_standard_graded, is_z_graded, and is_zm_graded carry over analogously to subquotients. They return true if the respective property is satisfied, and false otherwise. In addition, we have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"==(M::SubquoModule{T}, N::SubquoModule{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#==-Union{Tuple{T}, Tuple{SubquoModule{T}, SubquoModule{T}}} where T","page":"Subquotients","title":"==","text":"==(M::SubquoModule{T}, N::SubquoModule{T}) where {T}\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return true if M equals N, where M and N are regarded as submodules of the common ambient module.\n\nHere, ambient_module(M) == ambient_module(N) if\n\nambient_free_module(M) === ambient_free_module(N), and\nthe submodules of the common ambient free module generated by the relations of M and N, respectively, are equal.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[x; y]\n[x]\n[y]\n\njulia> BN = R[x^2+y^4; y^3; z^4]\n[x^2 + y^4]\n[ y^3]\n[ z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> (x^2 + y^4)*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> M == N\nfalse\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1], Z[1], Z[1]]);\n\njulia> F = graded_free_module(Rg,2);\n\njulia> O1 = [x*F[1]+y*F[2],y*F[2]];\n\njulia> O1a = [x*F[1],y*F[2]];\n\njulia> O2 = [x^2*F[1]+y^2*F[2],y^2*F[2]];\n\njulia> M1 = SubquoModule(F, O1, O2)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1] + y*e[2]\n2 -> y*e[2]\nby submodule of F generated by\n1 -> x^2*e[1] + y^2*e[2]\n2 -> y^2*e[2]\n\njulia> M2 = SubquoModule(F, O1a, O2)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[2]\nby submodule of F generated by\n1 -> x^2*e[1] + y^2*e[2]\n2 -> y^2*e[2]\n\njulia> M1 == M2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"is_subset(M::SubquoModule{T}, N::SubquoModule{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#is_subset-Union{Tuple{T}, Tuple{SubquoModule{T}, SubquoModule{T}}} where T","page":"Subquotients","title":"is_subset","text":"is_subset(M::SubquoModule{T}, N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return true if M is contained in N, where M and N are regarded as submodules of the common ambient module.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[x; y]\n[x]\n[y]\n\njulia> BN = R[x^2+y^4; y^3; z^4]\n[x^2 + y^4]\n[ y^3]\n[ z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> (x^2 + y^4)*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> is_subset(M, N)\ntrue\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1], Z[1], Z[1]]);\n\njulia> F = graded_free_module(Rg,2);\n\njulia> O1 = [x*F[1]+y*F[2],y*F[2]];\n\njulia> O1a = [x*F[1],y*F[2]];\n\njulia> O2 = [x^2*F[1]+y^2*F[2],y^2*F[2]];\n\njulia> M1 = SubquoModule(F, O1, O2)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1] + y*e[2]\n2 -> y*e[2]\nby submodule of F generated by\n1 -> x^2*e[1] + y^2*e[2]\n2 -> y^2*e[2]\n\njulia> M2 = SubquoModule(F, O1a, O2)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[2]\nby submodule of F generated by\n1 -> x^2*e[1] + y^2*e[2]\n2 -> y^2*e[2]\n\njulia> is_subset(M1,M2)\ntrue\n\njulia> is_subset(M2,M1)\ntrue\n\njulia> M1 == M2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"is_zero(M::SubquoModule)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#is_zero-Tuple{SubquoModule}","page":"Subquotients","title":"is_zero","text":"is_zero(M::SubquoModule)\n\nReturn true if M is the zero module, false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x^2+y^2;]\n[x^2 + y^2]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 1 generator\n1 -> (x^2 + y^2)*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> is_zero(M)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Basic-Operations-on-Subquotients","page":"Subquotients","title":"Basic Operations on Subquotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":":+(M::SubquoModule{T},N::SubquoModule{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#+-Union{Tuple{T}, Tuple{SubquoModule{T}, SubquoModule{T}}} where T","page":"Subquotients","title":"+","text":"+(M::SubquoModule{T},N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return the sum of M and N regarded as submodules of the common ambient module. \n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[y;]\n[y]\n\njulia> BN = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> O = M + N\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> AM = Rg[x;];\n\njulia> BM = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, AM, BM)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = Rg[y;];\n\njulia> BN = Rg[x^2; y^3; z^4];\n\njulia> N = SubquoModule(F, AN, BN)\nGraded subquotient of submodule of F generated by\n1 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> M + N\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"sum(M::SubquoModule{T},N::SubquoModule{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#sum-Union{Tuple{T}, Tuple{SubquoModule{T}, SubquoModule{T}}} where T","page":"Subquotients","title":"sum","text":"sum(M::SubquoModule{T},N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return the sum of M and N regarded as submodules of the common ambient module.\n\nAdditionally, return the inclusion maps M to M + N and N to M + N.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[y;]\n[y]\n\njulia> BN = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> O = sum(M, N);\n\njulia> O[1]\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> O[2]\nMap with following data\nDomain:\n=======\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> O[3]\nMap with following data\nDomain:\n=======\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> AM = Rg[x;];\n\njulia> BM = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, AM, BM)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = Rg[y;];\n\njulia> BN = Rg[x^2; y^3; z^4];\n\njulia> N = SubquoModule(F, AN, BN)\nGraded subquotient of submodule of F generated by\n1 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> sum(M, N)\n(Graded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], M -> Graded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nx*e[1] -> x*e[1]\nHomogeneous module homomorphism, N -> Graded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\ny*e[1] -> y*e[1]\nHomogeneous module homomorphism)\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#intersect-Union{Tuple{T}, Tuple{SubquoModule{T}, SubquoModule{T}}} where T","page":"Subquotients","title":"intersect","text":"intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.\n\nAdditionally, return the inclusion maps M cap N to M and M cap N to N.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[y;]\n[y]\n\njulia> BN = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Subquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n, Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n)\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> AM = Rg[x;];\n\njulia> BM = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, AM, BM)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = Rg[y;];\n\njulia> BN = Rg[x^2; y^3; z^4];\n\njulia> N = SubquoModule(F, AN, BN)\nGraded subquotient of submodule of F generated by\n1 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> M\n-x*y*e[1] -> -x*y*e[1]\nx*z^4*e[1] -> x*z^4*e[1]\nHomogeneous module homomorphism, Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> N\n-x*y*e[1] -> x*y*e[1]\nx*z^4*e[1] -> 0\nHomogeneous module homomorphism)\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Submodules-and-Quotients","page":"Subquotients","title":"Submodules and Quotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#sub-Union{Tuple{T}, Tuple{ModuleFP{T}, Vector{<:ModuleFPElem{T}}}, Tuple{ModuleFP{T}, Vector{<:ModuleFPElem{T}}, Symbol}} where T","page":"Subquotients","title":"sub","text":"sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T\n\nGiven a vector V of (homogeneous) elements of M, return the (graded) submodule of M generated by these elements.\n\nPut more precisely, return this submodule as an object of type SubquoModule. \n\nAdditionally, if N denotes this object,\n\nreturn the inclusion map N to M if task = :with_morphism (default),\nreturn and cache the inclusion map N to M if task = :cache_morphism,\ndo none of the above if task = :none.\n\nIf task = :only_morphism, return only the inclusion map.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];\n\njulia> N, incl = sub(F, V);\n\njulia> N\nSubmodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nrepresented as subquotient with no relations.\n\njulia> incl\nMap with following data\nDomain:\n=======\nSubmodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nrepresented as subquotient with no relations.\nCodomain:\n=========\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#quo-Union{Tuple{T}, Tuple{ModuleFP{T}, Vector{<:ModuleFPElem{T}}}, Tuple{ModuleFP{T}, Vector{<:ModuleFPElem{T}}, Symbol}} where T","page":"Subquotients","title":"quo","text":"quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T\n\nGiven a vector V of (homogeneous) elements of M, return the quotient of M by the (graded) submodule of M which is generated by these elements.\n\nPut more precisely, return the quotient as an object of type SubquoModule. \n\nAdditionally, if N denotes this object,\n\nreturn the projection map M to N if task = :with_morphism (default),\nreturn and cache the projection map M to N if task = :cache_morphism,\ndo none of the above if task = :none or task = :module.\n\nIf task = :only_morphism, return only the projection map.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];\n\njulia> N, proj = quo(F, V);\n\njulia> N\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> proj\nMap with following data\nDomain:\n=======\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#Homomorphisms-From-Subqotients","page":"Subquotients","title":"Homomorphisms From Subqotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"All OSCAR types for homomorphisms of finitely presented modules considered here belong to the abstract type ModuleFPHom{T1, T2}, where T1 and T2 are the types of domain and codomain respectively. For homomorphisms from subquotients, OSCAR provides the concrete type SubQuoHom{T1, T2} <: ModuleFPHom{T1, T2} as well as the following constructors:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"hom(M::SubquoModule{T}, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#hom-Union{Tuple{T}, Tuple{SubquoModule{T}, ModuleFP{T}, Vector{<:ModuleFPElem{T}}}} where T","page":"Subquotients","title":"hom","text":"hom(M::SubquoModule{T}, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T\n\nGiven a vector V of ngens(M) elements of N, return the homomorphism M to N which sends the i-th generator M[i] of M to the i-th entry of V.\n\nhom(M::SubquoModule{T}, N::ModuleFP{T}, A::MatElem{T})) where T\n\nGiven a matrix A with ngens(M) rows and ngens(N) columns, return the homomorphism M to N which sends the i-th generator M[i] of M to the linear combination sum_j Aij*Nj of the generators N[j] of N.\n\nnote: Note\nThe module N may be of type FreeMod or SubquoMod. If both modules M and N are graded, the data must define a graded module homomorphism of some degree. If this degree is the zero element of the (common) grading group, we refer to the homomorphism under consideration as a homogeneous module homomorphism.\n\nwarning: Warning\nThe functions do not check whether the resulting homomorphism is well-defined, that is, whether it sends the relations of M into the relations of N. \n\nIf you are uncertain with regard to well-definedness, use the function below. Note, however, that the check performed by the function requires a Gröbner basis computation. This may take some time.\n\nis_welldefined(a::ModuleFPHom)\n\nReturn true if a is well-defined, and false otherwise.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x*N[2]]\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x*y^2*e[1]\n x*y*e[1]\n\njulia> a = hom(M, N, V)\nMap with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> is_welldefined(a)\ntrue\n\njulia> W = R[y^2 0; 0 x]\n[y^2 0]\n[ 0 x]\n\njulia> b = hom(M, N, W);\n\njulia> a == b\ntrue\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x; y];\n\njulia> B = R[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> N = M;\n\njulia> W = [y*N[1], x*N[2]]\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x*y*e[1]\n x*y*e[1]\n\njulia> c = hom(M, N, W);\n\njulia> is_welldefined(c)\nfalse\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> is_welldefined(a)\ntrue\n\njulia> W = Rg[y^2 0; 0 x^2]\n[y^2 0]\n[ 0 x^2]\n\njulia> b = hom(M, N, W)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> a == b\ntrue\n\njulia> W = [y*N[1], x*N[2]]\n2-element Vector{SubquoModuleElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n x*y*e[1]\n x*y*e[1]\n\njulia> c = hom(M, N, W)\nM -> M\nx*e[1] -> x*y*e[1]\ny*e[1] -> x*y*e[1]\nGraded module homomorphism of degree [1]\n\njulia> is_welldefined(c)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"Given a homomorphism of type SubQuoHom, a matrix A representing it is recovered by the following function:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"matrix(a::SubQuoHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#matrix-Tuple{SubQuoHom}","page":"Subquotients","title":"matrix","text":"matrix(a::SubQuoHom)\n\nGiven a homomorphism a of type SubQuoHom with domain M and codomain N, return a matrix A with ngens(M) rows and ngens(N) columns such that a == hom(M, N, A).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x*N[2]];\n\njulia> a = hom(M, N, V);\n\njulia> A = matrix(a)\n[y^2 0]\n[ 0 x]\n\njulia> a(M[1])\nx*y^2*e[1]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> matrix(a)\n[y^2 0]\n[ 0 x^2]\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"The domain and codomain of a homomorphism a of type SubQuoHom can be recovered by entering domain(a) and codomain(a), respectively.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"The functions below test whether a homomorphism of type SubQuoHom is graded and homogeneous, respectively.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"is_graded(a:: SubQuoHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#is_graded-Tuple{SubQuoHom}","page":"Subquotients","title":"is_graded","text":"is_graded(a::SubQuoHom)\n\nReturn true if a is graded, false otherwise.\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> is_graded(a)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"is_homogeneous(a:: SubQuoHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#is_homogeneous-Tuple{SubQuoHom}","page":"Subquotients","title":"is_homogeneous","text":"is_homogeneous(a::SubQuoHom)\n\nReturn true if a is homogeneous, false otherwise\n\nHere, if G is the grading group of a, a is homogeneous if a is graded of degree zero(G).\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> is_homogeneous(a)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"degree(a:: SubQuoHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#degree-Tuple{SubQuoHom}","page":"Subquotients","title":"degree","text":"degree(a::SubQuoHom)\n\nIf a is graded, return the degree of a.\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> degree(a)\nElement of Z with components [2]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"grading_group(a:: SubQuoHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#grading_group-Tuple{SubQuoHom}","page":"Subquotients","title":"grading_group","text":"grading_group(a::SubQuoHom)\n\nIf a is graded, return the grading group of a.\n\nExamples\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B);\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> grading_group(a)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/matrix/#Matrices","page":"Matrices","title":"Matrices","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Nemo allow the creation of dense matrices over any computable ring R. There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of matrices over numerous specific rings, usually provided by C/C++ libraries.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"The following table shows each of the matrix types available in Nemo, the base ring R, and the Julia/Nemo types for that kind of matrix (the type information is mainly of concern to developers).","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl Generic.Mat{T} Generic.MatSpace{T}\nmathbbZ Flint ZZMatrix ZZMatrixSpace\nmathbbZnmathbbZ (small n) Flint zzModMatrix zzModMatrixSpace\nmathbbZnmathbbZ (large n) Flint ZZModMatrix ZZModMatrixSpace\nmathbbQ Flint QQMatrix QQMatrixSpace\nmathbbZpmathbbZ (small p) Flint fpMatrix fpMatrixSpace\nmathbbF_p^n (small p) Flint fqPolyRepMatrix fqPolyRepMatrixSpace\nmathbbF_p^n (large p) Flint FqPolyRepMatrix `FqPolyRepMatrixSpace\nmathbbR (arbitrary precision) Arb RealMat RealMatSpace\nmathbbC (arbitrary precision) Arb ComplexMat ComplexMatSpace\nmathbbR (fixed precision) Arb arb_mat ArbMatSpace\nmathbbC (fixed precision) Arb acb_mat AcbMatSpace","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"The dimensions and base ring R of a generic matrix are stored in its parent object.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"All matrix element types belong to the abstract type MatElem and all of the matrix space types belong to the abstract type MatSpace. This enables one to write generic functions that can accept any Nemo matrix type.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Note that the preferred way to create matrices is not to use the type constructors but to use the matrix function, see also the Matrix element constructors section of the AbstractAlgebra manual.","category":"page"},{"location":"Nemo/matrix/#Matrix-functionality","page":"Matrices","title":"Matrix functionality","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"All matrix spaces in Nemo provide the matrix functionality of AbstractAlgebra:","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/matrix","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Some of this functionality is provided in Nemo by C libraries, such as Flint, for various specific rings.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"In the following, we list the functionality which is provided in addition to the generic matrix functionality, for specific rings in Nemo.","category":"page"},{"location":"Nemo/matrix/#Comparison-operators","page":"Matrices","title":"Comparison operators","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"overlaps(::RealMat, ::RealMat)","category":"page"},{"location":"Nemo/matrix/#overlaps-Tuple{RealMat, RealMat}","page":"Matrices","title":"overlaps","text":"overlaps(x::RealMat, y::RealMat)\n\nReturns true if all entries of x overlap with the corresponding entry of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"overlaps(::ComplexMat, ::ComplexMat)","category":"page"},{"location":"Nemo/matrix/#overlaps-Tuple{ComplexMat, ComplexMat}","page":"Matrices","title":"overlaps","text":"overlaps(x::ComplexMat, y::ComplexMat)\n\nReturns true if all entries of x overlap with the corresponding entry of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"contains(::RealMat, ::RealMat)","category":"page"},{"location":"Nemo/matrix/#contains-Tuple{RealMat, RealMat}","page":"Matrices","title":"contains","text":"contains(x::RealMat, y::RealMat)\n\nReturns true if all entries of x contain the corresponding entry of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"contains(::ComplexMat, ::ComplexMat)","category":"page"},{"location":"Nemo/matrix/#contains-Tuple{ComplexMat, ComplexMat}","page":"Matrices","title":"contains","text":"contains(x::ComplexMat, y::ComplexMat)\n\nReturns true if all entries of x contain the corresponding entry of y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"In addition we have the following ad hoc comparison operators.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"C = RR[1 2; 3 4]\nD = RR[\"1 +/- 0.1\" \"2 +/- 0.1\"; \"3 +/- 0.1\" \"4 +/- 0.1\"]\noverlaps(C, D)\ncontains(D, C)","category":"page"},{"location":"Nemo/matrix/#Scaling","page":"Matrices","title":"Scaling","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"<<(::ZZMatrix, ::Int)","category":"page"},{"location":"Nemo/matrix/#<<-Tuple{ZZMatrix, Int64}","page":"Matrices","title":"<<","text":"<<(x::ZZMatrix, y::Int)\n\nReturn 2^yx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":">>(::ZZMatrix, ::Int)","category":"page"},{"location":"Nemo/matrix/#>>-Tuple{ZZMatrix, Int64}","page":"Matrices","title":">>","text":">>(x::ZZMatrix, y::Int)\n\nReturn x2^y where rounding is towards zero.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\n\nA = S([ZZ(2) 3 5; 1 4 7; 9 6 3])\n\nB = A<<5\nC = B>>2","category":"page"},{"location":"Nemo/matrix/#Determinant","page":"Matrices","title":"Determinant","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"det_divisor(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#det_divisor-Tuple{ZZMatrix}","page":"Matrices","title":"det_divisor","text":"det_divisor(x::ZZMatrix)\n\nReturn some positive divisor of the determinant of x, if the determinant is nonzero, otherwise return zero.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"det_given_divisor(::ZZMatrix, ::Integer, ::Bool)\ndet_given_divisor(::ZZMatrix, ::ZZRingElem, ::Bool)","category":"page"},{"location":"Nemo/matrix/#det_given_divisor-Tuple{ZZMatrix, Integer, Bool}","page":"Matrices","title":"det_given_divisor","text":"det_given_divisor(x::ZZMatrix, d::Integer, proved=true)\n\nReturn the determinant of x given a positive divisor of its determinant. If proved == true (the default), the output is guaranteed to be correct, otherwise a heuristic algorithm is used.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#det_given_divisor-Tuple{ZZMatrix, ZZRingElem, Bool}","page":"Matrices","title":"det_given_divisor","text":"det_given_divisor(x::ZZMatrix, d::ZZRingElem, proved=true)\n\nReturn the determinant of x given a positive divisor of its determinant. If proved == true (the default), the output is guaranteed to be correct, otherwise a heuristic algorithm is used.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\n\nA = S([ZZ(2) 3 5; 1 4 7; 9 6 3])\n\nc = det_divisor(A)\nd = det_given_divisor(A, c)","category":"page"},{"location":"Nemo/matrix/#Linear-solving","page":"Matrices","title":"Linear solving","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"cansolve(::ZZMatrix, ::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#cansolve-Tuple{ZZMatrix, ZZMatrix}","page":"Matrices","title":"cansolve","text":"cansolve(a::ZZMatrix, b::ZZMatrix) -> Bool, ZZMatrix\n\nReturn true and a matrix x such that ax = b, or false and some matrix in case x does not exist.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"solve_dixon(::ZZMatrix, ::ZZMatrix)\nsolve_dixon(::QQMatrix, ::QQMatrix)","category":"page"},{"location":"Nemo/matrix/#solve_dixon-Tuple{ZZMatrix, ZZMatrix}","page":"Matrices","title":"solve_dixon","text":"solve_dixon(a::ZZMatrix, b::ZZMatrix)\n\nReturn a tuple (x m) consisting of a column vector x such that ax = b pmodm. The element b must be a column vector with the same number > of rows as a and a must be a square matrix. If these conditions are not met or (x d) does not exist, an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#solve_dixon-Tuple{QQMatrix, QQMatrix}","page":"Matrices","title":"solve_dixon","text":"solve_dixon(a::QQMatrix, b::QQMatrix)\n\nSolve ax = b by clearing denominators and using Dixon's algorithm. This is usually faster for large systems.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\nT = matrix_space(ZZ, 3, 1)\n\nA = S([ZZ(2) 3 5; 1 4 7; 9 2 2])\nB = T([ZZ(4), 5, 7])\n\nX, m = solve_dixon(A, B)","category":"page"},{"location":"Nemo/matrix/#Pseudo-inverse","page":"Matrices","title":"Pseudo inverse","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"pseudo_inv(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#pseudo_inv-Tuple{ZZMatrix}","page":"Matrices","title":"pseudo_inv","text":"pseudo_inv(x::ZZMatrix)\n\nReturn a tuple (z d) consisting of a matrix z and denominator d such that zd is the inverse of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\n\nA = S([1 0 1; 2 3 1; 5 6 7])\n\nB, d = pseudo_inv(A)","category":"page"},{"location":"Nemo/matrix/#Nullspace","page":"Matrices","title":"Nullspace","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"nullspace_right_rational(x::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#nullspace_right_rational-Tuple{ZZMatrix}","page":"Matrices","title":"nullspace_right_rational","text":"nullspace_right_rational(x::ZZMatrix)\n\nReturn a tuple (r U) consisting of a matrix U such that the first r columns form the right rational nullspace of x, i.e. a set of vectors over mathbbZ giving a mathbbQ-basis for the nullspace of x considered as a matrix over mathbbQ.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#Modular-reduction","page":"Matrices","title":"Modular reduction","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"reduce_mod(::ZZMatrix, ::Integer)\nreduce_mod(::ZZMatrix, ::ZZRingElem)","category":"page"},{"location":"Nemo/matrix/#reduce_mod-Tuple{ZZMatrix, Integer}","page":"Matrices","title":"reduce_mod","text":"reduce_mod(x::ZZMatrix, y::Integer)\n\nReduce the entries of x modulo y and return the result.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#reduce_mod-Tuple{ZZMatrix, ZZRingElem}","page":"Matrices","title":"reduce_mod","text":"reduce_mod(x::ZZMatrix, y::ZZRingElem)\n\nReduce the entries of x modulo y and return the result.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\n\nA = S([ZZ(2) 3 5; 1 4 7; 9 2 2])\n\nreduce_mod(A, ZZ(5))\nreduce_mod(A, 2)","category":"page"},{"location":"Nemo/matrix/#Lifting","page":"Matrices","title":"Lifting","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lift(::zzModMatrix)\nlift(::fpMatrix)","category":"page"},{"location":"Nemo/matrix/#lift-Tuple{zzModMatrix}","page":"Matrices","title":"lift","text":"lift(a::T) where {T <: Zmodn_mat}\n\nReturn a lift of the matrix a to a matrix over mathbbZ, i.e. where the entries of the returned matrix are those of a lifted to mathbbZ.\n\n\n\n\n\nlift(M::smodule{T}, SM::smodule{T}) where T\n\nRepresents the generators of SM in terms of the generators of M. If SM is in M, rest is the null module, otherwise rest = reduce(SM, std(M)). Returns (result, rest) with for global orderings: Matrix(SM) - Matrix(rest) = Matrix(M)*Matrix(result) for non-global orderings: Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) where U is some diagonal matrix of units. To compute this U, see lift(M::smodule, SM::smodule, goodShape::Bool, isSB::Bool, divide::Bool).\n\n\n\n\n\nlift(M::smodule{T}, SM::smodule{T}, goodShape::Bool, isSB::Bool, divide::Bool) where T\n\nRepresents the generators of SM in terms of the generators of M. Returns (result, rest, U) with Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) If SM is in M, then rest is the null module. Otherwise, rest = SM if !divide, and rest = normalform(SM, std(M)) if divide. U is a diagonal matrix of units, differing from the identity matrix only for local ring orderings.\n\nThere are three boolean options. goodShape: maximal non-zero index in generators of SM <= that of M, which should be come from a rank check rank(SM)==rank(M). isSB: generators of M form a Groebner basis. divide: allow SM not to be a submodule of M.\n\n\n\n\n\nlift(M::sideal{T}, SM::sideal{T}) where T\n\nRepresents the generators of SM in terms of the generators of M. If SM is in M, rest is the null module, otherwise rest = reduce(SM, std(M)). Returns (result, rest) with for global orderings: Matrix(SM) - Matrix(rest) = Matrix(M)*Matrix(result) for non-global orderings: Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) where U is some diagonal matrix of units. To compute this U, see lift(M::sideal, SM::sideal, goodShape::Bool, isSB::Bool, divide::Bool).\n\n\n\n\n\nlift(M::sideal{T}, SM::sideal{T}, goodShape::Bool, isSB::Bool, divide::Bool) where T\n\nRepresents the generators of SM in terms of the generators of M. Returns (result, rest, U) with Matrix(SM)*U - Matrix(rest) = Matrix(M)*Matrix(result) If SM is in M, then rest is the null module. Otherwise, rest = SM if !divide, and rest = normalform(SM, std(M)) if divide. U is a diagonal matrix of units, differing from the identity matrix only for local ring orderings.\n\nThere are three boolean options. goodShape: maximal non-zero index in generators of SM <= that of M, which should be come from a rank check rank(SM)==rank(M). isSB: generators of M form a Groebner basis divide: allow SM not to be a submodule of M, which is useful for division with remainder.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#lift-Tuple{fpMatrix}","page":"Matrices","title":"lift","text":"lift(a::fpMatrix)\n\nReturn a lift of the matrix a to a matrix over mathbbZ, i.e. where the entries of the returned matrix are those of a lifted to mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"R = residue_ring(ZZ, 7)\nS = matrix_space(R, 3, 3)\n\na = S([4 5 6; 7 3 2; 1 4 5])\n\n b = lift(a)","category":"page"},{"location":"Nemo/matrix/#Special-matrices","page":"Matrices","title":"Special matrices","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"hadamard(::ZZMatrixSpace)","category":"page"},{"location":"Nemo/matrix/#hadamard-Tuple{ZZMatrixSpace}","page":"Matrices","title":"hadamard","text":"hadamard(R::ZZMatrixSpace)\n\nReturn the Hadamard matrix for the given matrix space. The number of rows and columns must be equal.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"is_hadamard(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#is_hadamard-Tuple{ZZMatrix}","page":"Matrices","title":"is_hadamard","text":"is_hadamard(x::ZZMatrix)\n\nReturn true if the given matrix is Hadamard, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"hilbert(::QQMatrixSpace)","category":"page"},{"location":"Nemo/matrix/#hilbert-Tuple{QQMatrixSpace}","page":"Matrices","title":"hilbert","text":"hilbert(R::QQMatrixSpace)\n\nReturn the Hilbert matrix in the given matrix space. This is the matrix with entries H_ij = 1(i + j - 1).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"R = matrix_space(ZZ, 3, 3)\nS = matrix_space(QQ, 3, 3)\n\nA = hadamard(R)\nis_hadamard(A)\nB = hilbert(R)","category":"page"},{"location":"Nemo/matrix/#Hermite-Normal-Form","page":"Matrices","title":"Hermite Normal Form","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"hnf(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#hnf-Tuple{ZZMatrix}","page":"Matrices","title":"hnf","text":"hnf(x::ZZMatrix)\n\nReturn the Hermite Normal Form of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"hnf_with_transform(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#hnf_with_transform-Tuple{ZZMatrix}","page":"Matrices","title":"hnf_with_transform","text":"hnf_with_transform(x::ZZMatrix)\n\nCompute a tuple (H T) where H is the Hermite normal form of x and T is a transformation matrix so that H = Tx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"hnf_modular(::ZZMatrix, ::ZZRingElem)","category":"page"},{"location":"Nemo/matrix/#hnf_modular-Tuple{ZZMatrix, ZZRingElem}","page":"Matrices","title":"hnf_modular","text":"hnf_modular(x::ZZMatrix, d::ZZRingElem)\n\nCompute the Hermite normal form of x given that d is a multiple of the determinant of the nonzero rows of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"hnf_modular_eldiv(::ZZMatrix, ::ZZRingElem)","category":"page"},{"location":"Nemo/matrix/#hnf_modular_eldiv-Tuple{ZZMatrix, ZZRingElem}","page":"Matrices","title":"hnf_modular_eldiv","text":"hnf_modular_eldiv(x::ZZMatrix, d::ZZRingElem)\n\nCompute the Hermite normal form of x given that d is a multiple of the largest elementary divisor of x. The matrix x must have full rank.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"is_hnf(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#is_hnf-Tuple{ZZMatrix}","page":"Matrices","title":"is_hnf","text":"is_hnf(x::ZZMatrix)\n\nReturn true if the given matrix is in Hermite Normal Form, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\n\nA = S([ZZ(2) 3 5; 1 4 7; 19 3 7])\n\nB = hnf(A)\nH, T = hnf_with_transform(A)\nM = hnf_modular(A, ZZ(27))\nN = hnf_modular_eldiv(A, ZZ(27))\nis_hnf(M)","category":"page"},{"location":"Nemo/matrix/#Lattice-basis-reduction","page":"Matrices","title":"Lattice basis reduction","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Nemo provides LLL lattice basis reduction. Optionally one can specify the setup using a context object created by the following function.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_ctx(delta::Float64, eta::Float64, rep=:zbasis, gram=:approx)","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Return a LLL context object specifying LLL parameters delta and eta and specifying the representation as either :zbasis or :gram and the Gram type as either :approx or :exact.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll(::ZZMatrix, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll-Tuple{ZZMatrix, lll_ctx}","page":"Matrices","title":"lll","text":"lll(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51))\n\nReturn the LLL reduction of the matrix x. By default the matrix x is a mathbbZ-basis and the Gram matrix is maintained throughout in approximate form. The LLL is performed with reduction parameters delta = 099 and eta = 051. All of these defaults can be overridden by specifying an optional context object.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_with_transform(::ZZMatrix, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll_with_transform-Tuple{ZZMatrix, lll_ctx}","page":"Matrices","title":"lll_with_transform","text":"lll_with_transform(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51))\n\nCompute a tuple (L T) where L is the LLL reduction of a and T is a transformation matrix so that L = Ta. All the default parameters can be overridden by supplying an optional context object.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_gram(::ZZMatrix, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll_gram-Tuple{ZZMatrix, lll_ctx}","page":"Matrices","title":"lll_gram","text":"lll_gram(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51, :gram))\n\nGiven the Gram matrix x of a matrix, compute the Gram matrix of its LLL reduction.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_gram_with_transform(::ZZMatrix, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll_gram_with_transform-Tuple{ZZMatrix, lll_ctx}","page":"Matrices","title":"lll_gram_with_transform","text":"lll_gram_with_transform(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51, :gram))\n\nGiven the Gram matrix x of a matrix M, compute a tuple (L T) where L is the gram matrix of the LLL reduction of the matrix and T is a transformation matrix so that L = TM.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_with_removal(::ZZMatrix, ::ZZRingElem, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll_with_removal-Tuple{ZZMatrix, ZZRingElem, lll_ctx}","page":"Matrices","title":"lll_with_removal","text":"lll_with_removal(x::ZZMatrix, b::ZZRingElem, ctx::lll_ctx = lll_ctx(0.99, 0.51))\n\nCompute the LLL reduction of x and throw away rows whose norm exceeds the given bound b. Return a tuple (r L) where the first r rows of L are the rows remaining after removal.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_with_removal_transform(::ZZMatrix, ::ZZRingElem, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll_with_removal_transform-Tuple{ZZMatrix, ZZRingElem, lll_ctx}","page":"Matrices","title":"lll_with_removal_transform","text":"lll_with_removal_transform(x::ZZMatrix, b::ZZRingElem, ctx::lll_ctx = lll_ctx(0.99, 0.51))\n\nCompute a tuple (r L T) where the first r rows of L are those remaining from the LLL reduction after removal of vectors with norm exceeding the bound b and T is a transformation matrix so that L = Tx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll!(::ZZMatrix, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll!-Tuple{ZZMatrix, lll_ctx}","page":"Matrices","title":"lll!","text":"lll!(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51))\n\nPerform the LLL reduction of the matrix x inplace. By default the matrix x is a > mathbbZ-basis and the Gram matrix is maintained throughout in approximate form. The LLL is performed with reduction parameters delta = 099 and eta = 051. All of these defaults can be overridden by specifying an optional context object.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_gram!(::ZZMatrix, ::lll_ctx)","category":"page"},{"location":"Nemo/matrix/#lll_gram!-Tuple{ZZMatrix, lll_ctx}","page":"Matrices","title":"lll_gram!","text":"lll_gram!(x::ZZMatrix, ctx::lll_ctx = lll_ctx(0.99, 0.51, :gram))\n\nGiven the Gram matrix x of a matrix, compute the Gram matrix of its LLL reduction inplace.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\n\nA = S([ZZ(2) 3 5; 1 4 7; 19 3 7])\n\nL = lll(A, lll_ctx(0.95, 0.55, :zbasis, :approx)\nL, T = lll_with_transform(A)\n\nG == lll_gram(gram(A))\nG, T = lll_gram_with_transform(gram(A))\n\nr, L = lll_with_removal(A, ZZ(100))\nr, L, T = lll_with_removal_transform(A, ZZ(100))","category":"page"},{"location":"Nemo/matrix/#Smith-Normal-Form","page":"Matrices","title":"Smith Normal Form","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"snf(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#snf-Tuple{ZZMatrix}","page":"Matrices","title":"snf","text":"snf(x::ZZMatrix)\n\nCompute the Smith normal form of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"snf_diagonal(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#snf_diagonal-Tuple{ZZMatrix}","page":"Matrices","title":"snf_diagonal","text":"snf_diagonal(x::ZZMatrix)\n\nGiven a diagonal matrix x compute the Smith normal form of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"is_snf(::ZZMatrix)","category":"page"},{"location":"Nemo/matrix/#is_snf-Tuple{ZZMatrix}","page":"Matrices","title":"is_snf","text":"is_snf(x::ZZMatrix)\n\nReturn true if x is in Smith normal form, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"S = matrix_space(ZZ, 3, 3)\n\nA = S([ZZ(2) 3 5; 1 4 7; 19 3 7])\n\nB = snf(A)\nis_snf(B) == true\n\nB = S([ZZ(2) 0 0; 0 4 0; 0 0 7])\n\nC = snf_diagonal(B)","category":"page"},{"location":"Nemo/matrix/#Strong-Echelon-Form","page":"Matrices","title":"Strong Echelon Form","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"strong_echelon_form(::zzModMatrix)\nstrong_echelon_form(::fpMatrix)","category":"page"},{"location":"Nemo/matrix/#strong_echelon_form-Tuple{zzModMatrix}","page":"Matrices","title":"strong_echelon_form","text":"strong_echelon_form(a::zzModMatrix)\n\nReturn the strong echeleon form of a. The matrix a must have at least as many rows as columns.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#strong_echelon_form-Tuple{fpMatrix}","page":"Matrices","title":"strong_echelon_form","text":"strong_echelon_form(a::fpMatrix)\n\nReturn the strong echeleon form of a. The matrix a must have at least as many rows as columns.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"R = residue_ring(ZZ, 12)\nS = matrix_space(R, 3, 3)\n\nA = S([4 1 0; 0 0 5; 0 0 0 ])\n\nB = strong_echelon_form(A)","category":"page"},{"location":"Nemo/matrix/#Howell-Form","page":"Matrices","title":"Howell Form","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"howell_form(::zzModMatrix)\nhowell_form(::fpMatrix)","category":"page"},{"location":"Nemo/matrix/#howell_form-Tuple{zzModMatrix}","page":"Matrices","title":"howell_form","text":"howell_form(a::zzModMatrix)\n\nReturn the Howell normal form of a. The matrix a must have at least as many rows as columns.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#howell_form-Tuple{fpMatrix}","page":"Matrices","title":"howell_form","text":"howell_form(a::fpMatrix)\n\nReturn the Howell normal form of a. The matrix a must have at least as many rows as columns.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"R = residue_ring(ZZ, 12)\nS = matrix_space(R, 3, 3)\n\nA = S([4 1 0; 0 0 5; 0 0 0 ])\n\nB = howell_form(A)","category":"page"},{"location":"Nemo/matrix/#Gram-Schmidt-Orthogonalisation","page":"Matrices","title":"Gram-Schmidt Orthogonalisation","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"gram_schmidt_orthogonalisation(::QQMatrix)","category":"page"},{"location":"Nemo/matrix/#gram_schmidt_orthogonalisation-Tuple{QQMatrix}","page":"Matrices","title":"gram_schmidt_orthogonalisation","text":"gram_schmidt_orthogonalisation(x::QQMatrix)\n\nTakes the columns of x as the generators of a subset of mathbbQ^m and returns a matrix whose columns are an orthogonal generating set for the same subspace.\n\nExamples\n\njulia> S = matrix_space(QQ, 3, 3);\n\njulia> A = S([4 7 3; 2 9 1; 0 5 3])\n[4 7 3]\n[2 9 1]\n[0 5 3]\n\njulia> B = gram_schmidt_orthogonalisation(A)\n[4 -11//5 95//123]\n[2 22//5 -190//123]\n[0 5 209//123]\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#Exponential","page":"Matrices","title":"Exponential","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"A = RR[2 0 0; 0 3 0; 0 0 1]\n\nB = exp(A)","category":"page"},{"location":"Nemo/matrix/#Norm","page":"Matrices","title":"Norm","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"bound_inf_norm(::RealMat)","category":"page"},{"location":"Nemo/matrix/#bound_inf_norm-Tuple{RealMat}","page":"Matrices","title":"bound_inf_norm","text":"bound_inf_norm(x::RealMat)\n\nReturns a nonnegative element z of type arb, such that z is an upper bound for the infinity norm for every matrix in x\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"bound_inf_norm(::ComplexMat)","category":"page"},{"location":"Nemo/matrix/#bound_inf_norm-Tuple{ComplexMat}","page":"Matrices","title":"bound_inf_norm","text":"bound_inf_norm(x::ComplexMat)\n\nReturns a nonnegative element z of type acb, such that z is an upper bound for the infinity norm for every matrix in x\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"A = RR[1 2 3; 4 5 6; 7 8 9]\n\nd = bound_inf_norm(A)","category":"page"},{"location":"Nemo/matrix/#Shifting","page":"Matrices","title":"Shifting","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"A = RR[1 2 3; 4 5 6; 7 8 9]\n\nB = ldexp(A, 4)\n\noverlaps(16*A, B)","category":"page"},{"location":"Nemo/matrix/#Predicates","page":"Matrices","title":"Predicates","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"A = CC[1 2 3; 4 5 6; 7 8 9]\n\nisreal(A)\n\nisreal(onei(CC)*A)","category":"page"},{"location":"Nemo/matrix/#Conversion-to-Julia-matrices","page":"Matrices","title":"Conversion to Julia matrices","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Julia matrices use a different data structure than Nemo matrices. Conversion to Julia matrices is usually only required for interfacing with other packages. It isn't necessary to convert Nemo matrices to Julia matrices in order to manipulate them.","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"This conversion can be performed with standard Julia syntax, such as the following, where A is an ZZMatrix:","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"Matrix{Int}(A)\nMatrix{BigInt}(A)","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"In case the matrix cannot be converted without loss, an InexactError is thrown: in this case, cast to a matrix of BigInts rather than Ints.","category":"page"},{"location":"Nemo/matrix/#Eigenvalues-and-Eigenvectors-(experimental)","page":"Matrices","title":"Eigenvalues and Eigenvectors (experimental)","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"eigvals(::ComplexMat)\neigvals_simple(a::ComplexMat)","category":"page"},{"location":"Nemo/matrix/#eigvals-Tuple{ComplexMat}","page":"Matrices","title":"eigvals","text":"eigvals(A::ComplexMat)\n\nReturns the eigenvalues of A as a vector of tuples (ComplexFieldElem, Int). Each tuple (z, k) corresponds to a cluster of k eigenvalues of A.\n\nThis function is experimental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#eigvals_simple-Tuple{ComplexMat}","page":"Matrices","title":"eigvals_simple","text":"eigvals_simple(A::ComplexMat, algorithm::Symbol = :default)\n\nReturns the eigenvalues of A as a vector of acb. It is assumed that A has only simple eigenvalues.\n\nThe algorithm used can be changed by setting the algorithm keyword to :vdhoeven_mourrain or :rump.\n\nThis function is experimental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"A = CC[1 2 3; 0 4 5; 0 0 6]\neigvals_simple(A)\nA = CC[2 2 3; 0 2 5; 0 0 2])\neigvals(A)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Coverings","page":"Coverings","title":"Coverings","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":"Coverings are the backbone data structure for CoveredSchemes in Oscar. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" Covering","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Covering","page":"Coverings","title":"Covering","text":"Covering\n\nA covering of a scheme X by affine charts Uᵢ which are glued along isomorphisms gᵢⱼ Uᵢ Vᵢⱼ Vⱼᵢ Uⱼ.\n\nNote: The distinction between the different affine charts of the scheme is made from their hashes. Thus, an affine scheme must not appear more than once in any covering!\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Constructors","page":"Coverings","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" Covering(patches::Vector{<:AbsSpec})\n disjoint_union(C1::Covering, C2::Covering)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Covering-Tuple{Vector{<:AbsSpec}}","page":"Coverings","title":"Covering","text":"Covering(patches::Vector{<:AbsSpec})\n\nReturn a Covering with pairwise disjoint affine charts Uᵢ given by the entries of patches. This Covering will have no glueings except those glueings along the identity of every affine chart to itself.\n\nExamples\n\njulia> P1, (x,y) = QQ[\"x\", \"y\"];\n\njulia> P2, (u,v) = QQ[\"u\", \"v\"];\n\njulia> U1 = Spec(P1);\n\njulia> U2 = Spec(P2);\n\njulia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#disjoint_union-Tuple{Covering, Covering}","page":"Coverings","title":"disjoint_union","text":"disjoint_union(C1::Covering, C2::Covering)\n\nReturn the Covering corresponding to the disjoint union of C1 and C2. \n\nThe charts and glueings of the disjoint union are given by the disjoint union of the charts and glueings of the covers C1 and C2.\n\nExamples\n\njulia> P1, (x,y) = QQ[\"x\", \"y\"];\n\njulia> P2, (u,v) = QQ[\"u\", \"v\"];\n\njulia> U1 = Spec(P1);\n\njulia> U2 = Spec(P2);\n\njulia> C1 = Covering(U1) # Set up the trivial covering with only one patch\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n\njulia> C2 = Covering(U2)\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [u, v]\n\njulia> C = disjoint_union(C1, C2)\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Attributes","page":"Coverings","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" affine_charts(C::Covering)\n glueings(C::Covering)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#affine_charts-Tuple{Covering}","page":"Coverings","title":"affine_charts","text":"affine_charts(C::Covering)\n\nReturn the list of affine charts that make up the Covering C.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#glueings-Tuple{Covering}","page":"Coverings","title":"glueings","text":"glueings(C::Covering)\n\nReturn a dictionary of glueings of the affine_charts of C.\n\nThe keys are pairs (U, V) of affine_charts. One can also use C[U, V] to obtain the respective glueing.\n\nNote: Glueings are lazy in the sense that they are in general only computed when asked for. This method only returns the internal cache, but does not try to compute new glueings.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Methods","page":"Coverings","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" add_glueing!(C::Covering, G::AbsGlueing)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#add_glueing!-Tuple{Covering, AbsGlueing}","page":"Coverings","title":"add_glueing!","text":"add_glueing!(C::Covering, G::AbsGlueing)\n\nAdd a glueing G to the covering C. \n\nThe patches of G must be among the affine_charts of C.\n\nExamples\n\njulia> P1, (x,y) = QQ[\"x\", \"y\"];\n\njulia> P2, (u,v) = QQ[\"u\", \"v\"];\n\njulia> U1 = Spec(P1);\n\njulia> U2 = Spec(P2);\n\njulia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> V1 = PrincipalOpenSubset(U1, x); # Preparations for glueing\n\njulia> V2 = PrincipalOpenSubset(U2, u);\n\njulia> f = SpecMor(V1, V2, [1//x, y//x]); # The glueing isomorphism\n\njulia> g = SpecMor(V2, V1, [1//u, v//u]); # and its inverse\n\njulia> G = Glueing(U1, U2, f, g); # Construct the glueing\n\njulia> add_glueing!(C, G) # Make the glueing part of the Covering\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> C[U1, U2] == G # Check whether the glueing of U1 and U2 in C is G.\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Glueings","page":"Coverings","title":"Glueings","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":"Glueings are used to identify open subsets U subset X and V subset Y of affine schemes along an isomorphism f colon U leftrightarrow V colon g. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Types","page":"Coverings","title":"Types","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":"The abstract type of any such glueing is ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" AbsGlueing","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#AbsGlueing","page":"Coverings","title":"AbsGlueing","text":"AbsGlueing\n\nA glueing of two affine schemes X and Y (the patches) along open subsets U in X and V in Y (the glueing_domains) along mutual isomorphisms f U V g (the glueing_morphisms).\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":"The available concrete types are ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" Glueing\n SimpleGlueing","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Glueing","page":"Coverings","title":"Glueing","text":"Glueing\n\nConcrete instance of an AbsGlueing for glueings of affine schemes X U V Y along open subsets U and V of type SpecOpen.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#SimpleGlueing","page":"Coverings","title":"SimpleGlueing","text":"SimpleGlueing\n\nConcrete instance of an AbsGlueing for glueings of affine schemes X U V Y along open subsets U and V of type PrincipalOpenSubset.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Constructors-2","page":"Coverings","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" Glueing(X::AbsSpec, Y::AbsSpec, f::SchemeMor, g::SchemeMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Glueing-Tuple{AbsSpec, AbsSpec, SchemeMor, SchemeMor}","page":"Coverings","title":"Glueing","text":"Glueing(X::AbsSpec, Y::AbsSpec, f::SchemeMor, g::SchemeMor)\n\nGlue two affine schemes X and Y along mutual isomorphisms f and g of open subsets U of X and V of Y.\n\nExamples\n\njulia> P1, (x,y) = QQ[\"x\", \"y\"]; P2, (u,v) = QQ[\"u\", \"v\"];\n\njulia> U1 = Spec(P1); U2 = Spec(P2);\n\njulia> V1 = PrincipalOpenSubset(U1, x); # Preparations for glueing\n\njulia> V2 = PrincipalOpenSubset(U2, u);\n\njulia> f = SpecMor(V1, V2, [1//x, y//x]); # The glueing isomorphism\n\njulia> g = SpecMor(V2, V1, [1//u, v//u]); # and its inverse\n\njulia> G = Glueing(U1, U2, f, g) # Construct the glueing\nGlueing\n of spec of multivariate polynomial ring\n and spec of multivariate polynomial ring\nalong the open subsets\n [x, y] spec of localized ring\n [u, v] spec of localized ring\ngiven by the pullback function\n u -> 1/x\n v -> y/x\n\njulia> typeof(G)<:SimpleGlueing # Since the glueing domains were `PrincipalOpenSubsets`, this defaults to a `SimpleGlueing`\ntrue\n\njulia> # Alternative using SpecOpens as glueing domains:\n\njulia> W1 = SpecOpen(U1, [x]); W2 = SpecOpen(U2, [u]);\n\njulia> h1 = SpecOpenMor(W1, W2, [1//x, y//x]);\n\njulia> h2 = SpecOpenMor(W2, W1, [1//u, v//u]);\n\njulia> H = Glueing(U1, U2, h1, h2)\nGlueing\n of spec of multivariate polynomial ring\n and spec of multivariate polynomial ring\nalong the open subsets\n [x, y] complement to V(x) in affine scheme with coordinates [x, y]\n [u, v] complement to V(u) in affine scheme with coordinates [u, v]\ndefined by the map\n morphism\n from [x, y] spec of localized ring\n to [u, v] spec of multivariate polynomial ring\n given by the pullback function\n u -> 1/x\n v -> y/x\n\njulia> typeof(H)<:Glueing\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Attributes-2","page":"Coverings","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" patches(G::AbsGlueing)\n glueing_domains(G::AbsGlueing)\n glueing_morphisms(G::AbsGlueing)\n inverse(G::AbsGlueing)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#patches-Tuple{AbsGlueing}","page":"Coverings","title":"patches","text":"patches(G::AbsGlueing)\n\nReturn a pair of affine schemes (X, Y) which are glued by G.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#glueing_domains-Tuple{AbsGlueing}","page":"Coverings","title":"glueing_domains","text":"glueing_domains(G::AbsGlueing)\n\nReturn a pair of open subsets U and V of the respective patches of G which are glued by G along the glueing_morphisms of G.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#glueing_morphisms-Tuple{AbsGlueing}","page":"Coverings","title":"glueing_morphisms","text":"glueing_morphisms(G::AbsGlueing)\n\nReturn a pair of mutually inverse isomorphisms (f, g) of open subsets U and V of the respective patches of G which are used for the glueing identification.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#inverse-Tuple{AbsGlueing}","page":"Coverings","title":"inverse","text":"inverse(G::AbsGlueing)\n\nReturn the glueing H with patches, glueing_domains, and glueing_morphisms in opposite order compared to G.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#Methods-2","page":"Coverings","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/","page":"Coverings","title":"Coverings","text":" compose(G::AbsGlueing, H::AbsGlueing)\n maximal_extension(G::Glueing)\n restrict(G::AbsGlueing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#compose-Tuple{AbsGlueing, AbsGlueing}","page":"Coverings","title":"compose","text":"compose(G::AbsGlueing, H::AbsGlueing)\n\nGiven glueings X ↩ U ≅ V ↪ Y and Y ↩ V' ≅ W ↪ Z, return the glueing X ↩ V ∩ V' ↪ Z. \n\nWARNING: In general such a glueing will not provide a separated scheme. Use maximal_extension to extend the glueing.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#maximal_extension-Tuple{Glueing}","page":"Coverings","title":"maximal_extension","text":"maximal_extension(G::Glueing)\n\nGiven a glueing X ↩ U ≅ V ↪ Y, try to find the maximal extension to an open subset U' ⊃ U in X and V' ⊃ V in Y so that the resulting scheme is separated.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGlueings/#restrict-Tuple{AbsGlueing, AbsSpecMor, AbsSpecMor}","page":"Coverings","title":"restrict","text":"restrict(G::AbsGlueing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true)\n\nGiven a glueing X U V Y and isomorphisms f X X and g Y Y, return the induced glueing of X and Y.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Sparse-distributed-multivariate-polynomials","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"AbstractAlgebra.jl provides a module, implemented in src/MPoly.jl for sparse distributed multivariate polynomials over any commutative ring belonging to the AbstractAlgebra abstract type hierarchy.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Generic-sparse-distributed-multivariable-polynomial-types","page":"Sparse distributed multivariate polynomials","title":"Generic sparse distributed multivariable polynomial types","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"AbstractAlgebra provides a generic multivariate polynomial type Generic.MPoly{T} where T is the type of elements of the coefficient ring.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The polynomials are implemented using a Julia array of coefficients and a 2-dimensional Julia array of UInts for the exponent vectors. Note that exponent n is represented by the n-th column of the exponent array, not the n-th row. This is because Julia uses a column major representation. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The top bit of each UInt is reserved for overflow detection.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Parent objects of such polynomials have type Generic.MPolyRing{T}.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The string representation of the variables of the polynomial ring and the base/coefficient ring R and the ordering are stored in the parent object.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Abstract-types","page":"Sparse distributed multivariate polynomials","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The polynomial element types belong to the abstract type MPolyRingElem{T} and the polynomial ring types belong to the abstract type MPolyRing{T}.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"note: Note\nNote that both the generic polynomial ring type Generic.MPolyRing{T} and the abstract type it belongs to, MPolyRing{T} are both called MPolyRing. The former is a (parameterised) concrete type for a polynomial ring over a given base ring whose elements have type T. The latter is an abstract type representing all multivariate polynomial ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Polynomial-ring-constructors","page":"Sparse distributed multivariate polynomials","title":"Polynomial ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"In order to construct multivariate polynomials in AbstractAlgebra.jl, one must first construct the polynomial ring itself. This is accomplished with one of the following constructors.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"polynomial_ring(R::Ring, S::Vector{VarName}; cached::Bool = true, ordering::Symbol=:lex)\npolynomial_ring(R::Ring, n::Int, s::VarName; cached::Bool = false, ordering::Symbol = :lex)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#polynomial_ring-Tuple{Ring, Vector{Union{Char, AbstractString, Symbol}}}","page":"Sparse distributed multivariate polynomials","title":"polynomial_ring","text":"polynomial_ring(R::Ring, s::Vector{T}; cached::Bool = true, ordering::Symbol = :lex) where T <: VarName\n\nGiven a base ring R and a vector s of variable names x1 x2 dots specifying how the generators (variables) should be printed, return a tuple S, [x1, x2, ...] representing the new polynomial ring S = Rx1 x2 and the generators x1 x2 dots of the polynomial ring.\n\nMathematically the object S depends only on R and x1, x2, ... and by default it will be cached, i.e., if polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting the optional argument cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.\n\nThe ordering of the polynomial ring can be one of :lex, :deglex or :degrevlex.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#polynomial_ring-Tuple{Ring, Int64, Union{Char, AbstractString, Symbol}}","page":"Sparse distributed multivariate polynomials","title":"polynomial_ring","text":"polynomial_ring(R::Ring, n::Int, s::VarName = :x; cached, ordering)\n\nGiven a symbol, string or character s and a number of variables n will do the same as the first constructor except that the variables will be automatically numbered. For example if s is the string x and n = 3 then the variables will print as x1, x2, x3.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Like for univariate polynomials, a shorthand constructor is provided when the number of generators is greater than 1: given a base ring R, we abbreviate the constructor as follows:","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"R[\"x\", \"y\", ...]","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Here are some examples of creating multivariate polynomial rings and making use of the resulting parent objects to coerce various elements into the polynomial ring.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"]; ordering=:deglex)\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> T, (z, t) = QQ[\"z\", \"t\"]\n(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[z, t])\n\njulia> f = R()\n0\n\njulia> g = R(123)\n123\n\njulia> h = R(BigInt(1234))\n1234\n\njulia> k = R(x + 1)\nx + 1\n\njulia> m = R(x + y + 1)\nx + y + 1\n\njulia> derivative(k, 1)\n1\n\njulia> derivative(k, 2)\n0\n","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Polynomial-constructors","page":"Sparse distributed multivariate polynomials","title":"Polynomial constructors","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Multivariate polynomials can be constructed from the generators in the usual way using arithmetic operations.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Also, all of the standard ring element constructors may be used to construct multivariate polynomials.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"(R::MPolyRing{T})() where T <: RingElement\n(R::MPolyRing{T})(c::Integer) where T <: RingElement\n(R::MPolyRing{T})(a::elem_type(R)) where T <: RingElement\n(R::MPolyRing{T})(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"For more efficient construction of multivariate polynomial, one can use the MPoly build context, where terms (coefficient followed by an exponent vector) are pushed onto a context one at a time and then the polynomial constructed from those terms in one go using the finish function.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"MPolyBuildCtx(R::MPolyRing)\npush_term!(M::MPolyBuildCtx, c::RingElem, v::Vector{Int})\nfinish(M::MPolyBuildCtx)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#MPolyBuildCtx-Tuple{MPolyRing}","page":"Sparse distributed multivariate polynomials","title":"MPolyBuildCtx","text":"MPolyBuildCtx(R::MPolyRing)\n\nReturn a build context for creating polynomials in the given ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#push_term!-Tuple{MPolyBuildCtx, RingElem, Vector{Int64}}","page":"Sparse distributed multivariate polynomials","title":"push_term!","text":"push_term!(M::MPolyBuildCtx, c::RingElem, v::Vector{Int})\n\nAdd the term with coefficient c and exponent vector v to the polynomial under construction in the build context M.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#finish-Tuple{MPolyBuildCtx}","page":"Sparse distributed multivariate polynomials","title":"finish","text":"finish(M::MPolyBuildCtx)\n\nFinish construction of the polynomial, sort the terms, remove duplicate and zero terms and return the created polynomial.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Note that the finish function resets the build context so that it can be used to construct multiple polynomials..","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"When a multivariate polynomial type has a representation that allows constant time access (e.g. it is represented internally by arrays), the following additional constructor is available. It takes and array of coefficients and and array of exponent vectors.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"(S::MPolyRing{T})(A::Vector{T}, m::Vector{Vector{Int}}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Create the polynomial in the given ring with nonzero coefficients specified by the elements of A and corresponding exponent vectors given by the elements of m.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> C = MPolyBuildCtx(R)\nBuilder for an element of Multivariate polynomial ring in 2 variables over integers\n\njulia> push_term!(C, ZZ(3), [1, 2]);\n\n\njulia> push_term!(C, ZZ(2), [1, 1]);\n\n\njulia> push_term!(C, ZZ(4), [0, 0]);\n\n\njulia> f = finish(C)\n3*x*y^2 + 2*x*y + 4\n\njulia> push_term!(C, ZZ(4), [1, 1]);\n\n\njulia> f = finish(C)\n4*x*y\n\njulia> S, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])\n\njulia> f = S(Rational{BigInt}[2, 3, 1], [[3, 2], [1, 0], [0, 1]])\n2*x^3*y^2 + 3*x + y","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Functions-for-types-and-parents-of-multivariate-polynomial-rings","page":"Sparse distributed multivariate polynomials","title":"Functions for types and parents of multivariate polynomial rings","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"base_ring(R::MPolyRing)\nbase_ring(a::MPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Return the coefficient ring of the given polynomial ring or polynomial, respectively.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"parent(a::MPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Return the polynomial ring of the given polynomial.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"characteristic(R::MPolyRing)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Return the characteristic of the given polynomial ring. If the characteristic is not known, an exception is raised.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Polynomial-functions","page":"Sparse distributed multivariate polynomials","title":"Polynomial functions","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/#Basic-manipulation","page":"Sparse distributed multivariate polynomials","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"All the standard ring functions are available, including the following.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"zero(R::MPolyRing)\none(R::MPolyRing)\niszero(a::MPolyRingElem)\nisone(a::MPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"divexact(a::T, b::T) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"All basic functions from the Multivariate Polynomial interface are provided.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"symbols(S::MPolyRing)\nnvars(f::MPolyRing)\ngens(S::MPolyRing)\ngen(S::MPolyRing, i::Int)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"ordering(S::MPolyRing{T})","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Note that the currently supported orderings are :lex, :deglex and :degrevlex.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"length(f::MPolyRingElem)\ndegrees(f::MPolyRingElem)\ntotal_degree(f::MPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"is_gen(x::MPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"divexact(f::T, g::T) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"For multivariate polynomial types that allow constant time access to coefficients, the following are also available, allowing access to the given coefficient, monomial or term. Terms are numbered from the most significant first.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"coeff(f::MPolyRingElem, n::Int)\ncoeff(a::MPolyRingElem, exps::Vector{Int})","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Access a coefficient by term number or exponent vector.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"monomial(f::MPolyRingElem, n::Int)\nmonomial!(m::T, f::T, n::Int) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The second version writes the result into a preexisting polynomial object to save an allocation.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"term(f::MPolyRingElem, n::Int)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"exponent(f::MyMPolyRingElem, i::Int, j::Int)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Return the exponent of the j-th variable in the i-th term of the polynomial f.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"exponent_vector(a::MPolyRingElem, i::Int)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"setcoeff!(a::MPolyRingElem{T}, exps::Vector{Int}, c::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Although multivariate polynomial rings are not usually Euclidean, the following functions from the Euclidean interface are often provided.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"divides(f::T, g::T) where T <: MPolyRingElem\nremove(f::T, g::T) where T <: MPolyRingElem\nvaluation(f::T, g::T) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"divrem(f::T, g::T) where T <: MPolyRingElem\ndiv(f::T, g::T) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Compute a tuple (q r) such that f = qg + r, where the coefficients of terms of r whose monomials are divisible by the leading monomial of g are reduced modulo the leading coefficient of g (according to the Euclidean function on the coefficients). The divrem version returns both quotient and remainder whilst the div version only returns the quotient.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Note that the result of these functions depend on the ordering of the polynomial ring.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"gcd(f::T, g::T) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The following functionality is also provided for all multivariate polynomials.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"is_univariate(::MPolyRing{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#is_univariate-Union{Tuple{MPolyRing{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"is_univariate","text":"is_univariate(R::AbstractAlgebra.MPolyRing)\n\nReturns true if R is a univariate polynomial ring, i.e. has exactly one variable, and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"vars(p::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#vars-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"vars","text":"vars(p::AbstractAlgebra.MPolyRingElem{T}) where {T <: RingElement}\n\nReturn the variables actually occurring in p.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"var_index(::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#var_index-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"var_index","text":"var_index(p::AbstractAlgebra.MPolyRingElem{T}) where {T <: RingElement}\n\nReturn the index of the given variable x. If x is not a variable in a multivariate polynomial ring, an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"degree(::MPolyRingElem{T}, ::Int) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#degree-Union{Tuple{T}, Tuple{MPolyRingElem{T}, Int64}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"degree","text":"degree(f::AbstractAlgebra.MPolyRingElem{T}, i::Int) where T <: RingElement\n\nReturn the degree of the polynomial f in terms of the i-th variable.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"degree(::MPolyRingElem{T}, ::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#degree-Union{Tuple{T}, Tuple{MPolyRingElem{T}, MPolyRingElem{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"degree","text":"degree(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn the degree of the polynomial f in terms of the variable x.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"degrees(::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#degrees-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"degrees","text":"degrees(f::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn an array of the degrees of the polynomial f in terms of each variable.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"is_constant(::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#is_constant-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"is_constant","text":"is_constant(x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn true if x is a degree zero polynomial or the zero polynomial, i.e. a constant polynomial.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"is_term(::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#is_term-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"is_term","text":"is_term(x::MPoly)\n\nReturn true if the given polynomial has precisely one term.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"is_monomial(::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#is_monomial-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"is_monomial","text":"is_monomial(x::AbstractAlgebra.MPolyRingElem)\n\nReturn true if the given polynomial has precisely one term whose coefficient is one.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"is_univariate(::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#is_univariate-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"is_univariate","text":"is_univariate(p::AbstractAlgebra.MPolyRingElem)\n\nReturns true if p is a univariate polynomial, i.e. involves at most one variable (thus constant polynomials are considered univariate), and false otherwise. The result depends on the terms of the polynomial, not simply on the number of variables in the polynomial ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"coeff(::MPolyRingElem{T}, ::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#coeff-Union{Tuple{T}, Tuple{MPolyRingElem{T}, MPolyRingElem{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"coeff","text":"coeff(f::AbstractAlgebra.MPolyRingElem{T}, m::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn the coefficient of the monomial m of the polynomial f. If there is no such monomial, zero is returned.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = x^2 + 2x + 1\nx^2 + 2*x + 1\n\njulia> V = vars(f)\n1-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:\n x\n\njulia> var_index(y) == 2\ntrue\n\njulia> degree(f, x) == 2\ntrue\n\njulia> degree(f, 2) == 0\ntrue\n\njulia> d = degrees(f)\n2-element Vector{Int64}:\n 2\n 0\n\njulia> is_constant(R(1))\ntrue\n\njulia> is_term(2x)\ntrue\n\njulia> is_monomial(y)\ntrue\n\njulia> is_unit(R(1))\ntrue\n\njulia> S, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = x^3*y + 3x*y^2 + 1\nx^3*y + 3*x*y^2 + 1\n\njulia> c1 = coeff(f, 1)\n1\n\njulia> c2 = coeff(f, x^3*y)\n1\n\njulia> m = monomial(f, 2)\nx*y^2\n\njulia> e1 = exponent(f, 1, 1)\n3\n\njulia> v1 = exponent_vector(f, 1)\n2-element Vector{Int64}:\n 3\n 1\n\njulia> t1 = term(f, 1)\nx^3*y\n\njulia> setcoeff!(f, [3, 1], 12)\n12*x^3*y + 3*x*y^2 + 1\n\njulia> S, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]; ordering=:deglex)\n(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])\n\njulia> V = symbols(S)\n2-element Vector{Symbol}:\n :x\n :y\n\njulia> X = gens(S)\n2-element Vector{AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}:\n x\n y\n\njulia> ord = ordering(S)\n:deglex\n\njulia> S, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = x^3*y + 3x*y^2 + 1\nx^3*y + 3*x*y^2 + 1\n\njulia> n = length(f)\n3\n\njulia> is_gen(y)\ntrue\n\njulia> nvars(S) == 2\ntrue\n\njulia> d = total_degree(f)\n4\n\njulia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = 2x^2*y + 2x + y + 1\n2*x^2*y + 2*x + y + 1\n\njulia> g = x^2*y^2 + 1\nx^2*y^2 + 1\n\njulia> flag, q = divides(f*g, f)\n(true, x^2*y^2 + 1)\n\njulia> d = divexact(f*g, f)\nx^2*y^2 + 1\n\njulia> v, q = remove(f*g^3, g)\n(3, 2*x^2*y + 2*x + y + 1)\n\njulia> n = valuation(f*g^3, g)\n3\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])\n\njulia> f = 3x^2*y^2 + 2x + 1\n3*x^2*y^2 + 2*x + 1\n\njulia> f1 = divexact(f, 5)\n3//5*x^2*y^2 + 2//5*x + 1//5\n\njulia> f2 = divexact(f, QQ(2, 3))\n9//2*x^2*y^2 + 3*x + 3//2","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Square-root","page":"Sparse distributed multivariate polynomials","title":"Square root","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Over rings for which an exact square root is available, it is possible to take the square root of a polynomial or test whether it is a square.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"sqrt(f::MPolyRingElem, check::bool=true)\nis_square(::MPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = -4*x^5*y^4 + 5*x^5*y^3 + 4*x^4 - x^3*y^4\n-4*x^5*y^4 + 5*x^5*y^3 + 4*x^4 - x^3*y^4\n\njulia> sqrt(f^2)\n4*x^5*y^4 - 5*x^5*y^3 - 4*x^4 + x^3*y^4\n\njulia> is_square(f)\nfalse","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Iterators","page":"Sparse distributed multivariate polynomials","title":"Iterators","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The following iterators are provided for multivariate polynomials.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"coefficients(p::MPoly)\nmonomials(p::MPoly)\nterms(p::MPoly)\nexponent_vectors(a::MPoly)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> S, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = x^3*y + 3x*y^2 + 1\nx^3*y + 3*x*y^2 + 1\n\njulia> C = collect(coefficients(f))\n3-element Vector{BigInt}:\n 1\n 3\n 1\n\njulia> M = collect(monomials(f))\n3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:\n x^3*y\n x*y^2\n 1\n\njulia> T = collect(terms(f))\n3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:\n x^3*y\n 3*x*y^2\n 1\n\njulia> V = collect(exponent_vectors(f))\n3-element Vector{Vector{Int64}}:\n [3, 1]\n [1, 2]\n [0, 0]","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Changing-base-(coefficient)-rings","page":"Sparse distributed multivariate polynomials","title":"Changing base (coefficient) rings","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"In order to substitute the variables of a polynomial f over a ring T by elements in a T-algebra S, you first have to change the base ring of f using the following function, where g is a function representing the structure homomorphism of the T-algebra S.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"change_base_ring(::Ring, p::MPolyRingElem{T}) where {T <: RingElement}\nchange_coefficient_ring(::Ring, p::MPolyRingElem{T}) where {T <: RingElement}\nmap_coefficients(::Any, p::MPolyRingElem)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#change_base_ring-Union{Tuple{T}, Tuple{Ring, MPolyRingElem{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"change_base_ring","text":"change_base_ring(R::Ring, p::MPolyRingElem{<: RingElement}; parent::MPolyRing, cached::Bool=true)\n\nReturn the polynomial obtained by coercing the non-zero coefficients of p into R.\n\nIf the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#change_coefficient_ring-Union{Tuple{T}, Tuple{Ring, MPolyRingElem{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"change_coefficient_ring","text":"change_coefficient_ring(R::Ring, p::MPolyRingElem{<: RingElement}; parent::MPolyRing, cached::Bool=true)\n\nReturn the polynomial obtained by coercing the non-zero coefficients of p into R.\n\nIf the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#map_coefficients-Tuple{Any, MPolyRingElem}","page":"Sparse distributed multivariate polynomials","title":"map_coefficients","text":"map_coefficients(f, p::MPolyRingElem{<: RingElement}; parent::MPolyRing)\n\nTransform the polynomial p by applying f on each non-zero coefficient.\n\nIf the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> fz = x^2*y^2 + x + 1\nx^2*y^2 + x + 1\n\njulia> fq = change_base_ring(QQ, fz)\nx^2*y^2 + x + 1\n\njulia> fq = change_coefficient_ring(QQ, fz)\nx^2*y^2 + x + 1\n","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"In case a specific parent ring is constructed, it can also be passed to the function.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> S, = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x, y])\n\njulia> fz = x^5 + y^3 + 1\nx^5 + y^3 + 1\n\njulia> fq = change_base_ring(QQ, fz, parent=S)\nx^5 + y^3 + 1","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Multivariate-coefficients","page":"Sparse distributed multivariate polynomials","title":"Multivariate coefficients","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"In order to return the \"coefficient\" (as a multivariate polynomial in the same ring), of a given monomial (in which some of the variables may not appear and others may be required to appear to exponent zero), we can use the following function.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"coeff(a::MPolyRingElem{T}, vars::Vector{Int}, exps::Vector{Int}) where T <: RingElement\ncoeff(a::T, vars::Vector{T}, exps::Vector{Int}) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#coeff-Union{Tuple{T}, Tuple{MPolyRingElem{T}, Vector{Int64}, Vector{Int64}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"coeff","text":"coeff(a::AbstractAlgebra.MPolyRingElem{T}, vars::Vector{Int}, exps::Vector{Int}) where T <: RingElement\n\nReturn the \"coefficient\" of a (as a multivariate polynomial in the same ring) of the monomial consisting of the product of the variables of the given indices raised to the given exponents (note that not all variables need to appear and the exponents can be zero). E.g. coeff(f, [1, 3], [0, 2]) returns the coefficient of x^0*z^2 in the polynomial f (assuming variables x y z in that order).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#coeff-Union{Tuple{T}, Tuple{T, Vector{T}, Vector{Int64}}} where T<:MPolyRingElem","page":"Sparse distributed multivariate polynomials","title":"coeff","text":"coeff(a::T, vars::Vector{T}, exps::Vector{Int}) where T <: AbstractAlgebra.MPolyRingElem\n\nReturn the \"coefficient\" of a (as a multivariate polynomial in the same ring) of the monomial consisting of the product of the given variables to the given exponents (note that not all variables need to appear and the exponents can be zero). E.g. coeff(f, [x, z], [0, 2]) returns the coefficient of x^0*z^2 in the polynomial f.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y, z) = polynomial_ring(ZZ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])\n\njulia> f = x^4*y^2*z^2 - 2x^4*y*z^2 + 4x^4*z^2 + 2x^2*y^2 + x + 1\nx^4*y^2*z^2 - 2*x^4*y*z^2 + 4*x^4*z^2 + 2*x^2*y^2 + x + 1\n\njulia> coeff(f, [1, 3], [4, 2]) == coeff(f, [x, z], [4, 2])\ntrue\n","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Inflation/deflation","page":"Sparse distributed multivariate polynomials","title":"Inflation/deflation","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"deflation(f::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#deflation-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"deflation","text":"deflation(f::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nCompute deflation parameters for the exponents of the polynomial f. This is a pair of arrays of integers, the first array of which (the shift) gives the minimum exponent for each variable of the polynomial, and the second of which (the deflation) gives the gcds of all the exponents after subtracting the shift, again per variable. This functionality is used by gcd (and can be used by factorisation algorithms).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"deflate(f::MPolyRingElem{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: RingElement\ndeflate(f::MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement\ndeflate(f::MPolyRingElem{T}) where T <: RingElement\ndeflate(f::MPolyRingElem, vars::Vector{Int}, shift::Vector{Int}, defl::Vector{Int})\ndeflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#deflate-Union{Tuple{T}, Tuple{MPolyRingElem{T}, Vector{Int64}, Vector{Int64}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"deflate","text":"deflate(f::AbstractAlgebra.MPolyRingElem{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: RingElement\n\nReturn a polynomial with the same coefficients as f but whose exponents have been reduced by the given shifts (supplied as an array of shifts, one for each variable), then deflated (divided) by the given exponents (again supplied as an array of deflation factors, one for each variable). The algorithm automatically replaces a deflation of 0 by 1, to avoid division by 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#deflate-Union{Tuple{T}, Tuple{MPolyRingElem{T}, Vector{Int64}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"deflate","text":"deflate(f::AbstractAlgebra.MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement\n\nReturn a polynomial with the same coefficients as f but whose exponents have been deflated (divided) by the given exponents (supplied as an array of deflation factors, one for each variable).\n\nThe algorithm automatically replaces a deflation of 0 by 1, to avoid division by 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#deflate-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"deflate","text":"deflate(f::AbstractAlgebra.MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement\n\nReturn a polynomial with the same coefficients as f but whose exponents have been deflated maximally, i.e. with each exponent divide by the largest integer which divides the degrees of all exponents of that variable in f.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#deflate-Tuple{MPolyRingElem, Vector{Int64}, Vector{Int64}, Vector{Int64}}","page":"Sparse distributed multivariate polynomials","title":"deflate","text":"deflate(f::AbstractAlgebra.MPolyRingElem, vars::Vector{Int}, shift::Vector{Int}, defl::Vector{Int})\n\nReturn a polynomial with the same coefficients as f but where exponents of some variables (supplied as an array of variable indices) have been reduced by the given shifts (supplied as an array of shifts), then deflated (divided) by the given exponents (again supplied as an array of deflation factors). The algorithm automatically replaces a deflation of 0 by 1, to avoid division by 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#deflate-Union{Tuple{T}, Tuple{T, Vector{T}, Vector{Int64}, Vector{Int64}}} where T<:MPolyRingElem","page":"Sparse distributed multivariate polynomials","title":"deflate","text":"deflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: AbstractAlgebra.MPolyRingElem\n\nReturn a polynomial with the same coefficients as f but where the exponents of the given variables have been reduced by the given shifts (supplied as an array of shifts), then deflated (divided) by the given exponents (again supplied as an array of deflation factors). The algorithm automatically replaces a deflation of 0 by 1, to avoid division by 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"inflate(f::MPolyRingElem{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: RingElement\ninflate(f::MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement\ninflate(f::MPolyRingElem, vars::Vector{Int}, shift::Vector{Int}, defl::Vector{Int})\ninflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: MPolyRingElem","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#inflate-Union{Tuple{T}, Tuple{MPolyRingElem{T}, Vector{Int64}, Vector{Int64}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"inflate","text":"inflate(f::AbstractAlgebra.MPolyRingElem{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: RingElement\n\nReturn a polynomial with the same coefficients as f but whose exponents have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors, one for each variable) and then increased by the given shifts (again supplied as an array of shifts, one for each variable).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#inflate-Union{Tuple{T}, Tuple{MPolyRingElem{T}, Vector{Int64}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"inflate","text":"inflate(f::AbstractAlgebra.MPolyRingElem{T}, defl::Vector{Int}) where T <: RingElement\n\nReturn a polynomial with the same coefficients as f but whose exponents have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors, one for each variable).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#inflate-Tuple{MPolyRingElem, Vector{Int64}, Vector{Int64}, Vector{Int64}}","page":"Sparse distributed multivariate polynomials","title":"inflate","text":"inflate(f::AbstractAlgebra.MPolyRingElem, vars::Vector{Int}, shift::Vector{Int}, defl::Vector{Int})\n\nReturn a polynomial with the same coefficients as f but where exponents of some variables (supplied as an array of variable indices) have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors) and then increased by the given shifts (again supplied as an array of shifts).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#inflate-Union{Tuple{T}, Tuple{T, Vector{T}, Vector{Int64}, Vector{Int64}}} where T<:MPolyRingElem","page":"Sparse distributed multivariate polynomials","title":"inflate","text":"inflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: AbstractAlgebra.MPolyRingElem\n\nReturn a polynomial with the same coefficients as f but where the exponents of the given variables have been inflated (multiplied) by the given deflation exponents (supplied as an array of inflation factors) and then increased by the given shifts (again supplied as an array of shifts).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = x^7*y^8 + 3*x^4*y^8 - x^4*y^2 + 5x*y^5 - x*y^2\nx^7*y^8 + 3*x^4*y^8 - x^4*y^2 + 5*x*y^5 - x*y^2\n\njulia> def, shift = deflation(f)\n([1, 2], [3, 3])\n\njulia> f1 = deflate(f, def, shift)\nx^2*y^2 + 3*x*y^2 - x + 5*y - 1\n\njulia> f2 = inflate(f1, def, shift)\nx^7*y^8 + 3*x^4*y^8 - x^4*y^2 + 5*x*y^5 - x*y^2\n\njulia> f2 == f\ntrue\n\njulia> g = (x+y+1)^2\nx^2 + 2*x*y + 2*x + y^2 + 2*y + 1\n\njulia> g0 = coeff(g, [y], [0])\nx^2 + 2*x + 1\n\njulia> g1 = deflate(g - g0, [y], [1], [1])\n2*x + y + 2\n\njulia> g == g0 + y * g1\ntrue\n","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Conversions","page":"Sparse distributed multivariate polynomials","title":"Conversions","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"to_univariate(R::PolyRing{T}, p::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#to_univariate-Union{Tuple{T}, Tuple{PolyRing{T}, MPolyRingElem{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"to_univariate","text":"to_univariate(R::AbstractAlgebra.PolyRing{T}, p::AbstractAlgebra.MPolyRingElem{T}) where T <: AbstractAlgebra.RingElement\n\nAssuming the polynomial p is actually a univariate polynomial, convert the polynomial to a univariate polynomial in the given univariate polynomial ring R. An exception is raised if the polynomial p involves more than one variable.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> S, z = polynomial_ring(ZZ, \"z\")\n(Univariate polynomial ring in z over integers, z)\n\njulia> f = 2x^5 + 3x^4 - 2x^2 - 1\n2*x^5 + 3*x^4 - 2*x^2 - 1\n\njulia> g = to_univariate(S, f)\n2*z^5 + 3*z^4 - 2*z^2 - 1\n","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Evaluation","page":"Sparse distributed multivariate polynomials","title":"Evaluation","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The following function allows evaluation of a polynomial at all its variables. The result is always in the ring that a product of a coefficient and one of the values belongs to, i.e. if all the values are in the coefficient ring, the result of the evaluation will be too.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"evaluate(::MPolyRingElem{T}, ::Vector{U}) where {T <: RingElement, U <: RingElement}","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#evaluate-Union{Tuple{U}, Tuple{T}, Tuple{MPolyRingElem{T}, Vector{U}}} where {T<:RingElement, U<:RingElement}","page":"Sparse distributed multivariate polynomials","title":"evaluate","text":"evaluate(a::AbstractAlgebra.MPolyRingElem{T}, vals::Vector{U}) where {T <: RingElement, U <: RingElement}\n\nEvaluate the polynomial expression by substituting in the array of values for each of the variables. The evaluation will succeed if multiplication is defined between elements of the coefficient ring of a and elements of the supplied vector.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The following functions allow evaluation of a polynomial at some of its variables. Note that the result will be a product of values and an element of the polynomial ring, i.e. even if all the values are in the coefficient ring and all variables are given values, the result will be a constant polynomial, not a coefficient.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"evaluate(::MPolyRingElem{T}, ::Vector{Int}, ::Vector{U}) where {T <: RingElement, U <: RingElement}","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#evaluate-Union{Tuple{U}, Tuple{T}, Tuple{MPolyRingElem{T}, Vector{Int64}, Vector{U}}} where {T<:RingElement, U<:RingElement}","page":"Sparse distributed multivariate polynomials","title":"evaluate","text":"evaluate(a::AbstractAlgebra.MPolyRingElem{T}, vars::Vector{Int}, vals::Vector{U}) where {T <: RingElement, U <: RingElement}\n\nEvaluate the polynomial expression by substituting in the supplied values in the array vals for the corresponding variables with indices given by the array vars. The evaluation will succeed if multiplication is defined between elements of the coefficient ring of a and elements of vals.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"evaluate(::S, ::Vector{S}, ::Vector{U}) where {S <: MPolyRingElem{T}, U <: RingElement} where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#evaluate-Union{Tuple{U}, Tuple{S}, Tuple{T}, Tuple{S, Vector{S}, Vector{U}}} where {T<:RingElement, S<:MPolyRingElem{T}, U<:RingElement}","page":"Sparse distributed multivariate polynomials","title":"evaluate","text":"evaluate(a::S, vars::Vector{S}, vals::Vector{U}) where {S <: AbstractAlgebra.MPolyRingElem{T}, U <: RingElement} where T <: RingElement\n\nEvaluate the polynomial expression by substituting in the supplied values in the array vals for the corresponding variables (supplied as polynomials) given by the array vars. The evaluation will succeed if multiplication is defined between elements of the coefficient ring of a and elements of vals.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The following function allows evaluation of a polynomial at values in a not necessarily commutative ring, e.g. elements of a matrix algebra.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"evaluate(::MPolyRingElem{T}, ::Vector{U}) where {T <: RingElement, U <: NCRingElem}","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#evaluate-Union{Tuple{U}, Tuple{T}, Tuple{MPolyRingElem{T}, Vector{U}}} where {T<:RingElement, U<:NCRingElem}","page":"Sparse distributed multivariate polynomials","title":"evaluate","text":"evaluate(a::AbstractAlgebra.MPolyRingElem{T}, vals::Vector{U}) where {T <: RingElement, U <: NCRingElem}\n\nEvaluate the polynomial expression at the supplied values, which may be any ring elements, commutative or non-commutative, but in the same ring. Evaluation always proceeds in the order of the variables as supplied when creating the polynomial ring to which a belongs. The evaluation will succeed if a product of a coefficient of the polynomial by one of the values is defined.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = 2x^2*y^2 + 3x + y + 1\n2*x^2*y^2 + 3*x + y + 1\n\njulia> evaluate(f, BigInt[1, 2])\n14\n\njulia> evaluate(f, [QQ(1), QQ(2)])\n14//1\n\njulia> evaluate(f, [1, 2])\n14\n\njulia> f(1, 2) == 14\ntrue\n\njulia> evaluate(f, [x + y, 2y - x])\n2*x^4 - 4*x^3*y - 6*x^2*y^2 + 8*x*y^3 + 2*x + 8*y^4 + 5*y + 1\n\njulia> f(x + y, 2y - x)\n2*x^4 - 4*x^3*y - 6*x^2*y^2 + 8*x*y^3 + 2*x + 8*y^4 + 5*y + 1\n\njulia> R, (x, y, z) = polynomial_ring(ZZ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])\n\njulia> f = x^2*y^2 + 2x*z + 3y*z + z + 1\nx^2*y^2 + 2*x*z + 3*y*z + z + 1\n\njulia> evaluate(f, [1, 3], [3, 4])\n9*y^2 + 12*y + 29\n\njulia> evaluate(f, [x, z], [3, 4])\n9*y^2 + 12*y + 29\n\njulia> evaluate(f, [1, 2], [x + z, x - z])\nx^4 - 2*x^2*z^2 + 5*x*z + z^4 - z^2 + z + 1\n\njulia> S = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> M1 = S([1 2; 3 4])\n[1 2]\n[3 4]\n\njulia> M2 = S([2 3; 1 -1])\n[2 3]\n[1 -1]\n\njulia> M3 = S([-1 1; 1 1])\n[-1 1]\n[ 1 1]\n\njulia> evaluate(f, [M1, M2, M3])\n[ 64 83]\n[124 149]","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Leading-and-constant-coefficients,-leading-monomials-and-leading-terms","page":"Sparse distributed multivariate polynomials","title":"Leading and constant coefficients, leading monomials and leading terms","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The leading and trailing coefficient, constant coefficient, leading monomial and leading term of a polynomial p are returned by the following functions:","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"leading_coefficient(::MPolyRingElem{T}) where T <: RingElement\ntrailing_coefficient(p::MPolyRingElem{T}) where T <: RingElement\nleading_monomial(::MPolyRingElem{T}) where T <: RingElement\nleading_term(::MPolyRingElem{T}) where T <: RingElement\nconstant_coefficient(::MPolyRingElem{T}) where T <: RingElement\ntail(::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#leading_coefficient-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"leading_coefficient","text":"leading_coefficient(p::MPolyRingElem)\n\nReturn the leading coefficient of the polynomial p.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#trailing_coefficient-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"trailing_coefficient","text":"trailing_coefficient(p::MPolyRingElem)\n\nReturn the trailing coefficient of the polynomial p, i.e. the coefficient of the last nonzero term, or zero if the polynomial is zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#leading_monomial-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"leading_monomial","text":"leading_monomial(p::MPolyRingElem)\n\nReturn the leading monomial of p. This function throws an ArgumentError if p is zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#leading_term-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"leading_term","text":"leading_term(p::MPolyRingElem)\n\nReturn the leading term of the polynomial p. This function throws an ArgumentError if p is zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#constant_coefficient-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"constant_coefficient","text":"constant_coefficient(p::MPolyRingElem)\n\nReturn the constant coefficient of the polynomial p or zero if it doesn't have one.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#tail-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"tail","text":"tail(p::MPolyRingElem)\n\nReturn the tail of the polynomial p, i.e. the polynomial without its leading term (if any).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"using AbstractAlgebra\nR,(x,y) = polynomial_ring(ZZ, [\"x\", \"y\"], ordering=:deglex)\np = 2*x*y + 3*y^3 + 1\nleading_term(p)\nleading_monomial(p)\nleading_coefficient(p)\nleading_term(p) == leading_coefficient(p) * leading_monomial(p)\nconstant_coefficient(p)\ntail(p)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Least-common-multiple,-greatest-common-divisor","page":"Sparse distributed multivariate polynomials","title":"Least common multiple, greatest common divisor","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"The greatest common divisor of two polynomials a and b is returned by","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"gcd(a::Generic.MPoly{T}, b::Generic.MPoly{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#gcd-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.MPoly{T}, AbstractAlgebra.Generic.MPoly{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"gcd","text":"gcd(a::MPoly{T}, a::MPoly{T}) where {T <: RingElement}\n\nReturn the greatest common divisor of a and b in parent(a).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Note that this functionality is currently only provided for AbstractAlgebra generic polynomials. It is not automatically provided for all multivariate rings that implement the multivariate interface.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"However, if such a gcd is provided, the least common multiple of two polynomials a and b is returned by","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"lcm(a::MPolyRingElem{T}, b::MPolyRingElem{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#lcm-Union{Tuple{T}, Tuple{MPolyRingElem{T}, MPolyRingElem{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"lcm","text":"lcm(a::AbstractAlgebra.MPolyRingElem{T}, a::AbstractAlgebra.MPolyRingElem{T}) where {T <: RingElement}\n\nReturn the least common multiple of a and b in parent(a).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> using AbstractAlgebra\n\njulia> R,(x,y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> a = x*y + 2*y\nx*y + 2*y\n\njulia> b = x^3*y + y\nx^3*y + y\n\njulia> gcd(a,b)\ny\n\njulia> lcm(a,b)\nx^4*y + 2*x^3*y + x*y + 2*y\n\njulia> lcm(a,b) == a * b // gcd(a,b)\ntrue\n","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Derivations","page":"Sparse distributed multivariate polynomials","title":"Derivations","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"derivative(::MPolyRingElem{T}, ::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#derivative-Union{Tuple{T}, Tuple{MPolyRingElem{T}, MPolyRingElem{T}}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"derivative","text":"derivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = AbstractAlgebra.polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = x*y + x + y + 1\nx*y + x + y + 1\n\njulia> derivative(f, x)\ny + 1\n\njulia> derivative(f, y)\nx + 1\n\njulia> derivative(f, 1)\ny + 1\n\njulia> derivative(f, 2)\nx + 1","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#Homogeneous-polynomials","page":"Sparse distributed multivariate polynomials","title":"Homogeneous polynomials","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"It is possible to test whether a polynomial is homogeneous with respect to the standard grading using the function","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"is_homogeneous(x::MPolyRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#is_homogeneous-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Sparse distributed multivariate polynomials","title":"is_homogeneous","text":"is_homogeneous(x::MPoly{T}) where {T <: RingElement}\n\nReturn true if the given polynomial is homogeneous with respect to the standard grading and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#Random-generation","page":"Sparse distributed multivariate polynomials","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Random multivariate polynomials in a given ring can be constructed by passing a range of degrees for the variables and a range on the number of terms. Additional parameters are used to generate the coefficients of the polynomial.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Note that zero coefficients may currently be generated, leading to less than the requested number of terms.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"rand(R::MPolyRing, exp_range::UnitRange{Int}, term_range::UnitRange{Int}, v...)","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"Examples","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"julia> R, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y])\n\njulia> f = rand(R, -1:2, 3:5, -10:10)\n4*x^4*y^4\n\njulia> S, (s, t) = polynomial_ring(GF(7), [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over finite field F_7, AbstractAlgebra.Generic.MPoly{AbstractAlgebra.GFElem{Int64}}[x, y])\n\njulia> g = rand(S, -1:2, 3:5)\n4*x^3*y^4","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/quotients/#quotient","page":"Quotients","title":"Quotients","text":"","category":"section"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"Quotient groups in OSCAR can be defined using the instruction quo in two ways.","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"Quotients by normal subgroups.","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"quo(G::T, H::T) where T <: GAPGroup","category":"page"},{"location":"Groups/quotients/#quo-Union{Tuple{T}, Tuple{T, T}} where T<:Oscar.GAPGroup","page":"Quotients","title":"quo","text":"quo([::Type{Q}, ]G::T, N::T) where {Q <: GAPGroup, T <: GAPGroup}\n\nReturn the quotient group G/N, together with the projection G -> G/N.\n\nIf Q is given then G/N has type Q if possible, and an exception is thrown if not.\n\nIf Q is not given then the type of G/N is not determined by the type of G.\n\nG/N may have the same type as G (which is reasonable if N is trivial),\nG/N may have type PcGroup (which is reasonable if G/N is finite and solvable), or\nG/N may have type PermGroup (which is reasonable if G/N is finite and non-solvable).\nG/N may have type FPGroup (which is reasonable if G/N is infinite).\n\nAn exception is thrown if N is not a normal subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> N = pcore(G, 2)[1];\n\njulia> typeof(quo(G, N)[1])\nPcGroup\n\njulia> typeof(quo(PermGroup, G, N)[1])\nPermGroup\n\n\n\n\n\n","category":"method"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"Quotients by elements.","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"quo(G::T, elements::Vector{S}) where T <: GAPGroup where S <: GAPGroupElem","category":"page"},{"location":"Groups/quotients/#quo-Union{Tuple{T}, Tuple{S}, Tuple{T, Vector{S}}} where {S<:GAPGroupElem, T<:Oscar.GAPGroup}","page":"Quotients","title":"quo","text":"quo([::Type{Q}, ]G::T, elements::Vector{elem_type(G)})) where {Q <: GAPGroup, T <: GAPGroup}\n\nReturn the quotient group G/N, together with the projection G -> G/N, where N is the normal closure of elements in G.\n\nSee quo(G::T, N::T) where T <: GAPGroup for information about the type of G/N.\n\n\n\n\n\n","category":"method"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"This is the typical way to build finitely presented groups.","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"Example:","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"julia> F=free_group(2);\n\njulia> (f1,f2)=gens(F);\n\njulia> G,_=quo(F,[f1^2,f2^3,(f1*f2)^2]);\n\njulia> is_finite(G)\ntrue\n\njulia> is_isomorphic(G,symmetric_group(3))\ntrue","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"Similarly to the subgroups, the output consists of a pair (Q,p), where Q is the quotient group and p is the projection homomorphism of G into Q.","category":"page"},{"location":"Groups/quotients/","page":"Quotients","title":"Quotients","text":"maximal_abelian_quotient","category":"page"},{"location":"Groups/quotients/#maximal_abelian_quotient","page":"Quotients","title":"maximal_abelian_quotient","text":"maximal_abelian_quotient([::Type{Q}, ]G::GAPGroup) where Q <: Union{GAPGroup, GrpAbFinGen}\n\nReturn F, epi such that F is the largest abelian factor group of G and epi is an epimorphism from G to F.\n\nIf Q is given then F has type Q if possible, and an exception is thrown if not.\n\nIf Q is not given then the type of F is not determined by the type of G.\n\nF may have the same type as G (which is reasonable if G is abelian),\nF may have type PcGroup (which is reasonable if F is finite), or\nF may have type FPGroup (which is reasonable if F is infinite).\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> F, epi = maximal_abelian_quotient(G);\n\njulia> order(F)\n2\n\njulia> domain(epi) === G && codomain(epi) === F\ntrue\n\njulia> typeof(F)\nPcGroup\n\njulia> typeof(maximal_abelian_quotient(free_group(1))[1])\nFPGroup\n\njulia> typeof(maximal_abelian_quotient(PermGroup, G)[1])\nPermGroup\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#Covered-schemes","page":"Covered schemes","title":"Covered schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"Oscar supports modeling abstract schemes by means of a covering by affine charts. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#Types","page":"Covered schemes","title":"Types","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"The abstract type for these is:","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" AbsCoveredScheme{BaseRingType}","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#AbsCoveredScheme","page":"Covered schemes","title":"AbsCoveredScheme","text":"AbsCoveredScheme{BaseRingType}\n\nAn abstract scheme X over some base_ring 𝕜 of type BaseRingType, given by means of affine charts and their glueings.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"The basic concrete instance of an AbsCoveredScheme is:","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" CoveredScheme{BaseRingType}","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#CoveredScheme","page":"Covered schemes","title":"CoveredScheme","text":"CoveredScheme{BaseRingType}\n\nA covered scheme X given by means of at least one Covering.\n\nA scheme may possess several coverings which are partially ordered by refinement. Use default_covering(X) to obtain one covering of X.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#Constructors","page":"Covered schemes","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"You can manually construct a CoveredScheme from a Covering using ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" CoveredScheme(C::Covering)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#CoveredScheme-Tuple{Covering}","page":"Covered schemes","title":"CoveredScheme","text":"CoveredScheme(C::Covering)\n\nReturn a CoveredScheme X with C as its default_covering.\n\nExamples\n\njulia> P1, (x,y) = QQ[\"x\", \"y\"];\n\njulia> P2, (u,v) = QQ[\"u\", \"v\"];\n\njulia> U1 = Spec(P1);\n\njulia> U2 = Spec(P2);\n\njulia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> V1 = PrincipalOpenSubset(U1, x); # Preparations for glueing\n\njulia> V2 = PrincipalOpenSubset(U2, u);\n\njulia> f = SpecMor(V1, V2, [1//x, y//x]); # The glueing isomorphism\n\njulia> g = SpecMor(V2, V1, [1//u, v//u]); # and its inverse\n\njulia> G = Glueing(U1, U2, f, g); # Construct the glueing\n\njulia> add_glueing!(C, G) # Make the glueing part of the Covering\nCovering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> X = CoveredScheme(C) # Create a CoveredScheme from the Glueing\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"In most cases, however, you may wish for the computer to provide you with a ready-made Covering and use a more high-level constructor, such as, for instance, ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" covered_scheme(P::ProjectiveScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#covered_scheme-Tuple{ProjectiveScheme}","page":"Covered schemes","title":"covered_scheme","text":"covered_scheme(P::AbsProjectiveScheme)\n\nReturn a CoveredScheme X isomorphic to P with standard affine charts given by dehomogenization.\n\nUse dehomogenization_map with U one of the affine_charts of X to obtain the dehomogenization map from the homogeneous_coordinate_ring of P to the coordinate_ring of U.\n\nExamples\n\njulia> P = projective_space(QQ, 2);\n\njulia> Pcov = covered_scheme(P)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n 3: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [(s1//s0), (s2//s0)]\n 2: [(s0//s1), (s2//s1)]\n 3: [(s0//s2), (s1//s2)]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#Attributes","page":"Covered schemes","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"To access the affine charts of a CoveredScheme X use ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" affine_charts(X::AbsCoveredScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#affine_charts-Tuple{AbsCoveredScheme}","page":"Covered schemes","title":"affine_charts","text":"affine_charts(X::AbsCoveredScheme)\n\nReturn the affine charts in the default_covering of X.\n\nExamples\n\njulia> P = projective_space(QQ, 2);\n\njulia> S = homogeneous_coordinate_ring(P);\n\njulia> I = ideal(S, [S[1]*S[2]-S[3]^2]);\n\njulia> X = subscheme(P, I)\nProjective scheme\n over rational field\ndefined by ideal(s0*s1 - s2^2)\n\njulia> Xcov = covered_scheme(X)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of quotient of multivariate polynomial ring\n 2: spec of quotient of multivariate polynomial ring\n 3: spec of quotient of multivariate polynomial ring\n in the coordinate(s)\n 1: [(s1//s0), (s2//s0)]\n 2: [(s0//s1), (s2//s1)]\n 3: [(s0//s2), (s1//s2)]\n\njulia> affine_charts(Xcov)\n3-element Vector{AbsSpec}:\n Spec of quotient of multivariate polynomial ring\n Spec of quotient of multivariate polynomial ring\n Spec of quotient of multivariate polynomial ring\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"Other attributes are the base_ring over which the scheme is defined and ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" default_covering(X::AbsCoveredScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#default_covering-Tuple{AbsCoveredScheme}","page":"Covered schemes","title":"default_covering","text":"default_covering(X::AbsCoveredScheme)\n\nReturn the default covering for X.\n\nExamples\n\njulia> P = projective_space(QQ, 2);\n\njulia> S = homogeneous_coordinate_ring(P);\n\njulia> I = ideal(S, [S[1]*S[2]-S[3]^2]);\n\njulia> X = subscheme(P, I)\nProjective scheme\n over rational field\ndefined by ideal(s0*s1 - s2^2)\n\njulia> Xcov = covered_scheme(X)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of quotient of multivariate polynomial ring\n 2: spec of quotient of multivariate polynomial ring\n 3: spec of quotient of multivariate polynomial ring\n in the coordinate(s)\n 1: [(s1//s0), (s2//s0)]\n 2: [(s0//s1), (s2//s1)]\n 3: [(s0//s2), (s1//s2)]\n\njulia> default_covering(Xcov)\nCovering\n described by patches\n 1: spec of quotient of multivariate polynomial ring\n 2: spec of quotient of multivariate polynomial ring\n 3: spec of quotient of multivariate polynomial ring\n in the coordinate(s)\n 1: [(s1//s0), (s2//s0)]\n 2: [(s0//s1), (s2//s1)]\n 3: [(s0//s2), (s1//s2)]\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#Properties","page":"Covered schemes","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"An AbsCoveredScheme may have different properties such as ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" is_empty(X::AbsCoveredScheme)\n is_smooth(X::AbsCoveredScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#The-modeling-of-covered-schemes-and-their-expected-behaviour","page":"Covered schemes","title":"The modeling of covered schemes and their expected behaviour","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"Any AbsCoveredScheme may possess several Coverings. This is necessary for several reasons; for instance, a morphism f X to Y between AbsCoveredSchemes will in general only be given on affine patches on a refinement of the default_covering of X. The list of available Coverings can be obtained using ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":" coverings(X::AbsCoveredScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#coverings-Tuple{AbsCoveredScheme}","page":"Covered schemes","title":"coverings","text":"coverings(X::AbsCoveredScheme)\n\nReturn the list of internally stored Coverings of X.\n\nExamples\n\njulia> P = projective_space(QQ, 2);\n\njulia> Pcov = covered_scheme(P)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of multivariate polynomial ring\n 2: spec of multivariate polynomial ring\n 3: spec of multivariate polynomial ring\n in the coordinate(s)\n 1: [(s1//s0), (s2//s0)]\n 2: [(s0//s1), (s2//s1)]\n 3: [(s0//s2), (s1//s2)]\n\njulia> coverings(Pcov)\n1-element Vector{Covering{QQField}}:\n Covering with 3 patches\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"Every AbsCoveredScheme X has to be modeled using one original default_covering C, simply to gather the data necessary to fully describe X. The affine_charts of X return the patches of this covering. For any refinement D C, we require the following to hold: Every element U of the affine_charts of D is either ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"directly an element of the affine_charts of C;\na PrincipalOpenSubset with some ancestor in the affine_charts of C; \na SimplifiedSpec with some original in the affine_charts of C.","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"In all these cases, the affine subsets in the refinements form a tree and thus remember their origins and ambient spaces. In particular, affine patches and also their glueings can be recycled and reused in different coverings and the latter should be merely seen as lists pointing to the objects involved. ","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/map_cache/#Cached-maps","page":"Cached maps","title":"Cached maps","text":"","category":"section"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"All basic map (i.e. those not built up from other maps) in AbstractAlgebra can be cached.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"A cache is a dictionary that can be switched on and off at run time that keeps a cache of previous evaluations of the map. This can be useful if the map is extremely difficult to evaluate, e.g. a discrete logarithm map. Rather than evaluate the map afresh each time, the map first looks up the dictionary of previous known values of the map.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"To facilitate caching of maps, the Generic module provides a type Generic.MapCache, which can be used to wrap any existing map object with a dictionary.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Importantly, the supertype of the resulting Generic.MapCache object is identical to that of the map being cached. This means that any functions that would accept the original map will also accept the cached version.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"note: Note\nCaching of maps only works for maps that correctly abstract access to their fields using accessor functions, as described in the map interface.","category":"page"},{"location":"AbstractAlgebra/map_cache/#Cached-map-constructors","page":"Cached maps","title":"Cached map constructors","text":"","category":"section"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"To construct a cached map from an existing map object, we have the following function:","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"cached(M::Map; enabled=true, limit=100)","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Return a cached map with the same supertype as M, caching up to limit values of the map M in a dictionary, assuming that the cache is enabled.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Caches can be disabled by setting the value of the parameter enabled to false. This allows for the user to quickly go through code and completely disable caches of maps that were previously enabled, for testing purposes, etc.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Caches can also be turned on and off at run time (see below).","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Examples","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"julia> f = map_from_func(x -> x + 1, ZZ, ZZ)\nMap with the following data\n\nDomain:\n=======\nIntegers\n\nCodomain:\n========\nIntegers\n\njulia> g = cached(f);\n\njulia> f(ZZ(1)) == g(ZZ(1))\ntrue","category":"page"},{"location":"AbstractAlgebra/map_cache/#Functionality-for-cached-maps","page":"Cached maps","title":"Functionality for cached maps","text":"","category":"section"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"The following functions are provided for cached maps.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"enable_cache!(M::MapCache)\ndisable_cache!(M::MapCache)","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Temporarily enable or disable the cache for the given map. The values stored in the cache are not lost when it is disabled.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"set_limit!(M::MapCache, limit::Int)","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Set the limit on the number of values that can be cached in the dictionary, to the given value. Setting the value to 0 will effectively disable further caching for this map.","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"Examples","category":"page"},{"location":"AbstractAlgebra/map_cache/","page":"Cached maps","title":"Cached maps","text":"julia> f = cached(map_from_func(x -> x + 1, ZZ, ZZ));\n\njulia> a = f(ZZ(1))\n2\n\njulia> disable_cache!(f)\n\njulia> b = f(ZZ(1))\n2\n\njulia> enable_cache!(f)\n\njulia> c = f(ZZ(1))\n2\n\njulia> set_limit!(f, 200)\n200\n\njulia> d = f(ZZ(1))\n2","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#Free-algebras","page":"Free algebras","title":"Free algebras","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"AbstractAlgebra.jl provides a module, implemented in src/FreeAssAlgebra.jl for free associative algebras over any commutative ring belonging to the AbstractAlgebra abstract type hierarchy.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#Generic-free-algebra-types","page":"Free algebras","title":"Generic free algebra types","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"AbstractAlgebra provides a generic type Generic.FreeAssAlgElem{T} where T is the type of elements of the coefficient ring. The elements are implemented using a Julia array of coefficients and a vector of vectors of Ints for the monomial words. Parent objects of such elements have type Generic.FreeAssAlgebra{T}.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The element types belong to the abstract type NCRingElem, and the algebra types belong to the abstract type NCRing.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The following basic functions are implemented.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"base_ring(R::FreeAssAlgebra)\nbase_ring(a::FreeAssAlgElem)\nparent(a::FreeAssAlgElem)\ncharacteristic(R::FreeAssAlgebra)","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#Free-algebra-constructors","page":"Free algebras","title":"Free algebra constructors","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"free_associative_algebra(R::Ring, s::AbstractVector{<:VarName}; cached::Bool = true)\nfree_associative_algebra(R::Ring, n::Int, s::VarName; cached::Bool = false)","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The first constructor, given a base ring R and an array s of variables, will return a tuple S, (x, ...) representing the new algebra S = R leftx ldots right and a tuple of generators (x ).","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The second constructor given a string s and a number of variables n will do the same as the first constructor except that the variables will be automatically numbered as, s1, s2, ..., sn.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"By default the parent object S will depend only on R and (x, ...) and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"Examples","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"julia> R, (x, y) = free_associative_algebra(ZZ, [\"x\", \"y\"])\n(Free associative algebra on 2 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[x, y])\n\njulia> (x + y + 1)^2\nx^2 + x*y + y*x + y^2 + 2*x + 2*y + 1\n\n\njulia> (x*y*x*x)^4\nx*y*x^3*y*x^3*y*x^3*y*x^2","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#Free-algebra-element-constructors","page":"Free algebras","title":"Free algebra element constructors","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"Elements of a free algebra can be constructed from the generators in the usual way using arithmetic operations. Also, all of the standard ring element constructors may be used. Finally, the MPolyBuildCtx is overloaded to work with coefficients and monomial words and not exponent vectors.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"Examples","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"julia> R, (x, y, z) = free_associative_algebra(ZZ, [\"x\", \"y\", \"z\"])\n(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[x, y, z])\n\njulia> B = MPolyBuildCtx(R)\nBuilder for an element of Free associative algebra on 3 indeterminates over integers\n\njulia> push_term!(B, ZZ(1), [1,2,3,1]); push_term!(B, ZZ(2), [3,3,1]); finish(B)\nx*y*z*x + 2*z^2*x\n\njulia> push_term!(B, ZZ(3), [3,3,3]); push_term!(B, ZZ(4), Int[]); finish(B)\n3*z^3 + 4\n\njulia> [gen(R, 2), R(9)]\n2-element Vector{AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}}:\n y\n 9","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#Element-functions","page":"Free algebras","title":"Element functions","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/#Basic-manipulation","page":"Free algebras","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The standard ring functions are available. The following functions from the multivariate polynomial interface are provided.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"symbols(S::FreeAssAlgebra)\nnvars(f::FreeAssAlgebra)\ngens(S::FreeAssAlgebra)\ngen(S::FreeAssAlgebra, i::Int)\nis_gen(x::FreeAssAlgElem)\ntotal_degree(a::FreeAssAlgElem)\nlength(f::FreeAssAlgElem)","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"As with multivariate polynomials, an implementation must provide access to the elements as a sum of individual terms in some order. The length function provides the number of such terms, and the following functions provide the first such term.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"leading_coefficient(a::FreeAssAlgElem)\nleading_monomial(a::FreeAssAlgElem)\nleading_term(a::FreeAssAlgElem)\nleading_exponent_word(a::FreeAssAlgElem)","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"For types that allow constant time access to coefficients, the following are also available, allowing access to the given coefficient, monomial or term. Terms are numbered from the most significant first.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"coeff(f::FreeAssAlgElem, n::Int)\nmonomial(f::FreeAssAlgElem, n::Int)\nterm(f::FreeAssAlgElem, n::Int)","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"In contrast with the interface for multivariable polynomials, the function exponent_vector is replaced by exponent_word","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"exponent_word(a::Generic.FreeAssAlgElem{T}, i::Int) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#exponent_word-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.FreeAssAlgElem{T}, Int64}} where T<:RingElement","page":"Free algebras","title":"exponent_word","text":"exponent_word(a::FreeAssAlgElem{T}, i::Int) where T <: RingElement\n\nReturn a vector of variable indices corresponding to the monomial of the i-th term of a. Term numbering begins at 1, and the variable indices are given in the order of the variables for the ring.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"Examples","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"julia> R, (x, y, z) = free_associative_algebra(ZZ, [\"x\", \"y\", \"z\"])\n(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[x, y, z])\n\njulia> map(total_degree, (R(0), R(1), -x^2*y^2*z^2*x + z*y))\n(-1, 0, 7)\n\njulia> leading_term(-x^2*y^2*z^2*x + z*y)\n-x^2*y^2*z^2*x\n\njulia> leading_monomial(-x^2*y^2*z^2*x + z*y)\nx^2*y^2*z^2*x\n\njulia> leading_coefficient(-x^2*y^2*z^2*x + z*y)\n-1\n\njulia> exponent_word(-x^2*y^2*z^2*x + z*y, 1)\n7-element Vector{Int64}:\n 1\n 1\n 2\n 2\n 3\n 3\n 1","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#Iterators","page":"Free algebras","title":"Iterators","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The following iterators are provided for elements of a free associative algebra, with exponent_words providing the analogous functionality that exponent_vectors provides for multivariate polynomials.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"terms(p::FreeAssAlgElem)\ncoefficients(p::FreeAssAlgElem)\nmonomials(p::FreeAssAlgElem)","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"exponent_words(a::FreeAssAlgElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#exponent_words-Union{Tuple{FreeAssAlgElem{T}}, Tuple{T}} where T<:RingElement","page":"Free algebras","title":"exponent_words","text":"exponent_words(a::AbstractAlgebra.FreeAssAlgElem{T}) where T <: RingElement\n\nReturn an iterator for the exponent words of the given polynomial. To retrieve an array of the exponent words, use collect(exponent_words(a)).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"Examples","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"julia> R, (a, b, c) = free_associative_algebra(ZZ, [\"a\", \"b\", \"c\"])\n(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssAlgElem{BigInt}[a, b, c])\n\njulia> collect(terms(3*b*a*c - b + c + 2))\n4-element Vector{Any}:\n 3*b*a*c\n -b\n c\n 2\n\njulia> collect(coefficients(3*b*a*c - b + c + 2))\n4-element Vector{Any}:\n 3\n -1\n 1\n 2\n\njulia> collect(monomials(3*b*a*c - b + c + 2))\n4-element Vector{Any}:\n b*a*c\n b\n c\n 1\n\njulia> collect(exponent_words(3*b*a*c - b + c + 2))\n4-element Vector{Vector{Int64}}:\n [2, 1, 3]\n [2]\n [3]\n []","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Quadratic-forms-and-isometries","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"This project is a complement to the code about hermitian lattices available in Hecke. We aim here to connect Hecke and GAP to handle some algorithmic methods regarding quadratic forms with their isometries. In particular, the integration of this code within Oscar is necessary to benefit from all the performance of GAP with respect to computations with groups and automorphisms in general.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"For now, the project covers methods regarding rational and integral quadratic forms.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Content","page":"Quadratic forms and isometries","title":"Content","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"We introduce two new structures","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"QuadSpaceWithIsom\nZZLatWithIsom","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"The former parametrizes pairs (V f) where V is a rational quadratic form and f is an isometry of V. The latter parametrizes pairs (L f) where L is an integral quadratic form, also known as mathbb Z-lattice and f is an isometry of L. One of the main features of this project is the enumeration of isomorphism classes of pairs (L f), where f is an isometry of finite order with at most two prime divisors. The methods we resort to for this purpose are developed in the paper [BH23].","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"We also provide some algorithms computing isomorphism classes of primitive embeddings of even lattices following Nikulin's theory. More precisely, the function primitive_embeddings offers, under certain conditions, the possibility to compute representatives of primitive embeddings and classify them in different ways. Note nonetheless that these functions are not efficient in the case were the discriminant groups have a large number of subgroups.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Status","page":"Quadratic forms and isometries","title":"Status","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"This project has been slightly tested on simple and known examples. It is currently being tested on a larger scale to test its reliability. Moreover, there are still computational bottlenecks due to non-optimized algorithms.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Among the possible improvements and extensions:","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Implement extra methods for lattices with isometries of infinite order;\nExtend existing methods for equivariant primitive embeddings/extensions.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Currently-application-of-this-project","page":"Quadratic forms and isometries","title":"Currently application of this project","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"The project was initiated by S. Brandhorst and T. Hofmann for classifying finite subgroups of automorphisms of K3 surfaces. Our current goal is to use this code, and further extensions of it, to classify finite subgroups of bimeromorphic self-maps of hyperkaehler manifolds, which are a higher dimensional analogues of K3 surface.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Tutorials","page":"Quadratic forms and isometries","title":"Tutorials","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"No tutorials available at the moment.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Examples","page":"Quadratic forms and isometries","title":"Examples","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"No examples available at the moment.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Notice-to-the-user","page":"Quadratic forms and isometries","title":"Notice to the user","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/#Disclaimer","page":"Quadratic forms and isometries","title":"Disclaimer","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Since this project is still under development, feel free to try any feature and report all the bugs you may have found. Any suggestions for improvements or extensions are more than welcome. Refer to the next section to know who you should contact and how. Do not hesitate either to ask for new features - we will be glad to add anything you may need for your research.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"One may expect many things to vary within the next months: name of the functions, available features, performance. This is due to the fact that the current version of the code is still at an experimental stage.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Report-an-issue","page":"Quadratic forms and isometries","title":"Report an issue","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"If you are working with some objects of type QuadSpaceWithIsom or ZZLatWithIsom and you need to report an issue, you can produce directly some lines of codes helping to reconstruct your example. This can help the reviewers to understand your issue and assist you. We have implemented a method to_oscar which prints few lines of codes for reconstructing your example.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"using Oscar # hide\nV = quadratic_space(QQ, 2);\nVf = quadratic_space_with_isometry(V, neg = true)\nOscar.to_oscar(Vf)\n\nLf = lattice(Vf)\nOscar.to_oscar(Lf)","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Make-the-code-more-talkative","page":"Quadratic forms and isometries","title":"Make the code more talkative","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Within the code, there are more hidden messages and testing which are disabled by default. If you plan to experiment with the codes with your favourite examples, you may want to be able to detect some issues to be reported, as well as knowing what the code is doing. Indeed, some functions might take time in term of compilation but also computations. For this, you can enable these extra tests and printings by setting:","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Oscar.set_lwi_level(2)","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Contact","page":"Quadratic forms and isometries","title":"Contact","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Simon Brandhorst,\nTommy Hofmann\nStevell Muller.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"Alternatively, you can raise an issue on GitHub.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/polynomial/#Univariate-polynomial-functionality","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"AbstractAlgebra.jl provides a module, implemented in src/Poly.jl for polynomials over any commutative ring belonging to the AbstractAlgebra abstract type hierarchy. This functionality will work for any univariate polynomial type which follows the Univariate Polynomial Ring interface.","category":"page"},{"location":"AbstractAlgebra/polynomial/#Generic-univariate-polynomial-types","page":"Univariate polynomial functionality","title":"Generic univariate polynomial types","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"AbstractAlgebra.jl provides a generic polynomial type based on Julia arrays which is implemented in src/generic/Poly.jl.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"These generic polynomials have type Generic.Poly{T} where T is the type of elements of the coefficient ring. Internally they consist of a Julia array of coefficients and some additional fields for length and a parent object, etc. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Parent objects of such polynomials have type Generic.PolyRing{T}.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"The string representation of the variable of the polynomial ring and the base/coefficient ring R is stored in the parent object.","category":"page"},{"location":"AbstractAlgebra/polynomial/#Abstract-types","page":"Univariate polynomial functionality","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"All univariate polynomial element types belong to the abstract type PolyRingElem{T} and the polynomial ring types belong to the abstract type PolyRing{T}. This enables one to write generic functions that can accept any AbstractAlgebra polynomial type.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"note: Note\nBoth the generic polynomial ring type Generic.PolyRing{T} and the abstract type it belongs to, PolyRing{T}, are called PolyRing. The former is a (parameterised) concrete type for a polynomial ring over a given base ring whose elements have type T. The latter is an abstract type representing all polynomial ring types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).","category":"page"},{"location":"AbstractAlgebra/polynomial/#Polynomial-ring-constructors","page":"Univariate polynomial functionality","title":"Polynomial ring constructors","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"In order to construct polynomials in AbstractAlgebra.jl, one must first construct the polynomial ring itself. This is accomplished with the following constructor.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"polynomial_ring(R::Ring, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/polynomial/#polynomial_ring-Tuple{Ring, Union{Char, AbstractString, Symbol}}","page":"Univariate polynomial functionality","title":"polynomial_ring","text":"polynomial_ring(R::NCRing, s::VarName; cached::Bool = true)\n\nGiven a base ring R and symbol/string s specifying how the generator (variable) should be printed, return a tuple S, x representing the new polynomial ring S = Rx and the generator x of the ring.\n\nBy default the parent object S depends only on R and x and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.\n\nExamples\n\njulia> R, x = polynomial_ring(ZZ, :x)\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, :y)\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"A shorthand version of this function is provided: given a base ring R, we abbreviate the constructor as follows.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"R[:x]","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"It is also possible to create a polynomial ring with default symbol as follows. This is a lightweight constructor and should be used in generic algorithms wherever possible when creating polynomial rings where the symbol does not matter.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"PolyRing(R::Ring)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Given a base ring R return the polynomial ring S = Rx. Note that unlike the constructors above, the return type is not a tuple. Only the ring is returned and not the generator. The polynomial ring is not cached.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Here are some examples of creating polynomial rings and their associated generators.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> T, z = QQ[\"z\"]\n(Univariate polynomial ring in z over rationals, z)\n\njulia> U = PolyRing(ZZ)\nUnivariate polynomial ring in x over integers","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"All of the examples here are generic polynomial rings, but specialised implementations of polynomial rings provided by external modules will also usually provide a polynomial_ring constructor to allow creation of their polynomial rings.","category":"page"},{"location":"AbstractAlgebra/polynomial/#Polynomial-constructors","page":"Univariate polynomial functionality","title":"Polynomial constructors","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Once a polynomial ring is constructed, there are various ways to construct polynomials in that ring.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"The easiest way is simply using the generator returned by the polynomial_ring constructor and build up the polynomial using basic arithmetic.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"The Julia language has special syntax for the construction of polynomials in terms of a generator, e.g. we can write 2x instead of 2*x.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"A second way is to use the polynomial ring to construct a polynomial. There are the usual ways of constructing an element of a ring.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"(R::PolyRing)() # constructs zero\n(R::PolyRing)(c::Integer)\n(R::PolyRing)(c::elem_type(R))\n(R::PolyRing{T})(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"For polynommials there is also the following more general constructor accepting an array of coefficients.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"(S::PolyRing{T})(A::Vector{T}) where T <: RingElem\n(S::PolyRing{T})(A::Vector{U}) where T <: RingElem, U <: RingElem\n(S::PolyRing{T})(A::Vector{U}) where T <: RingElem, U <: Integer","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Construct the polynomial in the ring S with the given array of coefficients, i.e. where A[1] is the constant coefficient.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"A third way of constructing polynomials is to construct them directly without creating the polynomial ring.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"polynomial(R::Ring, arr::Vector{T}, var::VarName=:x; cached::Bool=true)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Given an array of coefficients construct the polynomial with those coefficients over the given ring and with the given variable.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = x^3 + 3x + 21\nx^3 + 3*x + 21\n\njulia> g = (x + 1)*y^2 + 2x + 1\n(x + 1)*y^2 + 2*x + 1\n\njulia> R()\n0\n\njulia> S(1)\n1\n\njulia> S(y)\ny\n\njulia> S(x)\nx\n\njulia> S, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> f = S(Rational{BigInt}[2, 3, 1])\nx^2 + 3*x + 2\n\njulia> g = S(BigInt[1, 0, 4])\n4*x^2 + 1\n\njulia> h = S([4, 7, 2, 9])\n9*x^3 + 2*x^2 + 7*x + 4\n\njulia> p = polynomial(ZZ, [1, 2, 3])\n3*x^2 + 2*x + 1\n\njulia> f = polynomial(ZZ, [1, 2, 3], \"y\")\n3*y^2 + 2*y + 1","category":"page"},{"location":"AbstractAlgebra/polynomial/#Similar-and-zero","page":"Univariate polynomial functionality","title":"Similar and zero","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Another way of constructing polynomials is to construct one similar to an existing polynomial using either similar or zero. ","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"similar(x::MyPoly{T}, R::Ring=base_ring(x)) where T <: RingElem\nzero(x::MyPoly{T}, R::Ring=base_ring(x)) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Construct the zero polynomial with the same variable as the given polynomial with coefficients in the given ring. Both functions behave the same way for polynomials.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"similar(x::MyPoly{T}, R::Ring, var::VarName=var(parent(x))) where T <: RingElem\nsimilar(x::MyPoly{T}, var::VarName=var(parent(x))) where T <: RingElem\nzero(x::MyPoly{T}, R::Ring, var::VarName=var(parent(x))) where T <: RingElem\nzero(x::MyPoly{T}, var::VarName=var(parent(x))) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Construct the zero polynomial with the given variable and coefficients in the given ring, if specified, and in the coefficient ring of the given polynomial otherwise.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> f = 1 + 2x + 3x^2\n3*x^2 + 2*x + 1\n\njulia> g = similar(f)\n0\n\njulia> h = similar(f, QQ)\n0\n\njulia> k = similar(f, QQ, \"y\")\n0","category":"page"},{"location":"AbstractAlgebra/polynomial/#Functions-for-types-and-parents-of-polynomial-rings","page":"Univariate polynomial functionality","title":"Functions for types and parents of polynomial rings","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"base_ring(R::PolyRing)\nbase_ring(a::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Return the coefficient ring of the given polynomial ring or polynomial.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"parent(a::NCRingElement)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Return the polynomial ring of the given polynomial..","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"characteristic(R::NCRing)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Return the characteristic of the given polynomial ring. If the characteristic is not known, an exception is raised.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> U = base_ring(S)\nUnivariate polynomial ring in x over integers\n\njulia> V = base_ring(y + 1)\nUnivariate polynomial ring in x over integers\n\njulia> T = parent(y + 1)\nUnivariate polynomial ring in y over univariate polynomial ring","category":"page"},{"location":"AbstractAlgebra/polynomial/#Euclidean-polynomial-rings","page":"Univariate polynomial functionality","title":"Euclidean polynomial rings","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"For polynomials over a field, the Euclidean Ring Interface is implemented.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"mod(f::PolyRingElem, g::PolyRingElem)\ndivrem(f::PolyRingElem, g::PolyRingElem)\ndiv(f::PolyRingElem, g::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"mulmod(f::PolyRingElem, g::PolyRingElem, m::PolyRingElem)\npowermod(f::PolyRingElem, e::Int, m::PolyRingElem)\ninvmod(f::PolyRingElem, m::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"divides(f::PolyRingElem, g::PolyRingElem)\nremove(f::PolyRingElem, p::PolyRingElem)\nvaluation(f::PolyRingElem, p::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"gcd(f::PolyRingElem, g::PolyRingElem)\nlcm(f::PolyRingElem, g::PolyRingElem)\ngcdx(f::PolyRingElem, g::PolyRingElem)\ngcdinv(f::PolyRingElem, g::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> S = residue_ring(R, x^3 + 3x + 1)\nResidue ring of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> T, y = polynomial_ring(S, \"y\")\n(Univariate polynomial ring in y over residue ring, y)\n\njulia> f = (3*x^2 + x + 2)*y + x^2 + 1\n(3*x^2 + x + 2)*y + x^2 + 1\n\njulia> g = (5*x^2 + 2*x + 1)*y^2 + 2x*y + x + 1\n(5*x^2 + 2*x + 1)*y^2 + 2*x*y + x + 1\n\njulia> h = (3*x^3 + 2*x^2 + x + 7)*y^5 + 2x*y + 1\n(2*x^2 - 8*x + 4)*y^5 + 2*x*y + 1\n\njulia> invmod(f, g)\n(707//3530*x^2 + 2151//1765*x + 123//3530)*y - 178//1765*x^2 - 551//3530*x + 698//1765\n\njulia> mulmod(f, g, h)\n(-30*x^2 - 43*x - 9)*y^3 + (-7*x^2 - 23*x - 7)*y^2 + (4*x^2 - 10*x - 3)*y + x^2 - 2*x\n\njulia> powermod(f, 3, h)\n(69*x^2 + 243*x + 79)*y^3 + (78*x^2 + 180*x + 63)*y^2 + (27*x^2 + 42*x + 18)*y + 3*x^2 + 3*x + 2\n\njulia> h = mod(f, g)\n(3*x^2 + x + 2)*y + x^2 + 1\n\njulia> q, r = divrem(f, g)\n(0, (3*x^2 + x + 2)*y + x^2 + 1)\n\njulia> div(g, f)\n(-5//11*x^2 + 2//11*x + 6//11)*y - 13//121*x^2 - 3//11*x - 78//121\n\njulia> d = gcd(f*h, g*h)\ny + 1//11*x^2 + 6//11\n\njulia> k = gcdinv(f, h)\n(y + 1//11*x^2 + 6//11, 0)\n\njulia> m = lcm(f, h)\n(-14*x^2 - 23*x - 2)*y - 4*x^2 - 5*x + 1\n\njulia> flag, q = divides(g^2, g)\n(true, (5*x^2 + 2*x + 1)*y^2 + 2*x*y + x + 1)\n\njulia> valuation(3g^3, g) == 3\ntrue\n\njulia> val, q = remove(5g^3, g)\n(3, 5)\n\njulia> r, s, t = gcdx(g, h)\n(1, 311//3530*x^2 - 2419//3530*x + 947//1765, (707//3530*x^2 + 2151//1765*x + 123//3530)*y - 178//1765*x^2 - 551//3530*x + 698//1765)\n","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Functions in the Euclidean Ring interface are supported over residue rings that are not fields, except that if an impossible inverse is encountered during the computation an error is thrown.","category":"page"},{"location":"AbstractAlgebra/polynomial/#Polynomial-functions","page":"Univariate polynomial functionality","title":"Polynomial functions","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/#Basic-functionality","page":"Univariate polynomial functionality","title":"Basic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"All basic ring functionality is provided for polynomials. The most important such functions are the following.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"zero(R::PolyRing)\none(R::PolyRing)\niszero(a::PolyRingElem)\nisone(a::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"divexact(a::T, b::T) where T <: PolyRingElem","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"All functions in the polynomial interface are provided. The most important are the following.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"var(S::PolyRing)\nsymbols(S::PolyRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Return a symbol or length 1 array of symbols, respectively, specifying the variable of the polynomial ring. This symbol is converted to a string when printing polynomials in that ring.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"In addition, the following basic functions are provided.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"modulus{T <: ResElem}(::PolyRingElem{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#modulus-Union{Tuple{PolyRingElem{T}}, Tuple{T}} where T<:ResElem","page":"Univariate polynomial functionality","title":"modulus","text":"modulus(a::PolyRingElem{T}) where {T <: ResElem}\n\nReturn the modulus of the coefficients of the given polynomial.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"leading_coefficient(::PolyRingElem)\ntrailing_coefficient(::PolyRingElem)\nconstant_coefficient(::PolynomialElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#leading_coefficient-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"leading_coefficient","text":"leading_coefficient(a::PolynomialElem)\n\nReturn the leading coefficient of the given polynomial. This will be the nonzero coefficient of the term with highest degree unless the polynomial in the zero polynomial, in which case a zero coefficient is returned.\n\n\n\n\n\nleading_coefficient(p::MPolyRingElem)\n\nReturn the leading coefficient of the polynomial p.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#trailing_coefficient-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"trailing_coefficient","text":"trailing_coefficient(a::PolynomialElem)\n\nReturn the trailing coefficient of the given polynomial. This will be the nonzero coefficient of the term with lowest degree unless the polynomial is the zero polynomial, in which case a zero coefficient is returned.\n\n\n\n\n\ntrailing_coefficient(p::MPolyRingElem)\n\nReturn the trailing coefficient of the polynomial p, i.e. the coefficient of the last nonzero term, or zero if the polynomial is zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#constant_coefficient-Tuple{PolynomialElem}","page":"Univariate polynomial functionality","title":"constant_coefficient","text":"constant_coefficient(a::PolynomialElem)\n\nReturn the constant coefficient of the given polynomial. If the polynomial is the zero polynomial, the function will return zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"set_coefficient!(::PolynomialElem{T}, ::Int, c::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/polynomial/#set_coefficient!-Union{Tuple{T}, Tuple{PolynomialElem{T}, Int64, T}} where T<:RingElement","page":"Univariate polynomial functionality","title":"set_coefficient!","text":"set_coefficient!(c::PolynomialElem{T}, n::Int, a::T) where T <: RingElement\nset_coefficient!(c::PolynomialElem{T}, n::Int, a::U) where {T <: RingElement, U <: Integer}\n\nSet the coefficient of degree n to a.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"tail(::PolynomialElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#tail-Tuple{PolynomialElem}","page":"Univariate polynomial functionality","title":"tail","text":"tail(a::PolynomialElem)\n\nReturn the tail of the given polynomial, i.e. the polynomial without its leading term (if any).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"gen(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#gen-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"gen","text":"gen(M::SubquoModule{T}, i::Int) where T\n\nReturn the ith generator of M.\n\n\n\n\n\ngen(a::MPolyRing{T}, i::Int) where {T <: RingElement}\n\nReturn the i-th generator (variable) of the given polynomial ring.\n\n\n\n\n\ngen(R::AbsPowerSeriesRing{T}) where T <: RingElement\n\nReturn the generator of the power series ring, i.e. x + O(x^n) where n is the precision of the power series ring R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_gen(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_gen-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"is_gen","text":"is_gen(x::MPoly{T}) where {T <: RingElement}\n\nReturn true if the given polynomial is a generator (variable) of the polynomial ring it belongs to.\n\n\n\n\n\nis_gen(a::PolynomialElem)\n\nReturn true if the given polynomial is the constant generator of its polynomial ring, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_monic(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_monic-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"is_monic","text":"is_monic(a::PolynomialElem)\n\nReturn true if the given polynomial is monic, i.e. has leading coefficient equal to one, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_square(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_square-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"is_square","text":"is_square(f::PolyRingElem{T}) where T <: RingElement\n\nReturn true if f is a perfect square.\n\n\n\n\n\nis_square(a::FracElem{T}) where T <: RingElem\n\nReturn true if a is a square.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"length(::PolynomialElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#length-Tuple{PolynomialElem}","page":"Univariate polynomial functionality","title":"length","text":"length(a::PolynomialElem)\n\nReturn the length of the polynomial. The length of a univariate polynomial is defined to be the number of coefficients in its dense representation, including zero coefficients. Thus naturally the zero polynomial has length zero and additionally for nonzero polynomials the length is one more than the degree. (Note that the leading coefficient will always be nonzero.)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"degree(::PolynomialElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#degree-Tuple{PolynomialElem}","page":"Univariate polynomial functionality","title":"degree","text":"degree(a::PolynomialElem)\n\nReturn the degree of the given polynomial. This is defined to be one less than the length, even for constant polynomials.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_monomial(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_monomial-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"is_monomial","text":"is_monomial(a::PolynomialElem)\n\nReturn true if the given polynomial is a monomial.\n\n\n\n\n\nis_monomial(x::AbstractAlgebra.MPolyRingElem)\n\nReturn true if the given polynomial has precisely one term whose coefficient is one.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_monomial_recursive(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_monomial_recursive-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"is_monomial_recursive","text":"is_monomial_recursive(a::PolynomialElem)\n\nReturn true if the given polynomial is a monomial. This function is recursive, with all scalar types returning true.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_term(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_term-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"is_term","text":"is_term(a::PolynomialElem)\n\nReturn true if the given polynomial has one term.\n\n\n\n\n\nis_term(x::MPoly)\n\nReturn true if the given polynomial has precisely one term.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_term_recursive(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_term_recursive-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"is_term_recursive","text":"is_term_recursive(a::PolynomialElem)\n\nReturn true if the given polynomial has one term. This function is recursive, with all scalar types returning true.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"is_constant(::PolynomialElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#is_constant-Tuple{PolynomialElem}","page":"Univariate polynomial functionality","title":"is_constant","text":"is_constant(a::PolynomialElem)\n\nReturn true if a is a degree zero polynomial or the zero polynomial, i.e. a constant polynomial.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> T, z = polynomial_ring(QQ, \"z\")\n(Univariate polynomial ring in z over rationals, z)\n\njulia> U = residue_ring(ZZ, 17)\nResidue ring of integers modulo 17\n\njulia> V, w = polynomial_ring(U, \"w\")\n(Univariate polynomial ring in w over residue ring, w)\n\njulia> var(R)\n:x\n\njulia> symbols(R)\n1-element Vector{Symbol}:\n :x\n\njulia> a = zero(S)\n0\n\njulia> b = one(S)\n1\n\njulia> isone(b)\ntrue\n\njulia> c = BigInt(1)//2*z^2 + BigInt(1)//3\n1//2*z^2 + 1//3\n\njulia> d = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + 3\n\njulia> f = leading_coefficient(d)\nx\n\njulia> y = gen(S)\ny\n\njulia> g = is_gen(w)\ntrue\n\njulia> divexact((2x + 1)*(x + 1), (x + 1))\n2*x + 1\n\njulia> m = is_unit(b)\ntrue\n\njulia> n = degree(d)\n2\n\njulia> r = modulus(w)\n17\n\njulia> is_term(2y^2)\ntrue\n\njulia> is_monomial(y^2)\ntrue\n\njulia> is_monomial_recursive(x*y^2)\ntrue\n\njulia> is_monomial(x*y^2)\nfalse\n\njulia> S, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> f = x^3 + 3x + 1\nx^3 + 3*x + 1\n\njulia> g = S(BigInt[1, 2, 0, 1, 0, 0, 0]);\n\njulia> n = length(f)\n4\n\njulia> c = coeff(f, 1)\n3\n\njulia> g = set_coefficient!(g, 2, ZZ(11))\nx^3 + 11*x^2 + 2*x + 1\n\njulia> g = set_coefficient!(g, 7, ZZ(4))\n4*x^7 + x^3 + 11*x^2 + 2*x + 1","category":"page"},{"location":"AbstractAlgebra/polynomial/#Iterators","page":"Univariate polynomial functionality","title":"Iterators","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"An iterator is provided to return the coefficients of a univariate polynomial. The iterator is called coefficients and allows iteration over the coefficients, starting with the term of degree zero (if there is one). Note that coefficients of each degree are given, even if they are zero. This is best illustrated by example.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> f = x^2 + 2\nx^2 + 2\n\njulia> C = collect(coefficients(f))\n3-element Vector{BigInt}:\n 2\n 0\n 1\n\njulia> for c in coefficients(f)\n println(c)\n end\n2\n0\n1","category":"page"},{"location":"AbstractAlgebra/polynomial/#Truncation","page":"Univariate polynomial functionality","title":"Truncation","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"truncate(::PolyRingElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/polynomial/#truncate-Tuple{PolyRingElem, Int64}","page":"Univariate polynomial functionality","title":"truncate","text":"truncate(a::PolynomialElem, n::Int)\n\nReturn a truncated to n terms, i.e. the remainder upon division by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"mullow{T <: RingElem}(::PolyRingElem{T}, ::PolyRingElem{T}, ::Int)","category":"page"},{"location":"AbstractAlgebra/polynomial/#mullow-Union{Tuple{T}, Tuple{PolyRingElem{T}, PolyRingElem{T}, Int64}} where T<:RingElem","page":"Univariate polynomial functionality","title":"mullow","text":"mullow(a::PolyRingElem{T}, b::PolyRingElem{T}, n::Int) where T <: RingElement\n\nReturn atimes b truncated to n terms.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + 3\n\njulia> g = (x + 1)*y + (x^3 + 2x + 2)\n(x + 1)*y + x^3 + 2*x + 2\n\njulia> h = truncate(f, 1)\n3\n\njulia> k = mullow(f, g, 4)\n(x^2 + x)*y^3 + (x^4 + 3*x^2 + 4*x + 1)*y^2 + (x^4 + x^3 + 2*x^2 + 7*x + 5)*y + 3*x^3 + 6*x + 6\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Reversal","page":"Univariate polynomial functionality","title":"Reversal","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"reverse(::PolyRingElem, ::Int)\nreverse(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#reverse-Tuple{PolyRingElem, Int64}","page":"Univariate polynomial functionality","title":"reverse","text":"reverse(x::PolynomialElem, len::Int)\n\nReturn the reverse of the polynomial x, thought of as a polynomial of the given length (the polynomial will be notionally truncated or padded with zeroes before the leading term if necessary to match the specified length). The resulting polynomial is normalised. If len is negative we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#reverse-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"reverse","text":"reverse(x::PolynomialElem)\n\nReturn the reverse of the polynomial x, i.e. the leading coefficient of x becomes the constant coefficient of the result, etc. The resulting polynomial is normalised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + 3\n\njulia> g = reverse(f, 7)\n3*y^6 + (x + 1)*y^5 + x*y^4\n\njulia> h = reverse(f)\n3*y^2 + (x + 1)*y + x\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Shifting","page":"Univariate polynomial functionality","title":"Shifting","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"shift_left(::PolyRingElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/polynomial/#shift_left-Tuple{PolyRingElem, Int64}","page":"Univariate polynomial functionality","title":"shift_left","text":"shift_left(f::PolynomialElem, n::Int)\n\nReturn the polynomial f shifted left by n terms, i.e. multiplied by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"shift_right(::PolyRingElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/polynomial/#shift_right-Tuple{PolyRingElem, Int64}","page":"Univariate polynomial functionality","title":"shift_right","text":"shift_right(f::PolynomialElem, n::Int)\n\nReturn the polynomial f shifted right by n terms, i.e. divided by x^n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + 3\n\njulia> g = shift_left(f, 7)\nx*y^9 + (x + 1)*y^8 + 3*y^7\n\njulia> h = shift_right(f, 2)\nx\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Inflation-and-deflation","page":"Univariate polynomial functionality","title":"Inflation and deflation","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"deflation(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#deflation-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"deflation","text":"deflation(p::PolyRingElem)\n\nReturn a tuple (shift, defl) where shift is the exponent of the trailing term of p and defl is the gcd of the distance between the exponents of the nonzero terms of p. If p = 0, both shift and defl will be zero.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"inflate(::PolyRingElem, ::Int, ::Int)\ninflate(::PolyRingElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/polynomial/#inflate-Tuple{PolyRingElem, Int64, Int64}","page":"Univariate polynomial functionality","title":"inflate","text":"inflate(f::PolyRingElem, shift::Int64, n::Int64) -> PolyRingElem\n\nGiven a polynomial f in x, return f(x^n)*x^j, i.e. multiply all exponents by n and shift f left by j.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#inflate-Tuple{PolyRingElem, Int64}","page":"Univariate polynomial functionality","title":"inflate","text":"inflate(f::PolyRingElem, n::Int64) -> PolyRingElem\n\nGiven a polynomial f in x, return f(x^n), i.e. multiply all exponents by n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"deflate(::PolyRingElem, ::Int, ::Int)\ndeflate(::PolyRingElem, ::Int)\ndeflate(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#deflate-Tuple{PolyRingElem, Int64, Int64}","page":"Univariate polynomial functionality","title":"deflate","text":"deflate(f::PolyRingElem, shift::Int64, n::Int64) -> PolyRingElem\n\nGiven a polynomial g in x^n such that f = g(x)*x^{shift}, write f as a polynomial in x, i.e. divide all exponents of g by n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#deflate-Tuple{PolyRingElem, Int64}","page":"Univariate polynomial functionality","title":"deflate","text":"deflate(f::PolyRingElem, n::Int64) -> PolyRingElem\n\nGiven a polynomial f in x^n, write it as a polynomial in x, i.e. divide all exponents by n.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#deflate-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"deflate","text":"deflate(x::PolyRingElem) -> PolyRingElem, Int\n\nDeflate the polynomial f maximally, i.e. find the largest n s.th. f can be deflated by n, i.e. f is actually a polynomial in x^n. Return g n where g is the deflation of f.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#Square-root","page":"Univariate polynomial functionality","title":"Square root","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Base.sqrt(::PolyRingElem{T}; check::Bool) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/polynomial/#sqrt-Union{Tuple{PolyRingElem{T}}, Tuple{T}} where T<:RingElement","page":"Univariate polynomial functionality","title":"sqrt","text":"sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of the given Puiseux series a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nBase.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of f. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"R, x = polynomial_ring(ZZ, \"x\")\ng = x^2+6*x+1\nsqrt(g^2)","category":"page"},{"location":"AbstractAlgebra/polynomial/#Change-of-base-ring","page":"Univariate polynomial functionality","title":"Change of base ring","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"change_base_ring(::Ring, ::PolyRingElem{T}) where T <: RingElement\nchange_coefficient_ring(::Ring, ::PolyRingElem{T}) where T <: RingElement\nmap_coefficients(::Any, ::PolyRingElem{<:RingElement})","category":"page"},{"location":"AbstractAlgebra/polynomial/#change_base_ring-Union{Tuple{T}, Tuple{Ring, PolyRingElem{T}}} where T<:RingElement","page":"Univariate polynomial functionality","title":"change_base_ring","text":"change_base_ring(R::Ring, p::PolyRingElem{<: RingElement}; parent::PolyRing)\n\nReturn the polynomial obtained by coercing the non-zero coefficients of p into R.\n\nIf the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#change_coefficient_ring-Union{Tuple{T}, Tuple{Ring, PolyRingElem{T}}} where T<:RingElement","page":"Univariate polynomial functionality","title":"change_coefficient_ring","text":"change_coefficient_ring(R::Ring, p::PolyRingElem{<: RingElement}; parent::PolyRing)\n\nReturn the polynomial obtained by coercing the non-zero coefficients of p into R.\n\nIf the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#map_coefficients-Tuple{Any, PolyRingElem{<:RingElement}}","page":"Univariate polynomial functionality","title":"map_coefficients","text":"map_coefficients(f, p::PolyRingElem{<: RingElement}; cached::Bool=true, parent::PolyRing)\n\nTransform the polynomial p by applying f on each non-zero coefficient.\n\nIf the optional parent keyword is provided, the polynomial will be an element of parent. The caching of the parent object can be controlled via the cached keyword argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"R, x = polynomial_ring(ZZ, \"x\")\ng = x^3+6*x + 1\nchange_base_ring(GF(2), g)\nchange_coefficient_ring(GF(2), g)","category":"page"},{"location":"AbstractAlgebra/polynomial/#Pseudodivision","page":"Univariate polynomial functionality","title":"Pseudodivision","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Given two polynomials a b, pseudodivision computes polynomials q and r with length(r) length(b) such that L^d a = bq + r where d = length(a) - length(b) + 1 and L is the leading coefficient of b.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"We call q the pseudoquotient and r the pseudoremainder.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"pseudorem{T <: RingElem}(::PolyRingElem{T}, ::PolyRingElem{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#pseudorem-Union{Tuple{T}, Tuple{PolyRingElem{T}, PolyRingElem{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"pseudorem","text":"pseudorem(f::PolyRingElem{T}, g::PolyRingElem{T}) where T <: RingElement\n\nReturn the pseudoremainder of f divided by g. If g = 0 we throw a DivideError().\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"pseudodivrem{T <: RingElem}(::PolyRingElem{T}, ::PolyRingElem{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#pseudodivrem-Union{Tuple{T}, Tuple{PolyRingElem{T}, PolyRingElem{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"pseudodivrem","text":"pseudodivrem(f::PolyRingElem{T}, g::PolyRingElem{T}) where T <: RingElement\n\nReturn a tuple (q r) consisting of the pseudoquotient and pseudoremainder of f divided by g. If g = 0 we throw a DivideError().\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + 3\n\njulia> g = (x + 1)*y + (x^3 + 2x + 2)\n(x + 1)*y + x^3 + 2*x + 2\n\njulia> h = pseudorem(f, g)\nx^7 + 3*x^5 + 2*x^4 + x^3 + 5*x^2 + 4*x + 1\n\njulia> q, r = pseudodivrem(f, g)\n((x^2 + x)*y - x^4 - x^2 + 1, x^7 + 3*x^5 + 2*x^4 + x^3 + 5*x^2 + 4*x + 1)\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Content-and-primitive-part","page":"Univariate polynomial functionality","title":"Content and primitive part","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"content(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#content-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"content","text":"content(a::PolyRingElem)\n\nReturn the content of a, i.e. the greatest common divisor of its coefficients.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"primpart(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#primpart-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"primpart","text":"primpart(a::PolyRingElem)\n\nReturn the primitive part of a, i.e. the polynomial divided by its content.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"R, x = polynomial_ring(ZZ, \"x\")\nS, y = polynomial_ring(R, \"y\")\n\nk = x*y^2 + (x + 1)*y + 3\n\nn = content(k)\np = primpart(k*(x^2 + 1))","category":"page"},{"location":"AbstractAlgebra/polynomial/#Evaluation,-composition-and-substitution","page":"Univariate polynomial functionality","title":"Evaluation, composition and substitution","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"evaluate{T <: RingElem}(::PolyRingElem{T}, ::T)\nevaluate(::PolyRingElem, ::Integer)","category":"page"},{"location":"AbstractAlgebra/polynomial/#evaluate-Union{Tuple{T}, Tuple{PolyRingElem{T}, T}} where T<:RingElem","page":"Univariate polynomial functionality","title":"evaluate","text":"evaluate(a::PolyRingElem, b::T) where T <: RingElement\n\nEvaluate the polynomial expression a at the value b and return the result.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#evaluate-Tuple{PolyRingElem, Integer}","page":"Univariate polynomial functionality","title":"evaluate","text":"evaluate(a::PolyRingElem, b::T) where T <: RingElement\n\nEvaluate the polynomial expression a at the value b and return the result.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"compose(::PolyRingElem, ::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#compose-Tuple{PolyRingElem, PolyRingElem}","page":"Univariate polynomial functionality","title":"compose","text":"compose(a::PolyRingElem, b::PolyRingElem)\n\nCompose the polynomial a with the polynomial b and return the result, i.e. return acirc b.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"subst{T <: RingElem}(::PolyRingElem{T}, ::Any)","category":"page"},{"location":"AbstractAlgebra/polynomial/#subst-Union{Tuple{T}, Tuple{PolyRingElem{T}, Any}} where T<:RingElem","page":"Univariate polynomial functionality","title":"subst","text":"subst(f::PolyRingElem{T}, a::Any) where T <: RingElement\n\nEvaluate the polynomial f at a. Note that a can be anything, whether a ring element or not.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"We also overload the functional notation so that the polynomial f can be evaluated at a by writing f(a).","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + 3\n\njulia> g = (x + 1)*y + (x^3 + 2x + 2)\n(x + 1)*y + x^3 + 2*x + 2\n\njulia> M = R[x + 1 2x; x - 3 2x - 1]\n[x + 1 2*x]\n[x - 3 2*x - 1]\n\njulia> k = evaluate(f, 3)\n12*x + 6\n\njulia> m = evaluate(f, x^2 + 2x + 1)\nx^5 + 4*x^4 + 7*x^3 + 7*x^2 + 4*x + 4\n\njulia> n = compose(f, g)\n(x^3 + 2*x^2 + x)*y^2 + (2*x^5 + 2*x^4 + 4*x^3 + 9*x^2 + 6*x + 1)*y + x^7 + 4*x^5 + 5*x^4 + 5*x^3 + 10*x^2 + 8*x + 5\n\njulia> p = subst(f, M)\n[3*x^3 - 3*x^2 + 3*x + 4 6*x^3 + 2*x^2 + 2*x]\n[3*x^3 - 8*x^2 - 2*x - 3 6*x^3 - 8*x^2 + 2*x + 2]\n\njulia> q = f(M)\n[3*x^3 - 3*x^2 + 3*x + 4 6*x^3 + 2*x^2 + 2*x]\n[3*x^3 - 8*x^2 - 2*x - 3 6*x^3 - 8*x^2 + 2*x + 2]\n\njulia> r = f(23)\n552*x + 26\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Derivative-and-integral","page":"Univariate polynomial functionality","title":"Derivative and integral","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"derivative(::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#derivative-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"derivative","text":"derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the derivative of the given Puiseux series a.\n\n\n\n\n\nderivative(a::PolynomialElem)\n\nReturn the derivative of the polynomial a.\n\n\n\n\n\nderivative(f::AbsPowerSeriesRingElem{T})\n\nReturn the derivative of the power series f.\n\n\n\n\n\nderivative(f::RelPowerSeriesRingElem{T})\n\nReturn the derivative of the power series f.\n\njulia> R, x = power_series_ring(QQ, 10, \"x\")\n(Univariate power series ring in x over Rationals, x + O(x^11))\n\njulia> f = 2 + x + 3x^3\n2 + x + 3*x^3 + O(x^10)\n\njulia> derivative(f)\n1 + 9*x^2 + O(x^9)\n\n\n\n\n\nderivative(f::AbstractAlgebra.MPolyRingElem{T}, j::Int) where {T <: RingElement}\n\nReturn the partial derivative of f with respect to j-th variable of the polynomial ring.\n\n\n\n\n\nderivative(f::AbstractAlgebra.MPolyRingElem{T}, x::AbstractAlgebra.MPolyRingElem{T}) where T <: RingElement\n\nReturn the partial derivative of f with respect to x. The value x must be a generator of the polynomial ring of f.\n\n\n\n\n\nderivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem\n\nReturn the derivative of x with respect to the variable of index n.\n\n\n\n\n\nderivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem\n\nReturn the derivative of x with respect to the variable v.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"integral{T <: Union{ResElem, FieldElem}}(::PolyRingElem{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#integral-Union{Tuple{PolyRingElem{T}}, Tuple{T}} where T<:Union{FieldElem, ResElem}","page":"Univariate polynomial functionality","title":"integral","text":"integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the integral of the given Puiseux series a.\n\n\n\n\n\nintegral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(x::PolyRingElem{T}) where {T <: Union{ResElem, FieldElement}}\n\nReturn the integral of the polynomial x.\n\n\n\n\n\nintegral(f::AbsPowerSeriesRingElem{T})\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(f::RelPowerSeriesRingElem{T})\n\nReturn the integral of the power series f.\n\njulia> R, x = power_series_ring(QQ, 10, \"x\")\n(Univariate power series ring in x over Rationals, x + O(x^11))\n\njulia> f = 2 + x + 3x^3\n2 + x + 3*x^3 + O(x^10)\n\njulia> integral(f)\n2*x + 1//2*x^2 + 3//4*x^4 + O(x^11)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> T, z = polynomial_ring(QQ, \"z\")\n(Univariate polynomial ring in z over rationals, z)\n\njulia> U = residue_ring(T, z^3 + 3z + 1)\nResidue ring of univariate polynomial ring modulo z^3 + 3*z + 1\n\njulia> V, w = polynomial_ring(U, \"w\")\n(Univariate polynomial ring in w over residue ring, w)\n\njulia> f = x*y^2 + (x + 1)*y + 3\nx*y^2 + (x + 1)*y + 3\n\njulia> g = (z^2 + 2z + 1)*w^2 + (z + 1)*w - 2z + 4\n(z^2 + 2*z + 1)*w^2 + (z + 1)*w - 2*z + 4\n\njulia> h = derivative(f)\n2*x*y + x + 1\n\njulia> k = integral(g)\n(1//3*z^2 + 2//3*z + 1//3)*w^3 + (1//2*z + 1//2)*w^2 + (-2*z + 4)*w\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Resultant-and-discriminant","page":"Univariate polynomial functionality","title":"Resultant and discriminant","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"sylvester_matrix{T <: RingElem}(::PolyRingElem{T}, ::PolyRingElem{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#sylvester_matrix-Union{Tuple{T}, Tuple{PolyRingElem{T}, PolyRingElem{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"sylvester_matrix","text":"sylvester_matrix(p::PolyRingElem, q::PolyRingElem)\n\nReturn the sylvester matrix of the given polynomials.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"resultant{T <: RingElem}(::PolyRingElem{T}, ::PolyRingElem{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#resultant-Union{Tuple{T}, Tuple{PolyRingElem{T}, PolyRingElem{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"resultant","text":"resultant(p::PolyRingElem{T}, q::PolyRingElem{T}) where T <: RingElement\n\nReturn the resultant of the given polynomials.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"resx{T <: RingElem}(::PolyRingElem{T}, ::PolyRingElem{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#resx-Union{Tuple{T}, Tuple{PolyRingElem{T}, PolyRingElem{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"resx","text":"resx(a::PolyRingElem{T}, b::PolyRingElem{T}) where T <: RingElement\n\nReturn a tuple (r s t) such that r is the resultant of a and b and such that r = atimes s + btimes t.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"discriminant(a::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#discriminant-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"discriminant","text":"discriminant(a::PolyRingElem)\n\nReturn the discriminant of the given polynomial.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = 3x*y^2 + (x + 1)*y + 3\n3*x*y^2 + (x + 1)*y + 3\n\njulia> g = 6(x + 1)*y + (x^3 + 2x + 2)\n(6*x + 6)*y + x^3 + 2*x + 2\n\njulia> S = sylvester_matrix(f, g)\n[ 3*x x + 1 3]\n[6*x + 6 x^3 + 2*x + 2 0]\n[ 0 6*x + 6 x^3 + 2*x + 2]\n\njulia> h = resultant(f, g)\n3*x^7 + 6*x^5 - 6*x^3 + 96*x^2 + 192*x + 96\n\njulia> k = discriminant(f)\nx^2 - 34*x + 1\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Newton-representation","page":"Univariate polynomial functionality","title":"Newton representation","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"monomial_to_newton!{T <: RingElem}(::Vector{T}, ::Vector{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#monomial_to_newton!-Union{Tuple{T}, Tuple{Vector{T}, Vector{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"monomial_to_newton!","text":"monomial_to_newton!(P::Vector{T}, roots::Vector{T}) where T <: RingElement\n\nConverts a polynomial p, given as an array of coefficients, in-place from its coefficients given in the standard monomial basis to the Newton basis for the roots r_0 r_1 ldots r_n-2. In other words, this determines output coefficients c_i such that c_0 + c_1(x-r_0) + c_2(x-r_0)(x-r_1) + ldots + c_n-1(x-r_0)(x-r_1)cdots(x-r_n-2) is equal to the input polynomial.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"newton_to_monomial!{T <: RingElem}(::Vector{T}, ::Vector{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#newton_to_monomial!-Union{Tuple{T}, Tuple{Vector{T}, Vector{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"newton_to_monomial!","text":"newton_to_monomial!(P::Vector{T}, roots::Vector{T}) where T <: RingElement\n\nConverts a polynomial p, given as an array of coefficients, in-place from its coefficients given in the Newton basis for the roots r_0 r_1 ldots r_n-2 to the standard monomial basis. In other words, this evaluates c_0 + c_1(x-r_0) + c_2(x-r_0)(x-r_1) + ldots + c_n-1(x-r_0)(x-r_1)cdots(x-r_n-2) where c_i are the input coefficients given by p.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = 3x*y^2 + (x + 1)*y + 3\n3*x*y^2 + (x + 1)*y + 3\n\njulia> g = deepcopy(f)\n3*x*y^2 + (x + 1)*y + 3\n\njulia> roots = [R(1), R(2), R(3)]\n3-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:\n 1\n 2\n 3\n\njulia> monomial_to_newton!(g.coeffs, roots)\n\njulia> newton_to_monomial!(g.coeffs, roots)","category":"page"},{"location":"AbstractAlgebra/polynomial/#Roots","page":"Univariate polynomial functionality","title":"Roots","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"roots(f::PolyRingElem)\nroots(R::Field, f::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#roots-Tuple{PolyRingElem}","page":"Univariate polynomial functionality","title":"roots","text":"roots(f::PolyRingElem)\n\nReturns the roots of the polynomial f in the base ring of f as an array.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#roots-Tuple{Field, PolyRingElem}","page":"Univariate polynomial functionality","title":"roots","text":"roots(R::Field, f::PolyRingElem)\n\nReturns the roots of the polynomial f in the field R as an array.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/#Interpolation","page":"Univariate polynomial functionality","title":"Interpolation","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"interpolate{T <: RingElem}(::PolyRing, ::Vector{T}, ::Vector{T})","category":"page"},{"location":"AbstractAlgebra/polynomial/#interpolate-Union{Tuple{T}, Tuple{PolyRing, Vector{T}, Vector{T}}} where T<:RingElem","page":"Univariate polynomial functionality","title":"interpolate","text":"interpolate(S::PolyRing, x::Vector{T}, y::Vector{T}) where T <: RingElement\n\nGiven two arrays of values xs and ys of the same length n, find the polynomial f in the polynomial ring R of length at most n such that f has the value ys at the points xs. The values in the arrays xs and ys must belong to the base ring of the polynomial ring R. If no such polynomial exists, an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> xs = [R(1), R(2), R(3), R(4)]\n4-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:\n 1\n 2\n 3\n 4\n\njulia> ys = [R(1), R(4), R(9), R(16)]\n4-element Vector{AbstractAlgebra.Generic.Poly{BigInt}}:\n 1\n 4\n 9\n 16\n\njulia> f = interpolate(S, xs, ys)\ny^2\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Power-sums","page":"Univariate polynomial functionality","title":"Power sums","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"polynomial_to_power_sums(::PolyRingElem{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/polynomial/#polynomial_to_power_sums-Union{Tuple{PolyRingElem{T}}, Tuple{T}} where T<:RingElem","page":"Univariate polynomial functionality","title":"polynomial_to_power_sums","text":"polynomial_to_power_sums(f::PolyRingElem{T}, n::Int=degree(f)) where T <: RingElement -> Vector{T}\n\nUses Newton (or Newton-Girard) formulas to compute the first n sums of powers of the roots of f from the coefficients of f, starting with the sum of (first powers of) the roots. The input polynomial must be monic, at least degree 1 and have nonzero constant coefficient.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"power_sums_to_polynomial(::Vector{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/polynomial/#power_sums_to_polynomial-Union{Tuple{Vector{T}}, Tuple{T}} where T<:RingElem","page":"Univariate polynomial functionality","title":"power_sums_to_polynomial","text":"power_sums_to_polynomial(P::Vector{T};\n parent::AbstractAlgebra.PolyRing{T}=\n\nAbstractAlgebra.PolyRing(parent(P[1])) where T <: RingElement -> PolyRingElem{T}\n\nUses the Newton (or Newton-Girard) identities to obtain the polynomial with given sums of powers of roots. The list must be nonempty and contain degree(f) entries where f is the polynomial to be recovered. The list must start with the sum of first powers of the roots.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> f = x^4 - 2*x^3 + 10*x^2 + 7*x - 5\nx^4 - 2*x^3 + 10*x^2 + 7*x - 5\n\njulia> V = polynomial_to_power_sums(f)\n4-element Vector{BigInt}:\n 2\n -16\n -73\n 20\n\njulia> power_sums_to_polynomial(V)\nx^4 - 2*x^3 + 10*x^2 + 7*x - 5","category":"page"},{"location":"AbstractAlgebra/polynomial/#Special-functions","page":"Univariate polynomial functionality","title":"Special functions","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"The following special functions can be computed for any polynomial ring. Typically one uses the generator x of a polynomial ring to get the respective special polynomials expressed in terms of that generator.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"chebyshev_t(::Int, ::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#chebyshev_t-Tuple{Int64, PolyRingElem}","page":"Univariate polynomial functionality","title":"chebyshev_t","text":"chebyshev_t(n::Int, x::PolyRingElem)\n\nReturn the Chebyshev polynomial of the first kind T_n(x), defined by T_n(x) = cos(n cos^-1(x)).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"chebyshev_u(::Int, ::PolyRingElem)","category":"page"},{"location":"AbstractAlgebra/polynomial/#chebyshev_u-Tuple{Int64, PolyRingElem}","page":"Univariate polynomial functionality","title":"chebyshev_u","text":"chebyshev_u(n::Int, x::PolyRingElem)\n\nReturn the Chebyshev polynomial of the first kind U_n(x), defined by (n+1) U_n(x) = T_n+1(x).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over univariate polynomial ring, y)\n\njulia> f = chebyshev_t(20, y)\n524288*y^20 - 2621440*y^18 + 5570560*y^16 - 6553600*y^14 + 4659200*y^12 - 2050048*y^10 + 549120*y^8 - 84480*y^6 + 6600*y^4 - 200*y^2 + 1\n\njulia> g = chebyshev_u(15, y)\n32768*y^15 - 114688*y^13 + 159744*y^11 - 112640*y^9 + 42240*y^7 - 8064*y^5 + 672*y^3 - 16*y\n","category":"page"},{"location":"AbstractAlgebra/polynomial/#Random-generation","page":"Univariate polynomial functionality","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"One may generate random polynomials with degrees in a given range. Additional parameters are used to construct coefficients as elements of the coefficient ring.","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"rand(R::PolyRing, deg_range::UnitRange{Int}, v...)\nrand(R::PolyRing, deg::Int, v...)","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"R, x = polynomial_ring(ZZ, \"x\")\nf = rand(R, -1:3, -10:10)\n\nS, y = polynomial_ring(GF(7), \"y\")\ng = rand(S, 2:2)\n\nU, z = polynomial_ring(R, \"z\")\nh = rand(U, 3:3, -1:2, -10:10)","category":"page"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"DocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/abelian/introduction/#AbelianGroupLink","page":"Abelian Groups","title":"Abelian Groups","text":"","category":"section"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"Here we describe the interface to abelian groups in Hecke.","category":"page"},{"location":"Hecke/abelian/introduction/#Introduction","page":"Abelian Groups","title":"Introduction","text":"","category":"section"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"Within Hecke, abelian groups are of generic abstract type GrpAb which does not have to be finitely generated, mathbb Qmathbb Z is an example of a more general abelian group. Having said that, most of the functionality is restricted to abelian groups that are finitely presented as mathbb Z-modules.","category":"page"},{"location":"Hecke/abelian/introduction/#Basic-Creation","page":"Abelian Groups","title":"Basic Creation","text":"","category":"section"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"Finitely presented (as mathbb Z-modules) abelian groups are of type GrpAbFinGen with elements of type GrpAbFinGenElem. The creation is mostly via a relation matrix M = (m_ij) for 1le ile n and 1le jle m. This creates a group with m generators e_j and relations","category":"page"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":" sum_i=1^n m_ij e_j = 0","category":"page"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"abelian_group(M::ZZMatrix)\nabelian_group(M::Matrix{ZZRingElem})\nabelian_group(M::Matrix{Integer})","category":"page"},{"location":"Hecke/abelian/introduction/#abelian_group-Tuple{ZZMatrix}","page":"Abelian Groups","title":"abelian_group","text":"abelian_group(::Type{T} = GrpAbFinGen, M::ZZMatrix) -> GrpAbFinGen\n\nCreates the abelian group with relation matrix M. That is, the group will have ncols(M) generators and each row of M describes one relation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#abelian_group-Tuple{Matrix{ZZRingElem}}","page":"Abelian Groups","title":"abelian_group","text":"abelian_group(::Type{T} = GrpAbFinGen, M::AbstractMatrix{<:IntegerUnion})\n\nCreates the abelian group with relation matrix M. That is, the group will have ncols(M) generators and each row of M describes one relation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#abelian_group-Tuple{Matrix{Integer}}","page":"Abelian Groups","title":"abelian_group","text":"abelian_group(::Type{T} = GrpAbFinGen, M::AbstractMatrix{<:IntegerUnion})\n\nCreates the abelian group with relation matrix M. That is, the group will have ncols(M) generators and each row of M describes one relation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"Alternatively, there are shortcuts to create products of cyclic groups:","category":"page"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"abelian_group(M::Vector{Union{ZZRingElem, Integer}})","category":"page"},{"location":"Hecke/abelian/introduction/#abelian_group-Tuple{Vector{Union{Integer, ZZRingElem}}}","page":"Abelian Groups","title":"abelian_group","text":"abelian_group(::Type{T} = GrpAbFinGen, M::AbstractVector{<:IntegerUnion}) -> GrpAbFinGen\nabelian_group(::Type{T} = GrpAbFinGen, M::IntegerUnion...) -> GrpAbFinGen\n\nCreates the direct product of the cyclic groups mathbfZm_i, where m_i is the ith entry of M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"using Hecke # hide\nG = abelian_group(2, 2, 6)","category":"page"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"or even","category":"page"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"free_abelian_group(::Int)\nabelian_groups(n::Int)","category":"page"},{"location":"Hecke/abelian/introduction/#free_abelian_group-Tuple{Int64}","page":"Abelian Groups","title":"free_abelian_group","text":"free_abelian_group(::Type{T} = GrpAbFinGen, n::Int) -> GrpAbFinGen\n\nCreates the free abelian group of rank n.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#abelian_groups-Tuple{Int64}","page":"Abelian Groups","title":"abelian_groups","text":"abelian_groups(n::Int) -> Vector{GrpAbFinGen}\n\nGiven a positive integer n, return a list of all abelian groups of order n.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"using Hecke # hide\nabelian_groups(8)","category":"page"},{"location":"Hecke/abelian/introduction/#Invariants","page":"Abelian Groups","title":"Invariants","text":"","category":"section"},{"location":"Hecke/abelian/introduction/","page":"Abelian Groups","title":"Abelian Groups","text":"is_snf(A::GrpAbFinGen)\nngens(A::GrpAbFinGen)\nnrels(G::GrpAbFinGen)\nrels(A::GrpAbFinGen)\nisfinite(A::GrpAbFinGen)\nis_infinite(A::GrpAbFinGen)\nrank(A::GrpAbFinGen)\norder(A::GrpAbFinGen)\nexponent(A::GrpAbFinGen)\nistrivial(A::GrpAbFinGen)\nis_torsion(G::GrpAbFinGen)\nis_cyclic(G::GrpAbFinGen)\nelementary_divisors(G::GrpAbFinGen)","category":"page"},{"location":"Hecke/abelian/introduction/#is_snf-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"is_snf","text":"is_snf(G::GrpAbFinGen) -> Bool\n\nReturn whether the current relation matrix of the group G is in Smith normal form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#ngens-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"ngens","text":"ngens(G::GrpAbFinGen) -> Int\n\nReturn the number of generators of G in the current representation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#nrels-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"nrels","text":"nrels(G::GrpAbFinGen) -> Int\n\nReturn the number of relations of G in the current representation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#rels-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"rels","text":"rels(A::GrpAbFinGen) -> ZZMatrix\n\nReturn the currently used relations of G as a single matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#isfinite-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"isfinite","text":"isfinite(A::GrpAbFinGen) -> Bool\n\nReturn whether A is finite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#is_infinite-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"is_infinite","text":"is_infinite(x::Any) -> Bool\n\nTests whether x is infinite, by returning !isfinite(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#rank-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"rank","text":"rank(A::GrpAbFinGen) -> Int\n\nReturn the rank of A, that is, the dimension of the mathbfQ-vectorspace A otimes_mathbf Z mathbf Q.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#order-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"order","text":"order(A::GrpAbFinGen) -> ZZRingElem\n\nReturn the order of A. It is assumed that A is finite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#exponent-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"exponent","text":"exponent(A::GrpAbFinGen) -> ZZRingElem\n\nReturn the exponent of A. It is assumed that A is finite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#istrivial-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"istrivial","text":"istrivial(A::GrpAbFinGen) -> Bool\n\nReturn whether A is the trivial group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#is_torsion-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"is_torsion","text":"is_torsion(G::GrpAbFinGen) -> Bool\n\nReturn whether G is a torsion group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#is_cyclic-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"is_cyclic","text":"is_cyclic(G::GrpAbFinGen) -> Bool\n\nReturn whether G is cyclic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/abelian/introduction/#elementary_divisors-Tuple{GrpAbFinGen}","page":"Abelian Groups","title":"elementary_divisors","text":"elementary_divisors(G::GrpAbFinGen) -> Vector{ZZRingElem}\n\nGiven G, return the elementary divisors of G, that is, the unique positive integers e_1dotsce_k with e_i mid e_i + 1 and G cong mathbfZe_1mathbfZ times dotsb times mathbfZe_kmathbfZ.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Lattice-with-isometry","page":"Lattice with isometry","title":"Lattice with isometry","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"We call lattice with isometry any pair (L f) consisting of an integer lattice L together with an isometry f in O(L). We refer to the section about integer lattices of the documentation for new users.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"In Oscar, such a pair is encoded in the type called ZZLatWithIsom:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"ZZLatWithIsom","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#ZZLatWithIsom","page":"Lattice with isometry","title":"ZZLatWithIsom","text":"ZZLatWithIsom\n\nA container type for pairs (L, f) consisting on an integer lattice L of type ZZLat and an isometry f given as a QQMatrix representing the action on a given basis of L.\n\nWe store the ambient space V of L together with an isometry f_ambient inducing f on L seen as a pair (V f_ambient) of type QuadSpaceWithIsom. We moreover store the order n of f, which can be finite or infinite.\n\nTo construct an object of type ZZLatWithIsom, see the following examples:\n\nExamples\n\nOne first way to construct such object, is by entering directly the lattice with an isometry. The isometry can be a honnest isometry of the lattice, or it can be an isometry of the ambient space preserving the lattice. Depending on this choice, one should enter the appropriate boolean value ambient_representation. This direct construction is done through the constructors integer_lattice_with_isometry.\n\njulia> L = root_lattice(:E, 6);\n\njulia> f = matrix(QQ, 6, 6, [ 1 2 3 2 1 1;\n -1 -2 -2 -2 -1 -1; \n 0 1 0 0 0 0; \n 1 0 0 0 0 0;\n -1 -1 -1 0 0 -1;\n 0 0 1 1 0 1]);\n\njulia> Lf = integer_lattice_with_isometry(L, f, ambient_representation = false)\nInteger lattice of rank 6 and degree 6\n with isometry of finite order 8\n given by\n [ 1 2 3 2 1 1]\n [-1 -2 -2 -2 -1 -1]\n [ 0 1 0 0 0 0]\n [ 1 0 0 0 0 0]\n [-1 -1 -1 0 0 -1]\n [ 0 0 1 1 0 1]\n\njulia> B = matrix(QQ,1,6, [1 2 3 1 -1 3]);\n\njulia> I = lattice_in_same_ambient_space(L, B); # This is the invariant sublattice L^f\n\njulia> If = integer_lattice_with_isometry(I, ambient_isometry(Lf))\nInteger lattice of rank 1 and degree 6\n with isometry of finite order 1\n given by\n [1]\n\njulia> integer_lattice_with_isometry(I, neg=true)\nInteger lattice of rank 1 and degree 6\n with isometry of finite order 2\n given by\n [-1]\n\nAnother way to construct such objects is to see them as sub-objects of their ambient space, of type QuadSpaceWithIsom. Through the constructors lattice and lattice_in_same_ambient_space, one can then construct lattices with isometry for free, in a given space, as long as the module they define is preserved by the fixed isometry of the ambient space.\n\nExamples\n\njulia> G = matrix(QQ, 6, 6 , [ 3 1 -1 1 0 0;\n 1 3 1 1 1 1;\n -1 1 3 0 0 1;\n 1 1 0 4 2 2;\n 0 1 0 2 4 2;\n 0 1 1 2 2 4]);\n\njulia> V = quadratic_space(QQ, G);\n\njulia> f = matrix(QQ, 6, 6, [ 1 0 0 0 0 0\n 0 0 -1 0 0 0\n -1 1 -1 0 0 0\n 0 0 0 1 0 -1\n 0 0 0 0 0 -1\n 0 0 0 0 1 -1]);\n\njulia> Vf = quadratic_space_with_isometry(V, f);\n\njulia> Lf = lattice(Vf)\nInteger lattice of rank 6 and degree 6\n with isometry of finite order 3\n given by\n [ 1 0 0 0 0 0]\n [ 0 0 -1 0 0 0]\n [-1 1 -1 0 0 0]\n [ 0 0 0 1 0 -1]\n [ 0 0 0 0 0 -1]\n [ 0 0 0 0 1 -1]\n\njulia> B = matrix(QQ, 4, 6, [1 0 3 0 0 0;\n 0 1 1 0 0 0;\n 0 0 0 0 1 0;\n 0 0 0 0 0 1]);\n\njulia> Cf = lattice(Vf, B) # coinvariant sublattice L_f\nInteger lattice of rank 4 and degree 6\n with isometry of finite order 3\n given by\n [-2 3 0 0]\n [-1 1 0 0]\n [ 0 0 0 -1]\n [ 0 0 1 -1]\n\njulia> Cf2 = lattice_in_same_ambient_space(Lf, B)\nInteger lattice of rank 4 and degree 6\n with isometry of finite order 3\n given by\n [-2 3 0 0]\n [-1 1 0 0]\n [ 0 0 0 -1]\n [ 0 0 1 -1]\n\njulia> Cf == Cf2\ntrue\n\nThe last equality of the last example shows why we care about \"ambient context\": the two pairs of lattice with isometry Cf and Cf2 are basically the same mathematical objects. Indeed, they lie in the same space, defines the same module and their respective isometries are induced by the same isometry of the ambient space. As for regular ZZLat, as soon as the lattices are in the same ambient space, we can compare them as mathbb Z-modules, endowed with an isometry.\n\n\n\n\n\n","category":"type"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"and it is seen as a quadruple (Vf L f n) where Vf = (V f_a) consists of the ambient rational quadratic space V of L and an isometry f_a of V preserving L and inducing f on L. The integer n is the order of f, which is a divisor of the order of the isometry f_ain O(V).","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Given a lattice with isometry (L f), we provide the following accessors to the elements of the previously described quadruple:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"ambient_isometry(::ZZLatWithIsom)\nambient_space(::ZZLatWithIsom)\nisometry(::ZZLatWithIsom)\nlattice(::ZZLatWithIsom)\norder_of_isometry(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#ambient_isometry-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"ambient_isometry","text":"ambient_isometry(Lf::ZZLatWithIsom) -> QQMatrix\n\nGiven a lattice with isometry (L f), return an isometry of the ambient space of L inducing f on L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> ambient_isometry(Lf)\n[-1 0 0 0 0]\n[ 0 -1 0 0 0]\n[ 0 0 -1 0 0]\n[ 0 0 0 -1 0]\n[ 0 0 0 0 -1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#ambient_space-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"ambient_space","text":"ambient_space(Lf::ZZLatWithIsom) -> QuadSpaceWithIsom\n\nGiven a lattice with isometry (L f), return the pair (V g) where V is the ambient quadratic space of L and g is an isometry of V inducing f on L.\n\nNote that g might not be unique and we fix such a global isometry together with V into a container type QuadSpaceWithIsom.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> Vf = ambient_space(Lf)\nQuadratic space of dimension 5\n with isometry of finite order 2\n given by\n [-1 0 0 0 0]\n [ 0 -1 0 0 0]\n [ 0 0 -1 0 0]\n [ 0 0 0 -1 0]\n [ 0 0 0 0 -1]\n\njulia> typeof(Vf)\nQuadSpaceWithIsom\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#isometry-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"isometry","text":"isometry(Lf::ZZLatWithIsom) -> QQMatrix\n\nGiven a lattice with isometry (L f), return the underlying isometry f.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> isometry(Lf)\n[-1 0 0 0 0]\n[ 0 -1 0 0 0]\n[ 0 0 -1 0 0]\n[ 0 0 0 -1 0]\n[ 0 0 0 0 -1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lattice-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"lattice","text":"lattice(Lf::ZZLatWithIsom) -> ZZLat\n\nGiven a lattice with isometry (L f), return the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> lattice(Lf) === L\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#order_of_isometry-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"order_of_isometry","text":"order_of_isometry(Lf::ZZLatWithIsom) -> IntExt\n\nGiven a lattice with isometry (L f), return the order of the underlying isometry f.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> order_of_isometry(Lf) == 2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Note that for some computations, it is more convenient to work either with the isometry of the lattice itself, or with the fixed isometry of the ambient quadratic space inducing it on the lattice.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Constructor","page":"Lattice with isometry","title":"Constructor","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"We provide two ways to construct a pair Lf = (Lf) consisting of an integer lattice endowed with an isometry. One way to construct an object of type ZZLatWithIsom is through the methods integer_lattice_with_isometry. These two methods do not require as input an ambient quadratic space with isometry.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"integer_lattice_with_isometry(::ZZLat, ::QQMatrix)\ninteger_lattice_with_isometry(::ZZLat)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#integer_lattice_with_isometry-Tuple{ZZLat, QQMatrix}","page":"Lattice with isometry","title":"integer_lattice_with_isometry","text":"integer_lattice_with_isometry(L::ZZLat, f::QQMatrix; check::Bool = true,\n ambient_representation = true)\n\t\t\t -> ZZLatWithIsom\n\nGiven a mathbb Z-lattice L and a matrix f, if f defines an isometry of L of order n, return the corresponding lattice with isometry pair (L f).\n\nIf ambient_representation is set to true, f is consider as an isometry of the ambient space of L and the induced isometry on L is automatically computed. Otherwise, an isometry of the ambient space of L is constructed, setting the identity on the complement of the rational span of L if it is not of full rank.\n\nExamples\n\nThe way we construct the lattice can have an influence on the isometry of the ambient space we store. Indeed, if one mentions an isometry of the lattice, this isometry will be extended by the identity on the orthogonal complement of the rational span of the lattice. In the following example, Lf and Lf2 are the same object, but the isometry of their ambient space stored are different (one has order 2, the other one is the identity).\n\njulia> B = matrix(QQ, 3, 5, [1 0 0 0 0;\n 0 0 1 0 1;\n 0 0 0 1 0]);\n\njulia> G = matrix(QQ, 5, 5, [ 2 -1 0 0 0;\n -1 2 -1 0 0;\n 0 -1 2 -1 0;\n 0 0 -1 2 -1;\n 0 0 0 -1 2]);\n\njulia> L = integer_lattice(B; gram = G);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 3 and degree 5\n with isometry of finite order 1\n given by\n [1 0 0]\n [0 1 0]\n [0 0 1]\n\njulia> ambient_isometry(Lf)\n[ 1 0 0 0 0]\n[-1 -1 -1 -1 -1]\n[ 0 0 0 0 1]\n[ 0 0 0 1 0]\n[ 0 0 1 0 0]\n\njulia> Lf2 = integer_lattice_with_isometry(L, isometry(Lf); ambient_representation=false)\nInteger lattice of rank 3 and degree 5\n with isometry of finite order 1\n given by\n [1 0 0]\n [0 1 0]\n [0 0 1]\n\njulia> ambient_isometry(Lf2)\n[1 0 0 0 0]\n[0 1 0 0 0]\n[0 0 1 0 0]\n[0 0 0 1 0]\n[0 0 0 0 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#integer_lattice_with_isometry-Tuple{ZZLat}","page":"Lattice with isometry","title":"integer_lattice_with_isometry","text":"integer_lattice_with_isometry(L::ZZLat; neg::Bool = false) -> ZZLatWithIsom\n\nGiven a mathbb Z-lattice L return the lattice with isometry pair (L f), where f corresponds to the identity mapping of L.\n\nIf neg is set to true, then the isometry f is negative the identity of L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [-1 0 0 0 0]\n [ 0 -1 0 0 0]\n [ 0 0 -1 0 0]\n [ 0 0 0 -1 0]\n [ 0 0 0 0 -1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"By default, the first constructor will always check whether the matrix defines an isometry of the lattice, or its ambient space. We recommend not to disable this parameter to avoid any further issues. Note that as in the case of quadratic spaces with isometry, both isometries of integer lattices of finite order and infinite order are supported.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Another way of constructing such lattices with isometry is by fixing an ambient quadratic space with isometry, of type QuadSpaceWithIsom, and specifying a basis for an integral lattice in that space. If this lattice is preserved by the fixed isometry of the quadratic space considered, then we endow it with the induced action.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"lattice(::QuadSpaceWithIsom)\nlattice(::QuadSpaceWithIsom, ::MatElem{ <:RationalUnion})\nlattice_in_same_ambient_space(::ZZLatWithIsom, ::MatElem)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lattice-Tuple{QuadSpaceWithIsom}","page":"Lattice with isometry","title":"lattice","text":"lattice(Vf::QuadSpaceWithIsom) -> ZZLatWithIsom\n\nGiven a quadratic space with isometry (V f), return the full rank lattice L in V with basis the standard basis, together with the induced action of f on L.\n\nExamples\n\njulia> V = quadratic_space(QQ, QQ[2 -1; -1 2])\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 2 -1]\n[-1 2]\n\njulia> f = matrix(QQ, 2, 2, [1 1; 0 -1])\n[1 1]\n[0 -1]\n\njulia> Vf = quadratic_space_with_isometry(V, f)\nQuadratic space of dimension 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\njulia> Lf = lattice(Vf)\nInteger lattice of rank 2 and degree 2\n with isometry of finite order 2\n given by\n [1 1]\n [0 -1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lattice-Tuple{QuadSpaceWithIsom, MatElem{<:Union{Integer, QQFieldElem, ZZRingElem, Rational}}}","page":"Lattice with isometry","title":"lattice","text":"lattice(Vf::QuadSpaceWithIsom, B::MatElem{<:RationalUnion};\n isbasis::Bool = true, check::Bool = true)\n -> ZZLatWithIsom\n\nGiven a quadratic space with isometry (V f) and a matrix B generating a lattice L in V, if L is preserved under the action of f, return the lattice with isometry (L f_L) where f_L is induced by the action of f on L.\n\nExamples\n\njulia> V = quadratic_space(QQ, QQ[ 2 -1 0 0 0;\n -1 2 -1 0 0;\n 0 -1 2 -1 0;\n 0 0 -1 2 -1;\n 0 0 0 -1 2]);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Vf = quadratic_space_with_isometry(V, f);\n\njulia> B = matrix(QQ,3,5,[1 0 0 0 0;\n 0 0 1 0 1;\n 0 0 0 1 0])\n[1 0 0 0 0]\n[0 0 1 0 1]\n[0 0 0 1 0]\n\njulia> lattice(Vf, B)\nInteger lattice of rank 3 and degree 5\n with isometry of finite order 1\n given by\n [1 0 0]\n [0 1 0]\n [0 0 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lattice_in_same_ambient_space-Tuple{ZZLatWithIsom, MatElem}","page":"Lattice with isometry","title":"lattice_in_same_ambient_space","text":"lattice_in_same_ambient_space(L::ZZLatWithIsom, B::MatElem;\n check::Bool = true)\n -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f) and a matrix B whose rows define a free system of vectors in the ambient space V of L, if the lattice M in V defined by B is preserved under the fixed isometry g of V inducing f on L, return the lattice with isometry pair (M f_M) where f_M is induced by the action of g on M.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> B = matrix(QQ,3,5,[1 0 0 0 0;\n 0 0 1 0 1;\n 0 0 0 1 0])\n[1 0 0 0 0]\n[0 0 1 0 1]\n[0 0 0 1 0]\n\njulia> I = lattice_in_same_ambient_space(Lf, B)\nInteger lattice of rank 3 and degree 5\n with isometry of finite order 1\n given by\n [1 0 0]\n [0 1 0]\n [0 0 1]\n\njulia> ambient_space(I) === ambient_space(Lf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Attributes-and-first-operations","page":"Lattice with isometry","title":"Attributes and first operations","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Given a lattice with isometry Lf = (L f), one can have access most of the attributes of L and f by calling the similar function for the pair. For instance, in order to know the genus of L, one can simply call genus(Lf). Here is a list of what are the current accessible attributes:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"basis_matrix(::ZZLatWithIsom)\ncharacteristic_polynomial(::ZZLatWithIsom)\ndegree(::ZZLatWithIsom)\ndet(::ZZLatWithIsom)\ndiscriminant(::ZZLatWithIsom)\ngenus(::ZZLatWithIsom)\ngram_matrix(::ZZLatWithIsom)\nis_definite(::ZZLatWithIsom)\nis_even(::ZZLatWithIsom)\nis_integral(::ZZLatWithIsom)\nis_positive_definite(::ZZLatWithIsom)\nis_negative_definite(::ZZLatWithIsom)\nminimum(::ZZLatWithIsom)\nminimal_polynomial(::ZZLatWithIsom)\nnorm(::ZZLatWithIsom)\nrank(::ZZLatWithIsom)\nrational_span(::ZZLatWithIsom)\nscale(::ZZLatWithIsom)\nsignature_tuple(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#basis_matrix-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"basis_matrix","text":"basis_matrix(Lf::ZZLatWithIsom) -> QQMatrix\n\nGiven a lattice with isometry (L f), return the basis matrix of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ,5,5,[ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0])\n[ 1 0 0 0 0]\n[-1 -1 -1 -1 -1]\n[ 0 0 0 0 1]\n[ 0 0 0 1 0]\n[ 0 0 1 0 0]\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> invariant_lattice(Lf);\n\njulia> I = invariant_lattice(Lf);\n\njulia> basis_matrix(I)\n[1 0 0 0 0]\n[0 0 1 0 1]\n[0 0 0 1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#characteristic_polynomial-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"characteristic_polynomial","text":"characteristic_polynomial(Lf::ZZLatWithIsom) -> QQPolyRingElem\n\nGiven a lattice with isometry (L f), return the characteristic polynomial of the underlying isometry f.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> factor(characteristic_polynomial(Lf))\n1 * (x + 1)^5\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#degree-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"degree","text":"degree(Lf::ZZLatWithIsom) -> Int\n\nGiven a lattice with isometry (L f), return the degree of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> degree(Lf)\n5\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#det-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"det","text":"det(Lf::ZZLatWithIsom) -> QQFieldElem\n\nGiven a lattice with isometry (L f), return the determinant of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> det(Lf)\n6\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#discriminant-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"discriminant","text":"discriminant(Lf::ZZLatWithIsom) -> QQFieldElem\n\nGiven a lattice with isometry (L f), return the discriminant of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> discriminant(Lf) == det(Lf) == 6\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#genus-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"genus","text":"genus(Lf::ZZLatWithIsom) -> ZZGenus\n\nGiven a lattice with isometry (L f), return the genus of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> genus(Lf)\nGenus symbol for integer lattices\nSignatures: (5, 0, 0)\nLocal symbols:\n Local genus symbol at 2: 1^-4 2^1_7\n Local genus symbol at 3: 1^-4 3^1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#gram_matrix-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"gram_matrix","text":"gram_matrix(Lf::ZZLatWithIsom) -> QQMatrix\n\nGiven a lattice with isometry (L f), return the gram matrix of the underlying lattice L with respect to its basis matrix.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> gram_matrix(Lf)\n[ 2 -1 0 0 0]\n[-1 2 -1 0 0]\n[ 0 -1 2 -1 0]\n[ 0 0 -1 2 -1]\n[ 0 0 0 -1 2]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_definite-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"is_definite","text":"is_definite(Lf::ZZLatWithIsom) -> Bool\n\nGiven a lattice with isometry (L f), return whether the underlying lattice L is definite.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_definite(Lf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_even-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"is_even","text":"is_even(Lf::ZZLatWithIsom) -> Bool\n\nGiven a lattice with isometry (L f), return whether the underlying lattice L is even.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_even(Lf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_integral-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"is_integral","text":"is_integral(Lf::ZZLatWithIsom) -> Bool\n\nGiven a lattice with isometry (L f), return whether the underlying lattice L is integral.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_integral(Lf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_positive_definite-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"is_positive_definite","text":"is_positive_definite(Lf::ZZLatWithIsom) -> Bool\n\nGiven a lattice with isometry (L f), return whether the underlying lattice L is positive definite.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_positive_definite(Lf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_negative_definite-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"is_negative_definite","text":"is_negative_definite(Lf::ZZLatWithIsom) -> Bool\n\nGiven a lattice with isometry (L f), return whether the underlying lattice L is negative definite.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_negative_definite(Lf)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#minimum-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"minimum","text":"minimum(Lf::ZZLatWithIsom) -> QQFieldElem\n\nGiven a positive definite lattice with isometry (L f), return the minimum of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> minimum(Lf)\n2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#minimal_polynomial-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"minimal_polynomial","text":"minimal_polynomial(Lf::ZZLatWithIsom) -> QQPolyRingElem\n\nGiven a lattice with isometry (L f), return the minimal polynomial of the underlying isometry f.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> minimal_polynomial(Lf)\nx + 1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#norm-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"norm","text":"norm(Lf::ZZLatWithIsom) -> QQFieldElem\n\nGiven a lattice with isometry (L f), return the norm of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> norm(Lf)\n2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#rank-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"rank","text":"rank(Lf::ZZLatWithIsom) -> Integer\n\nGiven a lattice with isometry (L f), return the rank of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L; neg=true);\n\njulia> rank(Lf)\n5\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#rational_span-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"rational_span","text":"rational_span(Lf::ZZLatWithIsom) -> QuadSpaceWithIsom\n\nGiven a lattice with isometry (L f), return the rational span L otimes mathbbQ of the underlying lattice L together with the underlying isometry of L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> Vf = rational_span(Lf)\nQuadratic space of dimension 5\n with isometry of finite order 1\n given by\n [1 0 0 0 0]\n [0 1 0 0 0]\n [0 0 1 0 0]\n [0 0 0 1 0]\n [0 0 0 0 1]\n\njulia> typeof(Vf)\nQuadSpaceWithIsom\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#scale-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"scale","text":"scale(Lf::ZZLatWithIsom) -> QQFieldElem\n\nGiven a lattice with isometry (L f), return the scale of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> scale(Lf)\n1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#signature_tuple-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"signature_tuple","text":"signature_tuple(Lf::ZZLatWithIsom) -> Tuple{Int, Int, Int}\n\nGiven a lattice with isometry (L f), return the signature tuple of the underlying lattice L.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> signature_tuple(Lf)\n(5, 0, 0)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Similarly, some basic operations on mathbb Z-lattices are available for lattices with isometry.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Base.:^(::ZZLatWithIsom, ::Int)\nbiproduct(::Vector{ZZLatWithIsom})\ndirect_product(::Vector{ZZLatWithIsom})\ndirect_sum(::Vector{ZZLatWithIsom})\ndual(::ZZLatWithIsom)\nlll(::ZZLatWithIsom)\nrescale(::ZZLatWithIsom, ::RationalUnion)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#^-Tuple{ZZLatWithIsom, Int64}","page":"Lattice with isometry","title":"^","text":"^(Lf::ZZLatWithIsom, n::Int) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f) and an integer n, return the pair (L f^n).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lf^0\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 1\n given by\n [1 0 0 0 0]\n [0 1 0 0 0]\n [0 0 1 0 0]\n [0 0 0 1 0]\n [0 0 0 0 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#biproduct-Tuple{Vector{ZZLatWithIsom}}","page":"Lattice with isometry","title":"biproduct","text":"biproduct(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor},\n Vector{AbstractSpaceMor}\nbiproduct(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor},\n Vector{AbstractSpaceMor}\n\nGiven a collection of lattices with isometries (L_1 f_1) ldots (L_n f_n), return the lattice with isometry (L f) together with the injections L_i to L and the projections L to L_i, where L is the biproduct L = L_1 oplus ldots oplus L_n and f is the isometry of L induced by the diagonal actions of the f_i's.\n\nFor objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (L f) as a direct sum with the injections L_i to L, one should call direct_sum(x). If one wants to obtain (L f) as a direct product with the projections L to L_i, one should call direct_product(x).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> g = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lg = integer_lattice_with_isometry(L, g)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 5\n given by\n [1 1 1 1 1]\n [0 -1 -1 -1 -1]\n [0 1 0 0 0]\n [0 0 1 0 0]\n [0 0 0 1 0]\n\njulia> Lh, inj, proj = biproduct(Lf, Lg)\n(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 5\nCodomain:\n=========\nQuadratic space of dimension 10, Map with following data\nDomain:\n=======\nQuadratic space of dimension 5\nCodomain:\n=========\nQuadratic space of dimension 10], AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 10\nCodomain:\n=========\nQuadratic space of dimension 5, Map with following data\nDomain:\n=======\nQuadratic space of dimension 10\nCodomain:\n=========\nQuadratic space of dimension 5])\n\njulia> Lh\nInteger lattice of rank 10 and degree 10\n with isometry of finite order 10\n given by\n [ 1 0 0 0 0 0 0 0 0 0]\n [-1 -1 -1 -1 -1 0 0 0 0 0]\n [ 0 0 0 0 1 0 0 0 0 0]\n [ 0 0 0 1 0 0 0 0 0 0]\n [ 0 0 1 0 0 0 0 0 0 0]\n [ 0 0 0 0 0 1 1 1 1 1]\n [ 0 0 0 0 0 0 -1 -1 -1 -1]\n [ 0 0 0 0 0 0 1 0 0 0]\n [ 0 0 0 0 0 0 0 1 0 0]\n [ 0 0 0 0 0 0 0 0 1 0]\n\njulia> matrix(compose(inj[1], proj[1]))\n[1 0 0 0 0]\n[0 1 0 0 0]\n[0 0 1 0 0]\n[0 0 0 1 0]\n[0 0 0 0 1]\n\njulia> matrix(compose(inj[1], proj[2]))\n[0 0 0 0 0]\n[0 0 0 0 0]\n[0 0 0 0 0]\n[0 0 0 0 0]\n[0 0 0 0 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#direct_product-Tuple{Vector{ZZLatWithIsom}}","page":"Lattice with isometry","title":"direct_product","text":"direct_product(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor}\ndirect_product(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor}\n\nGiven a collection of lattices with isometries (L_1 f_1) ldots (L_n f_n), return the lattice with isometry (L f) together with the projections L to L_i, where L is the direct product L = L_1 times ldots times L_n and f is the isometry of L induced by the diagonal actions of the f_i's.\n\nFor objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (L f) as a direct sum with the injections L_i to L, one should call direct_sum(x). If one wants to obtain (L f) as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> g = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lg = integer_lattice_with_isometry(L, g)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 5\n given by\n [1 1 1 1 1]\n [0 -1 -1 -1 -1]\n [0 1 0 0 0]\n [0 0 1 0 0]\n [0 0 0 1 0]\n\njulia> Lh, proj = direct_product(Lf, Lg)\n(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 10\nCodomain:\n=========\nQuadratic space of dimension 5, Map with following data\nDomain:\n=======\nQuadratic space of dimension 10\nCodomain:\n=========\nQuadratic space of dimension 5])\n\njulia> Lh\nInteger lattice of rank 10 and degree 10\n with isometry of finite order 10\n given by\n [ 1 0 0 0 0 0 0 0 0 0]\n [-1 -1 -1 -1 -1 0 0 0 0 0]\n [ 0 0 0 0 1 0 0 0 0 0]\n [ 0 0 0 1 0 0 0 0 0 0]\n [ 0 0 1 0 0 0 0 0 0 0]\n [ 0 0 0 0 0 1 1 1 1 1]\n [ 0 0 0 0 0 0 -1 -1 -1 -1]\n [ 0 0 0 0 0 0 1 0 0 0]\n [ 0 0 0 0 0 0 0 1 0 0]\n [ 0 0 0 0 0 0 0 0 1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#direct_sum-Tuple{Vector{ZZLatWithIsom}}","page":"Lattice with isometry","title":"direct_sum","text":"direct_sum(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor}\ndirect_sum(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,\n Vector{AbstractSpaceMor}\n\nGiven a collection of lattices with isometries (L_1 f_1) ldots (L_n f_n), return the lattice with isometry (L f) together with the injections L_i to L, where L is the direct sum L = L_1 oplus ldots oplus L_n and f is the isometry of L induced by the diagonal actions of the f_i's.\n\nFor objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain (L f) as a direct product with the projections L to L_i, one should call direct_product(x). If one wants to obtain (L f) as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> g = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lg = integer_lattice_with_isometry(L, g)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 5\n given by\n [1 1 1 1 1]\n [0 -1 -1 -1 -1]\n [0 1 0 0 0]\n [0 0 1 0 0]\n [0 0 0 1 0]\n\njulia> Lh, inj = direct_sum(Lf, Lg)\n(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map with following data\nDomain:\n=======\nQuadratic space of dimension 5\nCodomain:\n=========\nQuadratic space of dimension 10, Map with following data\nDomain:\n=======\nQuadratic space of dimension 5\nCodomain:\n=========\nQuadratic space of dimension 10])\n\njulia> Lh\nInteger lattice of rank 10 and degree 10\n with isometry of finite order 10\n given by\n [ 1 0 0 0 0 0 0 0 0 0]\n [-1 -1 -1 -1 -1 0 0 0 0 0]\n [ 0 0 0 0 1 0 0 0 0 0]\n [ 0 0 0 1 0 0 0 0 0 0]\n [ 0 0 1 0 0 0 0 0 0 0]\n [ 0 0 0 0 0 1 1 1 1 1]\n [ 0 0 0 0 0 0 -1 -1 -1 -1]\n [ 0 0 0 0 0 0 1 0 0 0]\n [ 0 0 0 0 0 0 0 1 0 0]\n [ 0 0 0 0 0 0 0 0 1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#dual-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"dual","text":"dual(Lf::ZZLatWithIsom) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f) inside the space (V Phi), such that f is induced by an isometry g of (V Phi), return the lattice with isometry (L^vee h) where L^vee is the dual of L in (V Phi) and h is induced by g.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lfv = dual(Lf)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [1 -1 0 0 0]\n [0 -1 0 0 0]\n [0 -1 0 0 1]\n [0 -1 0 1 0]\n [0 -1 1 0 0]\n\njulia> ambient_space(Lfv) == ambient_space(Lf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lll-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"lll","text":"lll(Lf::ZZLatWithIsom) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f), return the same lattice with isometry with a different basis matrix for L obtained by performing an LLL-reduction on the associated gram matrix of L.\n\nNote that matrix representing the action of f on L changes but the global action on the ambient space of L stays the same.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lf2 = lll(Lf)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 0 0 0 -1]\n [-1 0 0 -1 0]\n [-1 0 -1 0 0]\n [-1 -1 0 0 0]\n\njulia> ambient_space(Lf2) == ambient_space(Lf)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#rescale-Tuple{ZZLatWithIsom, Union{Integer, QQFieldElem, ZZRingElem, Rational}}","page":"Lattice with isometry","title":"rescale","text":"rescale(Lf::ZZLatWithIsom, a::RationalUnion) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f) and a rational number a, return the lattice with isometry (L(a) f).\n\nExamples\n\njulia> L = root_lattice(:A,5)\nInteger lattice of rank 5 and degree 5\nwith gram matrix\n[ 2 -1 0 0 0]\n[-1 2 -1 0 0]\n[ 0 -1 2 -1 0]\n[ 0 0 -1 2 -1]\n[ 0 0 0 -1 2]\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> Lf2 = rescale(Lf, 1//2)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 2\n given by\n [ 1 0 0 0 0]\n [-1 -1 -1 -1 -1]\n [ 0 0 0 0 1]\n [ 0 0 0 1 0]\n [ 0 0 1 0 0]\n\njulia> lattice(Lf2)\nInteger lattice of rank 5 and degree 5\nwith gram matrix\n[ 1 -1//2 0 0 0]\n[-1//2 1 -1//2 0 0]\n[ 0 -1//2 1 -1//2 0]\n[ 0 0 -1//2 1 -1//2]\n[ 0 0 0 -1//2 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Type-for-finite-order-isometries","page":"Lattice with isometry","title":"Type for finite order isometries","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Given a lattice with isometry Lf = (L f) where f is of finite order n, one can compute the type of Lf, which can be seen as an equivalent of the genus used to classified single lattices.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"type(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#type-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"type","text":"type(Lf::ZZLatWithIsom)\n -> Dict{Int, Tuple{ <: Union{ZZGenus, HermGenus}, ZZGenus}}\n\nGiven a lattice with isometry (L f) with f of finite order n, return the type of (L f).\n\nIn this context, the type is defined as follows: for each divisor k of n, the k-type of (L f) is the tuple (H_k A_K) consisting of the genus H_k of the lattice ker(Phi_k(f)) viewed as a hermitian mathbbZzeta_k- lattice (so a mathbbZ-lattice for k= 1, 2) and of the genus A_k of the mathbbZ-lattice ker(f^k-1).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> t = type(Lf);\n\njulia> genus(invariant_lattice(Lf)) == t[1][1]\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Since determining whether two pairs of lattices with isometry are isomorphic is a challenging task, one can perform a coarser comparison by looking at the type. This set of data keeps track of some local and global invariants of the pair (L f) with respect to the action of f on L.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"is_of_type(::ZZLatWithIsom, t::Dict)\nis_of_same_type(::ZZLatWithIsom, ::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_of_type-Tuple{ZZLatWithIsom, Dict}","page":"Lattice with isometry","title":"is_of_type","text":"is_of_type(Lf::ZZLatWithIsom, t::Dict) -> Bool\n\nGiven a lattice with isometry (L f), return whether (L f) is of type t.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> t = type(Lf);\n\njulia> is_of_type(Lf, t)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_of_same_type-Tuple{ZZLatWithIsom, ZZLatWithIsom}","page":"Lattice with isometry","title":"is_of_same_type","text":"is_of_same_type(Lf::ZZLatWithIsom, Mg::ZZLatWithIsom) -> Bool\n\nGiven two lattices with isometry (L f) and (M g), return whether they are of the same type.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> M = coinvariant_lattice(Lf);\n\njulia> is_of_same_type(Lf, M)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Finally, if the minimal polynomial of f is irreducible, then we say that the pair (L f) is of hermitian type. The type of a lattice with isometry of hermitian type is called hermitian (note that the type is only defined for finite order isometries).","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"These namings follow from the fact that, by the trace equivalence, one can associate to the pair (L f) a hermitian lattice over the equation order of f, if it is maximal in the associated number field mathbbQf.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"is_of_hermitian_type(::ZZLatWithIsom)\nis_hermitian(::Dict)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_of_hermitian_type-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"is_of_hermitian_type","text":"is_of_hermitian_type(Lf::ZZLatWithIsom) -> Bool\n\nGiven a lattice with isometry (L f), return whether the minimal polynomial of the underlying isometry f is irreducible.\n\nNote that if (L f) is of hermitian type with f of minimal polynomial chi, then L can be seen as a hermitian lattice over the order mathbbZchi.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f)\nInteger lattice of rank 5 and degree 5\n with isometry of finite order 5\n given by\n [1 1 1 1 1]\n [0 -1 -1 -1 -1]\n [0 1 0 0 0]\n [0 0 1 0 0]\n [0 0 0 1 0]\n\njulia> is_of_hermitian_type(Lf)\nfalse\n\njulia> is_of_hermitian_type(coinvariant_lattice(Lf))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_hermitian-Tuple{Dict}","page":"Lattice with isometry","title":"is_hermitian","text":"is_hermitian(t::Dict) -> Bool\n\nGiven a type t of lattices with isometry, return whether t is hermitian, i.e. whether it defines the type of a hermitian lattice with isometry.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> M = coinvariant_lattice(Lf);\n\njulia> is_hermitian(type(Lf))\nfalse\n\njulia> is_hermitian(type(M))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Hermitian-structure-and-trace-equivalence","page":"Lattice with isometry","title":"Hermitian structure and trace equivalence","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"As mentioned in the previous section, to a lattice with isometry Lf = (L f) such that the minimal polynomial of f is irreducible, one can associate a hermitian lattice mathfrakL over the equation order of f, if it is maximal, for which Lf is the associated trace lattice. Hecke provides the tools to perform the trace equivalence for lattices with isometry of hermitian type.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"hermitian_structure(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#hermitian_structure-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"hermitian_structure","text":"hermitian_structure(Lf::ZZLatWithIsom) -> HermLat\n\nGiven a lattice with isometry (L f) such that the minimal polynomial of the underlying isometry f is irreducible, return the hermitian structure of the underlying lattice L over the equation order of the minimal polynomial of f.\n\nIf it exists, the hermitian structure is stored. For now, we only cover the case where the equation order is maximal (which is always the case when the order is finite, for instance, since the minimal polynomial is cyclotomic).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> M = coinvariant_lattice(Lf)\nInteger lattice of rank 4 and degree 5\n with isometry of finite order 5\n given by\n [-1 -1 -1 -1]\n [ 1 0 0 0]\n [ 0 1 0 0]\n [ 0 0 1 0]\n\njulia> H = hermitian_structure(M)\nHermitian lattice of rank 1 and degree 1\n over relative maximal order of Relative number field of degree 2 over maximal real subfield of cyclotomic field of order 5\n with pseudo-basis \n (1, 1//1 * <1, 1>)\n (z_5, 1//1 * <1, 1>)\n\njulia> res = get_attribute(M, :transfer_data)\nMap of change of scalars\n from quadratic space of dimension 4\n to hermitian space of dimension 1\n\njulia> M2, f2 = trace_lattice_with_isometry(H, res)\n(Integer lattice of rank 4 and degree 4, [-1 -1 -1 -1; 1 0 0 0; 0 1 0 0; 0 0 1 0])\n\njulia> genus(M) == genus(M2) # One class in this genus, so they are isometric\ntrue\n\njulia> f2 == isometry(M)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Discriminant-group","page":"Lattice with isometry","title":"Discriminant group","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Given an integral lattice with isometry Lf = (L f), if one denotes by D_L the discriminant group of L, there exists a natural map picolon O(L) to O(D_L) sending any isometry to its induced action on the discriminant group of L. In general, this map is neither injective nor surjective. If we denote by D_f = pi(f) then pi induces a map between centralizers O(L f)to O(D_L D_f). Again, this induced map is in general neither injective nor surjective, and we denote its image by G_Lf.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"discriminant_group(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#discriminant_group-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"discriminant_group","text":"discriminant_group(Lf::ZZLatWithIsom) -> TorQuadModule, AutomorphismGroupElem\n\nGiven an integral lattice with isometry (L f), return the discriminant group q of the underlying lattice L as well as this image of the underlying isometry f inside O(q).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> qL, qf = discriminant_group(Lf)\n(Finite quadratic module: Z/6 -> Q/2Z, [1])\n\njulia> qL\nFinite quadratic module\n over integer ring\nAbelian group: Z/6\nBilinear value module: Q/Z\nQuadratic value module: Q/2Z\nGram matrix quadratic form: \n[5//6]\n\njulia> qf\nIsometry of Finite quadratic module: Z/6 -> Q/2Z defined by \n[1]\n\njulia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0;\n -1 -1 -1 -1 -1;\n 0 0 0 0 1;\n 0 0 0 1 0;\n 0 0 1 0 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> discriminant_group(Lf)[2]\nIsometry of Finite quadratic module: Z/6 -> Q/2Z defined by \n[5]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"For simple cases as for definite lattices, f being plus-or-minus the identity or if the rank of L is equal to the totient of the order of f (in the finite case), G_Lf can be easily computed. The only other case which can be currently handled is for lattices with isometry of hermitian type following the hermitian Miranda-Morisson theory from Simon Brandhorst, Tommy Hofmann (2023). This has been implemented in this project and it can be indirectly used through the general following method:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"image_centralizer_in_Oq(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#image_centralizer_in_Oq-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"image_centralizer_in_Oq","text":"image_centralizer_in_Oq(Lf::ZZLatWithIsom) -> AutomorphismGroup{TorQuadModule},\n GAPGroupHomomorphism\n\nGiven an integral lattice with isometry (L f), return the image G_L in O(q_L barf) of the centralizer O(L f) of f in O(L). Here q_L denotes the discriminant group of L and barf is the isometry of q_L induced by f.\n\nExamples\n\njulia> L = root_lattice(:A,2);\n\njulia> f = matrix(QQ, 2, 2, [1 1; 0 -1]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> G, _ = image_centralizer_in_Oq(Lf)\n(Group of isometries of Finite quadratic module: Z/3 -> Q/2Z generated by 2 elements, Group homomorphism from\nGroup of isometries of Finite quadratic module: Z/3 -> Q/2Z generated by 2 elements\nto\nGroup of isometries of Finite quadratic module: Z/3 -> Q/2Z generated by 1 elements)\n\njulia> order(G)\n2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"For an implementation of the regular Miranda-Morisson theory, we refer to the function image_in_Oq which actually computes the image of pi in both the definite and the indefinite case.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"We will see later in the section about enumeration of lattices with isometry that one can compute G_Lf in some particular cases arising from equivariant primitive embeddings of lattices with isometries.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Kernel-sublattices","page":"Lattice with isometry","title":"Kernel sublattices","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"As for single integer lattices, it is possible to compute kernel sublattices of some mathbbZ-module homomorphisms. We provide here the possibility to compute ker(p(f)) as a sublattice of L equipped with the induced action of f, where p is a polynomial with rational coefficients.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"kernel_lattice(::ZZLatWithIsom, ::Union{ZZPolyRingElem, QQPolyRingElem})\nkernel_lattice(::ZZLatWithIsom, ::Integer)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#kernel_lattice-Tuple{ZZLatWithIsom, Union{QQPolyRingElem, ZZPolyRingElem}}","page":"Lattice with isometry","title":"kernel_lattice","text":"kernel_lattice(Lf::ZZLatWithIsom, p::Union{fmpz_poly, QQPolyRingElem})\n -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f) and a polynomial p with rational coefficients, return the sublattice M = ker(p(f)) of the underlying lattice L with isometry f, together with the restriction f_mid M.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> Zx,x = ZZ[\"x\"]\n(Univariate polynomial ring in x over ZZ, x)\n\njulia> mf = minimal_polynomial(Lf)\nx^5 - 1\n\njulia> factor(mf)\n1 * (x - 1) * (x^4 + x^3 + x^2 + x + 1)\n\njulia> kernel_lattice(Lf, x-1)\nInteger lattice of rank 1 and degree 5\n with isometry of finite order 1\n given by\n [1]\n\njulia> kernel_lattice(Lf, cyclotomic_polynomial(5))\nInteger lattice of rank 4 and degree 5\n with isometry of finite order 5\n given by\n [-1 -1 -1 -1]\n [ 1 0 0 0]\n [ 0 1 0 0]\n [ 0 0 1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#kernel_lattice-Tuple{ZZLatWithIsom, Integer}","page":"Lattice with isometry","title":"kernel_lattice","text":"kernel_lattice(Lf::ZZLatWithIsom, l::Integer) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f) and an integer l, return the kernel lattice of (L f) associated to the l-th cyclotomic polynomial.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> kernel_lattice(Lf, 5)\nInteger lattice of rank 4 and degree 5\n with isometry of finite order 5\n given by\n [-1 -1 -1 -1]\n [ 1 0 0 0]\n [ 0 1 0 0]\n [ 0 0 1 0]\n\njulia> kernel_lattice(Lf, 1)\nInteger lattice of rank 1 and degree 5\n with isometry of finite order 1\n given by\n [1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Note that such sublattices are by definition primitive in L since L is non-degenerate. As particular kernel sublattices of L, one can also compute the so-called invariant and coinvariant lattices of (L f):","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"coinvariant_lattice(::ZZLatWithIsom)\ninvariant_lattice(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#coinvariant_lattice-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"coinvariant_lattice","text":"coinvariant_lattice(Lf::ZZLatWithIsom) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f), return the coinvariant lattice L_f of (L f) together with the restriction of f to L_f.\n\nThe coinvariant lattice L_f of (L f) is the orthogonal complement in L of the invariant lattice L_f.\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> coinvariant_lattice(Lf)\nInteger lattice of rank 4 and degree 5\n with isometry of finite order 5\n given by\n [-1 -1 -1 -1]\n [ 1 0 0 0]\n [ 0 1 0 0]\n [ 0 0 1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#invariant_lattice-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"invariant_lattice","text":"invariant_lattice(Lf::ZZLatWithIsom) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f), return the invariant lattice L^f of (L f) together with the restriction of f to L^f (which is the identity in this case).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> invariant_lattice(Lf)\nInteger lattice of rank 1 and degree 5\n with isometry of finite order 1\n given by\n [1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"Similarly, we provide the possibility to compute invariant and coinvariant sublattices given an orthogonal representation G in matrix form of a finite group on a given lattice L:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"coinvariant_lattice(::ZZLat, ::MatrixGroup)\ninvariant_lattice(::ZZLat, ::MatrixGroup)\ninvariant_coinvariant_pair(::ZZLat, ::MatrixGroup)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#coinvariant_lattice-Tuple{ZZLat, MatrixGroup}","page":"Lattice with isometry","title":"coinvariant_lattice","text":"coinvariant_lattice(L::ZZLat, G::MatrixGroup;\n ambient_representation::Bool = true)\n -> ZZLat, MatrixGroup\n\nGiven an integer lattice L and a group G of isometries of L in matrix, return the coinvariant sublattice L_G of L, together with the subgroup H of isometries of L_G induced by the action of G.\n\nIf ambient_representation is set to true, the isometries in G and H are seen as isometries of the ambient quadratic space of L preserving L. Otherwise, they are considered as honnest isometries of L.\n\nExamples\n\njulia> L = root_lattice(:A,2);\n\njulia> G = isometry_group(L);\n\njulia> L2, G2 = coinvariant_lattice(L, G)\n(Integer lattice of rank 2 and degree 2, Matrix group of degree 2 over Rational field)\n\njulia> L == L2\ntrue\n\njulia> G == G2\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#invariant_lattice-Tuple{ZZLat, MatrixGroup}","page":"Lattice with isometry","title":"invariant_lattice","text":"invariant_lattice(L::ZZLat, G::MatrixGroup;\n ambient_representation::Bool = true) -> ZZLat\n\nGiven an integer lattice L and a group G of isometries of L in matrix, return the invariant sublattice L^G of L.\n\nIf ambient_representation is set to true, the isometries in G are seen as isometries of the ambient quadratic space of L preserving L. Otherwise, they are considered as honnest isometries of L.\n\nExamples\n\njulia> L = root_lattice(:A,2);\n\njulia> G = isometry_group(L);\n\njulia> invariant_lattice(L, G)\nInteger lattice of rank 0 and degree 2\nwith gram matrix\n0 by 0 empty matrix\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#invariant_coinvariant_pair-Tuple{ZZLat, MatrixGroup}","page":"Lattice with isometry","title":"invariant_coinvariant_pair","text":"invariant_coinvariant_pair(L::ZZLat, G::MatrixGroup;\n ambient_representation::Bool = true)\n -> ZZLat, ZZLat, MatrixGroup\n\nGiven an integer lattice L and a group G of isometries of L in matrix, return the invariant sublattice L^G of L and its coinvariant sublattice L_G together with the subgroup H of isometries of L_G induced by the action of G.\n\nIf ambient_representation is set to true, the isometries in G and H are seen as isometries of the ambient quadratic space of L preserving L. Otherwise, they are considered as honnest isometries of L.\n\nExamples\n\njulia> L = root_lattice(:A,2);\n\njulia> G = isometry_group(L);\n\njulia> Gsub, _ = sub(G, [gens(G)[end]]);\n\njulia> F, C, G2 = invariant_coinvariant_pair(L, Gsub)\n(Integer lattice of rank 1 and degree 2, Integer lattice of rank 1 and degree 2, Matrix group of degree 2 over Rational field)\n\njulia> F\nInteger lattice of rank 1 and degree 2\nwith gram matrix\n[2]\n\njulia> C\nInteger lattice of rank 1 and degree 2\nwith gram matrix\n[6]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Signatures","page":"Lattice with isometry","title":"Signatures","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"We conclude this introduction about standard functionalities for lattices with isometry by introducing a last invariant for lattices with finite isometry of hermitian type (L f), called the signatures. These signatures are are intrinsequely connected to the local archimedean invariants of the hermitian structure associated to (L f) via the trace equivalence.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"signatures(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#signatures-Tuple{ZZLatWithIsom}","page":"Lattice with isometry","title":"signatures","text":"signatures(Lf::ZZLatWithIsom) -> Dict{Int, Tuple{Int, Int}}\n\nGiven a lattice with isometry (L f) where the minimal polynomial of f is irreducible cyclotomic, return the signatures of (L f).\n\nIn this context, if we denote z a primitive n-th root of unity, where n is the order of f, then for each 1 leq i leq n2 such that (i n) = 1, the i-th signature of (L f) is given by the signatures of the real quadratic form ker(f + f^-1 - z^i - z^-i).\n\nExamples\n\njulia> L = root_lattice(:A,5);\n\njulia> f = matrix(QQ, 5, 5, [1 1 1 1 1;\n 0 -1 -1 -1 -1;\n 0 1 0 0 0;\n 0 0 1 0 0;\n 0 0 0 1 0]);\n\njulia> Lf = integer_lattice_with_isometry(L, f);\n\njulia> M = coinvariant_lattice(Lf);\n\njulia> signatures(M)\nDict{Integer, Tuple{Int64, Int64}} with 2 entries:\n 2 => (2, 0)\n 1 => (2, 0)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Equality","page":"Lattice with isometry","title":"Equality","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattice with isometry","title":"Lattice with isometry","text":"We choose as a convention that two pairs (L f) and (L f) of integer lattices with isometries are equal if their ambient quadratic space with isometry of type QuadSpaceWithIsom are equal, and if the underlying lattices L and L are equal as mathbb Z-modules in the common ambient quadratic space.","category":"page"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/quotient_module/#Quotient-modules","page":"Quotient modules","title":"Quotient modules","text":"","category":"section"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"AbstractAlgebra allows the construction of quotient modules/spaces of AbstractAlgebra modules over euclidean domains. These are given as the quotient of a module by a submodule of that module.","category":"page"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"We define two quotient modules to be equal if they are quotients of the same module M by two equal submodules.","category":"page"},{"location":"AbstractAlgebra/quotient_module/#Generic-quotient-module-type","page":"Quotient modules","title":"Generic quotient module type","text":"","category":"section"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"AbstractAlgebra implements the generic quotient module type Generic.QuotientModule{T} where T is the element type of the base ring, in src/generic/QuotientModule.jl.","category":"page"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"Elements of generic quotient modules have type Generic.QuotientModuleElem{T}.","category":"page"},{"location":"AbstractAlgebra/quotient_module/#Abstract-types","page":"Quotient modules","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"Quotient module types belong to the FPModule{T} abstract type and their elements to FPModuleElem{T}.","category":"page"},{"location":"AbstractAlgebra/quotient_module/#Constructors","page":"Quotient modules","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"quo(M::FPModule{T}, v::Generic.Submodule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/quotient_module/#quo-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.Generic.Submodule{T}}} where T<:RingElement","page":"Quotient modules","title":"quo","text":"quo(m::FPModule{T}, subm::FPModule{T}) where T <: RingElement\n\nReturn the quotient M of the module m by the module subm (which must have been (transitively) constructed as a submodule of m or be m itself) along with the canonical quotient map from m to M.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"Note that a preimage of the canonical projection can be obtained using the preimage function described in the section on module homomorphisms. Note that a preimage element of the canonical projection is not unique and has no special properties.","category":"page"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"julia> M = FreeModule(ZZ, 2)\nFree module of rank 2 over integers\n\njulia> m = M([ZZ(1), ZZ(2)])\n(1, 2)\n\njulia> N, f = sub(M, [m])\n(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)\n\njulia> Q, g = quo(M, N)\n(Quotient module over Integers with 1 generator and no relations, Hom: Free module of rank 2 over integers -> Quotient module over Integers with 1 generator and no relations)\n\njulia> p = M([ZZ(3), ZZ(1)])\n(3, 1)\n\njulia> v2 = g(p)\n(-5)\n\njulia> V = VectorSpace(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> m = V([QQ(1), QQ(2)])\n(1//1, 2//1)\n\njulia> N, f = sub(V, [m])\n(Subspace over Rationals with 1 generator and no relations, Hom: Subspace over Rationals with 1 generator and no relations -> Vector space of dimension 2 over rationals)\n\njulia> Q, g = quo(V, N)\n(Quotient space over:\nRationals with 1 generator and no relations, Hom: Vector space of dimension 2 over rationals -> Quotient space over:\nRationals with 1 generator and no relations)\n","category":"page"},{"location":"AbstractAlgebra/quotient_module/#Functionality-for-submodules","page":"Quotient modules","title":"Functionality for submodules","text":"","category":"section"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"In addition to the Module interface, AbstractAlgebra submodules implement the following functionality.","category":"page"},{"location":"AbstractAlgebra/quotient_module/#Basic-manipulation","page":"Quotient modules","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"supermodule(M::Generic.QuotientModule{T}) where T <: RingElement\n\ndim(N::Generic.QuotientModule{T}) where T <: FieldElement","category":"page"},{"location":"AbstractAlgebra/quotient_module/#supermodule-Union{Tuple{AbstractAlgebra.Generic.QuotientModule{T}}, Tuple{T}} where T<:RingElement","page":"Quotient modules","title":"supermodule","text":"supermodule(M::QuotientModule{T}) where T <: RingElement\n\nReturn the module that this module is a quotient of.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/quotient_module/#dim-Union{Tuple{AbstractAlgebra.Generic.QuotientModule{T}}, Tuple{T}} where T<:FieldElement","page":"Quotient modules","title":"dim","text":"dim(N::QuotientModule{T}) where T <: FieldElement\n\nReturn the dimension of the given vector quotient space.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"Examples","category":"page"},{"location":"AbstractAlgebra/quotient_module/","page":"Quotient modules","title":"Quotient modules","text":"julia> M = FreeModule(ZZ, 2)\nFree module of rank 2 over integers\n\njulia> m = M([ZZ(2), ZZ(3)])\n(2, 3)\n\njulia> N, g = sub(M, [m])\n(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 2 over integers)\n\njulia> Q, h = quo(M, N)\n(Quotient module over Integers with 2 generators and relations:\n[2 3], Hom: Free module of rank 2 over integers -> Quotient module over Integers with 2 generators and relations:\n[2 3])\n\njulia> supermodule(Q) == M\ntrue\n\njulia> V = VectorSpace(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> m = V([QQ(1), QQ(2)])\n(1//1, 2//1)\n\njulia> N, f = sub(V, [m])\n(Subspace over Rationals with 1 generator and no relations, Hom: Subspace over Rationals with 1 generator and no relations -> Vector space of dimension 2 over rationals)\n\njulia> Q, g = quo(V, N)\n(Quotient space over:\nRationals with 1 generator and no relations, Hom: Vector space of dimension 2 over rationals -> Quotient space over:\nRationals with 1 generator and no relations)\n\njulia> dim(V)\n2\n\njulia> dim(Q)\n1\n","category":"page"},{"location":"AbstractAlgebra/ring_introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AbstractAlgebra/ring_introduction/","page":"Introduction","title":"Introduction","text":"A rich ring hierarchy is provided, supporting both commutative and noncommutative rings.","category":"page"},{"location":"AbstractAlgebra/ring_introduction/","page":"Introduction","title":"Introduction","text":"A number of basic rings are provided, such as the integers, integers mod n and numerous fields.","category":"page"},{"location":"AbstractAlgebra/ring_introduction/","page":"Introduction","title":"Introduction","text":"A recursive rings implementation is then built on top of the basic rings via a number of generic ring constructions. These include univariate and multivariate polynomials and power series, univariate Laurent and Puiseux series, residue rings, matrix algebras, etc.","category":"page"},{"location":"AbstractAlgebra/ring_introduction/","page":"Introduction","title":"Introduction","text":"Where possible, these constructions can be built on top of one another in generic towers.","category":"page"},{"location":"AbstractAlgebra/ring_introduction/","page":"Introduction","title":"Introduction","text":"The ring hierarchy can be extended by implementing new rings to follow one or more ring interfaces. Generic functionality provided by the system is then automatically available for the new rings. These implementations can either be generic or can be specialised implementations provided by, for example, a C library.","category":"page"},{"location":"AbstractAlgebra/ring_introduction/","page":"Introduction","title":"Introduction","text":"In most cases, the interfaces consist of a set of constructors and functions that must be implemented to satisfy the interface. These are the functions that the generic code relies on being available.","category":"page"},{"location":"Hecke/number_fields/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/number_fields/intro/#NumberFieldsLink","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/number_fields/intro/","page":"Introduction","title":"Introduction","text":"By definition, mathematically a number field is just a finite extension of the rational mathbfQ. In Hecke, a number field L is recursively defined as being the field of rational numbers mathbfQ or a finite extension of a number field K. In the second case, the extension can be defined in the one of the following two ways:","category":"page"},{"location":"Hecke/number_fields/intro/","page":"Introduction","title":"Introduction","text":"We have L = Kx(f), where f in Kx is an irreducible polynomial (simple extension), or\nWe have L = Kx_1dotscx_n(f_1(x_1)dotscf_n(x_n)), where f_1dotscf_n in Kx are univariate polynomials (non-simple extension).","category":"page"},{"location":"Hecke/number_fields/intro/","page":"Introduction","title":"Introduction","text":"In both cases we refer to K as the base field of the number field L. Another useful dichotomy comes from the type of the base field. We call L an absolute number field, if the base field is equal to the rational numbers mathbfQ.","category":"page"},{"location":"AbstractAlgebra/types/#Type-interface-of-AbstractAlgebra.jl","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"Apart from how we usually think of types in programming, we shall in this section discuss why we do not use the typical type interface.","category":"page"},{"location":"AbstractAlgebra/types/#Why-types-aren't-enough","page":"Type interface of AbstractAlgebra.jl","title":"Why types aren't enough","text":"","category":"section"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"Naively, one might have expected that structures like rings in AbstractAlgebra.jl could be modeled as types and their elements as objects with the given type. But there are various reasons why this is not a good model.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"Consider the ring R = mathbbZnmathbbZ for a multiprecision integer n. If we were to model the ring R as a type, then the type would somehow need to contain the modulus n. This is not possible in Julia, and in fact it is not desirable, since the compiler would then recompile all the associated functions every time a different modulus n was used.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"We could attach the modulus n to the objects representing elements of the ring, rather than their type.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"But now we cannot create new elements of the ring mathbbZnmathbbZ given only their type, since the type no longer contains the modulus n.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"Instead, the way we get around this in AbstractAlgebra.jl is to have special (singleton) objects that act like types, but are really just ordinary Julia objects. These objects, called parent objects, can contain extra information, such as the modulus n. In return, we associate this parent object with so called element objects.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"In order to create new elements of mathbbZnmathbbZ as above, we overload the call operator for the parent object.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"In the following AbstractAlgebra.jl example, we create the parent object R corresponding to the ring mathbbZ7mathbbZ. We then create a new element a of this ring by calling the parent object R.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"R = residue_ring(ZZ, 7)\na = R(3)","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"Here, R is the parent object, containing the modulus 7. So this example creates the element a = 3 pmod7.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"Objects known as parents which contain additional information about groups, rings, fields and modules, etc., that can't be stored in types alone.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"These details are technical and can be skipped or skimmed by new users of Julia/AbstractAlgebra.jl. Types are almost never dealt with directly when scripting AbstractAlgebra.jl to do mathematical computations.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"In contrast, AbstractAlgebra.jl developers will want to know how we model mathematical objects and their rings, fields, groups, etc.","category":"page"},{"location":"AbstractAlgebra/types/#The-abstract-type-hierarchy-in-AbstractAlgebra.jl","page":"Type interface of AbstractAlgebra.jl","title":"The abstract type hierarchy in AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"In AbstractAlgebra.jl, we use the abstract type hierarchy in order to give structure when programming the mathematical structures. For example, abstract types in Julia can belong to one another in a hierarchy.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"For example, the Field abstract type belongs to the Ring abstract type. The full hierarchy can be seen in diagrams under the section on visualisation of the abstract types.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"In practice this is practical since it means that any generic function designed to work with ring objects will also work with field objects.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"In AbstractAlgebra.jl we also distinguish between the elements of a field, say, and the field itself.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"For example, we have an object of type Generic.PolyRing to model a generic polynomial ring, and elements of that polynomial ring would have type Generic.PolyRingElem.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"For this purpose, we also have a hierarchy of abstract types, such as FieldElem, that the types of element objects can belong to.","category":"page"},{"location":"AbstractAlgebra/types/#More-complex-example-of-parent-objects","page":"Type interface of AbstractAlgebra.jl","title":"More complex example of parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"Here is some code which constructs a polynomial ring over the integers, a polynomial in that ring and then does some introspection to illustrate the various relations between the objects and types.","category":"page"},{"location":"AbstractAlgebra/types/","page":"Type interface of AbstractAlgebra.jl","title":"Type interface of AbstractAlgebra.jl","text":"julia> using AbstractAlgebra\n\njulia> R, x = ZZ[\"x\"]\n(Univariate polynomial ring in x over integers, x)\n\njulia> f = x^2 + 3x + 1\nx^2 + 3*x + 1\n\njulia> R isa PolyRing\ntrue\n\njulia> f isa PolyRingElem\ntrue\n\njulia> parent(f) == R\ntrue","category":"page"},{"location":"General/serialization/#Serialization","page":"Serialization","title":"Serialization","text":"","category":"section"},{"location":"General/serialization/#Introduction","page":"Serialization","title":"Introduction","text":"","category":"section"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"For some of our datatypes we provide a way to save them in and load them from JSON format. This is still experimental and it will take some time until all corners of OSCAR are covered by this effort. The goal of this effort is threefold:","category":"page"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"Avoid recomputation by providing an easy way to store data.\nIncrease portability by giving a convenient possibility to transport data.\nIncrease overall software quality by testing against existing data and tracking errors through data computed by different versions.","category":"page"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"save\nload\nis_basic_serialization_type","category":"page"},{"location":"General/serialization/#save","page":"Serialization","title":"save","text":"save(io::IO, obj::Any; metadata::MetaData=nothing)\nsave(filename::String, obj::Any, metadata::MetaData=nothing)\n\nSave an object T to the given io stream respectively to the file filename.\n\nSee load.\n\nExamples\n\njulia> meta = metadata(author_orcid=\"0000-0000-0000-0042\", name=\"the meaning of life the universe and everything\")\nOscar.MetaData(\"0000-0000-0000-0042\", \"the meaning of life the universe and everything\")\n\njulia> save(\"/tmp/fourtitwo.json\", 42; metadata=meta);\n\njulia> load(\"/tmp/fourtitwo.json\")\n42\n\n\n\n\n\n","category":"function"},{"location":"General/serialization/#load","page":"Serialization","title":"load","text":"load(io::IO; parent::Any = nothing, type::Any = nothing)\nload(filename::String; parent::Any = nothing, type::Any = nothing)\n\nLoad the object stored in the given io stream respectively in the file filename.\n\nIf parent is specified, then the root object of the loaded data either will have this as its parent, or it is a container such as Vector and Tuple, then the parent of the entries will be set to parent.\n\nIf a type T is given then attempt to load the root object of the data being loaded with this type; if this fails, an error is thrown.\n\nSee save.\n\nExamples\n\njulia> save(\"/tmp/fourtitwo.json\", 42);\n\njulia> load(\"/tmp/fourtitwo.json\")\n42\n\njulia> load(\"/tmp/fourtitwo.json\"; type=Int64)\n42\n\njulia> R, x = QQ[\"x\"]\n(Univariate polynomial ring in x over QQ, x)\n\njulia> p = x^2 - x + 1\nx^2 - x + 1\n\njulia> save(\"/tmp/p.json\", p)\n\njulia> p_loaded = load(\"/tmp/p.json\", parent=R)\nx^2 - x + 1\n\njulia> parent(p_loaded) === R\ntrue\n\njulia> save(\"/tmp/p_v.json\", [p, p])\n\njulia> loaded_p_v = load(\"/tmp/p_v.json\", parent=R)\n2-element Vector{QQPolyRingElem}:\n x^2 - x + 1\n x^2 - x + 1\n\njulia> parent(loaded_p_v[1]) === parent(loaded_p_v[2]) === R\ntrue\n\n\n\n\n\n","category":"function"},{"location":"General/serialization/#is_basic_serialization_type","page":"Serialization","title":"is_basic_serialization_type","text":"is_basic_serialization_type(::Type)\n\nDuring the serialization of types of the form Vector{T}, entries of type T will either be serialized as strings if is_basic_serialization_type returns true, or serialized as a dict provided the serialization for such a T exists. If Vector{T} is serialized with is_basic_serialization_type(T) = true then the entry_type keyword is used to store the type T as a property of the vector.\n\nExamples\n\njulia> is_basic_serialization_type(ZZRingElem)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"General/serialization/#Objects-that-can-be-serialized","page":"Serialization","title":"Objects that can be serialized","text":"","category":"section"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"In this section we will list objects that may be (de-)serialized. This list may be incomplete.","category":"page"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"Many low level objects may be stored and these in turn allow serializing higher level objects. Such low level objects are various types of matrices, vectors and sets.","category":"page"},{"location":"General/serialization/#Combinatorics","page":"Serialization","title":"Combinatorics","text":"","category":"section"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"Graph\nSimplicialComplex","category":"page"},{"location":"General/serialization/#Commutative-Algebra","page":"Serialization","title":"Commutative Algebra","text":"","category":"section"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"Ideal\nPolynomial\npolynomial_ring","category":"page"},{"location":"General/serialization/#Polyhedral-Geometry","page":"Serialization","title":"Polyhedral Geometry","text":"","category":"section"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"Cone\nLinearProgram\nPolyhedralFan\nPolyhedralComplex\nPolyhedron\nSubdivisionOfPoints","category":"page"},{"location":"General/serialization/#Toric-Geometry","page":"Serialization","title":"Toric Geometry","text":"","category":"section"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"NormalToricVariety\nToricDivisor","category":"page"},{"location":"General/serialization/#Tropical-Geometry","page":"Serialization","title":"Tropical Geometry","text":"","category":"section"},{"location":"General/serialization/","page":"Serialization","title":"Serialization","text":"TropicalCurve\nTropicalHypersurface","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"CommutativeAlgebra/ideals/#Ideals-in-Multivariate-Rings","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/#Types","page":"Ideals in Multivariate Rings","title":"Types","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"The OSCAR type for ideals in multivariate polynomial rings is of parametrized form MPolyIdeal{T}, where T is the element type of the polynomial ring.","category":"page"},{"location":"CommutativeAlgebra/ideals/#Constructors","page":"Ideals in Multivariate Rings","title":"Constructors","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"ideal(R::MPolyRing, g::Vector)","category":"page"},{"location":"CommutativeAlgebra/ideals/#ideal-Tuple{MPolyRing, Vector}","page":"Ideals in Multivariate Rings","title":"ideal","text":"ideal(R::MPolyRing, V::Vector)\n\nGiven a vector V of polynomials in R, return the ideal of R generated by these polynomials.\n\nnote: Note\nIn the graded case, the entries of V must be homogeneous.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x*y-3*x,y^3-2*x^2*y])\nideal(x*y - 3*x, -2*x^2*y + y^3)\n\njulia> typeof(I)\nMPolyIdeal{QQMPolyRingElem}\n\njulia> S, (x, y) = graded_polynomial_ring(QQ, [\"x\", \"y\"], [1, 2])\n(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])\n\njulia> J = ideal(S, [(x^2+y)^2])\nideal(x^4 + 2*x^2*y + y^2)\n\njulia> typeof(J)\nMPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Data-Associated-to-Ideals","page":"Ideals in Multivariate Rings","title":"Data Associated to Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/#Basic-Data","page":"Ideals in Multivariate Rings","title":"Basic Data","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"If I is an ideal of a multivariate polynomial ring R, then","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"base_ring(I) refers to R,\ngens(I) to the generators of I,\nngens(I) to the number of these generators, and\ngen(I, k) as well as I[k] to the k-th such generator.","category":"page"},{"location":"CommutativeAlgebra/ideals/#Examples","page":"Ideals in Multivariate Rings","title":"Examples","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"julia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> base_ring(I)\nMultivariate polynomial ring in 2 variables x, y\n over rational field\n\njulia> gens(I)\n3-element Vector{QQMPolyRingElem}:\n x^2\n x*y\n y^2\n\njulia> ngens(I)\n3\n\njulia> gen(I, 2)\nx*y\n","category":"page"},{"location":"CommutativeAlgebra/ideals/#Dimension","page":"Ideals in Multivariate Rings","title":"Dimension","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"dim(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#dim-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"dim","text":"dim(I::MPolyIdeal)\n\nReturn the Krull dimension of I.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [y-x^2, x-z^3])\nideal(-x^2 + y, x - z^3)\n\njulia> dim(I)\n1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Codimension","page":"Ideals in Multivariate Rings","title":"Codimension","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"codim(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#codim-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"codim","text":"codim(I::MPolyIdeal)\n\nReturn the codimension of I.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [y-x^2, x-z^3])\nideal(-x^2 + y, x - z^3)\n\njulia> codim(I)\n2\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"In the graded case, we additionally have:","category":"page"},{"location":"CommutativeAlgebra/ideals/#Minimal-Sets-of-Generators","page":"Ideals in Multivariate Rings","title":"Minimal Sets of Generators","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"minimal_generating_set(I::MPolyIdeal{<:MPolyDecRingElem})","category":"page"},{"location":"CommutativeAlgebra/ideals/#minimal_generating_set-Tuple{MPolyIdeal{<:MPolyDecRingElem}}","page":"Ideals in Multivariate Rings","title":"minimal_generating_set","text":"minimal_generating_set(I::MPolyIdeal{<:MPolyDecRingElem})\n\nGiven a (homogeneous) ideal I in a graded multivariate polynomial ring over a field, return an array containing a minimal set of generators of I. If I is the zero ideal, an empty list is returned.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> V = [x, z^2, x^3+y^3, y^4, y*z^5];\n\njulia> I = ideal(R, V)\nideal(x, z^2, x^3 + y^3, y^4, y*z^5)\n\njulia> minimal_generating_set(I)\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x\n z^2\n y^3\n\njulia> I = ideal(R, zero(R))\nideal(0)\n\njulia> minimal_generating_set(I)\nMPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Castelnuovo-Mumford-Regularity","page":"Ideals in Multivariate Rings","title":"Castelnuovo-Mumford Regularity","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"cm_regularity(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#cm_regularity-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"cm_regularity","text":"cm_regularity(I::MPolyIdeal)\n\nGiven a (homogeneous) ideal I in a standard mathbb Z-graded multivariate polynomial ring, return the Castelnuovo-Mumford regularity of I.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> I = ideal(R, [y^2*z − x^2*w, z^4 − x*w^3]);\n\njulia> cm_regularity(I)\n6\n\njulia> minimal_betti_table(I);\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Degree","page":"Ideals in Multivariate Rings","title":"Degree","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"degree(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#degree-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"degree","text":"degree(I::MPolyIdeal)\n\nGiven a (homogeneous) ideal I in a standard mathbb Z-graded multivariate polynomial ring, return the degree of I (that is, the degree of the quotient of base_ring(I) modulo I). Otherwise, return the degree of the homogenization of I with respect to the standard mathbb Z-grading.\n\nnote: Note\nGeometrically, the degree of a homogeneous ideal as above is the number of intersection points of its projective variety with a generic linear subspace of complementary dimension (counted with multiplicities). See also Mateusz Michałek, Bernd Sturmfels (2021).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [y-x^2, x-z^3])\nideal(-x^2 + y, x - z^3)\n\njulia> degree(I)\n6\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Operations-on-Ideals","page":"Ideals in Multivariate Rings","title":"Operations on Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/#Simple-Ideal-Operations","page":"Ideals in Multivariate Rings","title":"Simple Ideal Operations","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/#Powers-of-Ideal","page":"Ideals in Multivariate Rings","title":"Powers of Ideal","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"^(I::MPolyIdeal, m::Int)","category":"page"},{"location":"CommutativeAlgebra/ideals/#^-Tuple{MPolyIdeal, Int64}","page":"Ideals in Multivariate Rings","title":"^","text":"^(I::MPolyIdeal, m::Int)\n\nReturn the m-th power of I.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x, y])\nideal(x, y)\n\njulia> I^3\nideal(x^3, x^2*y, x*y^2, y^3)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Sum-of-Ideals","page":"Ideals in Multivariate Rings","title":"Sum of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"+(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#+-Union{Tuple{T}, Tuple{MPolyIdeal{T}, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"+","text":"+(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\n\nReturn the sum of I and J.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x, y])\nideal(x, y)\n\njulia> J = ideal(R, [z^2])\nideal(z^2)\n\njulia> I+J\nideal(x, y, z^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Product-of-Ideals","page":"Ideals in Multivariate Rings","title":"Product of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"*(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#*-Union{Tuple{T}, Tuple{MPolyIdeal{T}, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"*","text":"*(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\n\nReturn the product of I and J.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x, y])\nideal(x, y)\n\njulia> J = ideal(R, [z^2])\nideal(z^2)\n\njulia> I*J\nideal(x*z^2, y*z^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Intersection-of-Ideals","page":"Ideals in Multivariate Rings","title":"Intersection of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T\nintersect(V::Vector{MPolyIdeal{T}}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#intersect-Union{Tuple{T}, Tuple{MPolyIdeal{T}, Vararg{MPolyIdeal{T}}}} where T","page":"Ideals in Multivariate Rings","title":"intersect","text":"intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T\nintersect(V::Vector{MPolyIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2;\n\njulia> J = ideal(R, [y^2-x^3+x]);\n\njulia> intersect(I, J)\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> intersect([I, J])\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#intersect-Union{Tuple{Array{MPolyIdeal{T}, 1}}, Tuple{T}} where T","page":"Ideals in Multivariate Rings","title":"intersect","text":"intersect(I::MPolyIdeal{T}, Js::MPolyIdeal{T}...) where T\nintersect(V::Vector{MPolyIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2;\n\njulia> J = ideal(R, [y^2-x^3+x]);\n\njulia> intersect(I, J)\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> intersect([I, J])\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\n\n\n\n\nintersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T\nintersect(V::Vector{MPolyQuoIdeal{T}}) where T\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));\n\njulia> a = ideal(A, [y^2])\nideal(y^2)\n\njulia> b = ideal(A, [x])\nideal(x)\n\njulia> intersect(a,b)\nideal(x*y)\n\njulia> intersect([a,b])\nideal(x*y)\n\n\n\n\n\nintersect(I::PBWAlgIdeal{D, T, S}, Js::PBWAlgIdeal{D, T, S}...) where {D, T, S}\nintersect(V::Vector{PBWAlgIdeal{D, T, S}}) where {D, T, S}\n\nReturn the intersection of two or more ideals.\n\nExamples\n\njulia> D, (x, y, dx, dy) = weyl_algebra(QQ, [\"x\", \"y\"]);\n\njulia> I = intersect(left_ideal(D, [x^2, x*dy, dy^2])+left_ideal(D, [dx]), left_ideal(D, [dy^2-x^3+x]))\nleft_ideal(-x^3 + dy^2 + x)\n\n\n\n\n\nintersect(M::SubquoModule{T}, N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return the intersection of M and N regarded as submodules of the common ambient module.\n\nAdditionally, return the inclusion maps M cap N to M and M cap N to N.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> F = free_module(R, 1)\nFree module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> AM = R[x;]\n[x]\n\njulia> BM = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, AM, BM)\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = R[y;]\n[y]\n\njulia> BN = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> N = SubquoModule(F, AN, BN)\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Subquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> x*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n, Map with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 1 generator\n1 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n)\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> AM = Rg[x;];\n\njulia> BM = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, AM, BM)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> AN = Rg[y;];\n\njulia> BN = Rg[x^2; y^3; z^4];\n\njulia> N = SubquoModule(F, AN, BN)\nGraded subquotient of submodule of F generated by\n1 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> intersect(M, N)\n(Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> M\n-x*y*e[1] -> -x*y*e[1]\nx*z^4*e[1] -> x*z^4*e[1]\nHomogeneous module homomorphism, Graded subquotient of submodule of F generated by\n1 -> -x*y*e[1]\n2 -> x*z^4*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> N\n-x*y*e[1] -> x*y*e[1]\nx*z^4*e[1] -> 0\nHomogeneous module homomorphism)\n\n\n\n\n\n\nintersect(T1, T2)\n\nIntersect two tropical varieties.\n\nExamples\n\njulia> RR = TropicalSemiring(min)\nTropical semiring (min)\n\njulia> S,(x,y) = RR[\"x\",\"y\"]\n(Multivariate polynomial ring in 2 variables over tropical semiring (min), AbstractAlgebra.Generic.MPoly{Oscar.TropicalSemiringElem{typeof(min)}}[x, y])\n\njulia> f1 = x+y+1\nx + y + (1)\n\njulia> f2 = x^2+y^2+RR(-6)\nx^2 + y^2 + (-6)\n\njulia> hyp1 = TropicalHypersurface(f1)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> hyp2 = TropicalHypersurface(f2)\nmin tropical hypersurface embedded in 2-dimensional Euclidean space\n\njulia> tv12 = intersect(hyp1, hyp2)\nmin tropical variety of dimension 1 embedded in 2-dimensional Euclidean space\n\n\n\n\n\nintersect(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl\n\nReturns a cap b.\n\n\n\n\n\nintersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl\n\nReturns a cap b.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Ideal-Quotients","page":"Ideals in Multivariate Rings","title":"Ideal Quotients","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"Given two ideals I J of a ring R, the ideal quotient of I by J is the ideal","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"IJ= biglf in Rbig f J subset Ibigrsubset R","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"quotient(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#quotient-Union{Tuple{T}, Tuple{MPolyIdeal{T}, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"quotient","text":"quotient(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\n\nReturn the ideal quotient of I by J. Alternatively, use I:J.\n\nquotient(I::MPolyIdeal{T}, f::MPolyRingElem{T}) where T\n\nReturn the ideal quotient of I by the ideal generated by f. Alternatively, use I:f.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [x^4+x^2*y*z+y^3*z, y^4+x^3*z+x*y^2*z, x^3*y+x*y^3])\nideal(x^4 + x^2*y*z + y^3*z, x^3*z + x*y^2*z + y^4, x^3*y + x*y^3)\n\njulia> J = ideal(R, [x, y, z])^2\nideal(x^2, x*y, x*z, y^2, y*z, z^2)\n\njulia> L = quotient(I, J)\nideal(x^3*z + x*y^2*z + y^4, x^3*y + x*y^3, x^4 + x^2*y*z + y^3*z, x^3*z^2 - x^2*y*z^2 + x*y^2*z^2 - y^3*z^2, x^2*y^2*z - x^2*y*z^2 - y^3*z^2, x^3*z^2 + x^2*y^3 - x^2*y^2*z + x*y^2*z^2)\n\njulia> I:J\nideal(x^3*z + x*y^2*z + y^4, x^3*y + x*y^3, x^4 + x^2*y*z + y^3*z, x^3*z^2 - x^2*y*z^2 + x*y^2*z^2 - y^3*z^2, x^2*y^2*z - x^2*y*z^2 - y^3*z^2, x^3*z^2 + x^2*y^3 - x^2*y^2*z + x*y^2*z^2)\n\njulia> I:x\nideal(x^2*y + y^3, x^3*z + x*y^2*z + y^4, x^2*z^2 + x*y^3 - x*y^2*z + y^2*z^2, x^4, x^3*z^2 - x^2*z^3 + 2*x*y^2*z^2 - y^2*z^3, -x^2*z^4 + x*y^2*z^3 - y^2*z^4)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Saturation","page":"Ideals in Multivariate Rings","title":"Saturation","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"Given two ideals I J of a ring R, the saturation of I with respect to J is the ideal","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"IJ^infty = bigl f in R big f J^k subset I text for some kgeq 1 bigr = textstylebigcuplimits_k=1^infty (IJ^k)","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"saturation(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\nsaturation_with_index(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#saturation-Union{Tuple{T}, Tuple{MPolyIdeal{T}, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"saturation","text":"saturation(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\n\nReturn the saturation of I with respect to J.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y])\nideal(z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y)\n\njulia> J = ideal(R, [x, y, z])\nideal(x, y, z)\n\njulia> K = saturation(I, J)\nideal(z, x*y)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#saturation_with_index-Union{Tuple{T}, Tuple{MPolyIdeal{T}, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"saturation_with_index","text":"saturation_with_index(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\n\nReturn IJ^infty together with the smallest integer m such that IJ^m = IJ^infty.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> I = ideal(R, [z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y])\nideal(z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, x*y^2, x^2*y)\n\njulia> J = ideal(R, [x, y, z])\nideal(x, y, z)\n\njulia> K, m = saturation_with_index(I, J)\n(ideal(z, x*y), 2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Elimination","page":"Ideals in Multivariate Rings","title":"Elimination","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"eliminate(I::MPolyIdeal{T}, V::Vector{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/ideals/#eliminate-Union{Tuple{T}, Tuple{MPolyIdeal{T}, Vector{T}}} where T<:MPolyRingElem","page":"Ideals in Multivariate Rings","title":"eliminate","text":"eliminate(I::MPolyIdeal{T}, V::Vector{T}) where T <: MPolyRingElem\n\nGiven a vector V of polynomials which are variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.\n\neliminate(I::MPolyIdeal, V::AbstractVector{Int})\n\nGiven a vector V of indices which specify variables, these variables are eliminated from I. That is, return the ideal generated by all polynomials in I which only involve the remaining variables.\n\nnote: Note\nThe return value is an ideal of the original ring.\n\nExamples\n\njulia> R, (t, x, y, z) = polynomial_ring(QQ, [\"t\", \"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[t, x, y, z])\n\njulia> I = ideal(R, [t-x, t^2-y, t^3-z])\nideal(t - x, t^2 - y, t^3 - z)\n\njulia> A = [t]\n1-element Vector{QQMPolyRingElem}:\n t\n\njulia> TC = eliminate(I, A)\nideal(-x*z + y^2, x*y - z, x^2 - y)\n\njulia> A = [1]\n1-element Vector{Int64}:\n 1\n\njulia> TC = eliminate(I, A)\nideal(-x*z + y^2, x*y - z, x^2 - y)\n\njulia> base_ring(TC)\nMultivariate polynomial ring in 4 variables t, x, y, z\n over rational field\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Truncation","page":"Ideals in Multivariate Rings","title":"Truncation","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"truncate(I::MPolyIdeal, g::GrpAbFinGenElem)","category":"page"},{"location":"CommutativeAlgebra/ideals/#truncate-Tuple{MPolyIdeal, GrpAbFinGenElem}","page":"Ideals in Multivariate Rings","title":"truncate","text":"truncate(I::MPolyIdeal, g::GrpAbFinGenElem)\n\nGiven a (homogeneous) ideal I in a mathbb Z-graded multivariate polynomial ring with positive weights, return the truncation of I at degree g.\n\ntruncate(I::MPolyIdeal, d::Int)\n\nGiven an ideal I as above, and given an integer d, convert d into an element g of the grading group of base_ring(I) and proceed as above.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> I = ideal(R, [x, y^4, z^6])\nideal(x, y^4, z^6)\n\njulia> truncate(I, 3)\nideal(x*z^2, x*y*z, x*y^2, x^2*z, x^2*y, x^3, y^4, z^6)\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"], [3,2,1]);\n\njulia> I = ideal(R, [x, y^4, z^6])\nideal(x, y^4, z^6)\n\njulia> truncate(I, 3)\nideal(x, y^4, z^6)\n\njulia> truncate(I, 4)\nideal(x*z, z^6, y^4)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Tests-on-Ideals","page":"Ideals in Multivariate Rings","title":"Tests on Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/#Basic-Tests","page":"Ideals in Multivariate Rings","title":"Basic Tests","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"is_zero(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#is_zero-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"is_zero","text":"is_zero(I::MPolyIdeal)\n\nReturn true if I is the zero ideal, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, y-x^2)\nideal(-x^2 + y)\n\njulia> is_zero(I)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"is_one(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#is_one-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"is_one","text":"is_one(I::MPolyIdeal)\n\nReturn true if I is generated by 1, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, x + y, y - 1])\nideal(x, x + y, y - 1)\n\njulia> is_one(I)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"is_monomial(f::MPolyRingElem)","category":"page"},{"location":"CommutativeAlgebra/ideals/#is_monomial-Tuple{MPolyRingElem}","page":"Ideals in Multivariate Rings","title":"is_monomial","text":"is_monomial(f::MPolyRingElem)\n\nReturn true if f is a monomial, false otherwise.\n\nis_monomial(I::MPolyIdeal)\n\nReturn true if I can be generated by monomials, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> f = 2*x+y\n2*x + y\n\njulia> g = y\ny\n\njulia> is_monomial(f)\nfalse\n\njulia> is_monomial(g)\ntrue\n\njulia> is_monomial(ideal(R, [f, g]))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Containment-of-Ideals","page":"Ideals in Multivariate Rings","title":"Containment of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"is_subset(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#is_subset-Union{Tuple{T}, Tuple{MPolyIdeal{T}, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"is_subset","text":"is_subset(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\n\nReturn true if I is contained in J, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x^2])\nideal(x^2)\n\njulia> J = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> is_subset(I, J)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Equality-of-Ideals","page":"Ideals in Multivariate Rings","title":"Equality of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"==(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#==-Union{Tuple{T}, Tuple{MPolyIdeal{T}, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"==","text":"==(I::MPolyIdeal{T}, J::MPolyIdeal{T}) where T\n\nReturn true if I is equal to J, false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x^2])\nideal(x^2)\n\njulia> J = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> I == J\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Ideal-Membership","page":"Ideals in Multivariate Rings","title":"Ideal Membership","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"ideal_membership(f::T, I::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#ideal_membership-Union{Tuple{T}, Tuple{T, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"ideal_membership","text":"ideal_membership(f::T, I::MPolyIdeal{T}) where T\n\nReturn true if f is contained in I, false otherwise. Alternatively, use f in I.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> f = x^2\nx^2\n\njulia> I = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> ideal_membership(f, I)\ntrue\n\njulia> g = x\nx\n\njulia> g in I\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Radical-Membership","page":"Ideals in Multivariate Rings","title":"Radical Membership","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"radical_membership(f::T, I::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ideals/#radical_membership-Union{Tuple{T}, Tuple{T, MPolyIdeal{T}}} where T","page":"Ideals in Multivariate Rings","title":"radical_membership","text":"radical_membership(f::T, I::MPolyIdeal{T}) where T\n\nReturn true if f is contained in the radical of I, false otherwise. Alternatively, use inradical(f, I).\n\nExamples\n\njulia> R, (x,) = polynomial_ring(QQ, [\"x\"])\n(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])\n\njulia> f = x\nx\n\njulia> I = ideal(R, [x^2])\nideal(x^2)\n\njulia> radical_membership(f, I)\ntrue\n\njulia> g = x+1\nx + 1\n\njulia> inradical(g, I)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Primality-Test","page":"Ideals in Multivariate Rings","title":"Primality Test","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"is_prime(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#is_prime-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"is_prime","text":"is_prime(I::MPolyIdeal)\n\nReturn true if I is prime, false otherwise.\n\nwarning: Warning\nThe function computes the minimal associated primes of I. This may take some time.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> is_prime(I)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Primary-Test","page":"Ideals in Multivariate Rings","title":"Primary Test","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"is_primary(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#is_primary-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"is_primary","text":"is_primary(I::MPolyIdeal)\n\nReturn true if I is primary, false otherwise.\n\nwarning: Warning\nThe function computes a primary decomposition of I. This may take some time.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> is_primary(I)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Decomposition-of-Ideals","page":"Ideals in Multivariate Rings","title":"Decomposition of Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"We discuss various decomposition techniques. They are implemented for polynomial rings over fields and, if explicitly mentioned, also for polynomial rings over the integers. See Wolfram Decker, Gert-Martin Greuel, Gerhard Pfister (1999) for a survey.","category":"page"},{"location":"CommutativeAlgebra/ideals/#Radical","page":"Ideals in Multivariate Rings","title":"Radical","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"radical(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#radical-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"radical","text":"radical(I::MPolyIdeal)\n\nReturn the radical of I.\n\nImplemented Algorithms\n\nIf the base ring of I is a polynomial ring over a field, a combination of the algorithms of Krick and Logar (with modifications by Laplagne) and Kemper is used. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Teresa Krick, Alessandro Logar (1991), Gregor Kemper (2002), and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)\n\njulia> RI = radical(I)\nideal(x^4 - x^3*y - x^3 - x^2 - x*y^2 + x*y + x + y^3 + y^2)\n\njulia> R, (a, b, c, d) = polynomial_ring(ZZ, [\"a\", \"b\", \"c\", \"d\"])\n(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])\n\njulia> I = intersect(ideal(R, [9,a,b]), ideal(R, [3,c]))\nideal(9, 3*b, 3*a, b*c, a*c)\n\njulia> I = intersect(I, ideal(R, [11,2a,7b]))\nideal(99, 3*b, 3*a, b*c, a*c)\n\njulia> I = intersect(I, ideal(R, [13a^2,17b^4]))\nideal(39*a^2, 13*a^2*c, 51*b^4, 17*b^4*c, 3*a^2*b^4, a^2*b^4*c)\n\njulia> I = intersect(I, ideal(R, [9c^5,6d^5]))\nideal(78*a^2*d^5, 117*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 6*a^2*b^4*d^5, 9*a^2*b^4*c^5, 39*a^2*c^5*d^5, 51*b^4*c^5*d^5, 3*a^2*b^4*c^5*d^5)\n\njulia> I = intersect(I, ideal(R, [17,a^15,b^15,c^15,d^15]))\nideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)\n\njulia> RI = radical(I)\nideal(102*b*d, 78*a*d, 51*b*c, 39*a*c, 6*a*b*d, 3*a*b*c)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Primary-Decomposition","page":"Ideals in Multivariate Rings","title":"Primary Decomposition","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"primary_decomposition(I::MPolyIdeal; algorithm::Symbol = :GTZ)","category":"page"},{"location":"CommutativeAlgebra/ideals/#primary_decomposition-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"primary_decomposition","text":"primary_decomposition(I::MPolyIdeal; algorithm = :GTZ, cache=true)\n\nReturn a minimal primary decomposition of I.\n\nThe decomposition is returned as a vector of tuples (Q_1 P_1) dots (Q_t P_t), say, where each Q_i is a primary ideal with associated prime P_i, and where the intersection of the Q_i is I.\n\nImplemented Algorithms\n\nIf the base ring of I is a polynomial ring over a field, the algorithm of Gianni, Trager, and Zacharias is used by default (algorithm = :GTZ). Alternatively, the algorithm by Shimoyama and Yokoyama can be used by specifying algorithm = :SY. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Patrizia Gianni, Barry Trager, Gail Zacharias (1988), Takeshi Shimoyama, Kazuhiro Yokoyama (1996), and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).\n\nwarning: Warning\nThe algorithm of Gianni, Trager, and Zacharias may not terminate over a small finite field. If it terminates, the result is correct.\n\nIf cache=false is set, the primary decomposition is recomputed and not cached.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)\n\njulia> L = primary_decomposition(I)\n3-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}}}:\n (ideal(x^3 - x - y^2), ideal(x^3 - x - y^2))\n (ideal(x^2 - 2*x*y - 2*x + y^2 + 2*y + 1), ideal(x - y - 1))\n (ideal(y, x^2), ideal(x, y))\n\njulia> L = primary_decomposition(I, algorithm = :SY, cache=false)\n3-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}}}:\n (ideal(x^3 - x - y^2), ideal(x^3 - x - y^2))\n (ideal(x^2 - 2*x*y - 2*x + y^2 + 2*y + 1), ideal(x - y - 1))\n (ideal(y, x^2), ideal(y, x))\n\njulia> R, (a, b, c, d) = polynomial_ring(ZZ, [\"a\", \"b\", \"c\", \"d\"])\n(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])\n\njulia> I = ideal(R, [1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5,\n 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15,\n 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15,\n 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5,\n 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15,\n 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5])\nideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)\n\njulia> L = primary_decomposition(I)\n8-element Vector{Tuple{MPolyIdeal{ZZMPolyRingElem}, MPolyIdeal{ZZMPolyRingElem}}}:\n (ideal(d^5, c^5), ideal(d, c))\n (ideal(a^2, b^4), ideal(b, a))\n (ideal(2, c^5), ideal(2, c))\n (ideal(3), ideal(3))\n (ideal(13, b^4), ideal(13, b))\n (ideal(17, a^2), ideal(17, a))\n (ideal(17, d^15, c^15, b^15, a^15), ideal(17, d, c, b, a))\n (ideal(9, 3*d^5, d^10), ideal(3, d))\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Absolute-Primary-Decomposition","page":"Ideals in Multivariate Rings","title":"Absolute Primary Decomposition","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"absolute_primary_decomposition(I::MPolyIdeal{QQMPolyRingElem})","category":"page"},{"location":"CommutativeAlgebra/ideals/#absolute_primary_decomposition-Tuple{MPolyIdeal{QQMPolyRingElem}}","page":"Ideals in Multivariate Rings","title":"absolute_primary_decomposition","text":"absolute_primary_decomposition(I::MPolyIdeal{<:MPolyRingElem{QQFieldElem}})\n\nGiven an ideal I in a multivariate polynomial ring over the rationals, return an absolute minimal primary decomposition of I.\n\nReturn the decomposition as a vector of tuples (Q_i P_i P_ij d_ij), say, where (Q_i P_i) is a (primary, prime) tuple as returned by primary_decomposition(I), and P_ij represents a corresponding class of conjugated absolute associated primes defined over a number field of degree d_ij whose generator prints as _a.\n\nImplemented Algorithms\n\nThe implementation combines the algorithm of Gianni, Trager, and Zacharias for primary decomposition with absolute polynomial factorization.\n\nExamples\n\njulia> R, (y, z) = polynomial_ring(QQ, [\"y\", \"z\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[y, z])\n\njulia> p = z^2+1\nz^2 + 1\n\njulia> q = z^3+2\nz^3 + 2\n\njulia> I = ideal(R, [p*q^2, y-z^2])\nideal(z^8 + z^6 + 4*z^5 + 4*z^3 + 4*z^2 + 4, y - z^2)\n\njulia> L = primary_decomposition(I)\n2-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}}}:\n (ideal(z^2 + 1, y - z^2), ideal(z^2 + 1, y - z^2))\n (ideal(z^6 + 4*z^3 + 4, y - z^2), ideal(z^3 + 2, y - z^2))\n\njulia> AL = absolute_primary_decomposition(I)\n2-element Vector{Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{nf_elem}}, Int64}}:\n (ideal(z^2 + 1, y + 1), ideal(z^2 + 1, y + 1), ideal(z - _a, y + 1), 2)\n (ideal(z^6 + 4*z^3 + 4, y - z^2), ideal(z^3 + 2, y - z^2), ideal(z - _a, y - _a*z), 3)\n\njulia> AP = AL[1][3]\nideal(z - _a, y + 1)\n\njulia> RAP = base_ring(AP)\nMultivariate polynomial ring in 2 variables y, z\n over number field of degree 2 over QQ\n\njulia> NF = coefficient_ring(RAP)\nNumber field with defining polynomial x^2 + 1\n over rational field\n\njulia> a = gen(NF)\n_a\n\njulia> minpoly(a)\nx^2 + 1\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [\"x\", \"y\"])\n(Graded multivariate polynomial ring in 2 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y])\n\njulia> I = ideal(R, [x^2+y^2])\nideal(x^2 + y^2)\n\njulia> AL = absolute_primary_decomposition(I)\n1-element Vector{Tuple{MPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}, MPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}, MPolyIdeal{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}, Int64}}:\n (ideal(x^2 + y^2), ideal(x^2 + y^2), ideal(x + _a*y), 2)\n\njulia> AP = AL[1][3]\nideal(x + _a*y)\n\njulia> RAP = base_ring(AP)\nMultivariate polynomial ring in 2 variables over number field graded by \n x -> [1]\n y -> [1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Minimal-Associated-Primes","page":"Ideals in Multivariate Rings","title":"Minimal Associated Primes","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ)","category":"page"},{"location":"CommutativeAlgebra/ideals/#minimal_primes-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"minimal_primes","text":"minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ)\n\nReturn a vector containing the minimal associated prime ideals of I.\n\nImplemented Algorithms\n\nIf the base ring of I is a polynomial ring over a field, the algorithm of Gianni, Trager, and Zacharias is used by default (algorithm = :GTZ). Alternatively, characteristic sets can be used by specifying algorithm = :charSets. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Patrizia Gianni, Barry Trager, Gail Zacharias (1988) and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)\n\njulia> L = minimal_primes(I)\n2-element Vector{MPolyIdeal{QQMPolyRingElem}}:\n ideal(x - y - 1)\n ideal(x^3 - x - y^2)\n\njulia> L = minimal_primes(I, algorithm = :charSets)\n2-element Vector{MPolyIdeal{QQMPolyRingElem}}:\n ideal(x - y - 1)\n ideal(x^3 - x - y^2)\n\njulia> R, (a, b, c, d) = polynomial_ring(ZZ, [\"a\", \"b\", \"c\", \"d\"])\n(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])\n\njulia> I = ideal(R, [1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5,\n 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15,\n 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15,\n 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5,\n 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15,\n 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5])\nideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)\n\njulia> L = minimal_primes(I)\n6-element Vector{MPolyIdeal{ZZMPolyRingElem}}:\n ideal(d, c)\n ideal(b, a)\n ideal(2, c)\n ideal(3)\n ideal(13, b)\n ideal(17, a)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Weak-Equidimensional-Decomposition","page":"Ideals in Multivariate Rings","title":"Weak Equidimensional Decomposition","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"equidimensional_decomposition_weak(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#equidimensional_decomposition_weak-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"equidimensional_decomposition_weak","text":"equidimensional_decomposition_weak(I::MPolyIdeal)\n\nReturn a vector of equidimensional ideals where the last entry is the equidimensional hull of I, that is, the intersection of the primary components of I of maximal dimension. Each of the previous entries is an ideal of lower dimension whose associated primes are exactly the associated primes of I of that dimension.\n\nImplemented Algorithms\n\nThe implementation relies on ideas of Eisenbud, Huneke, and Vasconcelos. See David Eisenbud, Craig Huneke, Wolmer Vasconcelos (1992).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)\n\njulia> L = equidimensional_decomposition_weak(I)\n2-element Vector{MPolyIdeal{QQMPolyRingElem}}:\n ideal(y, x)\n ideal(x^5 - 2*x^4*y - 2*x^4 + x^3*y^2 + 2*x^3*y - x^2*y^2 + 2*x^2*y + 2*x^2 + 2*x*y^3 + x*y^2 - 2*x*y - x - y^4 - 2*y^3 - y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Equidimensional-Decomposition-of-radical","page":"Ideals in Multivariate Rings","title":"Equidimensional Decomposition of radical","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"equidimensional_decomposition_radical(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#equidimensional_decomposition_radical-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"equidimensional_decomposition_radical","text":"equidimensional_decomposition_radical(I::MPolyIdeal)\n\nReturn a vector of equidimensional radical ideals increasingly ordered by dimension. For each dimension, the returned radical ideal is the intersection of the associated primes of I of that dimension. \n\nImplemented Algorithms\n\nThe implementation combines the algorithms of Krick and Logar (with modifications by Laplagne) and Kemper. See Teresa Krick, Alessandro Logar (1991) and Gregor Kemper (2002).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)\n\njulia> L = equidimensional_decomposition_radical(I)\n2-element Vector{MPolyIdeal{QQMPolyRingElem}}:\n ideal(y, x)\n ideal(x^4 - x^3*y - x^3 - x^2 - x*y^2 + x*y + x + y^3 + y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Equidimensional-Hull","page":"Ideals in Multivariate Rings","title":"Equidimensional Hull","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"equidimensional_hull(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#equidimensional_hull-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"equidimensional_hull","text":"equidimensional_hull(I::MPolyIdeal)\n\nIf the base ring of I is a polynomial ring over a field, return the intersection of the primary components of I of maximal dimension. In the case of polynomials over the integers, return the intersection of the primary components of I of minimal height. If I is the unit ideal, return [ideal(1)].\n\nImplemented Algorithms\n\nFor polynomial rings over a field, the implementation relies on ideas as used by Gianni, Trager, and Zacharias or Krick and Logar. For polynomial rings over the integers, the algorithm proceeds as suggested by Pfister, Sadiq, and Steidel. See Patrizia Gianni, Barry Trager, Gail Zacharias (1988), Teresa Krick, Alessandro Logar (1991), and Gerhard Pfister, Afshan Sadiq, Stefan Steidel (2011).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)\n\njulia> L = equidimensional_hull(I)\nideal(x^5 - 2*x^4*y - 2*x^4 + x^3*y^2 + 2*x^3*y - x^2*y^2 + 2*x^2*y + 2*x^2 + 2*x*y^3 + x*y^2 - 2*x*y - x - y^4 - 2*y^3 - y^2)\n\njulia> R, (a, b, c, d) = polynomial_ring(ZZ, [\"a\", \"b\", \"c\", \"d\"])\n(Multivariate polynomial ring in 4 variables over ZZ, ZZMPolyRingElem[a, b, c, d])\n\njulia> I = ideal(R, [1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5,\n 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15,\n 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15,\n 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5,\n 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15,\n 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5])\nideal(1326*a^2*d^5, 1989*a^2*c^5, 102*b^4*d^5, 153*b^4*c^5, 663*a^2*c^5*d^5, 51*b^4*c^5*d^5, 78*a^2*d^15, 117*a^2*c^15, 78*a^15*d^5, 117*a^15*c^5, 6*a^2*b^4*d^15, 9*a^2*b^4*c^15, 39*a^2*c^5*d^15, 39*a^2*c^15*d^5, 6*a^2*b^15*d^5, 9*a^2*b^15*c^5, 6*a^15*b^4*d^5, 9*a^15*b^4*c^5, 39*a^15*c^5*d^5, 3*a^2*b^4*c^5*d^15, 3*a^2*b^4*c^15*d^5, 3*a^2*b^15*c^5*d^5, 3*a^15*b^4*c^5*d^5)\n\njulia> L = equidimensional_hull(I)\nideal(3)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Radical-of-the-Equidimensional-Hull","page":"Ideals in Multivariate Rings","title":"Radical of the Equidimensional Hull","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"equidimensional_hull_radical(I::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#equidimensional_hull_radical-Tuple{MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"equidimensional_hull_radical","text":"equidimensional_hull_radical(I::MPolyIdeal)\n\nReturn the intersection of the associated primes of I of maximal dimension. If I is the unit ideal, return [ideal(1)].\n\nImplemented Algorithms\n\nThe implementation relies on a combination of the algorithms of Krick and Logar (with modifications by Laplagne) and Kemper. See Teresa Krick, Alessandro Logar (1991) and Gregor Kemper (2002).\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = intersect(ideal(R, [x, y])^2, ideal(R, [y^2-x^3+x]))\nideal(x^3*y - x*y - y^3, x^4 - x^2 - x*y^2)\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nideal(x^5*y - 2*x^4*y^2 - 2*x^4*y + x^3*y^3 + 2*x^3*y^2 - x^2*y^3 + 2*x^2*y^2 + 2*x^2*y + 2*x*y^4 + x*y^3 - 2*x*y^2 - x*y - y^5 - 2*y^4 - y^3, x^6 - 2*x^5 - 3*x^4*y^2 - 2*x^4*y + 2*x^3*y^3 + 3*x^3*y^2 + 2*x^3*y + 2*x^3 + 5*x^2*y^2 + 2*x^2*y - x^2 + 3*x*y^4 - 5*x*y^2 - 2*x*y - 2*y^5 - 4*y^4 - 2*y^3)\n\njulia> L = equidimensional_hull_radical(I)\nideal(x^4 - x^3*y - x^3 - x^2 - x*y^2 + x*y + x + y^3 + y^2)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Homogenization-and-Dehomogenization","page":"Ideals in Multivariate Rings","title":"Homogenization and Dehomogenization","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"Referring to Martin Kreuzer, Lorenzo Robbiano (2005) for definitions and technical details, we discuss homogenization and dehomogenization in the context of mathbb Z^m-gradings. ","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"homogenization(f::MPolyRingElem, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName; pos::Union{Int,Nothing}=nothing)","category":"page"},{"location":"CommutativeAlgebra/ideals/#homogenization-Tuple{MPolyRingElem, Union{ZZMatrix, Matrix{<:Union{Integer, ZZRingElem}}}, Union{Char, AbstractString, Symbol}}","page":"Ideals in Multivariate Rings","title":"homogenization","text":"homogenization(f::MPolyRingElem, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName; pos::Int)\nhomogenization(f::MPolyRingElem, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName)\n\nIf m is the number of rows of W, extend the parent polynomial ring of f by inserting m extra variables, starting at position pos (if pos is not specified, it defaults to the position after the last variable). Correspondingly, extend the integer matrix W by inserting the standard unit vectors of size m as new columns, starting at column pos. Grade the extended ring by converting the columns of the extended matrix to elements of the group mathbb Z^m and assigning these as weights to the variables. Homogenize f with respect to the induced mathbb Z^m-grading on the original ring, using the extra variables as homogenizing variables. Return the result as an element of the extended ring with its mathbb Z^m-grading. If m=1, the extra variable prints as var. Otherwise, the extra variables print as var[i], for i = 1 dots m.\n\nhomogenization(V::Vector{T}, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName; pos::Int) where {T <: MPolyRingElem}\nhomogenization(V::Vector{T}, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName) where {T <: MPolyRingElem}\n\nGiven a vector V of elements in a common polynomial ring, create an extended ring with mathbb Z^m-grading as above. Homogenize the elements of V correspondingly, and return the vector of homogenized elements.\n\nhomogenization(I::MPolyIdeal{T}, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName; pos::Int) where {T <: MPolyRingElem}\nhomogenization(I::MPolyIdeal{T}, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, var::VarName) where {T <: MPolyRingElem}\n\nReturn the homogenization of I in an extended ring with mathbb Z^m-grading as above.\n\nnote: Note\nIf W comprises a single row of positive weights then the method used is essentially the same as for the standard-graded case: compute a wdegrevlex Groebner basis then homogenize its elements. Otherwise applied to an ideal I, the function first homogenizes the generators of I in the extended ring. It then creates the ideal generated by these homogenizations, and saturates this ideal with respect to the ideal which is generated by the product of the homogenizing variables. Source: Kreuzer+Robbiano (vol 2) Cor 4.3.8(a), Defn 4.4.1, Cor 4.4.9, Tutorial 37(g)\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> f = x^3+x^2*y+x*y^2+y^3\nx^3 + x^2*y + x*y^2 + y^3\n\njulia> W = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> F = homogenization(f, W, \"z\"; pos=3)\nx^3*z[1]^3*z[2]^3 + x^2*y*z[1]^2*z[2]^2 + x*y^2*z[1]*z[2] + y^3\n\njulia> parent(F)\nMultivariate polynomial ring in 4 variables over QQ graded by\n x -> [1 3]\n y -> [2 4]\n z[1] -> [1 0]\n z[2] -> [0 1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"homogenization(f::MPolyRingElem, var::VarName; pos::Union{Int,Nothing}=nothing)","category":"page"},{"location":"CommutativeAlgebra/ideals/#homogenization-Tuple{MPolyRingElem, Union{Char, AbstractString, Symbol}}","page":"Ideals in Multivariate Rings","title":"homogenization","text":"homogenization(f::MPolyRingElem, var::VarName)\nhomogenization(f::MPolyRingElem, var::VarName; pos::Int)\n\nhomogenization(V::Vector{T}, var::VarName) where {T <: MPolyRingElem}\nhomogenization(V::Vector{T}, var::VarName; pos::Int) where {T <: MPolyRingElem}\n\nhomogenization(I::MPolyIdeal{T}, var::VarName; ordering::Symbol = :degrevlex) where {T <: MPolyRingElem}\nhomogenization(I::MPolyIdeal{T}, var::VarName; pos::Int, ordering::Symbol = :degrevlex) where {T <: MPolyRingElem}\n\nHomogenize f, V, or I with respect to the standard mathbb Z-grading using a homogenizing variable printing as var. Return the result as an element of a graded polynomial ring with the homogenizing variable at position pos; if pos is not specified it defaults to just after the last variable.\n\nnote: Note\nApplied to an ideal I, the function proceeds by homogenizing the elements of a Gröbner basis of I with respect to a degree compatible monomial ordering such as degrevlex (default). If a Gröbner basis with respect to the specified ordering has not yet been computed and, thus, not yet been cached, executing the homogenization function with argument I may take some time. The degree compatibility of the specified ordering is not checked by the function.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> f = x^3-y^2-z\nx^3 - y^2 - z\n\njulia> F = homogenization(f, \"w\"; pos=4)\nx^3 - y^2*w - z*w^2\n\njulia> parent(F)\nMultivariate polynomial ring in 4 variables over QQ graded by\n x -> [1]\n y -> [1]\n z -> [1]\n w -> [1]\n\njulia> V = [y-x^2, z-x^3]\n2-element Vector{QQMPolyRingElem}:\n -x^2 + y\n -x^3 + z\n\njulia> homogenization(V, \"w\")\n2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n -x^2 + y*w\n -x^3 + z*w^2\n\njulia> I = ideal(R, V)\nideal(-x^2 + y, -x^3 + z)\n\njulia> PTC = homogenization(I, \"w\")\nideal(-x*z + y^2, x*y - z*w, x^2 - y*w)\n\njulia> parent(PTC[1])\nMultivariate polynomial ring in 4 variables over QQ graded by\n x -> [1]\n y -> [1]\n z -> [1]\n w -> [1]\n\njulia> homogenization(I, \"w\"; ordering = deglex(gens(base_ring(I))))\nideal(x*z - y^2, x*y - z*w, x^2 - y*w, y^3 - z^2*w)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"dehomogenization(F::MPolyDecRingElem, pos::Int)","category":"page"},{"location":"CommutativeAlgebra/ideals/#dehomogenization-Tuple{MPolyDecRingElem, Int64}","page":"Ideals in Multivariate Rings","title":"dehomogenization","text":"dehomogenization(F::MPolyDecRingElem, pos::Int)\n\nGiven an element F of a mathbb Z^m-graded ring, where the generators of mathbb Z^m are the assigned weights to the variables at positions pos, dots, pos -1+m, dehomogenize F using the variables at these positions. Return the result as an element of a polynomial ring not depending on the variables at these positions.\n\ndehomogenization(V::Vector{T}, pos::Int) where {T <: MPolyDecRingElem}\n\nGiven a vector V of elements in a common graded polynomial ring, create a polynomial ring not depending on the variables at positions pos, dots, pos -1+m. Dehomogenize the elements of V correspondingly, and return the vector of dehomogenized elements. \n\ndehomogenization(I::MPolyIdeal{T}, pos::Int) where {T <: MPolyDecRingElem}\n\nReturn the dehomogenization of I in a polynomial ring as above.\n\nExamples\n\njulia> S, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> F = x^3-x^2*y-x*z^2\nx^3 - x^2*y - x*z^2\n\njulia> f = dehomogenization(F, 1)\n-y - z^2 + 1\n\njulia> parent(f)\nMultivariate polynomial ring in 2 variables y, z\n over rational field\n\njulia> V = [x*y-z^2, x^2*z-x^3]\n2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x*y - z^2\n -x^3 + x^2*z\n\njulia> dehomogenization(V, 3)\n2-element Vector{QQMPolyRingElem}:\n x*y - 1\n -x^3 + x^2\n\njulia> I = ideal(S, V)\nideal(x*y - z^2, -x^3 + x^2*z)\n\njulia> dehomogenization(I, 3)\nideal(x*y - 1, -x^3 + x^2)\n\njulia> W = [1 2 1 0; 3 4 0 1]\n2×4 Matrix{Int64}:\n 1 2 1 0\n 3 4 0 1\n\njulia> S, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"], W)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[w, x, y, z])\n\njulia> F = w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3\nw^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3\n\njulia> dehomogenization(F, 3)\nw^3 + w^2*x + w*x^2 + x^3\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#Generating-Special-Ideals","page":"Ideals in Multivariate Rings","title":"Generating Special Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/#Katsura-n","page":"Ideals in Multivariate Rings","title":"Katsura-n","text":"","category":"section"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"These systems appeared in a problem of magnetism in physics. For a given n katsura(n) has 2^n solutions and is defined in a polynomial ring with n+1 variables over the rational numbers. For a given polynomial ring R with n variables katsura(R) defines the corresponding system with 2^n-1 solutions.","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"katsura(n::Int)","category":"page"},{"location":"CommutativeAlgebra/ideals/#katsura-Tuple{Int64}","page":"Ideals in Multivariate Rings","title":"katsura","text":"katsura(n::Int)\n\nGiven a natural number n return the Katsura ideal over the rational numbers generated by u_m - sum_l=-n^n u_l-m u_l, 1 - sum_l = -n^n u_l where u_-i = u_i, and u_i = 0 for i n and m in -n ldots n.\n\nNote that indices have been shifted to start from 1.\n\nExamples\n\njulia> I = katsura(2)\nideal(x1 + 2*x2 + 2*x3 - 1, x1^2 - x1 + 2*x2^2 + 2*x3^2, 2*x1*x2 + 2*x2*x3 - x2)\njulia> base_ring(I)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"katsura(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/ideals/#katsura-Tuple{MPolyRing}","page":"Ideals in Multivariate Rings","title":"katsura","text":"katsura(R::MPolyRing)\n\nReturn the Katsura ideal in the given polynomial ring R.\n\nExamples\n\njulia> R, _ = QQ[\"x\", \"y\", \"z\"]\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> katsura(R)\nideal(x + 2*y + 2*z - 1, x^2 - x + 2*y^2 + 2*z^2, 2*x*y + 2*y*z - y)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/matrix/#Matrix-functionality","page":"Matrix functionality","title":"Matrix functionality","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"AbstractAlgebra.jl provides a module, implemented in src/Matrix.jl for matrices over any ring belonging to the AbstractAlgebra abstract type hierarchy. This functionality will work for any matrix type which follows the Matrix interface.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Similarly, AbstractAlgebra.jl provides a module in src/MatrixAlgebra.jl for matrix algebras over a ring.","category":"page"},{"location":"AbstractAlgebra/matrix/#Generic-matrix-types","page":"Matrix functionality","title":"Generic matrix types","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"AbstractAlgebra.jl allows the creation of dense matrices over any computable ring R. Generic matrices over a ring are implemented in src/generic/Matrix.jl.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Generic matrix algebras of mtimes m matrices are implemented in src/generic/MatrixAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Generic matrices in AbstractAlgebra.jl have type Generic.MatSpaceElem{T} for matrices in a matrix space, or Generic.MatAlgElem{T} for matrices in a matrix algebra, where T is the type of elements of the matrix. Internally, generic matrices are implemented using an object wrapping a Julia two dimensional array, though they are not themselves Julia arrays. See the file src/generic/GenericTypes.jl for details.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"For the most part, one doesn't want to work directly with the MatSpaceElem type though, but with an abstract type called Generic.Mat which includes MatSpaceElem and views thereof.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Parents of generic matrices (matrix spaces) have type Generic.MatSpace{T}. Parents of matrices in a matrix algebra have type Generic.MatAlgebra{T}.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"The dimensions and base ring R of a generic matrix are stored in its parent object, however to allow creation of matrices without first creating the matrix space parent, generic matrices in Julia do not contain a reference to their parent. They contain the row and column numbers (or degree, in the case of matrix algebras) and the base ring on a per matrix basis. The parent object can then be reconstructed from this data on demand.","category":"page"},{"location":"AbstractAlgebra/matrix/#Abstract-types","page":"Matrix functionality","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"The generic matrix types (matrix spaces) belong to the abstract type MatElem{T} and the matrix space parent types belong to MatSpace{T}. Similarly the generic matrix algebra matrix types belong to the abstract type MatAlgElem{T} and the parent types belong to MatAlgebra{T} Note that both the concrete type of a matrix space parent object and the abstract class it belongs to have the name MatElem, therefore disambiguation is required to specify which is intended. The same is true for the abstract types for matrix spaces and their elements.","category":"page"},{"location":"AbstractAlgebra/matrix/#Matrix-space-constructors","page":"Matrix functionality","title":"Matrix space constructors","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"A matrix space in AbstractAlgebra.jl represents a collection of all matrices with given dimensions and base ring.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"In order to construct matrices in AbstractAlgebra.jl, one can first construct the matrix space itself. This is accomplished with the following constructor. We discuss creation of matrix algebras separately in a dedicated section elsewhere in the documentation.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"matrix_space(R::Ring, rows::Int, cols::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Construct the space of matrices with the given number of rows and columns over the given base ring.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Here are some examples of creating matrix spaces and making use of the resulting parent objects to coerce various elements into the matrix space.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> A = S()\n[0 0 0]\n[0 0 0]\n[0 0 0]\n\njulia> B = S(12)\n[12 0 0]\n[ 0 12 0]\n[ 0 0 12]\n\njulia> C = S(R(11))\n[11 0 0]\n[ 0 11 0]\n[ 0 0 11]\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Matrix-element-constructors","page":"Matrix functionality","title":"Matrix element constructors","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"There are a few ways to construct matrices other than by coercing elements as shown above. The first method is from an array of elements.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"This can be done with either two or one dimensional arrays.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"(S::MatSpace{T})(A::Matrix{S}) where {S <: RingElement, T <: RingElement}\n(S::MatAlgebra{T})(A::Matrix{S}) where {S <: RingElement, T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Create the matrix in the given space/algebra whose (i j) entry is given by A[i, j], where S is the type of elements that can be coerced into the base ring of the matrix.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"(S::MyMatSpace{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}\n(S::MyMatAlgebra{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Create the matrix in the given space/algebra of matrices (with dimensions mtimes n say), whose (i j) entry is given by A[i*(n - 1) + j] and where S is the type of elements that can be coerced into the base ring of the matrix.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"We also provide the following syntax for constructing literal matrices (similar to how Julia arrays can be be constructed).","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"R[a b c...;...]","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Create the matrix over the base ring R consisting of the given rows (separated by semicolons). Each entry is coerced into R automatically. Note that parentheses may be placed around individual entries if the lists would otherwise be ambiguous, e.g. R[1 2; 2 (- 3)].","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Also see the Matrix interface for a list of other ways to create matrices.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> S = matrix_space(QQ, 2, 3)\nMatrix space of 2 rows and 3 columns\n over rationals\n\njulia> T = MatrixAlgebra(QQ, 2)\nMatrix algebra of degree 2\n over rationals\n\njulia> M1 = S(Rational{BigInt}[2 3 1; 1 0 4])\n[2//1 3//1 1//1]\n[1//1 0//1 4//1]\n\njulia> M2 = S(BigInt[2 3 1; 1 0 4])\n[2//1 3//1 1//1]\n[1//1 0//1 4//1]\n\njulia> M3 = S(BigInt[2, 3, 1, 1, 0, 4])\n[2//1 3//1 1//1]\n[1//1 0//1 4//1]\n\njulia> N1 = T(Rational{BigInt}[2 3; 1 0])\n[2//1 3//1]\n[1//1 0//1]\n\njulia> N2 = T(BigInt[2 3; 1 0])\n[2//1 3//1]\n[1//1 0//1]\n\njulia> N3 = T(BigInt[2, 3, 1, 1])\n[2//1 3//1]\n[1//1 1//1]\n\njulia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> M = R[t + 1 1; t^2 0]\n[t + 1 1]\n[ t^2 0]\n\njulia> N = R[t + 1 2 t] # create a row vector\n[t + 1 2 t]\n\njulia> P = R[1; 2; t] # create a column vector\n[1]\n[2]\n[t]","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"It is also possible to create matrices (in a matrix space only) directly, without first creating the corresponding matrix space (the inner constructor being called directly).","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"matrix(R::Ring, arr::Matrix{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Given an mtimes n Julia matrix of entries, construct the corresponding AbstractAlgebra.jl matrix over the given ring R, assuming all the entries can be coerced into R.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"matrix(R::Ring, r::Int, c::Int, A::Vector{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Construct the given rtimes c AbstractAlgebra.jl matrix over the ring R whose (i j) entry is given by A[c*(i - 1) + j], assuming that all the entries can be coerced into R.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"zero_matrix(R::Ring, r::Int, c::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Construct the rtimes c AbstractAlgebra.jl zero matrix over the ring R.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> M = matrix(ZZ, BigInt[3 1 2; 2 0 1])\n[3 1 2]\n[2 0 1]\n\njulia> N = matrix(ZZ, 3, 2, BigInt[3, 1, 2, 2, 0, 1])\n[3 1]\n[2 2]\n[0 1]\n\njulia> P = zero_matrix(ZZ, 3, 2)\n[0 0]\n[0 0]\n[0 0]\n\njulia> R = MatrixAlgebra(ZZ, 2)\nMatrix algebra of degree 2\n over integers\n\njulia> M = R()\n[0 0]\n[0 0]","category":"page"},{"location":"AbstractAlgebra/matrix/#Block-diagonal-matrix-constructors","page":"Matrix functionality","title":"Block diagonal matrix constructors","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"It is also possible to create block diagonal matrices from a vector of existing matrices. It is also possible to construct them from Julia matrices if one supplies the base ring.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Note that if the input matrices are not square, the output matrix may not be square.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"block_diagonal_matrix(::Vector{<:MatElem{T}}) where T <: RingElement\nblock_diagonal_matrix(::Ring, ::Vector{<:Matrix{T}}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#block_diagonal_matrix-Union{Tuple{Vector{<:MatElem{T}}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"block_diagonal_matrix","text":"block_diagonal_matrix(V::Vector{<:MatElem{T}}) where T <: NCRingElement\n\nCreate the block diagonal matrix whose blocks are given by the matrices in V. There must be at least one matrix in V.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#block_diagonal_matrix-Union{Tuple{T}, Tuple{Ring, Vector{<:Matrix{T}}}} where T<:RingElement","page":"Matrix functionality","title":"block_diagonal_matrix","text":"block_diagonal_matrix(R::NCRing, V::Vector{<:Matrix{T}}) where T <: NCRingElement\n\nCreate the block diagonal matrix over the ring R whose blocks are given by the matrices in V. Entries are coerced into R upon creation.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> block_diagonal_matrix(ZZ, [[1 2; 3 4], [4 5 6; 7 8 9]])\n[1 2 0 0 0]\n[3 4 0 0 0]\n[0 0 4 5 6]\n[0 0 7 8 9]\n\njulia> M = matrix(ZZ, [1 2; 3 4])\n[1 2]\n[3 4]\n\njulia> N = matrix(ZZ, [4 5 6; 7 8 9])\n[4 5 6]\n[7 8 9]\n\njulia> block_diagonal_matrix([M, N])\n[1 2 0 0 0]\n[3 4 0 0 0]\n[0 0 4 5 6]\n[0 0 7 8 9]","category":"page"},{"location":"AbstractAlgebra/matrix/#Conversion-to-Julia-matrices-and-iteration","page":"Matrix functionality","title":"Conversion to Julia matrices and iteration","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"While AbstractAlgebra matrices are not instances of AbstractArray, they are closely related to Julia matrices. For convenience, a Matrix and an Array constructors taking an AbstractAlgebra matrix as input are provided:","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Matrix(::MatrixElem{T}) where T <: RingElement\nArray(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#Matrix-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"Matrix","text":"Matrix(A::MatrixElem{T}) where T <: RingElement\n\nConvert A to a Julia Matrix of the same dimensions with the same elements.\n\nExamples\n\njulia> A = ZZ[1 2 3; 4 5 6]\n[1 2 3]\n[4 5 6]\n\njulia> Matrix(A)\n2×3 Matrix{BigInt}:\n 1 2 3\n 4 5 6\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Array-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"Array","text":"Array(A::MatrixElem{T}) where T <: RingElement\n\nConvert A to a Julia Matrix of the same dimensions with the same elements.\n\nExamples\n\njulia> R, x = ZZ[\"x\"]; A = R[x^0 x^1; x^2 x^3]\n[ 1 x]\n[x^2 x^3]\n\njulia> Array(A)\n2×2 Matrix{AbstractAlgebra.Generic.Poly{BigInt}}:\n 1 x\n x^2 x^3\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Matrices also support iteration, and therefore functions accepting an iterator can be called on them, e.g.:","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> M = matrix_space(ZZ, 2, 3); x = M(1:6)\n[1 2 3]\n[4 5 6]\n\njulia> collect(x)\n2×3 Matrix{BigInt}:\n 1 2 3\n 4 5 6\n\njulia> Set(x)\nSet{BigInt} with 6 elements:\n 5\n 4\n 6\n 2\n 3\n 1","category":"page"},{"location":"AbstractAlgebra/matrix/#Views","page":"Matrix functionality","title":"Views","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"As per Julia, AbstractAlgebra supports the construction of matrix views. These allow one to work with a submatrix of a given matrix. Modifying the submatrix also modifies the original matrix.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"The syntax for views is as for Julia's own views.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> M = matrix(ZZ, 3, 3, BigInt[1, 2, 3, 2, 3, 4, 3, 4, 5])\n[1 2 3]\n[2 3 4]\n[3 4 5]\n\njulia> N1 = @view M[1:2, :]\n[1 2 3]\n[2 3 4]\n\njulia> N2 = @view M[:, 1:2]\n[1 2]\n[2 3]\n[3 4]\n\njulia> R = N1*N2\n[14 20]\n[20 29]","category":"page"},{"location":"AbstractAlgebra/matrix/#Matrix-functionality-provided-by-AbstractAlgebra.jl","page":"Matrix functionality","title":"Matrix functionality provided by AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Most of the following generic functionality is available for both matrix spaces and matrix algebras. Exceptions include functions that do not return or accept square matrices or which cannot specify a parent. Such functions include solve, kernel, and nullspace which can't be provided for matrix algebras.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"For details on functionality that is provided for matrix algebras only, see the dedicated section of the documentation.","category":"page"},{"location":"AbstractAlgebra/matrix/#Basic-matrix-functionality","page":"Matrix functionality","title":"Basic matrix functionality","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"As well as the Ring and Matrix interfaces, the following functions are provided to manipulate matrices and to set and retrieve entries and other basic data associated with the matrices.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"dense_matrix_type(::Ring)","category":"page"},{"location":"AbstractAlgebra/matrix/#dense_matrix_type-Tuple{Ring}","page":"Matrix functionality","title":"dense_matrix_type","text":"dense_matrix_type(::Type{T}) where T<:NCRingElement\ndense_matrix_type(::T) where T<:NCRingElement\ndense_matrix_type(::Type{S}) where S<:NCRing\ndense_matrix_type(::S) where S<:NCRing\n\nReturn the type of matrices with coefficients of type T respectively elem_type(S).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"nrows(::MatSpace)\nncols(::MatSpace)","category":"page"},{"location":"AbstractAlgebra/matrix/#nrows-Tuple{MatSpace}","page":"Matrix functionality","title":"nrows","text":"nrows(a::MatSpace)\n\nReturn the number of rows of the given matrix space.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#ncols-Tuple{MatSpace}","page":"Matrix functionality","title":"ncols","text":"ncols(a::MatSpace)\n\nReturn the number of columns of the given matrix space.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"nrows(::MatrixElem{T}) where T <: RingElement\nncols(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#nrows-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"nrows","text":"nrows(a::MatrixElem{T}) where T <: NCRingElement\n\nReturn the number of rows of the given matrix.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#ncols-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"ncols","text":"ncols(a::MatrixElem{T}) where T <: NCRingElement\n\nReturn the number of columns of the given matrix.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"length(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#length-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"length","text":"length(a::MatrixElem{T}) where T <: NCRingElement\n\nReturn the number of entries in the given matrix.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"isempty(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#isempty-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"isempty","text":"isempty(a::MatrixElem{T}) where T <: NCRingElement\n\nReturn true if a does not contain any entry (i.e. length(a) == 0), and false otherwise.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"identity_matrix(::Ring, ::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/#identity_matrix-Tuple{Ring, Int64}","page":"Matrix functionality","title":"identity_matrix","text":"identity_matrix(R::NCRing, n::Int)\n\nReturn the n times n identity matrix over R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"identity_matrix(::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#identity_matrix-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"identity_matrix","text":"identity_matrix(M::MatElem{T}) where T <: NCRingElement\n\nConstruct the identity matrix in the same matrix space as M, i.e. with ones down the diagonal and zeroes elsewhere. M must be square. This is an alias for one(M).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"diagonal_matrix(::RingElement, ::Int, ::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/#diagonal_matrix-Tuple{RingElement, Int64, Int64}","page":"Matrix functionality","title":"diagonal_matrix","text":"diagonal_matrix(x::RingElement, m::Int, [n::Int])\n\nReturn the m times n matrix over R with x along the main diagonal and zeroes elsewhere. If n is not specified, it defaults to m.\n\nExamples\n\njulia> diagonal_matrix(ZZ(2), 2, 3)\n[2 0 0]\n[0 2 0]\n\njulia> diagonal_matrix(QQ(-1), 3)\n[-1//1 0//1 0//1]\n[ 0//1 -1//1 0//1]\n[ 0//1 0//1 -1//1]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"zero(::MatSpace)\nzero(::MatrixElem{T}, ::Ring) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#zero-Tuple{MatSpace}","page":"Matrix functionality","title":"zero","text":"zero(a::MatSpace)\n\nReturn the zero matrix in the given matrix space.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#zero-Union{Tuple{T}, Tuple{MatrixElem{T}, Ring}} where T<:RingElement","page":"Matrix functionality","title":"zero","text":"zero(x::MatrixElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement\nzero(x::MatrixElem{T}, R::NCRing=base_ring(x)) where T <: NCRingElement\nzero(x::MatrixElem{T}, r::Int, c::Int) where T <: NCRingElement\n\nReturn a zero matrix similar to the given matrix, with optionally different base ring or dimensions.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"one(::MatSpace)\none(::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#one-Tuple{MatSpace}","page":"Matrix functionality","title":"one","text":"one(a::MatSpace)\n\nReturn the identity matrix of given matrix space. The matrix space must contain square matrices or else an error is thrown.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#one-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"one","text":"one(a::MatrixElem{T}) where T <: NCRingElement\n\nReturn the identity matrix in the same matrix space as a. If the space does not contain square matrices, an error is thrown.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"lower_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/matrix/#lower_triangular_matrix-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"lower_triangular_matrix","text":"lower_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}\n\nReturn the n by n matrix whose entries on and below the main diagonal are the elements of L, and which has zeroes elsewhere. The value of n is determined by the condition that L has length n(n+1)2.\n\nAn exception is thrown if there is no integer n with this property.\n\nExamples\n\njulia> lower_triangular_matrix([1, 2, 3])\n[1 0]\n[2 3]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"upper_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/matrix/#upper_triangular_matrix-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"upper_triangular_matrix","text":"upper_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}\n\nReturn the n by n matrix whose entries on and above the main diagonal are the elements of L, and which has zeroes elsewhere. The value of n is determined by the condition that L has length n(n+1)2.\n\nAn exception is thrown if there is no integer n with this property.\n\nExamples\n\njulia> upper_triangular_matrix([1, 2, 3])\n[1 2]\n[0 3]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"strictly_lower_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/matrix/#strictly_lower_triangular_matrix-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"strictly_lower_triangular_matrix","text":"strictly_lower_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}\n\nReturn the n by n matrix whose entries below the main diagonal are the elements of L, and which has zeroes elsewhere. The value of n is determined by the condition that L has length (n-1)n2.\n\nAn exception is thrown if there is no integer n with this property.\n\nExamples\n\njulia> strictly_lower_triangular_matrix([1, 2, 3])\n[0 0 0]\n[1 0 0]\n[2 3 0]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"strictly_upper_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/matrix/#strictly_upper_triangular_matrix-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"strictly_upper_triangular_matrix","text":"strictly_upper_triangular_matrix(L::AbstractVector{T}) where {T <: RingElement}\n\nReturn the n by n matrix whose entries above the main diagonal are the elements of L, and which has zeroes elsewhere. The value of n is determined by the condition that L has length (n-1)n2.\n\nAn exception is thrown if there is no integer n with this property.\n\nExamples\n\njulia> strictly_upper_triangular_matrix([1, 2, 3])\n[0 1 2]\n[0 0 3]\n[0 0 0]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_upper_triangular(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#is_upper_triangular-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"is_upper_triangular","text":"is_upper_triangular(A::MatrixElem{T}) where T <: RingElement\n\nReturn true if A is an upper triangular matrix.\n\nAlias for LinearAlgebra.istriu.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"change_base_ring(::Ring, ::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#change_base_ring-Union{Tuple{T}, Tuple{Ring, MatElem{T}}} where T<:RingElement","page":"Matrix functionality","title":"change_base_ring","text":"change_base_ring(R::NCRing, M::MatrixElem{T}) where T <: NCRingElement\n\nReturn the matrix obtained by coercing each entry into R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Base.map(f, ::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#map-Union{Tuple{T}, Tuple{Any, MatrixElem{T}}} where T<:RingElement","page":"Matrix functionality","title":"map","text":"map(f, a::MatrixElem{T}) where T <: NCRingElement\n\nTransform matrix a by applying f on each element. This is equivalent to map_entries(f, a).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Base.map!(f, ::MatrixElem{S}, ::MatrixElem{T}) where {S <: RingElement, T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/matrix/#map!-Union{Tuple{T}, Tuple{S}, Tuple{Any, MatrixElem{S}, MatrixElem{T}}} where {S<:RingElement, T<:RingElement}","page":"Matrix functionality","title":"map!","text":"map!(f, dst::MatrixElem{T}, src::MatrixElem{U}) where {T <: NCRingElement, U <: NCRingElement}\n\nLike map, but stores the result in dst rather than a new matrix. This is equivalent to map_entries!(f, dst, src).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> B = S([R(2) R(3) R(1); t t + 1 t + 2; R(-1) t^2 t^3])\n[ 2 3 1]\n[ t t + 1 t + 2]\n[-1 t^2 t^3]\n\njulia> T = dense_matrix_type(R)\nAbstractAlgebra.Generic.MatSpaceElem{AbstractAlgebra.Generic.Poly{Rational{BigInt}}}\n\njulia> r = nrows(B)\n3\n\njulia> c = ncols(B)\n3\n\njulia> length(B)\n9\n\njulia> isempty(B)\nfalse\n\njulia> M = A + B\n[ t + 3 t + 3 2]\n[t^2 + t 2*t + 1 2*t + 2]\n[ -3 t^2 + t + 2 t^3 + t^2 + t + 1]\n\njulia> N = 2 + A\n[t + 3 t 1]\n[ t^2 t + 2 t]\n[ -2 t + 2 t^2 + t + 3]\n\njulia> M1 = deepcopy(A)\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> A != B\ntrue\n\njulia> isone(one(S))\ntrue\n\njulia> V = A[1:2, :]\n[t + 1 t 1]\n[ t^2 t t]\n\njulia> W = A^3\n[ 3*t^4 + 4*t^3 + t^2 - 3*t - 5 t^4 + 5*t^3 + 10*t^2 + 7*t + 4 2*t^4 + 7*t^3 + 9*t^2 + 8*t + 1]\n[t^5 + 4*t^4 + 3*t^3 - 7*t^2 - 4*t 4*t^4 + 8*t^3 + 7*t^2 + 2*t t^5 + 5*t^4 + 9*t^3 + 7*t^2 - t]\n[ t^5 + 3*t^4 - 10*t^2 - 16*t - 2 t^5 + 6*t^4 + 12*t^3 + 11*t^2 + 5*t - 2 t^6 + 3*t^5 + 8*t^4 + 15*t^3 + 10*t^2 + t - 5]\n\njulia> Z = divexact(2*A, 2)\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> M = matrix(ZZ, BigInt[2 3 0; 1 1 1])\n[2 3 0]\n[1 1 1]\n\njulia> M[1, 2] = BigInt(4)\n4\n\njulia> c = M[1, 1]\n2\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Transpose","page":"Matrix functionality","title":"Transpose","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"transpose(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#transpose-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"transpose","text":"transpose(x::MatrixElem{T}) where T <: RingElement\n\nReturn the transpose of the given matrix.\n\nExamples\n\njulia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> B = transpose(A)\n[t + 1 t^2 -2]\n[ t t t + 2]\n[ 1 t t^2 + t + 1]\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Submatrices","page":"Matrix functionality","title":"Submatrices","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Submatrices are only available for matrix spaces, not for matrix algebras and generally only available for generic matrices built on Julia arrays.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Submatrices return a new matrix with the same entries as the submatrix with the given range of rows and columns. They are best illustrated with examples.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> M = matrix(ZZ, BigInt[1 2 3; 2 3 4; 3 4 5])\n[1 2 3]\n[2 3 4]\n[3 4 5]\n\njulia> N1 = M[1:2, :]\n[1 2 3]\n[2 3 4]\n\njulia> N2 = M[:, :]\n[1 2 3]\n[2 3 4]\n[3 4 5]\n\njulia> N3 = M[2:3, 2:3]\n[3 4]\n[4 5]\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Elementary-row-and-column-operations","page":"Matrix functionality","title":"Elementary row and column operations","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"add_column(::MatElem{T}, ::Int, ::Int, ::Int) where T <: RingElement\nadd_column!(::MatElem{T}, ::Int, ::Int, ::Int) where T <: RingElement\nadd_row(::MatElem{T}, ::Int, ::Int, ::Int) where T <: RingElement\nadd_row!(::MatElem{T}, ::Int, ::Int, ::Int) where T <: RingElement\nmultiply_column(::MatElem{T}, ::Int, ::Int) where T <: RingElement\nmultiply_column!(::MatElem{T}, ::Int, ::Int) where T <: RingElement\nmultiply_row(::MatElem{T}, ::Int, ::Int) where T <: RingElement\nmultiply_row!(::MatElem{T}, ::Int, ::Int) where T <: RingElement\n","category":"page"},{"location":"AbstractAlgebra/matrix/#add_column-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"add_column","text":"add_column(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, rows = 1:nrows(a)) where T <: RingElement\n\nCreate a copy of a and add s times the i-th row to the j-th row of a.\n\nBy default, the transformation is applied to all rows of a. This can be changed using the optional rows argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#add_column!-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"add_column!","text":"add_column!(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, rows = 1:nrows(a)) where T <: RingElement\n\nAdd s times the i-th row to the j-th row of a.\n\nBy default, the transformation is applied to all rows of a. This can be changed using the optional rows argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#add_row-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"add_row","text":"add_row(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, cols = 1:ncols(a)) where T <: RingElement\n\nCreate a copy of a and add s times the i-th row to the j-th row of a.\n\nBy default, the transformation is applied to all columns of a. This can be changed using the optional cols argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#add_row!-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"add_row!","text":"add_row!(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, cols = 1:ncols(a)) where T <: RingElement\n\nAdd s times the i-th row to the j-th row of a.\n\nBy default, the transformation is applied to all columns of a. This can be changed using the optional cols argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#multiply_column-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"multiply_column","text":"multiply_column(a::MatrixElem{T}, s::RingElement, i::Int, rows = 1:nrows(a)) where T <: RingElement\n\nCreate a copy of a and multiply the ith column of a with s.\n\nBy default, the transformation is applied to all rows of a. This can be changed using the optional rows argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#multiply_column!-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"multiply_column!","text":"multiply_column!(a::MatrixElem{T}, s::RingElement, i::Int, rows = 1:nrows(a)) where T <: RingElement\n\nMultiply the ith column of a with s.\n\nBy default, the transformation is applied to all rows of a. This can be changed using the optional rows argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#multiply_row-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"multiply_row","text":"multiply_row(a::MatrixElem{T}, s::RingElement, i::Int, cols = 1:ncols(a)) where T <: RingElement\n\nCreate a copy of a and multiply the ith row of a with s.\n\nBy default, the transformation is applied to all columns of a. This can be changed using the optional cols argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#multiply_row!-Union{Tuple{T}, Tuple{MatElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"multiply_row!","text":"multiply_row!(a::MatrixElem{T}, s::RingElement, i::Int, cols = 1:ncols(a)) where T <: RingElement\n\nMultiply the ith row of a with s.\n\nBy default, the transformation is applied to all columns of a. This can be changed using the optional cols argument.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> M = ZZ[1 2 3; 2 3 4; 4 5 5]\n[1 2 3]\n[2 3 4]\n[4 5 5]\n\njulia> add_column(M, 2, 3, 1)\n[ 7 2 3]\n[10 3 4]\n[14 5 5]\n\njulia> add_row(M, 1, 2, 3)\n[1 2 3]\n[2 3 4]\n[6 8 9]\n\njulia> multiply_column(M, 2, 3)\n[1 2 6]\n[2 3 8]\n[4 5 10]\n\njulia> multiply_row(M, 2, 3)\n[1 2 3]\n[2 3 4]\n[8 10 10]","category":"page"},{"location":"AbstractAlgebra/matrix/#Swapping-rows-and-columns","page":"Matrix functionality","title":"Swapping rows and columns","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"swap_rows(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement\nswap_rows!(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement\nswap_cols(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement\nswap_cols!(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#swap_rows-Union{Tuple{T}, Tuple{MatrixElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"swap_rows","text":"swap_rows(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement\n\nReturn a matrix b with the entries of a, where the ith and jth row are swapped.\n\nExamples\n\njulia> M = identity_matrix(ZZ, 3)\n[1 0 0]\n[0 1 0]\n[0 0 1]\n\njulia> swap_rows(M, 1, 2)\n[0 1 0]\n[1 0 0]\n[0 0 1]\n\njulia> M # was not modified\n[1 0 0]\n[0 1 0]\n[0 0 1]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#swap_rows!-Union{Tuple{T}, Tuple{MatrixElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"swap_rows!","text":"swap_rows!(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement\n\nSwap the ith and jth row of a in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).\n\nExamples\n\njulia> M = identity_matrix(ZZ, 3)\n[1 0 0]\n[0 1 0]\n[0 0 1]\n\njulia> swap_rows!(M, 1, 2)\n[0 1 0]\n[1 0 0]\n[0 0 1]\n\njulia> M # was modified\n[0 1 0]\n[1 0 0]\n[0 0 1]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#swap_cols-Union{Tuple{T}, Tuple{MatrixElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"swap_cols","text":"swap_cols(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement\n\nReturn a matrix b with the entries of a, where the ith and jth row are swapped.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#swap_cols!-Union{Tuple{T}, Tuple{MatrixElem{T}, Int64, Int64}} where T<:RingElement","page":"Matrix functionality","title":"swap_cols!","text":"swap_cols!(a::MatrixElem{T}, i::Int, j::Int) where T <: RingElement\n\nSwap the ith and jth column of a in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Swap the rows of M in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).","category":"page"},{"location":"AbstractAlgebra/matrix/#Concatenation","page":"Matrix functionality","title":"Concatenation","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"The following are only available for matrix spaces, not for matrix algebras.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"hcat(M::T, N::T) where T <: MatElem","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Return the horizontal concatenation of M and N. It is assumed that the number of rows of M and N are the same.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"vcat(M::T, N::T) where T <: MatElem","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Return the vertical concatenation of M and N. It is assumed that the number of columns of M and N are the same.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> M = matrix(ZZ, BigInt[1 2 3; 2 3 4; 3 4 5])\n[1 2 3]\n[2 3 4]\n[3 4 5]\n\njulia> N = matrix(ZZ, BigInt[1 0 1; 0 1 0; 1 0 1])\n[1 0 1]\n[0 1 0]\n[1 0 1]\n\njulia> P = hcat(M, N)\n[1 2 3 1 0 1]\n[2 3 4 0 1 0]\n[3 4 5 1 0 1]\n\njulia> Q = vcat(M, N)\n[1 2 3]\n[2 3 4]\n[3 4 5]\n[1 0 1]\n[0 1 0]\n[1 0 1]\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Similar-and-zero","page":"Matrix functionality","title":"Similar and zero","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Both similar and zero construct new matrices, but the entries are either undefined with similar or zero-initialized with zero.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"similar(x::MatElem, R::Ring=base_ring(x))\nzero(x::MatElem, R::Ring=base_ring(x))","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Construct the matrix with the same dimensions as the given matrix, and the same base ring unless explicitly specified.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"similar(x::MatElem, R::Ring, r::Int, c::Int)\nsimilar(x::MatElem, r::Int, c::Int)\nzero(x::MatElem, R::Ring, r::Int, c::Int)\nzero(x::MatElem, r::Int, c::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Construct the rtimes c matrix with R as base ring (which defaults to the base ring of the the given matrix). If x belongs to a matrix algebra and r neq c, an exception is raised, and it's also possible to specify only one Int as the order (e.g. similar(x, n)).","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Base.isassigned(M::MatElem, i, j)","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Test whether the given matrix has a value associated with indices i and j.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> M = matrix(ZZ, BigInt[3 1 2; 2 0 1])\n[3 1 2]\n[2 0 1]\n\njulia> isassigned(M, 1, 2)\ntrue\n\njulia> isassigned(M, 4, 4)\nfalse\n\njulia> A = similar(M)\n[#undef #undef #undef]\n[#undef #undef #undef]\n\njulia> isassigned(A, 1, 2)\nfalse\n\njulia> B = zero(M)\n[0 0 0]\n[0 0 0]\n\njulia> C = similar(M, 4, 5)\n[#undef #undef #undef #undef #undef]\n[#undef #undef #undef #undef #undef]\n[#undef #undef #undef #undef #undef]\n[#undef #undef #undef #undef #undef]\n\njulia> base_ring(B)\nIntegers\n\njulia> D = zero(M, QQ, 2, 2)\n[0//1 0//1]\n[0//1 0//1]\n\njulia> base_ring(D)\nRationals","category":"page"},{"location":"AbstractAlgebra/matrix/#Symmetry-testing","page":"Matrix functionality","title":"Symmetry testing","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_symmetric(a::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#is_symmetric-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"is_symmetric","text":"is_symmetric(a::MatrixElem{T}) where T <: RingElement\n\nReturn true if the given matrix is symmetric with respect to its main diagonal, i.e., tr(M) == M, otherwise return false.\n\nAlias for LinearAlgebra.issymmetric.\n\nExamples\n\njulia> M = matrix(ZZ, [1 2 3; 2 4 5; 3 5 6])\n[1 2 3]\n[2 4 5]\n[3 5 6]\n\njulia> is_symmetric(M)\ntrue\n\njulia> N = matrix(ZZ, [1 2 3; 4 5 6; 7 8 9])\n[1 2 3]\n[4 5 6]\n[7 8 9]\n\njulia> is_symmetric(N)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_skew_symmetric(::MatElem)","category":"page"},{"location":"AbstractAlgebra/matrix/#is_skew_symmetric-Tuple{MatElem}","page":"Matrix functionality","title":"is_skew_symmetric","text":"is_skew_symmetric(M::MatElem)\n\nReturn true if the given matrix is skew symmetric with respect to its main diagonal, i.e., tr(M) == -M, otherwise return false.\n\nExamples\n\njulia> M = matrix(ZZ, [0 -1 -2; 1 0 -3; 2 3 0])\n[0 -1 -2]\n[1 0 -3]\n[2 3 0]\n\njulia> is_skew_symmetric(M)\ntrue\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Powering","page":"Matrix functionality","title":"Powering","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"powers(::MatElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/#powers-Tuple{MatElem, Int64}","page":"Matrix functionality","title":"powers","text":"powers(a::Union{NCRingElement, MatElem}, d::Int)\n\nReturn an array M of \"powers\" of a where Mi + 1 = a^i for i = 0d.\n\nExamples\n\njulia> M = ZZ[1 2 3; 2 3 4; 4 5 5]\n[1 2 3]\n[2 3 4]\n[4 5 5]\n\njulia> A = powers(M, 4)\n5-element Vector{AbstractAlgebra.Generic.MatSpaceElem{BigInt}}:\n [1 0 0; 0 1 0; 0 0 1]\n [1 2 3; 2 3 4; 4 5 5]\n [17 23 26; 24 33 38; 34 48 57]\n [167 233 273; 242 337 394; 358 497 579]\n [1725 2398 2798; 2492 3465 4044; 3668 5102 5957]\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Gram-matrix","page":"Matrix functionality","title":"Gram matrix","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"gram(::MatElem)","category":"page"},{"location":"AbstractAlgebra/matrix/#gram-Tuple{MatElem}","page":"Matrix functionality","title":"gram","text":"gram(x::MatElem)\n\nReturn the Gram matrix of x, i.e. if x is an rtimes c matrix return the rtimes r matrix whose entries i j are the dot products of the i-th and j-th rows, respectively.\n\nExamples\n\njulia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> B = gram(A)\n[2*t^2 + 2*t + 2 t^3 + 2*t^2 + t 2*t^2 + t - 1]\n[t^3 + 2*t^2 + t t^4 + 2*t^2 t^3 + 3*t]\n[ 2*t^2 + t - 1 t^3 + 3*t t^4 + 2*t^3 + 4*t^2 + 6*t + 9]\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Trace","page":"Matrix functionality","title":"Trace","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"tr(::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#tr-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"tr","text":"tr(x::AbsAlgAssElem{T}) where T -> T\n\nReturns the trace of x.\n\n\n\n\n\ntr(x::MatrixElem{T}) where T <: RingElement\n\nReturn the trace of the matrix a, i.e. the sum of the diagonal elements. We require the matrix to be square.\n\nExamples\n\njulia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> b = tr(A)\nt^2 + 3*t + 2\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Content","page":"Matrix functionality","title":"Content","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"content(::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#content-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"content","text":"content(x::MatrixElem{T}) where T <: RingElement\n\nReturn the content of the matrix a, i.e. the greatest common divisor of all its entries, assuming it exists.\n\nExamples\n\njulia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> b = content(A)\n1\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Permutation","page":"Matrix functionality","title":"Permutation","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"*(::Perm, ::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#*-Union{Tuple{T}, Tuple{Perm, MatElem{T}}} where T<:RingElement","page":"Matrix functionality","title":"*","text":"*(P::perm, x::MatrixElem{T}) where T <: RingElement\n\nApply the pemutation P to the rows of the matrix x and return the result.\n\nExamples\n\njulia> R, t = polynomial_ring(QQ, \"t\")\n(Univariate polynomial ring in t over rationals, t)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in t over rationals\n\njulia> G = SymmetricGroup(3)\nFull symmetric group over 3 elements\n\njulia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])\n[t + 1 t 1]\n[ t^2 t t]\n[ -2 t + 2 t^2 + t + 1]\n\njulia> P = G([1, 3, 2])\n(2,3)\n\njulia> B = P*A\n[t + 1 t 1]\n[ -2 t + 2 t^2 + t + 1]\n[ t^2 t t]\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#LU-factorisation","page":"Matrix functionality","title":"LU factorisation","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"lu{T <: FieldElem}(::MatElem{T}, ::SymmetricGroup)","category":"page"},{"location":"AbstractAlgebra/matrix/#lu-Union{Tuple{T}, Tuple{MatElem{T}, AbstractAlgebra.SymmetricGroup}} where T<:FieldElem","page":"Matrix functionality","title":"lu","text":"lu(A::MatrixElem{T}, P = SymmetricGroup(nrows(A))) where {T <: FieldElement}\n\nReturn a tuple r p L U consisting of the rank of A, a permutation p of A belonging to P, a lower triangular matrix L and an upper triangular matrix U such that p(A) = LU, where p(A) stands for the matrix whose rows are the given permutation p of the rows of A.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"fflu{T <: RingElem}(::MatElem{T}, ::SymmetricGroup)","category":"page"},{"location":"AbstractAlgebra/matrix/#fflu-Union{Tuple{T}, Tuple{MatElem{T}, AbstractAlgebra.SymmetricGroup}} where T<:RingElem","page":"Matrix functionality","title":"fflu","text":"fflu(A::MatrixElem{T}, P = SymmetricGroup(nrows(A))) where {T <: RingElement}\n\nReturn a tuple r d p L U consisting of the rank of A, a denominator d, a permutation p of A belonging to P, a lower triangular matrix L and an upper triangular matrix U such that p(A) = LDU, where p(A) stands for the matrix whose rows are the given permutation p of the rows of A and such that D is the diagonal matrix diag(p_1 p_1p_2 ldots p_n-2p_n-1 p_n-1p_n) where the p_i are the inverses of the diagonal entries of L. The denominator d is set to pm mathrmdet(S) where S is an appropriate submatrix of A (S = A if A is square and nonsingular) and the sign is decided by the parity of the permutation.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)\n\njulia> S = matrix_space(K, 3, 3)\nMatrix space of 3 rows and 3 columns\n over residue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 - 2 a - 1 2a])\n[ 0 2*x + 3 x^2 + 1]\n[x^2 - 2 x - 1 2*x]\n[x^2 - 2 x - 1 2*x]\n\njulia> r, P, L, U = lu(A)\n(2, (1,2), [1 0 0; 0 1 0; 1 0 1], [x^2-2 x-1 2*x; 0 2*x+3 x^2+1; 0 0 0])\n\njulia> r, d, P, L, U = fflu(A)\n(2, 3*x^2 - 10*x - 8, (1,2), [x^2-2 0 0; 0 3*x^2-10*x-8 0; x^2-2 0 1], [x^2-2 x-1 2*x; 0 3*x^2-10*x-8 -4*x^2-x-2; 0 0 0])\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Reduced-row-echelon-form","page":"Matrix functionality","title":"Reduced row-echelon form","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"rref_rational{T <: RingElem}(::MatElem{T})\nrref{T <: FieldElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#rref_rational-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"rref_rational","text":"rref_rational(M::MatrixElem{T}) where {T <: RingElement}\n\nReturn a tuple (r A d) consisting of the rank r of M and a denominator d in the base ring of M and a matrix A such that Ad is the reduced row echelon form of M. Note that the denominator is not usually minimal.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#rref-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix functionality","title":"rref","text":"rref(M::MatrixElem{T}) where {T <: FieldElement}\n\nReturn a tuple (r A) consisting of the rank r of M and a reduced row echelon form A of M.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_rref{T <: RingElem}(::MatElem{T})\nis_rref{T <: FieldElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#is_rref-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"is_rref","text":"is_rref(M::MatrixElem{T}) where {T <: RingElement}\n\nReturn true if M is in reduced row echelon form, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#is_rref-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix functionality","title":"is_rref","text":"is_rref(M::MatrixElem{T}) where {T <: RingElement}\n\nReturn true if M is in reduced row echelon form, otherwise return false.\n\n\n\n\n\nis_rref(M::MatrixElem{T}) where {T <: FieldElement}\n\nReturn true if M is in reduced row echelon form, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)\n\njulia> S = matrix_space(K, 3, 3)\nMatrix space of 3 rows and 3 columns\n over residue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> M = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> r, A = rref(M)\n(3, [1 0 0; 0 1 0; 0 0 1])\n\njulia> is_rref(A)\ntrue\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in x over integers\n\njulia> M = S([R(0) 2x + 3 x^2 + 1; x^2 - 2 x - 1 2x; x^2 + 3x + 1 2x R(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> r, A, d = rref_rational(M)\n(3, [-x^5-2*x^4-15*x^3-18*x^2-8*x-7 0 0; 0 -x^5-2*x^4-15*x^3-18*x^2-8*x-7 0; 0 0 -x^5-2*x^4-15*x^3-18*x^2-8*x-7], -x^5 - 2*x^4 - 15*x^3 - 18*x^2 - 8*x - 7)\n\njulia> is_rref(A)\ntrue","category":"page"},{"location":"AbstractAlgebra/matrix/#Determinant","page":"Matrix functionality","title":"Determinant","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"det{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#det-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"det","text":"det(M::MatrixElem{T}) where {T <: RingElement}\n\nReturn the determinant of the matrix M. We assume M is square.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)\n\njulia> S = matrix_space(K, 3, 3)\nMatrix space of 3 rows and 3 columns\n over residue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> d = det(A)\n11*x^2 - 30*x - 5\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Rank","page":"Matrix functionality","title":"Rank","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"rank{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#rank-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"rank","text":"rank(M::MatrixElem{T}) where {T <: RingElement}\n\nReturn the rank of the matrix M.\n\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)\n\njulia> S = matrix_space(K, 3, 3)\nMatrix space of 3 rows and 3 columns\n over residue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> d = rank(A)\n3\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Minors","page":"Matrix functionality","title":"Minors","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"minors(::MatElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/#minors-Tuple{MatElem, Int64}","page":"Matrix functionality","title":"minors","text":"minors(A::MatElem, k::Int)\n\nReturn an array consisting of the k-minors of A.\n\nExamples\n\njulia> A = ZZ[1 2 3; 4 5 6]\n[1 2 3]\n[4 5 6]\n\njulia> minors(A, 2)\n3-element Vector{BigInt}:\n -3\n -6\n -3\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Exterior-power","page":"Matrix functionality","title":"Exterior power","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"exterior_power(::MatElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/#exterior_power-Tuple{MatElem, Int64}","page":"Matrix functionality","title":"exterior_power","text":"exterior_power(A::MatElem, k::Int) -> MatElem\n\nReturn the k-th exterior power of A.\n\nExamples\n\njulia> A = matrix(ZZ, 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9]);\n\njulia> exterior_power(A, 2)\n[-3 -6 -3]\n[-6 -12 -6]\n[-3 -6 -3]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Pfaffian","page":"Matrix functionality","title":"Pfaffian","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"pfaffian(::MatElem)\npfaffians(::MatElem, ::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/#pfaffian-Tuple{MatElem}","page":"Matrix functionality","title":"pfaffian","text":"pfaffian(M::MatElem)\n\nReturn the Pfaffian of a skew-symmetric matrix M.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#pfaffians-Tuple{MatElem, Int64}","page":"Matrix functionality","title":"pfaffians","text":"pfaffians(M::MatElem, k::Int)\n\nReturn a vector consisting of the k-Pfaffians of a skew-symmetric matrix M.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, x = polynomial_ring(QQ, [\"x$i\" for i in 1:6])\n(Multivariate polynomial ring in 6 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x1, x2, x3, x4, x5, x6])\n\njulia> M = R[0 x[1] x[2] x[3]; -x[1] 0 x[4] x[5]; -x[2] -x[4] 0 x[6]; -x[3] -x[5] -x[6] 0]\n[ 0 x1 x2 x3]\n[-x1 0 x4 x5]\n[-x2 -x4 0 x6]\n[-x3 -x5 -x6 0]\n\njulia> pfaffian(M)\nx1*x6 - x2*x5 + x3*x4\n\njulia> pfaffians(M, 2)\n6-element Vector{AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}:\n x1\n x2\n x4\n x3\n x5\n x6\n ","category":"page"},{"location":"AbstractAlgebra/matrix/#Linear-solving","page":"Matrix functionality","title":"Linear solving","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"solve{T <: FieldElem}(::MatElem{T}, ::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#solve-Union{Tuple{T}, Tuple{MatElem{T}, MatElem{T}}} where T<:FieldElem","page":"Matrix functionality","title":"solve","text":"solve(a::MatElem{S}, b::MatElem{S}) where {S <: RingElement}\n\nGiven an mtimes r matrix a over a ring and an mtimes n matrix b over the same ring, return an rtimes n matrix x such that ax = b. If no such matrix exists, an exception is raised. See also solve_left.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"solve_rational{T <: RingElem}(::MatElem{T}, ::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#solve_rational-Union{Tuple{T}, Tuple{MatElem{T}, MatElem{T}}} where T<:RingElem","page":"Matrix functionality","title":"solve_rational","text":"solve_rational(M::MatElem{T}, b::MatElem{T}) where T <: RingElement\n\nGiven a non-singular ntimes n matrix over a ring and an ntimes m matrix over the same ring, return a tuple x d consisting of an ntimes m matrix x and a denominator d such that Ax = db. The denominator will be the determinant of A up to sign. If A is singular an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"can_solve_with_solution{T <: RingElement}(::MatElem{T}, ::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#can_solve_with_solution-Union{Tuple{T}, Tuple{MatElem{T}, MatElem{T}}} where T<:RingElement","page":"Matrix functionality","title":"can_solve_with_solution","text":"can_solve_with_solution(a::MatElem{S}, b::MatElem{S}; side::Symbol = :right) where S <: RingElement\n\nGiven two matrices a and b over the same ring, try to solve ax = b if side is :right or xa = b if side is :left. In either case, return a tuple (flag, x). If a solution exists, flag is set to true and x is a solution. If no solution exists, flag is set to false and x is arbitrary. If the dimensions of a and b are incompatible, an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"can_solve{T <: RingElement}(::MatElem{T}, ::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#can_solve-Union{Tuple{T}, Tuple{MatElem{T}, MatElem{T}}} where T<:RingElement","page":"Matrix functionality","title":"can_solve","text":"can_solve(a::MatElem{S}, b::MatElem{S}; side::Symbol = :right) where S <: RingElement\n\nGiven two matrices a and b over the same ring, check the solubility of ax = b if side is :right or xa = b if side is :left. Return true if a solution exists, false otherwise. If the dimensions of a and b are incompatible, an exception is raised. If a solution should be computed as well, use can_solve_with_solution instead.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"solve_left{T <: RingElem}(::MatElem{T}, ::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#solve_left-Union{Tuple{T}, Tuple{MatElem{T}, MatElem{T}}} where T<:RingElem","page":"Matrix functionality","title":"solve_left","text":"solve_left(a::MatElem{S}, b::MatElem{S}) where S <: RingElement\n\nGiven an rtimes n matrix a over a ring and an mtimes n matrix b over the same ring, return an mtimes r matrix x such that xa = b. If no such matrix exists, an exception is raised. See also solve.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"solve_triu{T <: FieldElem}(::MatElem{T}, ::MatElem{T}, ::Bool)","category":"page"},{"location":"AbstractAlgebra/matrix/#solve_triu-Union{Tuple{T}, Tuple{MatElem{T}, MatElem{T}, Bool}} where T<:FieldElem","page":"Matrix functionality","title":"solve_triu","text":"solve_triu(U::MatElem{T}, b::MatElem{T}, unit::Bool = false) where {T <: FieldElement}\n\nGiven a non-singular ntimes n matrix over a field which is upper triangular, and an ntimes m matrix over the same field, return an ntimes m matrix x such that Ax = b. If A is singular an exception is raised. If unit is true then U is assumed to have ones on its diagonal, and the diagonal will not be read.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"can_solve_left_reduced_triu{T <: RingElement}(::MatElem{T}, ::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#can_solve_left_reduced_triu-Union{Tuple{T}, Tuple{MatElem{T}, MatElem{T}}} where T<:RingElement","page":"Matrix functionality","title":"can_solve_left_reduced_triu","text":"can_solve_left_reduced_triu(r::MatElem{T},\n M::MatElem{T}) where T <: RingElement\n\nReturn a tuple flag, x where flag is set to true if xM = r has a solution, where M is an mtimes n matrix in (upper triangular) Hermite normal form or reduced row echelon form and r and x are row vectors with m columns. If there is no solution, flag is set to false and x is set to the zero row.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)\n\njulia> S = matrix_space(K, 3, 3)\nMatrix space of 3 rows and 3 columns\n over residue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> U = matrix_space(K, 3, 1)\nMatrix space of 3 rows and 1 column\n over residue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> b = U([2a, a + 1, (-a - 1)])\n[ 2*x]\n[ x + 1]\n[-x - 1]\n\njulia> x = solve(A, b)\n[ 1984//7817*x^2 + 1573//7817*x - 937//7817]\n[ -2085//7817*x^2 + 1692//7817*x + 965//7817]\n[-3198//7817*x^2 + 3540//7817*x - 3525//7817]\n\njulia> A = matrix(ZZ, 2, 2, [1, 2, 0, 2])\n[1 2]\n[0 2]\n\njulia> b = matrix(ZZ, 2, 1, [2, 1])\n[2]\n[1]\n\njulia> can_solve(A, b, side = :right)\nfalse\n\njulia> A = matrix(QQ, 2, 2, [3, 4, 5, 6])\n[3//1 4//1]\n[5//1 6//1]\n\njulia> b = matrix(QQ, 1, 2, [2, 1])\n[2//1 1//1]\n\njulia> can_solve_with_solution(A, b; side = :left)\n(true, [-7//2 5//2])\n\njulia> A = S([a + 1 2a + 3 a^2 + 1; K(0) a^2 - 1 2a; K(0) K(0) a])\n[x + 1 2*x + 3 x^2 + 1]\n[ 0 x^2 - 1 2*x]\n[ 0 0 x]\n\njulia> bb = U([2a, a + 1, (-a - 1)])\n[ 2*x]\n[ x + 1]\n[-x - 1]\n\njulia> x = solve_triu(A, bb, false)\n[ 1//3*x^2 + 8//3*x + 13//3]\n[-3//5*x^2 - 3//5*x - 12//5]\n[ x^2 + 2]\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in x over integers\n\njulia> U = matrix_space(R, 3, 2)\nMatrix space of 3 rows and 2 columns\n over univariate polynomial ring in x over integers\n\njulia> A = S([R(0) 2x + 3 x^2 + 1; x^2 - 2 x - 1 2x; x^2 + 3x + 1 2x R(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> bbb = U(transpose([2x x + 1 (-x - 1); x + 1 (-x) x^2]))\n[ 2*x x + 1]\n[ x + 1 -x]\n[-x - 1 x^2]\n\njulia> x, d = solve_rational(A, bbb)\n([3*x^4-10*x^3-8*x^2-11*x-4 -x^5+3*x^4+x^3-2*x^2+3*x-1; -2*x^5-x^4+6*x^3+2*x+1 x^6+x^5+4*x^4+9*x^3+8*x^2+5*x+2; 6*x^4+12*x^3+15*x^2+6*x-3 -2*x^5-4*x^4-6*x^3-9*x^2-4*x+1], x^5 + 2*x^4 + 15*x^3 + 18*x^2 + 8*x + 7)\n\njulia> S = matrix_space(ZZ, 3, 3)\nMatrix space of 3 rows and 3 columns\n over integers\n\njulia> T = matrix_space(ZZ, 3, 1)\nMatrix space of 3 rows and 1 column\n over integers\n\njulia> A = S([BigInt(2) 3 5; 1 4 7; 9 2 2])\n[2 3 5]\n[1 4 7]\n[9 2 2]\n\njulia> B = T([BigInt(4), 5, 7])\n[4]\n[5]\n[7]","category":"page"},{"location":"AbstractAlgebra/matrix/#Inverse","page":"Matrix functionality","title":"Inverse","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Base.inv{T <: RingElement}(::MatrixElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#inv-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"inv","text":"inv(M::MatrixElem{T}) where {T <: RingElement}\n\nGiven a non-singular ntimes n matrix over a ring, return an ntimes n matrix X such that MX = I_n, where I_n is the ntimes n identity matrix. If M is not invertible over the base ring an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_invertible_with_inverse{T <: RingElement}(::MatrixElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#is_invertible_with_inverse-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"is_invertible_with_inverse","text":"is_invertible_with_inverse(A::MatrixElem{T}; side::Symbol = :left) where {T <: RingElement}\n\nGiven an ntimes m matrix A over a ring, return a tuple (flag, B). If side is :right and flag is true, B is the right inverse of A i.e. AB is the ntimes n unit matrix. If side is :left and flag is true, B is the left inverse of A i.e. BA is the mtimes m unit matrix. If flag is false, no right or left inverse exists.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_invertible{T <: RingElement}(::MatrixElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#is_invertible-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"is_invertible","text":"is_invertible(A::MatrixElem{T}) where {T <: RingElement}\n\nReturn true if a given square matrix is invertible, false otherwise. If the inverse should also be computed, use is_invertible_with_inverse.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)\n\njulia> S = matrix_space(K, 3, 3)\nMatrix space of 3 rows and 3 columns\n over residue field of univariate polynomial ring modulo x^3 + 3*x + 1\n\njulia> A = S([K(0) 2a + 3 a^2 + 1; a^2 - 2 a - 1 2a; a^2 + 3a + 1 2a K(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> X = inv(A)\n[-343//7817*x^2 + 717//7817*x - 2072//7817 -4964//23451*x^2 + 2195//23451*x - 11162//23451 -232//23451*x^2 - 4187//23451*x - 1561//23451]\n[ 128//7817*x^2 - 655//7817*x + 2209//7817 599//23451*x^2 - 2027//23451*x - 1327//23451 -1805//23451*x^2 + 2702//23451*x - 7394//23451]\n[ 545//7817*x^2 + 570//7817*x + 2016//7817 -1297//23451*x^2 - 5516//23451*x - 337//23451 8254//23451*x^2 - 2053//23451*x + 16519//23451]\n\njulia> is_invertible(A)\ntrue\n\njulia> is_invertible_with_inverse(A)\n(true, [-343//7817*x^2+717//7817*x-2072//7817 -4964//23451*x^2+2195//23451*x-11162//23451 -232//23451*x^2-4187//23451*x-1561//23451; 128//7817*x^2-655//7817*x+2209//7817 599//23451*x^2-2027//23451*x-1327//23451 -1805//23451*x^2+2702//23451*x-7394//23451; 545//7817*x^2+570//7817*x+2016//7817 -1297//23451*x^2-5516//23451*x-337//23451 8254//23451*x^2-2053//23451*x+16519//23451])\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = matrix_space(R, 3, 3)\nMatrix space of 3 rows and 3 columns\n over univariate polynomial ring in x over integers\n\njulia> A = S([R(0) 2x + 3 x^2 + 1; x^2 - 2 x - 1 2x; x^2 + 3x + 1 2x R(1)])\n[ 0 2*x + 3 x^2 + 1]\n[ x^2 - 2 x - 1 2*x]\n[x^2 + 3*x + 1 2*x 1]\n\njulia> X, d = pseudo_inv(A)\n([4*x^2-x+1 -2*x^3+3 x^3-5*x^2-5*x-1; -2*x^3-5*x^2-2*x-2 x^4+3*x^3+2*x^2+3*x+1 -x^4+x^2+2; -x^3+2*x^2+2*x-1 -2*x^3-9*x^2-11*x-3 2*x^3+3*x^2-4*x-6], -x^5 - 2*x^4 - 15*x^3 - 18*x^2 - 8*x - 7)\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Nullspace","page":"Matrix functionality","title":"Nullspace","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"nullspace{T <: FieldElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#nullspace-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix functionality","title":"nullspace","text":"nullspace(M::MatElem{T}) where {T <: RingElement}\n\nReturn a tuple (nu N) consisting of the nullity nu of M and a basis N (consisting of column vectors) for the right nullspace of M, i.e. such that MN is the zero matrix. If M is an mtimes n matrix N will be an ntimes nu matrix. Note that the nullspace is taken to be the vector space kernel over the fraction field of the base ring if the latter is not a field. In AbstractAlgebra we use the name \"kernel\" for a function to compute an integral kernel.\n\nExamples\n\njulia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over integers, x)\n\njulia> S = matrix_space(R, 4, 4)\nMatrix space of 4 rows and 4 columns\n over univariate polynomial ring in x over integers\n\njulia> M = S([-6*x^2+6*x+12 -12*x^2-21*x-15 -15*x^2+21*x+33 -21*x^2-9*x-9;\n -8*x^2+8*x+16 -16*x^2+38*x-20 90*x^2-82*x-44 60*x^2+54*x-34;\n -4*x^2+4*x+8 -8*x^2+13*x-10 35*x^2-31*x-14 22*x^2+21*x-15;\n -10*x^2+10*x+20 -20*x^2+70*x-25 150*x^2-140*x-85 105*x^2+90*x-50])\n[ -6*x^2 + 6*x + 12 -12*x^2 - 21*x - 15 -15*x^2 + 21*x + 33 -21*x^2 - 9*x - 9]\n[ -8*x^2 + 8*x + 16 -16*x^2 + 38*x - 20 90*x^2 - 82*x - 44 60*x^2 + 54*x - 34]\n[ -4*x^2 + 4*x + 8 -8*x^2 + 13*x - 10 35*x^2 - 31*x - 14 22*x^2 + 21*x - 15]\n[-10*x^2 + 10*x + 20 -20*x^2 + 70*x - 25 150*x^2 - 140*x - 85 105*x^2 + 90*x - 50]\n\njulia> n, N = nullspace(M)\n(2, [1320*x^4-330*x^2-1320*x-1320 1056*x^4+1254*x^3+1848*x^2-66*x-330; -660*x^4+1320*x^3+1188*x^2-1848*x-1056 -528*x^4+132*x^3+1584*x^2+660*x-264; 396*x^3-396*x^2-792*x 0; 0 396*x^3-396*x^2-792*x])\n\n\n\n\n\nnullspace(M::MatElem{T}) where {T <: FieldElement}\n\nReturn a tuple (nu N) consisting of the nullity nu of M and a basis N (consisting of column vectors) for the right nullspace of M, i.e. such that MN is the zero matrix. If M is an mtimes n matrix N will be an ntimes nu matrix.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Kernel","page":"Matrix functionality","title":"Kernel","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"kernel{T <: RingElem}(::MatElem{T})\nleft_kernel{T <: RingElem}(::MatElem{T})\nright_kernel{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#kernel-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"kernel","text":"kernel(a::MatElem{T}; side::Symbol = :right) where T <: RingElement\n\nReturn a tuple (n M), where n is the rank of the kernel of a and M is a basis for it. If side is :right or not specified, the right kernel is computed, i.e. the matrix of columns whose span gives the right kernel space. If side is :left, the left kernel is computed, i.e. the matrix of rows whose span is the left kernel space.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#left_kernel-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"left_kernel","text":"left_kernel(a::MatElem{T}) where T <: RingElement\n\nReturn a tuple n, M where M is a matrix whose rows generate the kernel of M and n is the rank of the kernel. The transpose of the output of this function is guaranteed to be in flipped upper triangular format (i.e. upper triangular format if columns and rows are reversed).\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#right_kernel-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"right_kernel","text":"right_kernel(a::MatElem{T}) where T <: RingElement\n\nReturn a tuple n, M where M is a matrix whose columns generate the kernel of a and n is the rank of the kernel.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> S = matrix_space(ZZ, 4, 4)\nMatrix space of 4 rows and 4 columns\n over integers\n\njulia> M = S([1 2 0 4;\n 2 0 1 1;\n 0 1 1 -1;\n 2 -1 0 2])\n[1 2 0 4]\n[2 0 1 1]\n[0 1 1 -1]\n[2 -1 0 2]\n\njulia> nr, Nr = kernel(M)\n(1, [-8; -6; 11; 5])\n\njulia> nl, Nl = left_kernel(M)\n(1, [0 -1 1 1])\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Hessenberg-form","page":"Matrix functionality","title":"Hessenberg form","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"hessenberg{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#hessenberg-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"hessenberg","text":"hessenberg(A::MatrixElem{T}) where {T <: RingElement}\n\nReturn the Hessenberg form of M, i.e. an upper Hessenberg matrix which is similar to M. The upper Hessenberg form has nonzero entries above and on the diagonal and in the diagonal line immediately below the diagonal.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_hessenberg{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#is_hessenberg-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"is_hessenberg","text":"is_hessenberg(A::MatrixElem{T}) where {T <: RingElement}\n\nReturn true if M is in Hessenberg form, otherwise returns false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R = residue_ring(ZZ, 7)\nResidue ring of integers modulo 7\n\njulia> S = matrix_space(R, 4, 4)\nMatrix space of 4 rows and 4 columns\n over residue ring of integers modulo 7\n\njulia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);\n R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])\n[1 2 4 3]\n[2 5 1 0]\n[6 1 3 2]\n[1 1 3 5]\n\njulia> A = hessenberg(M)\n[1 5 5 3]\n[2 1 1 0]\n[0 1 3 2]\n[0 0 2 2]\n\njulia> is_hessenberg(A)\ntrue\n","category":"page"},{"location":"AbstractAlgebra/matrix/#Characteristic-polynomial","page":"Matrix functionality","title":"Characteristic polynomial","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"charpoly{T <: RingElem}(::Ring, ::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#charpoly-Union{Tuple{T}, Tuple{Ring, MatElem{T}}} where T<:RingElem","page":"Matrix functionality","title":"charpoly","text":"charpoly(V::Ring, Y::MatrixElem{T}) where {T <: RingElement}\n\nReturn the characteristic polynomial p of the matrix M. The polynomial ring R of the resulting polynomial must be supplied and the matrix is assumed to be square.\n\nExamples\n\njulia> R = residue_ring(ZZ, 7)\nResidue ring of integers modulo 7\n\njulia> S = matrix_space(R, 4, 4)\nMatrix space of 4 rows and 4 columns\n over residue ring of integers modulo 7\n\njulia> T, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over residue ring, x)\n\njulia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);\n R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])\n[1 2 4 3]\n[2 5 1 0]\n[6 1 3 2]\n[1 1 3 5]\n\njulia> A = charpoly(T, M)\nx^4 + 2*x^2 + 6*x + 2\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Minimal-polynomial","page":"Matrix functionality","title":"Minimal polynomial","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"minpoly{T <: RingElem}(::Ring, ::MatElem{T}, ::Bool)","category":"page"},{"location":"AbstractAlgebra/matrix/#minpoly-Union{Tuple{T}, Tuple{Ring, MatElem{T}, Bool}} where T<:RingElem","page":"Matrix functionality","title":"minpoly","text":"minpoly(S::Ring, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}\n\nReturn the minimal polynomial p of the matrix M. The polynomial ring S of the resulting polynomial must be supplied and the matrix must be square.\n\nExamples\n\njulia> R = GF(13)\nFinite field F_13\n\njulia> T, y = polynomial_ring(R, \"y\")\n(Univariate polynomial ring in y over finite field F_13, y)\n\njulia> M = R[7 6 1;\n 7 7 5;\n 8 12 5]\n[7 6 1]\n[7 7 5]\n[8 12 5]\n\njulia> A = minpoly(T, M)\ny^2 + 10*y\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Transforms","page":"Matrix functionality","title":"Transforms","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"similarity!{T <: RingElem}(::MatElem{T}, ::Int, ::T)","category":"page"},{"location":"AbstractAlgebra/matrix/#similarity!-Union{Tuple{T}, Tuple{MatElem{T}, Int64, T}} where T<:RingElem","page":"Matrix functionality","title":"similarity!","text":"similarity!(A::MatrixElem{T}, r::Int, d::T) where {T <: RingElement}\n\nApplies a similarity transform to the ntimes n matrix M in-place. Let P be the ntimes n identity matrix that has had all zero entries of row r replaced with d, then the transform applied is equivalent to M = P^-1MP. We require M to be a square matrix. A similarity transform preserves the minimal and characteristic polynomials of a matrix.\n\nExamples\n\njulia> R = residue_ring(ZZ, 7)\nResidue ring of integers modulo 7\n\njulia> S = matrix_space(R, 4, 4)\nMatrix space of 4 rows and 4 columns\n over residue ring of integers modulo 7\n\njulia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);\n R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])\n[1 2 4 3]\n[2 5 1 0]\n[6 1 3 2]\n[1 1 3 5]\n\njulia> similarity!(M, 1, R(3))\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Hermite-normal-form","page":"Matrix functionality","title":"Hermite normal form","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"hnf{T <: RingElem}(::MatElem{T})\nhnf_with_transform{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#hnf-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"hnf","text":"hnf(A::MatrixElem{T}) where {T <: RingElement}\n\nReturn the upper right row Hermite normal form of A.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#hnf_with_transform-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"hnf_with_transform","text":"hnf_with_transform(A)\n\nReturn the tuple H U consisting of the upper right row Hermite normal form H of A together with invertible matrix U such that UA = H.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_hnf{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#is_hnf-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"is_hnf","text":"is_hnf(M::MatrixElem{T}) where T <: RingElement\n\nReturn true if the matrix is in Hermite normal form.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> A = matrix(ZZ, [2 3 -1; 3 5 7; 11 1 12])\n[ 2 3 -1]\n[ 3 5 7]\n[11 1 12]\n\njulia> H = hnf(A)\n[1 0 255]\n[0 1 17]\n[0 0 281]\n\njulia> is_hnf(H)\ntrue\n\njulia> H, U = hnf_with_transform(A)\n([1 0 255; 0 1 17; 0 0 281], [-47 28 1; -3 2 0; -52 31 1])\n\njulia> U*A\n[1 0 255]\n[0 1 17]\n[0 0 281]","category":"page"},{"location":"AbstractAlgebra/matrix/#Smith-normal-form","page":"Matrix functionality","title":"Smith normal form","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_snf(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#is_snf-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"is_snf","text":"is_snf(A::MatrixElem{T}) where T <: RingElement\n\nReturn true if A is in Smith Normal Form.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"snf{T <: RingElem}(::MatElem{T})\nsnf_with_transform{T <: RingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#snf-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"snf","text":"snf(A::MatrixElem{T}) where {T <: RingElement}\n\nReturn the Smith normal form of A.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#snf_with_transform-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:RingElem","page":"Matrix functionality","title":"snf_with_transform","text":"snf_with_transform(A)\n\nReturn the tuple S T U consisting of the Smith normal form S of A together with invertible matrices T and U such that TAU = S.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> A = matrix(ZZ, [2 3 -1; 3 5 7; 11 1 12])\n[ 2 3 -1]\n[ 3 5 7]\n[11 1 12]\n\njulia> S = snf(A)\n[1 0 0]\n[0 1 0]\n[0 0 281]\n\njulia> S, T, U = snf_with_transform(A)\n([1 0 0; 0 1 0; 0 0 281], [1 0 0; 7 1 0; 229 31 1], [0 -3 26; 0 2 -17; -1 0 1])\n\njulia> T*A*U\n[1 0 0]\n[0 1 0]\n[0 0 281]","category":"page"},{"location":"AbstractAlgebra/matrix/#(Weak)-Popov-form","page":"Matrix functionality","title":"(Weak) Popov form","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"AbstractAlgebra.jl provides algorithms for computing the (weak) Popov of a matrix with entries in a univariate polynomial ring over a field.","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_weak_popov(P::MatrixElem{T}, rank::Int) where T <: Generic.Poly","category":"page"},{"location":"AbstractAlgebra/matrix/#is_weak_popov-Union{Tuple{T}, Tuple{MatrixElem{T}, Int64}} where T<:AbstractAlgebra.Generic.Poly","page":"Matrix functionality","title":"is_weak_popov","text":"is_weak_popov(P::MatrixElem{T}, rank::Int) where T <: PolyRingElem\n\nReturn true if P is a matrix in weak Popov form of the given rank.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"weak_popov{T <: PolyRingElem}(::MatElem{T})\nweak_popov_with_transform{T <: PolyRingElem}(::MatElem{T})\npopov{T <: PolyRingElem}(::MatElem{T})\npopov_with_transform{T <: PolyRingElem}(::MatElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#weak_popov-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:PolyRingElem","page":"Matrix functionality","title":"weak_popov","text":"weak_popov(A::MatElem{T}) where {T <: PolyRingElem}\n\nReturn the weak Popov form of A.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#weak_popov_with_transform-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:PolyRingElem","page":"Matrix functionality","title":"weak_popov_with_transform","text":"weak_popov_with_transform(A::MatElem{T}) where {T <: PolyRingElem}\n\nCompute a tuple (P U) where P is the weak Popov form of A and U is a transformation matrix so that P = UA.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#popov-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:PolyRingElem","page":"Matrix functionality","title":"popov","text":"popov(A::MatElem{T}) where {T <: PolyRingElem}\n\nReturn the Popov form of A.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#popov_with_transform-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:PolyRingElem","page":"Matrix functionality","title":"popov_with_transform","text":"popov_with_transform(A::MatElem{T}) where {T <: PolyRingElem}\n\nCompute a tuple (P U) where P is the Popov form of A and U is a transformation matrix so that P = UA.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"Examples","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> R, x = polynomial_ring(QQ, \"x\");\n\njulia> A = matrix(R, map(R, Any[1 2 3 x; x 2*x 3*x x^2; x x^2+1 x^3+x^2 x^4+x^2+1]))\n[1 2 3 x]\n[x 2*x 3*x x^2]\n[x x^2 + 1 x^3 + x^2 x^4 + x^2 + 1]\n\njulia> P = weak_popov(A)\n[ 1 2 3 x]\n[ 0 0 0 0]\n[-x^3 -2*x^3 + x^2 - 2*x + 1 -2*x^3 + x^2 - 3*x 1]\n\njulia> P, U = weak_popov_with_transform(A)\n([1 2 3 x; 0 0 0 0; -x^3 -2*x^3+x^2-2*x+1 -2*x^3+x^2-3*x 1], [1 0 0; -x 1 0; -x^3-x 0 1])\n\njulia> U*A\n[ 1 2 3 x]\n[ 0 0 0 0]\n[-x^3 -2*x^3 + x^2 - 2*x + 1 -2*x^3 + x^2 - 3*x 1]","category":"page"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/numberfield/#Number-fields","page":"Number fields","title":"Number fields","text":"","category":"section"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"AbstractAlgebra.jl provides a very naive implementation of number fields. This allows arithmetic in algebraic number fields, which are currently modeled as mathbbQx modulo an irreducible polynomial, i.e. as a residue field.","category":"page"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"The definition of the number field constructor is given in src/generic/NumberField.jl but no type is defined for a number field. The definition mainly exists for testing purposes. It may later be replaced by a more standard implementation. For a more fully fleshed out number field implementation (based on a very high performance C library), see Nemo.jl.","category":"page"},{"location":"AbstractAlgebra/numberfield/#Number-field-constructors","page":"Number fields","title":"Number field constructors","text":"","category":"section"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"In order to construct number fields in AbstractAlgebra.jl, one must first construct the field itself. This is accomplished with the following constructor.","category":"page"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"number_field(f::Generic.Poly{Rational{BigInt}}, s::VarName, t = \"\\$\"; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"Given an irreducible defining polynomial f in mathbbQx, return a tuple (K x) consisting of the number field defined by that polynomial and a generator. The string fields are currently ignored, but are reserved for future use.","category":"page"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"Currently the generator of the number field prints the same way as the variable in mathbbQx.","category":"page"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"julia> R, x = polynomial_ring(QQ, \"x\")\n(Univariate polynomial ring in x over rationals, x)\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Residue field of univariate polynomial ring modulo x^3 + 3*x + 1, x)\n\njulia> f = a^2 + 2a + 7\nx^2 + 2*x + 7\n","category":"page"},{"location":"AbstractAlgebra/numberfield/#Basic-field-functionality","page":"Number fields","title":"Basic field functionality","text":"","category":"section"},{"location":"AbstractAlgebra/numberfield/","page":"Number fields","title":"Number fields","text":"The number field module in AbstractAlgebra.jl implements the full Field and residue_ring interfaces.","category":"page"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/","page":"Mixed Integer Linear Programs","title":"Mixed Integer Linear Programs","text":"CurrentModule = Oscar","category":"page"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#Mixed-Integer-Linear-Programs","page":"Mixed Integer Linear Programs","title":"Mixed Integer Linear Programs","text":"","category":"section"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#Introduction","page":"Mixed Integer Linear Programs","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/","page":"Mixed Integer Linear Programs","title":"Mixed Integer Linear Programs","text":"The purpose of a mixed integer linear program is to optimize a linear function over a polyhedron, where we require a given subset of the variables to be integers.","category":"page"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#Constructions","page":"Mixed Integer Linear Programs","title":"Constructions","text":"","category":"section"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/","page":"Mixed Integer Linear Programs","title":"Mixed Integer Linear Programs","text":"Mixed integer linear programs are constructed from a polyhedron and a linear objective function which is described by a vector and (optionally) a translation. One can select whether the optimization problem is to maximize or to minimize the objective function. Furthermore one can optionally specify integer_variables, a subset of variables that are required to be integral, given as a set of integers, their respective indices.","category":"page"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/","page":"Mixed Integer Linear Programs","title":"Mixed Integer Linear Programs","text":"mixed_integer_linear_program","category":"page"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#mixed_integer_linear_program","page":"Mixed Integer Linear Programs","title":"mixed_integer_linear_program","text":"mixed_integer_linear_program(P, c; integer_variables = [], k = 0, convention = :max)\n\nThe mixed integer linear program on the feasible set P (a Polyhedron) with respect to the function x ↦ dot(c,x)+k, where x_iinmathbbZ for all i in integer_variables. If integer_variables is empty, or not specified, all entries of x are required to be integral. If this is not intended, consider using a linear_program instead.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#Functions","page":"Mixed Integer Linear Programs","title":"Functions","text":"","category":"section"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/","page":"Mixed Integer Linear Programs","title":"Mixed Integer Linear Programs","text":"optimal_value(milp::MixedIntegerLinearProgram{T}) where T<:scalar_types\noptimal_solution\nsolve_milp","category":"page"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#optimal_value-Union{Tuple{MixedIntegerLinearProgram{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Mixed Integer Linear Programs","title":"optimal_value","text":"optimal_value(MILP::MixedIntegerLinearProgram)\n\nReturn, if it exists, the optimal value of the objective function of MILP over the feasible region of MILP. Otherwise, return -inf or inf depending on convention.\n\nExamples\n\nTake the square -1232^2 and optimize 11 in different settings.\n\njulia> c = cube(2, -1//2, 3//2)\nPolyhedron in ambient dimension 2\n\njulia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])\nMixed integer linear program\n\njulia> optimal_value(milp)\n5/2\n\njulia> milp = mixed_integer_linear_program(c, [1,1])\nMixed integer linear program\n\njulia> optimal_value(milp)\n2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#optimal_solution","page":"Mixed Integer Linear Programs","title":"optimal_solution","text":"optimal_solution(MILP::MixedIntegerLinearProgram)\n\nReturn either a point of the feasible region of MILP which optimizes the objective function of MILP, or nothing if no such point exists.\n\nExamples\n\nTake the square -1232^2 and optimize 11 in different settings.\n\njulia> c = cube(2, -1//2, 3//2)\nPolyhedron in ambient dimension 2\n\njulia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])\nMixed integer linear program\n\njulia> optimal_solution(milp)\n2-element PointVector{QQFieldElem}:\n 1\n 3//2\n\njulia> milp = mixed_integer_linear_program(c, [1,1])\nMixed integer linear program\n\njulia> optimal_solution(milp)\n2-element PointVector{QQFieldElem}:\n 1\n 1\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#solve_milp","page":"Mixed Integer Linear Programs","title":"solve_milp","text":"solve_milp(MILP::MixedIntegerLinearProgram)\n\nReturn a pair (m,v) where the optimal value m of the objective function of MILP is attained at v (if m exists). If the optimum is not attained, m may be inf or -inf in which case v is nothing.\n\nExamples\n\nTake the square -1232^2 and optimize 11 in different settings.\n\njulia> c = cube(2, -1//2, 3//2)\nPolyhedron in ambient dimension 2\n\njulia> milp = mixed_integer_linear_program(c, [1,1], integer_variables=[1])\nMixed integer linear program\n\njulia> solve_milp(milp)\n(5/2, QQFieldElem[1, 3//2])\n\njulia> milp = mixed_integer_linear_program(c, [1,1])\nMixed integer linear program\n\njulia> solve_milp(milp)\n(2, QQFieldElem[1, 1])\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Affine-schemes","page":"Affine schemes","title":"Affine schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"Let mathbb k be a commutative noetherian base ring (in practice: an algebraic extension of mathbb Q or mathbb F_p). We support functionality for affine schemes X = mathrmSpec(R) over mathbb k. Currently, we support rings R of type MPolyRing, MPolyQuoRing, MPolyLocRing, and MPolyQuoLocRing defined over the integers, a finite field or algebraic field extensions of mathbb Q","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Constructors","page":"Affine schemes","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#General-constructors","page":"Affine schemes","title":"General constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"Besides Spec(R) for R of either one of the types MPolyRing, MPolyQuoRing, MPolyLocRing, or MPolyQuoLocRing, we have the following constructors:","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"Spec(R::MPolyRing, I::MPolyIdeal)\nSpec(R::MPolyRing, U::AbsMPolyMultSet)\nSpec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Spec-Tuple{MPolyRing, MPolyIdeal}","page":"Affine schemes","title":"Spec","text":"Spec(R::MPolyRing, I::MPolyIdeal)\n\nConstructs the affine scheme of the ideal I in the ring R. This is the spectrum of the quotient ring RI.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [x]);\n\njulia> Spec(R, I)\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Spec-Tuple{MPolyRing, Oscar.AbsMPolyMultSet}","page":"Affine schemes","title":"Spec","text":"Spec(R::MPolyRing, U::AbsMPolyMultSet)\n\nGiven a polynomial ring R, we can localize that polynomial ring at a multiplicatively closed subset U of R. The spectrum of the localized ring U^-1 R is computed by this method.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [x]);\n\njulia> U = complement_of_prime_ideal(I);\n\njulia> Spec(R, U)\nSpectrum\n of localization\n of multivariate polynomial ring in 2 variables over QQ\n at complement of prime ideal(x)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Spec-Tuple{MPolyRing, MPolyIdeal, Oscar.AbsMPolyMultSet}","page":"Affine schemes","title":"Spec","text":"Spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet)\n\nWe allow to combine quotients and localizations at the same time. That is, consider a polynomial ring R, an ideal I of R and a multiplicatively closed subset U of R. The spectrum of the localized ring U^-1 (RI) is computed by this method.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"]);\n\njulia> I = ideal(R, [x]);\n\njulia> U = complement_of_prime_ideal(ideal(R, [y]));\n\njulia> Spec(R, I, U)\nSpectrum\n of localization\n of quotient of multivariate polynomial ring by ideal with 1 generator\n at complement of prime ideal(y)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"See inclusion_morphism(::AbsSpec, ::AbsSpec) for a way to obtain the ideal I from X = mathrmSpec(R I).","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Affine-n-space","page":"Affine schemes","title":"Affine n-space","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"affine_space(kk::BRT, n::Int; variable_name=\"x\") where {BRT<:Ring}\naffine_space(kk::BRT, var_symbols::Vector{Symbol}) where {BRT<:Ring}","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#affine_space-Union{Tuple{BRT}, Tuple{BRT, Int64}} where BRT<:Ring","page":"Affine schemes","title":"affine_space","text":"affine_space(kk::BRT, n::Int; variable_name=\"x\") where {BRT<:Ring}\n\nThe n-dimensional affine space over a ring kk is created by this method. By default, the variable names are chosen as x_1, x_2 and so on. This choice can be overwritten with a third optional argument.\n\nExamples\n\njulia> affine_space(QQ, 5)\nAffine space of dimension 5\n over rational field\nwith coordinates [x1, x2, x3, x4, x5]\n\njulia> affine_space(QQ,5,variable_name=\"y\")\nAffine space of dimension 5\n over rational field\nwith coordinates [y1, y2, y3, y4, y5]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#affine_space-Union{Tuple{BRT}, Tuple{BRT, Vector{Symbol}}} where BRT<:Ring","page":"Affine schemes","title":"affine_space","text":"affine_space(kk::BRT, var_symbols::Vector{Symbol}) where {BRT<:Ring}\n\nCreates the n-dimensional affine space over a ring kk, but allows more flexibility in the choice of variable names. The following example demonstrates this.\n\nExamples\n\njulia> affine_space(QQ,[:y1,:z2,:a])\nAffine space of dimension 3\n over rational field\nwith coordinates [y1, z2, a]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Closed-subschemes","page":"Affine schemes","title":"Closed subschemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"subscheme(X::AbsSpec, f::Vector{<:RingElem})\nsubscheme(X::AbsSpec, I::Ideal)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#subscheme-Tuple{AbsSpec, Vector{<:RingElem}}","page":"Affine schemes","title":"subscheme","text":"subscheme(X::AbsSpec, f::Vector{<:RingElem})\n\nFor an affine spectrum X and elements f_1, f_2, etc. of the coordinate ring of X, this method computes the subscheme V(f_1 f_2 dots) of X.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> subscheme(X,x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> subscheme(X,[x1,x2])\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1, x2)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#subscheme-Tuple{AbsSpec, Ideal}","page":"Affine schemes","title":"subscheme","text":"subscheme(X::AbsSpec, I::Ideal)\n\nFor a scheme X = Spec(R) and an ideal I 𝒪(X), return the closed subscheme defined by I.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> subscheme(X,ideal(R,[x1*x2]))\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1*x2)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Intersections","page":"Affine schemes","title":"Intersections","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"Base.intersect(X::AbsSpec{BRT, <:Ring}, Y::AbsSpec{BRT, <:Ring}) where {BRT<:Ring}","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#intersect-Union{Tuple{BRT}, Tuple{AbsSpec{BRT}, AbsSpec{BRT}}} where BRT<:Ring","page":"Affine schemes","title":"intersect","text":"Base.intersect(X::AbsSpec, Y::AbsSpec)\n\nThis method computes the intersection to two affine schemes that reside in the same ambient affine space.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y1 = subscheme(X,[x1])\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> Y2 = subscheme(X,[x2])\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x2)\n\njulia> intersect(Y1, Y2)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1, x2)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Open-subschemes","page":"Affine schemes","title":"Open subschemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"hypersurface_complement(X::AbsSpec, f::RingElem)\nhypersurface_complement(X::AbsSpec, f::Vector{<:RingElem})","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#hypersurface_complement-Tuple{AbsSpec, RingElem}","page":"Affine schemes","title":"hypersurface_complement","text":"hypersurface_complement(X::AbsSpec, f::RingElem)\n\nFor a scheme X = Spec(R) and an element f R, return the open subscheme U = Spec(Rf¹) = X V(f) defined by the complement of the vanishing locus of f.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1, x2, x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> hypersurface_complement(X, x1)\nSpectrum\n of localization\n of multivariate polynomial ring in 3 variables over QQ\n at products of 1 element\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#hypersurface_complement-Tuple{AbsSpec, Vector{<:RingElem}}","page":"Affine schemes","title":"hypersurface_complement","text":"hypersurface_complement(X::AbsSpec, f::Vector{<:RingElem})\n\nFor a scheme X = Spec(R) and elements f₁ f₂ R, return the open subscheme U = Spec(Rf₁¹f₂¹ ) = X V(f₁f₂) defined by the complement of the vanishing locus of the product f₁f₂.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> hypersurface_complement(X,[x1,x2])\nSpectrum\n of localization\n of multivariate polynomial ring in 3 variables over QQ\n at products of 2 elements\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Closure","page":"Affine schemes","title":"Closure","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"closure(X::AbsSpec, Y::AbsSpec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#closure-Tuple{AbsSpec, AbsSpec}","page":"Affine schemes","title":"closure","text":"closure(X::AbsSpec, Y::AbsSpec)\n\nReturn the closure of X in Y.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> H = subscheme(X,ideal(R,[x1]))\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> closure(H, X)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Attributes","page":"Affine schemes","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Ambient-affine-space","page":"Affine schemes","title":"Ambient affine space","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"Most affine schemes in Oscar X = mathrmSpec(R) over a ring B, come with an embedding into an affine space mathbbA_B. More precisely, ambient_space(X) is defined for X = Spec(R) if R is constructed from a polynomial ring. In particular mathrmSpec(mathbbZ) or mathrmSpec(mathbbk) for mathbb k a field do not have an ambient affine space.","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"ambient_space(X::AbsSpec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#ambient_space-Tuple{AbsSpec}","page":"Affine schemes","title":"ambient_space","text":"ambient_space(X::AbsSpec)\n\nReturn the ambient affine space of X. \n\nUse ambient_embedding(::AbsSpec) to obtain the embedding of X in its ambient affine space.\n\nExamples\n\njulia> X = affine_space(QQ, [:x,:y])\nAffine space of dimension 2\n over rational field\nwith coordinates [x, y]\n\njulia> ambient_space(X) == X\ntrue\n\njulia> (x, y) = coordinates(X);\n\njulia> Y = subscheme(X, [x])\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x)\n\njulia> X == ambient_space(Y)\ntrue\n\njulia> Z = subscheme(Y, y)\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x, y)\n\njulia> ambient_space(Z) == X\ntrue\n\njulia> V = hypersurface_complement(Y, y)\nSpectrum\n of localization\n of quotient of multivariate polynomial ring by ideal with 1 generator\n at products of 1 element\n\njulia> ambient_space(V) == X\ntrue\n\nWe can create X, Y and Z also by first constructing the corresponding coordinate rings. The subset relations are inferred from the coordinate rings. More precisely, for a polynomial ring P an ideal I P and a multiplicatively closed subset U of P let R be one of P, U^-1P, PI or U^-1(PI). In each case the ambient affine space is given by Spec(P).\n\nExamples\n\njulia> P, (x, y) = polynomial_ring(QQ, [:x, :y])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> X = Spec(P)\nSpectrum\n of multivariate polynomial ring in 2 variables x, y\n over rational field\n\njulia> I = ideal(P, x)\nideal(x)\n\njulia> RmodI, quotient_map = quo(P, I);\n\njulia> Y = Spec(RmodI)\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x)\n\njulia> ambient_space(Y) == X\ntrue\n\njulia> J = ideal(RmodI, y);\n\njulia> RmodJ, quotient_map2 = quo(RmodI, J);\n\njulia> Z = Spec(RmodJ)\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x, y)\n\njulia> ambient_space(Z) == X\ntrue\n\njulia> U = powers_of_element(y)\nMultiplicative subset\n of multivariate polynomial ring in 2 variables over QQ\n given by the products of [y]\n\njulia> URmodI, _ = localization(RmodI, U);\n\njulia> V = Spec(URmodI)\nSpectrum\n of localization\n of quotient of multivariate polynomial ring by ideal with 1 generator\n at products of 1 element\n\njulia> ambient_space(V) == X\ntrue\n\nNote: compare with ==, as the same affine space could be represented internally by different objects for technical reasons.\n\nExamples\n\njulia> AX = ambient_space(X);\n\njulia> AY = ambient_space(Y);\n\njulia> AX == AY\ntrue\n\njulia> AX === AY\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Other-attributes","page":"Affine schemes","title":"Other attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"base_ring(X::AbsSpec)\ncodim(X::AbsSpec)\nambient_embedding(X::AbsSpec)\ndim(X::AbsSpec)\nname(X::AbsSpec)\nOO(X::AbsSpec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#base_ring-Tuple{AbsSpec}","page":"Affine schemes","title":"base_ring","text":"base_ring(I::MPolyIdeal)\n\nReturn the ambient ring of I.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y])\n\njulia> I = ideal(R, [x, y])^2\nideal(x^2, x*y, y^2)\n\njulia> base_ring(I)\nMultivariate polynomial ring in 2 variables x, y\n over rational field\n\n\n\n\n\nbase_ring(X::AbsSpec)\n\nOn an affine scheme X𝕜 over 𝕜 this returns the ring 𝕜.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> base_ring(X)\nRational field\n\n\n\n\n\nbase_ring(M::PMat)\n\nThe PMat M defines an R-module for some maximal order R. This function returns the R that was used to defined M.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#codim-Tuple{AbsSpec}","page":"Affine schemes","title":"codim","text":"codim(X::AbsSpec)\n\nReturn the codimension of X in its ambient affine space.\n\nThrows and error if X does not have an ambient affine space.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> codim(X)\n0\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> codim(Y)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#ambient_embedding-Tuple{AbsSpec}","page":"Affine schemes","title":"ambient_embedding","text":"ambient_embedding(X::AbsSpec)\n\nReturn the embedding of X in its ambient affine space.\n\nExamples\n\njulia> X = affine_space(QQ, [:x,:y])\nAffine space of dimension 2\n over rational field\nwith coordinates [x, y]\n\njulia> (x, y) = coordinates(X);\n\njulia> Y = subscheme(X, [x])\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x)\n\njulia> inc = ambient_embedding(Y)\nMorphism\n from [x, y] spec of quotient of multivariate polynomial ring\n to [x, y] affine 2-space over QQ\ngiven by the pullback function\n x -> 0\n y -> y\n\njulia> inc == inclusion_morphism(Y, X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#dim-Tuple{AbsSpec}","page":"Affine schemes","title":"dim","text":"dim(X::AbsSpec)\n\nReturn the dimension the affine scheme X = Spec(R).\n\nBy definition, this is the Krull dimension of R.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> dim(X)\n3\n\njulia> Y = affine_space(ZZ, 2)\nSpectrum\n of multivariate polynomial ring in 2 variables x1, x2\n over integer Ring\n\njulia> dim(Y) # one dimension comes from ZZ and two from x1 and x2\n3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#name-Tuple{AbsSpec}","page":"Affine schemes","title":"name","text":"name(X::AbsSpec)\n\nReturn the current name of an affine scheme.\n\nThis name can be specified via set_name!.\n\nExamples\n\njulia> X = affine_space(QQ, 3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> name(X)\n\"unnamed affine variety\"\n\njulia> set_name!(X, \"affine 3-dimensional space\")\n\njulia> name(X)\n\"affine 3-dimensional space\"\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#OO-Tuple{AbsSpec}","page":"Affine schemes","title":"OO","text":"OO(X::AbsSpec)\n\nOn an affine scheme X = Spec(R), return the ring R.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Type-getters","page":"Affine schemes","title":"Type getters","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"We support functions which return the types of schemes, associated rings, and their elements. See the source code for details.","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Properties","page":"Affine schemes","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"is_open_embedding(X::AbsSpec, Y::AbsSpec)\nis_closed_embedding(X::AbsSpec, Y::AbsSpec)\nisempty(X::AbsSpec)\nissubset(X::AbsSpec, Y::AbsSpec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#is_open_embedding-Tuple{AbsSpec, AbsSpec}","page":"Affine schemes","title":"is_open_embedding","text":"is_open_embedding(X::AbsSpec, Y::AbsSpec)\n\nChecks whether X is openly embedded in Y.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X,ideal(R,[x1*x2]))\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1*x2)\n\njulia> is_open_embedding(Y, X)\nfalse\n\njulia> Z = hypersurface_complement(X, x1)\nSpectrum\n of localization\n of multivariate polynomial ring in 3 variables over QQ\n at products of 1 element\n\njulia> is_open_embedding(Z, X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#is_closed_embedding-Tuple{AbsSpec, AbsSpec}","page":"Affine schemes","title":"is_closed_embedding","text":"is_closed_embedding(X::AbsSpec, Y::AbsSpec)\n\nChecks whether X is closed embedded in Y.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X,ideal(R,[x1*x2]))\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1*x2)\n\njulia> is_closed_embedding(Y, X)\ntrue\n\njulia> Z = hypersurface_complement(X, x1)\nSpectrum\n of localization\n of multivariate polynomial ring in 3 variables over QQ\n at products of 1 element\n\njulia> is_closed_embedding(Z, X)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#isempty-Tuple{AbsSpec}","page":"Affine schemes","title":"isempty","text":"is_empty(X::AbsSpec)\n\nCheck whether the affine scheme X is empty.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> isempty(X)\nfalse\n\njulia> is_empty(subscheme(X, one(OO(X))))\ntrue\n\njulia> isempty(EmptyScheme(QQ))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#issubset-Tuple{AbsSpec, AbsSpec}","page":"Affine schemes","title":"issubset","text":"is_subset(X::AbsSpec, Y::AbsSpec)\n\nCheck whether X is a subset of Y based on the comparison of their coordinate rings. See inclusion_morphism(::AbsSpec, ::AbsSpec) for the corresponding morphism.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X,ideal(R,[x1*x2]))\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1*x2)\n\njulia> is_subset(X, Y)\nfalse\n\njulia> is_subset(Y, X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Methods","page":"Affine schemes","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"tangent_space(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#tangent_space-Tuple{AbsSpec{<:Field}, AbsAffineRationalPoint}","page":"Affine schemes","title":"tangent_space","text":"tangent_space(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint) -> AlgebraicSet\n\nReturn the Zariski tangent space of X at its rational point P.\n\nSee also tangent_space(P::AbsAffineRationalPoint{<:Field})\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Comparison","page":"Affine schemes","title":"Comparison","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"Two schemes X and Y can be compared if their ambient affine spaces are equal. In particular X and Y are considered equal (==) if and only if the identity morphism of their ambient affine space induces an isomorphism of X and Y. For X and Y with different ambient affine space X==Y is always false.","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#Auxiliary-methods","page":"Affine schemes","title":"Auxiliary methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/","page":"Affine schemes","title":"Affine schemes","text":"is_non_zero_divisor(f::RingElem, X::AbsSpec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#is_non_zero_divisor-Tuple{RingElem, AbsSpec}","page":"Affine schemes","title":"is_non_zero_divisor","text":"is_non_zero_divisor(f::RingElem, X::AbsSpec)\n\nChecks if a ring element is a non-zero divisor in the coordinate ring of an affine scheme.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> (x1, x2, x3) = gens(OO(X))\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> is_non_zero_divisor(x1, X)\ntrue\n\njulia> is_non_zero_divisor(zero(OO(X)), X)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Experimental/LieAlgebras/modules/#Lie-algebra-modules","page":"Lie algebra modules","title":"Lie algebra modules","text":"","category":"section"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"Lie algebra modules in OSCAR are always finite dimensional and represented by the type LieAlgebraModule{C}. Similar to other types in OSCAR, there is the corresponding element type LieAlgebraModuleElem{C}. The type parameter C is the element type of the coefficient ring.","category":"page"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"base_lie_algebra(V::LieAlgebraModule)\nzero(::LieAlgebraModule)\niszero(::LieAlgebraModuleElem)\ndim(::LieAlgebraModule)\nbasis(::LieAlgebraModule)\nbasis(::LieAlgebraModule, ::Int)\ncoefficients(::LieAlgebraModuleElem)\ncoeff(::LieAlgebraModuleElem, ::Int)\ngetindex(::LieAlgebraModuleElem, ::Int)\nsymbols(::LieAlgebraModule)","category":"page"},{"location":"Experimental/LieAlgebras/modules/#base_lie_algebra-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"base_lie_algebra","text":"base_lie_algebra(V::LieAlgebraModule{C}) -> LieAlgebra{C}\n\nReturn the Lie algebra V is a module over.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#zero-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"zero","text":"zero(V::LieAlgebraModule{C}) -> LieAlgebraModuleElem{C}\n\nReturn the zero element of the Lie algebra module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#iszero-Tuple{LieAlgebraModuleElem}","page":"Lie algebra modules","title":"iszero","text":"iszero(v::LieAlgebraModuleElem{C}) -> Bool\n\nCheck whether the Lie algebra module element v is zero.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#dim-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"dim","text":"dim(V::LieAlgebraModule{C}) -> Int\n\nReturn the dimension of the Lie algebra module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#basis-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"basis","text":"basis(V::LieAlgebraModule{C}) -> Vector{LieAlgebraModuleElem{C}}\n\nReturn a basis of the Lie algebra module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#basis-Tuple{LieAlgebraModule, Int64}","page":"Lie algebra modules","title":"basis","text":"basis(V::LieAlgebraModule{C}, i::Int) -> LieAlgebraModuleElem{C}\n\nReturn the i-th basis element of the Lie algebra module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#coefficients-Tuple{LieAlgebraModuleElem}","page":"Lie algebra modules","title":"coefficients","text":"coefficients(v::LieAlgebraModuleElem{C}) -> Vector{C}\n\nReturn the coefficients of v with respect to basis(::LieAlgebraModule).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#coeff-Tuple{LieAlgebraModuleElem, Int64}","page":"Lie algebra modules","title":"coeff","text":"coeff(v::LieAlgebraModuleElem{C}, i::Int) -> C\n\nReturn the i-th coefficient of v with respect to basis(::LieAlgebraModule).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#getindex-Tuple{LieAlgebraModuleElem, Int64}","page":"Lie algebra modules","title":"getindex","text":"getindex(v::LieAlgebraModuleElem{C}, i::Int) -> C\n\nReturn the i-th coefficient of v with respect to basis(::LieAlgebraModule).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#symbols-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"symbols","text":"symbols(V::LieAlgebraModule{C}) -> Vector{Symbol}\n\nReturn the symbols used for printing basis elements of the Lie algebra module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#Element-constructors","page":"Lie algebra modules","title":"Element constructors","text":"","category":"section"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"(V::LieAlgebraModule{C})() returns the zero element of the Lie algebra module V.","category":"page"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"(V::LieAlgebraModule{C})(v::LieAlgebraModuleElem{C}) returns v if v is an element of L. If V is the dual module of the parent of v, it returns the dual of v. In all other cases, it fails.","category":"page"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"(V::LieAlgebraModule{C})(v) constructs the element of V with coefficient vector v. v can be of type Vector{C}, Vector{Int}, SRow{C}, or MatElem{C} (of size 1 times dim(L)).","category":"page"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"(V::LieAlgebraModule{C})(a::Vector{T}) where {T<:LieAlgebraModuleElem{C}}): If V is a direct sum, return its element, where the i-th component is equal to a[i]. If V is a tensor product, return the tensor product of the a[i]. If V is a exterior (symmetric, tensor) power, return the wedge product (product, tensor product) of the a[i]. Requires that a has a suitable length, and that the a[i] are elements of the correct modules, where correct depends on the case above.","category":"page"},{"location":"Experimental/LieAlgebras/modules/#Arithmetics","page":"Lie algebra modules","title":"Arithmetics","text":"","category":"section"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"The usual arithmetics, e.g. +, -, and * (scalar multiplication), are defined for LieAlgebraModuleElems.","category":"page"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"The module action is defined as *.","category":"page"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"*(x::LieAlgebraElem{C}, v::LieAlgebraModuleElem{C}) where {C<:RingElement}","category":"page"},{"location":"Experimental/LieAlgebras/modules/#*-Union{Tuple{C}, Tuple{LieAlgebraElem{C}, LieAlgebraModuleElem{C}}} where C<:RingElement","page":"Lie algebra modules","title":"*","text":"action(x::LieAlgebraElem{C}, v::LieAlgebraModuleElem{C}) -> LieAlgebraModuleElem{C}\n*(x::LieAlgebraElem{C}, v::LieAlgebraModuleElem{C}) -> LieAlgebraModuleElem{C}\n\nApply the action of x on v.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#Module-constructors","page":"Lie algebra modules","title":"Module constructors","text":"","category":"section"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"standard_module(::LinearLieAlgebra)\ndual(::LieAlgebraModule{C}) where {C<:RingElement}\ndirect_sum(::LieAlgebraModule{C}, ::LieAlgebraModule{C}) where {C<:RingElement}\ntensor_product(::LieAlgebraModule{C}, ::LieAlgebraModule{C}) where {C<:RingElement}\nexterior_power(::LieAlgebraModule{C}, ::Int) where {C<:RingElement}\nsymmetric_power(::LieAlgebraModule{C}, ::Int) where {C<:RingElement}\ntensor_power(::LieAlgebraModule{C}, ::Int) where {C<:RingElement}\nabstract_module(::LieAlgebra{C}, ::Int, ::Vector{<:MatElem{C}}, ::Vector{<:VarName}; ::Bool) where {C<:RingElement}\nabstract_module(::LieAlgebra{C}, ::Int, ::Matrix{SRow{C}}, ::Vector{<:VarName}; ::Bool) where {C<:RingElement}","category":"page"},{"location":"Experimental/LieAlgebras/modules/#standard_module-Tuple{LinearLieAlgebra}","page":"Lie algebra modules","title":"standard_module","text":"standard_module(L::LinearLieAlgebra{C}) -> LieAlgebraModule{C}\n\nConstruct the standard module of the linear Lie algebra L. If L is a Lie subalgebra of mathfrakgl_n(R), then the standard module is R^n with the action of L given by left multiplication.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#dual-Union{Tuple{LieAlgebraModule{C}}, Tuple{C}} where C<:RingElement","page":"Lie algebra modules","title":"dual","text":"dual(V::LieAlgebraModule{C}) -> LieAlgebraModule{C}\n\nConstruct the dual module of V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#direct_sum-Union{Tuple{C}, Tuple{LieAlgebraModule{C}, LieAlgebraModule{C}}} where C<:RingElement","page":"Lie algebra modules","title":"direct_sum","text":"direct_sum(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}\n⊕(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}\n\nConstruct the direct sum of the modules V....\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#tensor_product-Union{Tuple{C}, Tuple{LieAlgebraModule{C}, LieAlgebraModule{C}}} where C<:RingElement","page":"Lie algebra modules","title":"tensor_product","text":"tensor_product(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C} ⊗(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}\n\nConstruct the tensor product of the modules V....\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#exterior_power-Union{Tuple{C}, Tuple{LieAlgebraModule{C}, Int64}} where C<:RingElement","page":"Lie algebra modules","title":"exterior_power","text":"exterior_power(V::LieAlgebraModule{C}, k::Int) -> LieAlgebraModule{C}\n\nConstruct the k-th exterior power bigwedge^k (V) of the module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#symmetric_power-Union{Tuple{C}, Tuple{LieAlgebraModule{C}, Int64}} where C<:RingElement","page":"Lie algebra modules","title":"symmetric_power","text":"symmetric_power(V::LieAlgebraModule{C}, k::Int) -> LieAlgebraModule{C}\n\nConstruct the k-th symmetric power S^k (V) of the module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#tensor_power-Union{Tuple{C}, Tuple{LieAlgebraModule{C}, Int64}} where C<:RingElement","page":"Lie algebra modules","title":"tensor_power","text":"tensor_power(V::LieAlgebraModule{C}, k::Int) -> LieAlgebraModule{C}\n\nConstruct the k-th tensor power T^k (V) of the module V.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#abstract_module-Union{Tuple{C}, Tuple{LieAlgebra{C}, Int64, Vector{<:MatElem{C}}, Vector{<:Union{Char, AbstractString, Symbol}}}} where C<:RingElement","page":"Lie algebra modules","title":"abstract_module","text":"abstract_module(L::LieAlgebra{C}, dimV::Int, transformation_matrices::Vector{<:MatElem{C}}, s::Vector{<:VarName}; check::Bool) -> LieAlgebraModule{C}\n\nConstruct the the Lie algebra module over L of dimension dimV given by transformation_matrices and with basis element names s.\n\ntransformation_matrices: The action of the i-th basis element of L on some element v of the constructed module is given by left multiplication of the matrix transformation_matrices[i] to the coefficient vector of v.\ns: A vector of basis element names. This is [Symbol(\"v_$i\") for i in 1:dimV] by default.\ncheck: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#abstract_module-Union{Tuple{C}, Tuple{LieAlgebra{C}, Int64, Array{SRow{C}, 2}, Vector{<:Union{Char, AbstractString, Symbol}}}} where C<:RingElement","page":"Lie algebra modules","title":"abstract_module","text":"abstract_module(L::LieAlgebra{C}, dimV::Int, struct_consts::Matrix{SRow{C}}, s::Vector{<:VarName}; check::Bool) -> LieAlgebraModule{C}\n\nConstruct the the Lie algebra module over L of dimension dimV given by structure constants struct_consts and with basis element names s.\n\nThe action on the newly constructed Lie algebra module V is determined by the structure constants in struct_consts as follows: let x_i denote the i-th standard basis vector of L, and v_i the i-th standard basis vector of V. Then the entry struct_consts[i,j][k] is a scalar a_ijk such that x_i * v_j = sum_k a_ijk v_k.\n\ns: A vector of basis element names. This is [Symbol(\"v_$i\") for i in 1:dimV] by default.\ncheck: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#Type-dependent-getters","page":"Lie algebra modules","title":"Type-dependent getters","text":"","category":"section"},{"location":"Experimental/LieAlgebras/modules/","page":"Lie algebra modules","title":"Lie algebra modules","text":"is_standard_module(::LieAlgebraModule)\nis_dual(::LieAlgebraModule)\nis_direct_sum(::LieAlgebraModule)\nis_tensor_product(::LieAlgebraModule)\nis_exterior_power(::LieAlgebraModule)\nis_symmetric_power(::LieAlgebraModule)\nis_tensor_power(::LieAlgebraModule)\nbase_module(::LieAlgebraModule{C}) where {C<:RingElement}\nbase_modules(::LieAlgebraModule{C}) where {C<:RingElement}","category":"page"},{"location":"Experimental/LieAlgebras/modules/#is_standard_module-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"is_standard_module","text":"is_standard_module(V::LieAlgebraModule{C}) -> Bool\n\nCheck whether V has been constructed as a standard module.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#is_dual-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"is_dual","text":"is_dual(V::LieAlgebraModule{C}) -> Bool\n\nCheck whether V has been constructed as a dual module.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#is_direct_sum-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"is_direct_sum","text":"is_direct_sum(V::LieAlgebraModule{C}) -> Bool\n\nCheck whether V has been constructed as a direct sum of modules.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#is_tensor_product-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"is_tensor_product","text":"is_tensor_product(V::LieAlgebraModule{C}) -> Bool\n\nCheck whether V has been constructed as a tensor product of modules.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#is_exterior_power-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"is_exterior_power","text":"is_exterior_power(V::LieAlgebraModule{C}) -> Bool\n\nCheck whether V has been constructed as an exterior power of a module.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#is_symmetric_power-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"is_symmetric_power","text":"is_symmetric_power(V::LieAlgebraModule{C}) -> Bool\n\nCheck whether V has been constructed as a symmetric power of a module.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#is_tensor_power-Tuple{LieAlgebraModule}","page":"Lie algebra modules","title":"is_tensor_power","text":"is_tensor_power(V::LieAlgebraModule{C}) -> Bool\n\nCheck whether V has been constructed as a tensor power of a module.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#base_module-Union{Tuple{LieAlgebraModule{C}}, Tuple{C}} where C<:RingElement","page":"Lie algebra modules","title":"base_module","text":"base_module(V::LieAlgebraModule{C}) -> LieAlgebraModule{C}\n\nReturns the base module of V, if V has been constructed as a power module.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#base_modules-Union{Tuple{LieAlgebraModule{C}}, Tuple{C}} where C<:RingElement","page":"Lie algebra modules","title":"base_modules","text":"base_modules(V::LieAlgebraModule{C}) -> Vector{LieAlgebraModule{C}}\n\nReturns the summands or tensor factors of V, if V has been constructed as a direct sum or tensor product of modules.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"CurrentModule = Oscar","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#Simplicial-Complexes","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/#Introduction","page":"Simplicial Complexes","title":"Introduction","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"Abstract simplicial complexes provide a combinatorial way to define topological spaces. By no means every topological space arises in this way, but this is a (most) natural choice in a computational setup.","category":"page"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"A simplicial complex K on a vertex set V is a nonempty subset of 2^V such that for each sigma in K and tau subsetsigma we have tauin K. Here V is usually n = 12dotsn for some ngeq 0.","category":"page"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"General textbooks offering details on the theory include:","category":"page"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"Dmitry Kozlov (2008)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#Construction","page":"Simplicial Complexes","title":"Construction","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"SimplicialComplex(K::Vector{Vector{Int}})","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#SimplicialComplex-Tuple{Vector{Vector{Int64}}}","page":"Simplicial Complexes","title":"SimplicialComplex","text":"SimplicialComplex(generators::Union{Vector{Vector{Int}}, Vector{Set{Int}}})\n\nConstruct an abstract simplicial complex from a set of faces. While arbitrary nonnegative integers are allowed as vertices, they will be relabeled to consecutive integers starting at 1.\n\nExamples\n\njulia> K = SimplicialComplex([[1,2,3],[2,3,4]])\nAbstract simplicial complex of dimension 2 on 4 vertices\n\nSimplicial complex comprising the empty set only:\n\njulia> empty = SimplicialComplex(Vector{Set{Int}}([]))\nAbstract simplicial complex of dimension -1 on 0 vertices\n\nThe original vertices can be recovered:\n\njulia> L = SimplicialComplex([[0,2,17],[2,17,90]]);\n\njulia> facets(L)\n2-element Vector{Set{Int64}}:\n Set([2, 3, 1])\n Set([4, 2, 3])\n\njulia> vertexindices(L)\n4-element Vector{Int64}:\n 0\n 2\n 17\n 90\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Subcomplexes","page":"Simplicial Complexes","title":"Subcomplexes","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"star_subcomplex(K::SimplicialComplex, sigma::Union{Vector{Int}, Set{Int}})\nlink_subcomplex(K::SimplicialComplex, sigma::Union{Vector{Int}, Set{Int}})","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#star_subcomplex-Tuple{SimplicialComplex, Union{Set{Int64}, Vector{Int64}}}","page":"Simplicial Complexes","title":"star_subcomplex","text":"star_subcomplex(K::SimplicialComplex, sigma::Union{Vector{Int}, Set{Int}})\n\nReturn the star of the face sigma in the abstract simplicial complex K.\n\nExamples\n\njulia> K = SimplicialComplex([[1,2,3],[2,3,4]]);\n\njulia> star_subcomplex(K,[1])\nAbstract simplicial complex of dimension 2 on 3 vertices\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#link_subcomplex-Tuple{SimplicialComplex, Union{Set{Int64}, Vector{Int64}}}","page":"Simplicial Complexes","title":"link_subcomplex","text":"link_subcomplex(K::SimplicialComplex, sigma::Union{Vector{Int}, Set{Int}})\n\nReturn the link of the face sigma in the abstract simplicial complex K.\n\nExamples\n\njulia> K = SimplicialComplex([[1,2,3],[2,3,4]]);\n\njulia> link_subcomplex(K,[2,3])\nAbstract simplicial complex of dimension 0 on 2 vertices\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Surface-examples","page":"Simplicial Complexes","title":"Surface examples","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"torus()\nklein_bottle()\nreal_projective_plane()","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#torus-Tuple{}","page":"Simplicial Complexes","title":"torus","text":"torus()\n\nConstruct Möbius' (vertex-minimal) 7-vertex triangulation of the torus (surface).\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#klein_bottle-Tuple{}","page":"Simplicial Complexes","title":"klein_bottle","text":"klein_bottle()\n\nConstruct a 9-vertex triangulation of the Klein bottle.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#real_projective_plane-Tuple{}","page":"Simplicial Complexes","title":"real_projective_plane","text":"real_projective_plane()\n\nConstruct the (vertex-minimal) 6-vertex triangulation of the real projective plane.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Other-examples","page":"Simplicial Complexes","title":"Other examples","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"complex_projective_plane()","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#complex_projective_plane-Tuple{}","page":"Simplicial Complexes","title":"complex_projective_plane","text":"complex_projective_plane()\n\nConstruct the (vertex-minimal) 9-vertex triangulation of the complex projective plane.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Basic-properties","page":"Simplicial Complexes","title":"Basic properties","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"nvertices(K::SimplicialComplex)\ndim(K::SimplicialComplex)\nf_vector(K::SimplicialComplex)\nh_vector(K::SimplicialComplex)\neuler_characteristic(K::SimplicialComplex)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#nvertices-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"nvertices","text":"nvertices(K::SimplicialComplex)\n\nReturn the number of vertices of the abstract simplicial complex K.\n\nExamples\n\njulia> nvertices(torus())\n7\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#dim-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"dim","text":"dim(K::SimplicialComplex)\n\nReturn the dimension of the abstract simplicial complex K.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#f_vector-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"f_vector","text":"f_vector(K::SimplicialComplex)\n\nReturn the face vector (number of faces per dimension) of the abstract simplicial complex K.\n\nExamples\n\njulia> f_vector(torus())\n3-element Vector{Int64}:\n 7\n 21\n 14\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#h_vector-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"h_vector","text":"h_vector(K::SimplicialComplex)\n\nReturn the h-vector of the abstract simplicial complex K.\n\nExamples\n\njulia> h_vector(torus())\n4-element Vector{Int64}:\n 1\n 4\n 10\n -1\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#euler_characteristic-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"euler_characteristic","text":"euler_characteristic(K::SimplicialComplex)\n\nReturn the reduced Euler characteristic of the abstract simplicial complex K.\n\nExamples\n\njulia> euler_characteristic(complex_projective_plane())\n2\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Homology-and-cohomology","page":"Simplicial Complexes","title":"Homology and cohomology","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"homology(K::SimplicialComplex, i::Int)\nbetti_numbers(K::SimplicialComplex)\ncohomology(K::SimplicialComplex, i::Int)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#homology-Tuple{SimplicialComplex, Int64}","page":"Simplicial Complexes","title":"homology","text":"homology(K::SimplicialComplex, i::Int)\n\nReturn i-th reduced integral homology group of K. Recall that the 0-th homology group is trivial if and only if K is connected.\n\nExamples\n\njulia> [ homology(real_projective_plane(), i) for i in [0,1,2] ]\n3-element Vector{GrpAbFinGen}:\n GrpAb: Z/1\n GrpAb: Z/2\n GrpAb: Z/1\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#betti_numbers-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"betti_numbers","text":"betti_numbers(K::SimplicialComplex)\n\nReturn the reduced rational Betti numbers of the abstract simplicial complex K.\n\nExamples\n\njulia> betti_numbers(klein_bottle())\n3-element Vector{Int64}:\n 0\n 1\n 0\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#cohomology-Tuple{SimplicialComplex, Int64}","page":"Simplicial Complexes","title":"cohomology","text":"cohomology(K::SimplicialComplex, i::Int)\n\nReturn i-th reduced integral cohomology group of K.\n\nExamples\n\njulia> K = SimplicialComplex([[0,1],[1,2],[0,2]]);\n\njulia> cohomology(K,1)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Fundamental-group","page":"Simplicial Complexes","title":"Fundamental group","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"fundamental_group(K::SimplicialComplex)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#fundamental_group-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"fundamental_group","text":"fundamental_group(K::SimplicialComplex)\n\nReturn the fundamental group of the abstract simplicial complex K.\n\nExamples\n\njulia> pi_1 = fundamental_group(torus());\n\njulia> describe(pi_1)\n\"Z x Z\"\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Connection-to-commutative-algebra","page":"Simplicial Complexes","title":"Connection to commutative algebra","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"The complements of the minimal non-faces form the facets of the Alexander dual.","category":"page"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"minimal_nonfaces(K::SimplicialComplex)\nalexander_dual(K::SimplicialComplex)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#minimal_nonfaces-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"minimal_nonfaces","text":"minimal_nonfaces(K::SimplicialComplex)\n\nReturn the minimal non-faces of the abstract simplicial complex K.\n\nExamples\n\njulia> K = SimplicialComplex([[1,2,3],[2,3,4]]);\n\njulia> minimal_nonfaces(K)\n1-element Vector{Set{Int64}}:\n Set([4, 1])\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#alexander_dual-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"alexander_dual","text":"alexander_dual(K::SimplicialComplex)\n\nReturn the Alexander dual of the abstract simplicial complex K.\n\nExamples\n\njulia> K = SimplicialComplex([[1,2,3],[2,3,4]]);\n\njulia> alexander_dual(K)\nAbstract simplicial complex of dimension 1 on 2 vertices\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"Let K be a simplicial complex on n vertices. The minimal non-faces of K generate a square-free monomial ideal, known as the Stanley-Reisner ideal of K. The quotient of the polynomial ring (in n variables, with integer coefficients) modulo that ideal is the Stanley-Reisner ring. For details see Chapter 5 of Winfried Bruns, Jürgen Herzog (2009).","category":"page"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"stanley_reisner_ideal(K::SimplicialComplex)\nstanley_reisner_ideal(R::MPolyRing, K::SimplicialComplex)\nstanley_reisner_ring(K::SimplicialComplex)\nstanley_reisner_ring(R::MPolyRing, K::SimplicialComplex)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#stanley_reisner_ideal-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"stanley_reisner_ideal","text":"stanley_reisner_ideal(K::SimplicialComplex)\n\nReturn the Stanley-Reisner ideal of the abstract simplicial complex K.\n\nExamples\n\njulia> stanley_reisner_ideal(real_projective_plane())\nideal(x1*x2*x3, x1*x2*x4, x1*x5*x6, x2*x5*x6, x1*x3*x6, x1*x4*x5, x3*x4*x5, x3*x4*x6, x2*x3*x5, x2*x4*x6)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#stanley_reisner_ideal-Tuple{MPolyRing, SimplicialComplex}","page":"Simplicial Complexes","title":"stanley_reisner_ideal","text":"stanley_reisner_ideal(R::MPolyRing, K::SimplicialComplex)\n\nReturn the Stanley-Reisner ideal of the abstract simplicial complex K, in the given ring R.\n\nExamples\n\njulia> R, _ = QQ[\"a\",\"b\",\"c\",\"d\",\"e\",\"f\"];\n\njulia> stanley_reisner_ideal(R, real_projective_plane())\nideal(a*b*c, a*b*d, a*e*f, b*e*f, a*c*f, a*d*e, c*d*e, c*d*f, b*c*e, b*d*f)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#stanley_reisner_ring-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"stanley_reisner_ring","text":"stanley_reisner_ring(K::SimplicialComplex)\n\nReturn the Stanley-Reisner ring of the abstract simplicial complex K.\n\nExamples\n\njulia> K = SimplicialComplex([[1,2,3],[2,3,4]]);\n\njulia> stanley_reisner_ring(K)\n(Quotient of multivariate polynomial ring by ideal with 1 generator, Map from\nMultivariate polynomial ring in 4 variables over QQ to Quotient of multivariate polynomial ring by ideal with 1 generator defined by a julia-function with inverse)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#stanley_reisner_ring-Tuple{MPolyRing, SimplicialComplex}","page":"Simplicial Complexes","title":"stanley_reisner_ring","text":"stanley_reisner_ring(R::MPolyRing, K::SimplicialComplex)\n\nReturn the Stanley-Reisner ring of the abstract simplicial complex K, as a quotient of a given ring R.\n\nExamples\n\njulia> R, _ = ZZ[\"a\",\"b\",\"c\",\"d\",\"e\",\"f\"];\n\njulia> stanley_reisner_ring(R, real_projective_plane())\n(Quotient of multivariate polynomial ring by ideal with 10 generators, Map from\nMultivariate polynomial ring in 6 variables over ZZ to Quotient of multivariate polynomial ring by ideal with 10 generators defined by a julia-function with inverse)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Saving-and-loading","page":"Simplicial Complexes","title":"Saving and loading","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"Objects of type SimplicialComplex can be saved to a file and loaded with the two methods save and load. The file is in JSON format and contains the underlying polymake object. In particular, such a file can be read by both polymake and OSCAR.","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"NoncommutativeAlgebra/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Working over a field K, our focus in this chapter is on noncommutative Gröbner bases and their application to the computational study of finitely presented associative K-algebras. At present state, OSCAR offers","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"a comprehensive toolkit for dealing with PBW-algebras and their quotients modulo two-sided ideals,\nfunctionality for computing and applying (partial) two-sided Gröbner bases in free associative algebras on finitely many letters.","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nIn contrast to the general case of finitely presented associative algebras, (left, right, two-sided) ideals in PBW-algebras admit finite (left, right, two-sided) Gröbner bases. In particular, PBW-algebras are Noetherian.","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nThe class of PBW-algebras includes the Weyl algebras. Algebras which arise as quotients of PBW-algebras include the Clifford algebras (in particular, the exterior algebras).","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"The textbooks","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Gert-Martin Greuel, Gerhard Pfister (2008)\nWolfram Decker, Christoph Lossen (2006)\nJosé Bueso, José Gómez-Torrecillas, Alain Verschoren (2003)","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"and the thesis","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Viktor Levandovskyy (2005)","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"offer details on theory and algorithms.","category":"page"},{"location":"NoncommutativeAlgebra/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Wolfram Decker.","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/series_interface/#Series-Ring-Interface","page":"Series Ring Interface","title":"Series Ring Interface","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Univariate power series rings are supported in AbstractAlgebra in a variety of different forms, including absolute and relative precision models and Laurent series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"In addition to the standard Ring interface, numerous additional functions are required to be present for power series rings.","category":"page"},{"location":"AbstractAlgebra/series_interface/#Types-and-parents","page":"Series Ring Interface","title":"Types and parents","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"AbstractAlgebra provides two abstract types for power series rings and their elements:","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"SeriesRing{T} is the abstract type for all power series ring parent types\nSeriesElem{T} is the abstract type for all power series types","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"We have that SeriesRing{T} <: Ring and SeriesElem{T} <: RingElem.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Note that both abstract types are parameterised. The type T should usually be the type of elements of the coefficient ring of the power series ring. For example, in the case of mathbbZx the type T would be the type of an integer, e.g. BigInt.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Within the SeriesElem{T} abstract type is the abstract type RelPowerSeriesRingElem{T} for relative power series, and AbsPowerSeriesRingElem{T} for absolute power series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Relative series are typically stored with a valuation and a series that is either zero or that has nonzero constant term. Absolute series are stored starting from the constant term, even if it is zero.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"If the parent object for a relative series ring over the bignum integers has type MySeriesRing and series in that ring have type MySeries then one would have:","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"MySeriesRing <: SeriesRing{BigInt}\nMySeries <: RelPowerSeriesRingElem{BigInt}","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Series rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Series rings should at least be distinguished based on their base (coefficient) ring. But if they have the same base ring and symbol (for their variable/generator) and same default precision, they should certainly have the same parent object.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).","category":"page"},{"location":"AbstractAlgebra/series_interface/#Required-functionality-for-series","page":"Series Ring Interface","title":"Required functionality for series","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"In addition to the required functionality for the Ring interface the Series Ring interface has the following required functions.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"We suppose that R is a fictitious base ring (coefficient ring) and that S is a series ring over R (e.g. S = Rx) with parent object S of type MySeriesRing{T}. We also assume the series in the ring have type MySeries{T}, where T is the type of elements of the base (coefficient) ring.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Note that the type T must (transitively) belong to the abstract type RingElem.","category":"page"},{"location":"AbstractAlgebra/series_interface/#Constructors","page":"Series Ring Interface","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"In addition to the standard constructors, the following constructors, taking an array of coefficients, must be available.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"For relative power series and Laurent series we have:","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"(S::MySeriesRing{T})(A::Vector{T}, len::Int, prec::Int, val::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Create the series in the given ring whose valuation is val, whose absolute precision is given by prec and the coefficients of which are given by A, starting from the first nonzero term. Only len terms of the array are used, the remaining terms being ignored. The value len cannot exceed the length of the supplied array.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"It is permitted to have trailing zeros in the array, but it is not needed, even if the precision minus the valuation is bigger than the length of the array.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"(S::MySeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: RingElem}","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"As above, but where the array is an array of coefficient that can be coerced into the base ring of the series ring.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"(S::MySeriesRing{T})(A::Vector{U}, len::Int, prec::Int, val::Int) where {T <: RingElem, U <: Integer}","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"As above, but where the array is an array of integers that can be coerced into the base ring of the series ring.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"It may be desirable to implement an addition version which accepts an array of Julia Int values if this can be done more efficiently.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"For absolute power series we have:","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"(S::MySeriesRing{T})(A::Vector{T}, len::Int, prec::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Create the series in the given ring whose absolute precision is given by prec and the coefficients of which are given by A, starting from the constant term. Only len terms of the array are used, the remaining terms being ignored.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Note that len is usually maintained separately of any polynomial that is underlying the power series. This allows for easy trucation of a power series without actually modifying the polynomial underlying it.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"It is permitted to have trailing zeros in the array, but it is not needed, even if the precision is bigger than the length of the array.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"It is also possible to create series directly without having to create the corresponding series ring.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"abs_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T\nrel_series(R::Ring, arr::Vector{T}, len::Int, prec::Int, val::Int, var::VarName=:x; max_precision::Int=prec, cached::Bool=true) where T","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Create the power series over the given base ring R with coefficients specified by arr with the given absolute precision prec and in the case of relative series with the given valuation val.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Note that more coefficients may be specified than are actually used. Only the first len coefficients are made part of the series, the remainder being stored internally but ignored.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"In the case of absolute series one must have prec >= len and in the case of relative series one must have prec >= len + val.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"By default the series are created in a ring with variable x and max_precision equal to prec, however one may specify these directly to override the defaults. Note that series are only compatible if they have the same coefficient ring R, max_precision and variable name var.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Also by default any parent ring created is cached. If this behaviour is not desired, set cached=false. However, this means that subsequent series created in the same way will not be compatible. Instead, one should use the parent object of the first series to create subsequent series instead of calling this function repeatedly with cached=false.","category":"page"},{"location":"AbstractAlgebra/series_interface/#Data-type-and-parent-object-methods","page":"Series Ring Interface","title":"Data type and parent object methods","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"var(S::MySeriesRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return a Symbol representing the variable (generator) of the series ring. Note that this is a Symbol not a String, though its string value will usually be used when printing series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Custom series types over a given ring should define one of the following functions which return the type of an absolute or relative series object over that ring.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"abs_series_type(::Type{T}) where T <: RingElement\nrel_series_type(::Type{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return the type of a series whose coefficients have the given type.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"This function is defined for generic series and only needs to be defined for custom series rings, e.g. ones defined by a C implementation.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"max_precision(S::MySeriesRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return the (default) maximum precision of the power series ring. This is the precision that the output of an operation will be if it cannot be represented to full precision (e.g. because it mathematically has infinite precision).","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"This value is usually supplied upon creation of the series ring and stored in the ring. It is independent of the precision which each series in the ring actually has. Those are stored on a per element basis in the actual series elements.","category":"page"},{"location":"AbstractAlgebra/series_interface/#Basic-manipulation-of-rings-and-elements","page":"Series Ring Interface","title":"Basic manipulation of rings and elements","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"pol_length(f::MySeries{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return the length of the polynomial underlying the given power series. This is not generally useful to the user, but is used internally.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"set_length!(f::MySeries{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"This function sets the effective length of the polynomial underlying the given series. The function doesn't modify the actual polynomial, but simply changes the number of terms of the polynomial which are considered to belong to the power series. The remaining terms are ignored.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"This function cannot set the length to a value greater than the length of any underlying polynomial.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"The function mutates the series in-place but does not return the mutated series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"precision(f::MySeries{T})","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return the absolute precision of f.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"set_precision!(f::MySeries{T}, prec::Int)","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Set the absolute precision of the given series to the given value.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"This return the updated series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"valuation(f::MySeries{T})","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return the valuation of the given series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"set_valuation!(f::MySeries{T}, val::Int)","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"For relative series and Laurent series only, this function alters the valuation of the given series to the given value.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"This function returns the updated series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"polcoeff(f::MySeries{T}, n::Int)","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return the coefficient of degree n of the polynomial underlying the series. If n is larger than the degree of this polynomial, zero is returned. This function is not generally of use to the user but is used internally.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"setcoeff!(f::MySeries{T}, n::Int, a::T) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Set the degree n coefficient of the polynomial underlying f to a. This mutates the polynomial in-place if possible and returns the mutated series (so that immutable types can also be supported). The function must not assume that the polynomial already has space for n + 1 coefficients. The polynomial must be resized if this is not the case.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"note: Note\nThis function is not required to normalise the polynomial and is not necessarily useful to the user, but is used extensively by the generic functionality in AbstractAlgebra.jl. It is for setting raw coefficients in the representation.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"normalise(f::MySeries{T}, n::Int)","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Given a series f represented by a polynomial of at least the given length, return the normalised length of the underlying polynomial assuming it has length at most n. This function does not actually normalise the polynomial and is not particularly useful to the user. It is used internally.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"renormalize!(f::MySeries{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Given a relative series or Laurent series whose underlying polynomial has zero constant term, say as the result of some internal computation, renormalise the series so that the polynomial has nonzero constant term. The precision and valuation of the series are adjusted to compensate. This function is not intended to be useful to the user, but is used internally.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"fit!(f::MySeries{T}, n::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Ensure that the polynomial underlying f internally has space for n coefficients. This function must mutate the series in-place if it is mutable. It does not return the mutated series. Immutable types can still be supported by defining this function to do nothing.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Some interfaces for C polynomial types automatically manage the internal allocation of polynomials in every function that can be called on them. Explicit adjustment by the generic code in AbstractAlgebra.jl is not required. In such cases, this function can also be defined to do nothing.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"gen(R::MySeriesRing{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Return the generator x of the series ring.","category":"page"},{"location":"AbstractAlgebra/series_interface/#Optional-functionality-for-series","page":"Series Ring Interface","title":"Optional functionality for series","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/#Similar-and-zero","page":"Series Ring Interface","title":"Similar and zero","text":"","category":"section"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"The following functions are available for all absolute and relative series types. The functions similar and zero do the same thing, but are provided for uniformity with other parts of the interface.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"similar(x::MySeries, R::Ring, max_prec::Int, var::VarName=var(parent(x)); cached::Bool=true)\nzero(a::MySeries, R::Ring, max_prec::Int, var::VarName=var(parent(a)); cached::Bool=true)","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Construct the zero series with the given variable (if specified), coefficients in the specified coefficient ring and with relative/absolute precision cap on its parent ring as given by max_prec.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"similar(x::MySeries, R::Ring, var::VarName=var(parent(x)); cached::Bool=true)\nsimilar(x::MySeries, max_prec::Int, var::VarName=var(parent(x)); cached::Bool=true)\nsimilar(x::MySeries, var::VarName=var(parent(x)); cached::Bool=true)\nsimilar(x::MySeries, R::Ring, max_prec::Int, var::VarName; cached::Bool=true)\nsimilar(x::MySeries, R::Ring, var::VarName; cached::Bool=true)\nsimilar(x::MySeries, max_prec::Int, var::VarName; cached::Bool=true)\nsimilar(x::MySeries, var::VarName; cached::Bool=true)\nzero(x::MySeries, R::Ring, var::VarName=var(parent(x)); cached::Bool=true)\nzero(x::MySeries, max_prec::Int, var::VarName=var(parent(x)); cached::Bool=true)\nzero(x::MySeries, var::VarName=var(parent(x)); cached::Bool=true)\nzero(x::MySeries, R::Ring, max_prec::Int, var::VarName; cached::Bool=true)\nzero(x::MySeries, R::Ring, var::VarName; cached::Bool=true)\nzero(x::MySeries, max_prec::Int, var::VarName; cached::Bool=true)\nzero(x::MySeries, var::VarName; cached::Bool=true)","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"As above, but use the precision cap of the parent ring of x and the base_ring of x if these are not specified.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"Custom series rings may choose which series type is best-suited to return for the given coefficient ring, precision cap and variable, however they should return a series with the same model as x, i.e. relative or series.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"If custom implementations don't specialise these function the default return type is a Generic.AbsSeries or Generic.RelSeries.","category":"page"},{"location":"AbstractAlgebra/series_interface/","page":"Series Ring Interface","title":"Series Ring Interface","text":"The default implementation of zero calls out to similar, so it's generally sufficient to specialise only similar. For both similar and zero only the most general method has to be implemented as all other methods call out to this more general method.","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\n Oscar.AbstractAlgebra.set_current_module(@__MODULE__)\nend","category":"page"},{"location":"InvariantTheory/finite_groups/#Invariants-of-Finite-Groups","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"In this section, with notation as in the introduction to this chapter, G will be a finite group.","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"note: Note\nThe ssumption that G is finite implies:By a result of Emmy Noether, KV is integral over KV^G. In particular,\n dim KV^G = dim KV = n\nMoreover, KV^G is finitely generated as a K-algebra.If the group order G is invertible in K, then we have the explicit Reynolds operator\n mathcal R KV to KV fmapsto frac1Gsum_piin G(f pi)","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"note: Note\nWe speak of non-modular invariant theory if G is invertible in K, and of modular invariant theory otherwise.","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"note: Note\nIn the non-modular case, using Emmy Noether's result and the Reynolds operator, it is not too difficult to show that KV^G is a free module over any of its graded Noether normalizations. That is, KV^G is Cohen-Macaulay. In the modular case, KV^G may not be Cohen-Macaulay.","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"note: Note\nIn the non-modular case, the Hilbert series of KV^G can be precomputed as its Molien series. See Harm Derksen, Gregor Kemper (2015) and Wolfram Decker, Theo de Jong (1998) for explicit formulas.","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"Knowing the Hilbert series means to know the dimension of each graded piece KV^G_d. This information can often be used to speed up algorithms for finding invariants. The most basic task here is to compute the invariants of some given degree d, that is, to find an explicit K-basis of KV^G_d. There are two different approaches:","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"The Reynolds Operator Method, available in the non-modular case, applies the Reynolds operator to sufficiently many monomials in Kx_1 dots x_n_dcong KV_d, and extracts a K-basis from the resulting generating set.\nThe Linear Algebra Method, available in the non-modular and the modular case, finds the elements of a K-basis all at once by setting up and solving an appropriate K-linear system of equations.","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"These methods are, in particular, crucial to the computation of primary and secondary invariants. Primary invariants and irreducible secondary invariants together generate KV^G as a K-algebra. Omitting redundant generators yields a system of fundamental invariants. In the non-modular case, an alternative and typically more effective way to compute generators of KV^G is King's algorithm which finds a system of fundamental invariants directly, without computing primary and secondary invariants. See Simon King (2013).","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"We discuss the relevant OSCAR functionality below.","category":"page"},{"location":"InvariantTheory/finite_groups/#Creating-Invariant-Rings","page":"Invariants of Finite Groups","title":"Creating Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/#How-Groups-are-Given","page":"Invariants of Finite Groups","title":"How Groups are Given","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"The invariant theory part of OSCAR distinguishes two ways of how finite groups and their actions on Kx_1 dots x_ncong KV are specified:","category":"page"},{"location":"InvariantTheory/finite_groups/#Matrix-Groups","page":"Invariants of Finite Groups","title":"Matrix Groups","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"Here, G will be explicitly given as a matrix group Gsubset textGL_n(K)cong textGL(V) by (finitely many) generating matrices acting on Kx_1 dots x_ncong KV by linear substitution:","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"(f pi) (x_1 dots x_n) = f((x_1 dots x_n) cdot rho(pi)) text for all piin G","category":"page"},{"location":"InvariantTheory/finite_groups/#Permutation-Groups","page":"Invariants of Finite Groups","title":"Permutation Groups","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"Here, G will be given as a permutation group, acting on Kx_1 dots x_ncong KV by permuting the variables.","category":"page"},{"location":"InvariantTheory/finite_groups/#Constructors-for-Invariant-Rings","page":"Invariants of Finite Groups","title":"Constructors for Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"invariant_ring(G::MatrixGroup)","category":"page"},{"location":"InvariantTheory/finite_groups/#invariant_ring-Tuple{MatrixGroup}","page":"Invariants of Finite Groups","title":"invariant_ring","text":"invariant_ring(G::MatrixGroup)\ninvariant_ring(K::Field = QQ, G::PermGroup)\n\nReturn the invariant ring of the finite matrix group or permutation group G.\n\nIn the latter case, use the specified field K as the coefficient field. The default value for K is QQ.\n\nnote: Note\nThe creation of invariant rings is lazy in the sense that no explicit computations are done until specifically invoked (for example, by the primary_invariants function).\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\");\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);\n\njulia> G = matrix_group(M1, M2);\n\njulia> IRm = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over K\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> IRp = invariant_ring(symmetric_group(3))\nInvariant ring of\nSym( [ 1 .. 3 ] )\nwith generators\nPermGroupElem[(1,2,3), (1,2)]\n\njulia> coefficient_ring(IRp)\nRational field\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#Basic-Data-Associated-to-Invariant-Rings","page":"Invariants of Finite Groups","title":"Basic Data Associated to Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"If IR is the invariant ring Kx_1 x_n^G of a finite matrix group G, then","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"group(IR) refers to G,\ncoefficient_ring(IR) to K, and\npolynomial_ring(IR) to Kx_1 x_n.","category":"page"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"Moreover, is_modular(IR) returns true in the modular case, and false otherwise.","category":"page"},{"location":"InvariantTheory/finite_groups/#Examples","page":"Invariants of Finite Groups","title":"Examples","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"julia> K, a = CyclotomicField(3, \"a\")\n(Cyclotomic field of order 3, a)\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])\n[0 0 1]\n[1 0 0]\n[0 1 0]\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])\n[1 0 0]\n[0 a 0]\n[0 0 -a - 1]\n\njulia> G = matrix_group(M1, M2)\nMatrix group of degree 3 over K\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over K\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> group(IR)\nMatrix group of degree 3 over K\n\njulia> coefficient_ring(IR)\nNumber field with defining polynomial _$^2 + _$ + 1\n over rational field\n\njulia> R = polynomial_ring(IR)\nMultivariate polynomial ring in 3 variables over cyclotomic field of order 3 graded by\n x[1] -> [1]\n x[2] -> [1]\n x[3] -> [1]\n\njulia> x = gens(R)\n3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]\n x[2]\n x[3]\n\njulia> is_modular(IR)\nfalse\n","category":"page"},{"location":"InvariantTheory/finite_groups/#The-Reynolds-Operator","page":"Invariants of Finite Groups","title":"The Reynolds Operator","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"reynolds_operator(IR::InvRing{FldT, GrpT, T}, f::T) where {FldT, GrpT, T <: MPolyRingElem}\n\nreynolds_operator(IR::InvRing{FldT, GrpT, T}, f::T, chi::GAPGroupClassFunction) where {FldT, GrpT, T <: MPolyRingElem}","category":"page"},{"location":"InvariantTheory/finite_groups/#reynolds_operator-Union{Tuple{T}, Tuple{GrpT}, Tuple{FldT}, Tuple{Oscar.InvRing{FldT, GrpT, T}, T}} where {FldT, GrpT, T<:MPolyRingElem}","page":"Invariants of Finite Groups","title":"reynolds_operator","text":" reynolds_operator(IR::InvRing{FldT, GrpT, T}, f::T) where {FldT, GrpT, T <: MPolyRingElem}\n\nIn the non-modular case, return the image of f under the Reynolds operator projecting onto IR.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\")\n(Cyclotomic field of order 3, a)\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])\n[0 0 1]\n[1 0 0]\n[0 1 0]\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])\n[1 0 0]\n[0 a 0]\n[0 0 -a - 1]\n\njulia> G = matrix_group(M1, M2)\nMatrix group of degree 3 over K\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over K\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> R = polynomial_ring(IR)\nMultivariate polynomial ring in 3 variables over cyclotomic field of order 3 graded by\n x[1] -> [1]\n x[2] -> [1]\n x[3] -> [1]\n\njulia> x = gens(R)\n3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]\n x[2]\n x[3]\n\njulia> f = x[1]^3\nx[1]^3\n\njulia> reynolds_operator(IR, f)\n1//3*x[1]^3 + 1//3*x[2]^3 + 1//3*x[3]^3\n\njulia> M = matrix(GF(3), [0 1 0; -1 0 0; 0 0 -1])\n[0 1 0]\n[2 0 0]\n[0 0 2]\n\njulia> G = matrix_group(M)\nMatrix group of degree 3 over Finite field of characteristic 3\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over Finite field of characteristic 3\nwith generators\nfpMatrix[[0 1 0; 2 0 0; 0 0 2]]\n\njulia> R = polynomial_ring(IR)\nMultivariate polynomial ring in 3 variables over GF(3) graded by\n x[1] -> [1]\n x[2] -> [1]\n x[3] -> [1]\n\njulia> x = gens(R)\n3-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:\n x[1]\n x[2]\n x[3]\n\njulia> f = x[1]^2\nx[1]^2\n\njulia> reynolds_operator(IR, f)\n2*x[1]^2 + 2*x[2]^2\n\njulia> f = x[1]^3\nx[1]^3\n\njulia> reynolds_operator(IR, f)\n0\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#reynolds_operator-Union{Tuple{T}, Tuple{GrpT}, Tuple{FldT}, Tuple{Oscar.InvRing{FldT, GrpT, T}, T, Oscar.GAPGroupClassFunction}} where {FldT, GrpT, T<:MPolyRingElem}","page":"Invariants of Finite Groups","title":"reynolds_operator","text":" reynolds_operator(IR::InvRing{FldT, GrpT, T}, f::T, chi::GAPGroupClassFunction)\n where {FldT, GrpT, T <: MPolyRingElem}\n\nIn the case of characteristic zero, return the image of f under the twisted Reynolds operator projecting onto the isotypic component of the polynomial ring with respect to chi, that is, the semi-invariants (or relative invariants) with respect to chi, see Richard P. Stanley (1979). It is assumed that chi is an irreducible character.\n\nIn case chi is a linear character, the returned polynomial, say h, fulfils h^g = chi(g)h for all g in group(IR) (possibly h is zero).\n\nnote: Note\nIf coefficient_ring(IR) does not contain all character values of chi, an error is raised.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\");\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);\n\njulia> G = matrix_group(M1, M2);\n\njulia> IR = invariant_ring(G);\n\njulia> R = polynomial_ring(IR);\n\njulia> x = gens(R);\n\njulia> f = x[1]^3\nx[1]^3\n\njulia> reynolds_operator(IR, f, trivial_character(G))\n1//3*x[1]^3 + 1//3*x[2]^3 + 1//3*x[3]^3\n\njulia> S2 = symmetric_group(2);\n\njulia> IR = invariant_ring(QQ, S2);\n\njulia> R = polynomial_ring(IR);\n\njulia> x = gens(R);\n\njulia> F = abelian_closure(QQ)[1];\n\njulia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])\nclass_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])\n\njulia> reynolds_operator(IR, x[1], chi)\n1//2*x[1] - 1//2*x[2]\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#Invariants-of-a-Given-Degree","page":"Invariants of Finite Groups","title":"Invariants of a Given Degree","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"basis(IR::InvRing, d::Int, algorithm::Symbol = :default)\n\nbasis(IR::InvRing, d::Int, chi::GAPGroupClassFunction)","category":"page"},{"location":"InvariantTheory/finite_groups/#basis","page":"Invariants of Finite Groups","title":"basis","text":" basis(IR::InvRing, d::Int, algorithm::Symbol = :default)\n\nGiven an invariant ring IR and an integer d, return a basis for the invariants in degree d.\n\nThe optional argument algorithm specifies the algorithm to be used. If algorithm = :reynolds, the Reynolds operator is utilized (this method is only available in the non-modular case). Setting algorithm = :linear_algebra means that plain linear algebra is used. The default option algorithm = :default asks to select the heuristically best algorithm.\n\nSee also iterate_basis.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\")\n(Cyclotomic field of order 3, a)\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])\n[0 0 1]\n[1 0 0]\n[0 1 0]\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])\n[1 0 0]\n[0 a 0]\n[0 0 -a - 1]\n\njulia> G = matrix_group(M1, M2)\nMatrix group of degree 3 over K\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over K\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> basis(IR, 6)\n4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]^2*x[2]^2*x[3]^2\n x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4\n x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3\n x[1]^6 + x[2]^6 + x[3]^6\n\njulia> M = matrix(GF(3), [0 1 0; -1 0 0; 0 0 -1])\n[0 1 0]\n[2 0 0]\n[0 0 2]\n\njulia> G = matrix_group(M)\nMatrix group of degree 3 over Finite field of characteristic 3\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over Finite field of characteristic 3\nwith generators\nfpMatrix[[0 1 0; 2 0 0; 0 0 2]]\n\njulia> basis(IR, 2)\n2-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:\n x[1]^2 + x[2]^2\n x[3]^2\n\njulia> basis(IR, 3)\n2-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:\n x[1]*x[2]*x[3]\n x[1]^2*x[3] + 2*x[2]^2*x[3]\n\n\n\n\n\n","category":"function"},{"location":"InvariantTheory/finite_groups/#basis-Tuple{Oscar.InvRing, Int64, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"basis","text":"basis(IR::InvRing, d::Int, chi::GAPGroupClassFunction)\n\nGiven an invariant ring IR, an integer d and an irreducible character chi, return a basis for the semi-invariants (or relative invariants) in degree d with respect to chi.\n\nThis function is only implemented in the case of characteristic zero.\n\nnote: Note\nIf coefficient_ring(IR) does not contain all character values of chi, an error is raised.\n\nSee also iterate_basis.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\");\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);\n\njulia> G = matrix_group(M1, M2);\n\njulia> IR = invariant_ring(G);\n\njulia> basis(IR, 6, trivial_character(G))\n4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]^6 + x[2]^6 + x[3]^6\n x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4\n x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3\n x[1]^2*x[2]^2*x[3]^2\n\njulia> S2 = symmetric_group(2);\n\njulia> R = invariant_ring(QQ, S2);\n\njulia> F = abelian_closure(QQ)[1];\n\njulia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])\nclass_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])\n\njulia> basis(R, 3, chi)\n2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x[1]^3 - x[2]^3\n x[1]^2*x[2] - x[1]*x[2]^2\n\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"iterate_basis(IR::InvRing, d::Int, algorithm::Symbol = :default)\n\niterate_basis(IR::InvRing, d::Int, chi::GAPGroupClassFunction)","category":"page"},{"location":"InvariantTheory/finite_groups/#iterate_basis","page":"Invariants of Finite Groups","title":"iterate_basis","text":" iterate_basis(IR::InvRing, d::Int, algorithm::Symbol = :default)\n\nGiven an invariant ring IR and an integer d, return an iterator over a basis for the invariants in degree d.\n\nThe optional argument algorithm specifies the algorithm to be used. If algorithm = :reynolds, the Reynolds operator is utilized (this method is only available in the non-modular case). Setting algorithm = :linear_algebra means that plain linear algebra is used. The default option algorithm = :default asks to select the heuristically best algorithm.\n\nWhen using the Reynolds operator, the basis is constructed element-by-element. With linear algebra, this is not possible and the basis will be constructed all at once when calling the function.\n\nSee also basis.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\")\n(Cyclotomic field of order 3, a)\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])\n[0 0 1]\n[1 0 0]\n[0 1 0]\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])\n[1 0 0]\n[0 a 0]\n[0 0 -a - 1]\n\njulia> G = matrix_group(M1, M2)\nMatrix group of degree 3 over Cyclotomic field of order 3\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over Cyclotomic field of order 3\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> B = iterate_basis(IR, 6)\nIterator over a basis of the component of degree 6 of\nInvariant ring of\nMatrix group of degree 3 over Cyclotomic field of order 3\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> collect(B)\n4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]^2*x[2]^2*x[3]^2\n x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4\n x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3\n x[1]^6 + x[2]^6 + x[3]^6\n\njulia> M = matrix(GF(3), [0 1 0; -1 0 0; 0 0 -1])\n[0 1 0]\n[2 0 0]\n[0 0 2]\n\njulia> G = matrix_group(M)\nMatrix group of degree 3 over Galois field with characteristic 3\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over Galois field with characteristic 3\nwith generators\nfpMatrix[[0 1 0; 2 0 0; 0 0 2]]\n\njulia> B = iterate_basis(IR, 2)\nIterator over a basis of the component of degree 2 of\nInvariant ring of\nMatrix group of degree 3 over Galois field with characteristic 3\nwith generators\nfpMatrix[[0 1 0; 2 0 0; 0 0 2]]\n\njulia> collect(B)\n2-element Vector{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}:\n x[1]^2 + x[2]^2\n x[3]^2\n\n\n\n\n\n","category":"function"},{"location":"InvariantTheory/finite_groups/#iterate_basis-Tuple{Oscar.InvRing, Int64, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"iterate_basis","text":"iterate_basis(IR::InvRing, d::Int, chi::GAPGroupClassFunction)\n\nGiven an invariant ring IR, an integer d and an irreducible character chi, return an iterator over a basis for the semi-invariants (or relative invariants) in degree d with respect to chi.\n\nThis function is only implemented in the case of characteristic zero.\n\nnote: Note\nIf coefficient_ring(IR) does not contain all character values of chi, an error is raised.\n\nSee also basis.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\");\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);\n\njulia> G = matrix_group(M1, M2);\n\njulia> IR = invariant_ring(G);\n\njulia> B = iterate_basis(IR, 6, trivial_character(G))\nIterator over a basis of the component of degree 6 of\nInvariant ring of\nMatrix group of degree 3 over Cyclotomic field of order 3\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\nrelative to a character\n\njulia> collect(B)\n4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]^6 + x[2]^6 + x[3]^6\n x[1]^4*x[2]*x[3] + x[1]*x[2]^4*x[3] + x[1]*x[2]*x[3]^4\n x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3\n x[1]^2*x[2]^2*x[3]^2\n\njulia> S2 = symmetric_group(2);\n\njulia> R = invariant_ring(QQ, S2);\n\njulia> F = abelian_closure(QQ)[1];\n\njulia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])\nclass_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])\n\njulia> B = iterate_basis(R, 3, chi)\nIterator over a basis of the component of degree 3 of\nInvariant ring of\nSym( [ 1 .. 2 ] )\nwith generators\nPermGroupElem[(1,2)]\nrelative to a character\n\njulia> collect(B)\n2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x[1]^3 - x[2]^3\n x[1]^2*x[2] - x[1]*x[2]^2\n\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#The-Molien-Series","page":"Invariants of Finite Groups","title":"The Molien Series","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":" molien_series([S::PolyRing], I::InvRing, [chi::GAPGroupClassFunction])","category":"page"},{"location":"InvariantTheory/finite_groups/#molien_series-Tuple{PolyRing, Oscar.InvRing, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"molien_series","text":"molien_series([S::PolyRing], I::InvRing, [chi::GAPGroupClassFunction])\n\nIn the non-modular case, return the Molien series of I as a rational function.\n\nIf a univariate polynomial ring with rational coefficients is specified by the optional argument S::PolyRing, then return the Molien series as an element of the fraction field of that ring.\n\nIf a character chi is specified, the series relative to chi is returned. This is the Molien series of the module of semi-invariants (or relative invariants) with respect to chi, see Richard P. Stanley (1979).\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\");\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);\n\njulia> G = matrix_group(M1, M2);\n\njulia> IR = invariant_ring(G);\n\njulia> MS = molien_series(IR)\n(-t^6 + t^3 - 1)//(t^9 - 3*t^6 + 3*t^3 - 1)\n\njulia> parent(MS)\nFraction field\n of univariate polynomial ring in t over QQ\n\njulia> expand(MS, 10)\n1 + 2*t^3 + 4*t^6 + 7*t^9 + O(t^11)\n\njulia> S2 = symmetric_group(2);\n\njulia> IR = invariant_ring(QQ, S2);\n\njulia> F = abelian_closure(QQ)[1];\n\njulia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])\nclass_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])\n\njulia> molien_series(IR)\n1//(t^3 - t^2 - t + 1)\n\njulia> molien_series(IR, chi)\nt//(t^3 - t^2 - t + 1)\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#Primary-Invariants","page":"Invariants of Finite Groups","title":"Primary Invariants","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"primary_invariants(IR::InvRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#primary_invariants-Tuple{Oscar.InvRing}","page":"Invariants of Finite Groups","title":"primary_invariants","text":"primary_invariants(IR::InvRing;\n ensure_minimality::Int = 0, degree_bound::Int = 1,\n primary_degrees::Vector{Int} = Int[])\n\nReturn a system of primary invariants for IR as a Vector sorted by increasing degree. The result is cached, so calling this function again with argument IR will be fast and give the same result.\n\nThe primary invariants are computed using the algorithm in Gregor Kemper (1999).\n\nThe product of the degrees d_1dots d_n of the returned primary invariants is guaranteed to be minimal among all possible sets of primary invariants.\n\nExpert users (or users happy to experiment) may enter the following keyword arguments to speed up the computation. Note that all of these options are ignored if there are already primary invariants cached. If admissible degrees d_1dots d_n for a system of primary invariants are known a priori, these degrees can be specified by primary_degrees = [d_1, ..., d_n]. Note that an error is raised if in fact no primary invariants of the given degrees exist. An a priori known number k geq 1 with d_1cdots d_n geq k cdot G, where G is the underlying group, can be specified by degree_bound = k. The default value is degree_bound = 1. In some situations, the runtime of the algorithm might be improved by assigning a positive integer to ensure_minimality. This leads to an early cancellation of loops in the algorithm and the described minimality of the degrees is not guaranteed anymore. A smaller (positive) value of ensure_minimality corresponds to an earlier cancellation. However, the default value ensure_minimality = 0 corresponds to no cancellation.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\");\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);\n\njulia> G = matrix_group(M1, M2);\n\njulia> IR = invariant_ring(G);\n\njulia> primary_invariants(IR)\n3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]*x[2]*x[3]\n x[1]^3 + x[2]^3 + x[3]^3\n x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3\n\njulia> IR = invariant_ring(G); # \"New\" ring to avoid caching\n\njulia> primary_invariants(IR, primary_degrees = [ 3, 6, 6 ])\n3-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]*x[2]*x[3]\n x[1]^3*x[2]^3 + x[1]^3*x[3]^3 + x[2]^3*x[3]^3\n x[1]^6 + x[2]^6 + x[3]^6\n\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#Secondary-Invariants","page":"Invariants of Finite Groups","title":"Secondary Invariants","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"secondary_invariants(IR::InvRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#secondary_invariants-Tuple{Oscar.InvRing}","page":"Invariants of Finite Groups","title":"secondary_invariants","text":"secondary_invariants(IR::InvRing)\n\nReturn a system of secondary invariants for IR as a Vector sorted by increasing degree. The result is cached, so calling this function again with argument IR will be fast and give the same result. Note that the secondary invariants are defined with respect to the currently cached system of primary invariants for IR (if no system of primary invariants for IR is cached, such a system is computed and cached first).\n\nImplemented Algorithms\n\nFor the non-modular case, the function relies on Algorithm 3.7.2 in Harm Derksen, Gregor Kemper (2015), enhanced by ideas from Simon King (2007). In the modular case, Algorithm 3.7.5 in Harm Derksen, Gregor Kemper (2015) is used.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\");\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0]);\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1]);\n\njulia> G = matrix_group(M1, M2);\n\njulia> IR = invariant_ring(G);\n\njulia> secondary_invariants(IR)\n2-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n 1\n x[1]^3*x[2]^6 + x[1]^6*x[3]^3 + x[2]^3*x[3]^6\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"irreducible_secondary_invariants(IR::InvRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#irreducible_secondary_invariants-Tuple{Oscar.InvRing}","page":"Invariants of Finite Groups","title":"irreducible_secondary_invariants","text":"irreducible_secondary_invariants(IR::InvRing)\n\nReturn a system of irreducible secondary invariants for IR as a Vector sorted by increasing degree. The result is cached, so calling this function again will be fast and give the same result. Here, a secondary invariant is called irreducible, if it cannot be written as a polynomial expression in the primary invariants and the other secondary invariants.\n\nNote that the secondary invariants and hence the irreducible secondary invariants are defined with respect to the currently cached system of primary invariants for IR (if no system of primary invariants for IR is cached, such a system is computed and cached first).\n\nExamples\n\njulia> M = matrix(QQ, [0 -1 0 0 0; 1 -1 0 0 0; 0 0 0 0 1; 0 0 1 0 0; 0 0 0 1 0]);\n\njulia> G = matrix_group(M);\n\njulia> IR = invariant_ring(G);\n\njulia> secondary_invariants(IR)\n12-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n 1\n x[1]*x[3] - x[2]*x[3] + x[2]*x[4] - x[1]*x[5]\n x[3]^2 + x[4]^2 + x[5]^2\n x[1]^3 - 3*x[1]*x[2]^2 + x[2]^3\n x[1]^2*x[3] - x[1]*x[2]*x[3] - x[1]*x[2]*x[4] + x[2]^2*x[4] + x[1]*x[2]*x[5]\n x[1]*x[3]^2 - x[2]*x[3]^2 + x[2]*x[4]^2 - x[1]*x[5]^2\n x[1]^2*x[3] + x[1]^2*x[4] - 2*x[1]*x[2]*x[4] + x[2]^2*x[4] + x[2]^2*x[5]\n x[1]*x[3]*x[4] - x[2]*x[3]*x[4] - x[1]*x[3]*x[5] + x[2]*x[4]*x[5]\n x[3]*x[4]^2 + x[3]^2*x[5] + x[4]*x[5]^2\n x[1]*x[3]^3 - x[2]*x[3]^3 + x[2]*x[3]^2*x[4] + x[1]*x[3]*x[4]^2 - x[2]*x[3]*x[4]^2 + x[2]*x[4]^3 - x[1]*x[3]^2*x[5] - x[1]*x[4]^2*x[5] + x[1]*x[3]*x[5]^2 - x[2]*x[3]*x[5]^2 + x[2]*x[4]*x[5]^2 - x[1]*x[5]^3\n x[3]^4 + 2*x[3]^2*x[4]^2 + x[4]^4 + 2*x[3]^2*x[5]^2 + 2*x[4]^2*x[5]^2 + x[5]^4\n x[1]*x[3]^5 - x[2]*x[3]^5 + x[2]*x[3]^4*x[4] + 2*x[1]*x[3]^3*x[4]^2 - 2*x[2]*x[3]^3*x[4]^2 + 2*x[2]*x[3]^2*x[4]^3 + x[1]*x[3]*x[4]^4 - x[2]*x[3]*x[4]^4 + x[2]*x[4]^5 - x[1]*x[3]^4*x[5] - 2*x[1]*x[3]^2*x[4]^2*x[5] - x[1]*x[4]^4*x[5] + 2*x[1]*x[3]^3*x[5]^2 - 2*x[2]*x[3]^3*x[5]^2 + 2*x[2]*x[3]^2*x[4]*x[5]^2 + 2*x[1]*x[3]*x[4]^2*x[5]^2 - 2*x[2]*x[3]*x[4]^2*x[5]^2 + 2*x[2]*x[4]^3*x[5]^2 - 2*x[1]*x[3]^2*x[5]^3 - 2*x[1]*x[4]^2*x[5]^3 + x[1]*x[3]*x[5]^4 - x[2]*x[3]*x[5]^4 + x[2]*x[4]*x[5]^4 - x[1]*x[5]^5\n\njulia> irreducible_secondary_invariants(IR)\n8-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x[1]*x[3] - x[2]*x[3] + x[2]*x[4] - x[1]*x[5]\n x[3]^2 + x[4]^2 + x[5]^2\n x[1]^3 - 3*x[1]*x[2]^2 + x[2]^3\n x[1]^2*x[3] - x[1]*x[2]*x[3] - x[1]*x[2]*x[4] + x[2]^2*x[4] + x[1]*x[2]*x[5]\n x[1]*x[3]^2 - x[2]*x[3]^2 + x[2]*x[4]^2 - x[1]*x[5]^2\n x[1]^2*x[3] + x[1]^2*x[4] - 2*x[1]*x[2]*x[4] + x[2]^2*x[4] + x[2]^2*x[5]\n x[1]*x[3]*x[4] - x[2]*x[3]*x[4] - x[1]*x[3]*x[5] + x[2]*x[4]*x[5]\n x[3]*x[4]^2 + x[3]^2*x[5] + x[4]*x[5]^2\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#Fundamental-Systems-of-Invariants","page":"Invariants of Finite Groups","title":"Fundamental Systems of Invariants","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"fundamental_invariants(IR::InvRing, algorithm::Symbol = :default; beta::Int = 0)","category":"page"},{"location":"InvariantTheory/finite_groups/#fundamental_invariants","page":"Invariants of Finite Groups","title":"fundamental_invariants","text":"fundamental_invariants(IR::InvRing, algorithm::Symbol = :default; beta::Int = 0)\n\nReturn a system of fundamental invariants for IR.\n\nThe result is cached, so calling this function again with argument IR will be fast and give the same result.\n\nImplemented Algorithms\n\nIn the non-modular case the function relies on King's algorithm Simon King (2013) which finds a system of fundamental invariants directly, without computing primary and secondary invariants. If an upper bound for the degrees of fundamental invariants is known, this can be supplied by the keyword argument beta and might result in an earlier termination of the algorithm. By default, the algorithm uses the bounds from Mátyás Domokos, Pál Hegedűs (2000) and Müfit Sezer (2002).\n\nAlternatively, if specified by algorithm = :primary_and_secondary, the function computes fundamental invariants from a collection of primary and irreducible secondary invariants. The optional keyword argument beta is ignored for this algorithm.\n\nIn the modular case, only the second method is available for theoretical reasons.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\")\n(Cyclotomic field of order 3, a)\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])\n[0 0 1]\n[1 0 0]\n[0 1 0]\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])\n[1 0 0]\n[0 a 0]\n[0 0 -a - 1]\n\njulia> G = matrix_group(M1, M2)\nMatrix group of degree 3 over K\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over K\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> fundamental_invariants(IR)\n4-element Vector{MPolyDecRingElem{nf_elem, AbstractAlgebra.Generic.MPoly{nf_elem}}}:\n x[1]^3 + x[2]^3 + x[3]^3\n x[1]*x[2]*x[3]\n x[1]^6 + x[2]^6 + x[3]^6\n x[1]^3*x[2]^6 + x[1]^6*x[3]^3 + x[2]^3*x[3]^6\n\n\n\n\n\n","category":"function"},{"location":"InvariantTheory/finite_groups/#Invariant-Rings-as-Affine-Algebras","page":"Invariants of Finite Groups","title":"Invariant Rings as Affine Algebras","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"affine_algebra(IR::InvRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#affine_algebra-Tuple{Oscar.InvRing}","page":"Invariants of Finite Groups","title":"affine_algebra","text":"affine_algebra(IR::InvRing;\n algo_gens::Symbol = :default, algo_rels::Symbol = :groebner_basis)\n\nGiven an invariant ring IR with underlying graded polynomial ring, say R, return a graded affine algebra, say A, together with a graded algebra homomorphism A to R which maps A isomorphically onto IR.\n\nnote: Note\nIf a system of fundamental invariants for IR is already cached, the function makes use of that system. Otherwise, such a system is computed and cached first. The algebra A is graded according to the degrees of the fundamental invariants, the modulus of A is generated by the algebra relations on these invariants, and the algebra homomorphism A to R is defined by sending the i-th generator of A to the i-th fundamental invariant.\n\nOptional arguments\n\nUsing the arguments :king or :primary_and_secondary for algo_gens selects the algorithm for the computation of the fundamental invariants (see fundamental_invariants for details). The argument :groebner_basis or :linear_algebra for algo_rels controls which algorithm for the computation of the relations between the fundamental invariants is used. With :groebner_basis, the relations are computed via the standard computation of a kernel of a morphism between multivariate polynomial rings. The option :linear_algebra uses an algorithm by Kemper and Steel Gregor Kemper, Allan Steel (1999), Section 17.5.5, to compute the relations without the use of Groebner bases. Note that this option is only available, if the fundamental invariants are computed via primary and secondary invariants (i.e. algo_gens = :primary_and_secondary).\n\nnote: Note\nIf a presentation of IR is already computed (and hence cached), this cached presentation will be returned and the values of algo_gens and algo_rels will be ignored. Further, if fundamental invariants are already computed and cached, the value of algo_gens might be ignored, as the cached system is used.\n\nExamples\n\njulia> K, a = CyclotomicField(3, \"a\")\n(Cyclotomic field of order 3, a)\n\njulia> M1 = matrix(K, [0 0 1; 1 0 0; 0 1 0])\n[0 0 1]\n[1 0 0]\n[0 1 0]\n\njulia> M2 = matrix(K, [1 0 0; 0 a 0; 0 0 -a-1])\n[1 0 0]\n[0 a 0]\n[0 0 -a - 1]\n\njulia> G = matrix_group(M1, M2)\nMatrix group of degree 3 over K\n\njulia> IR = invariant_ring(G)\nInvariant ring of\nMatrix group of degree 3 over K\nwith generators\nAbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[0 0 1; 1 0 0; 0 1 0], [1 0 0; 0 a 0; 0 0 -a-1]]\n\njulia> affine_algebra(IR)\n(Quotient of multivariate polynomial ring by ideal with 1 generator, Map with following data\nDomain:\n=======\nQuotient of multivariate polynomial ring by ideal with 1 generator\nCodomain:\n=========\nGraded multivariate polynomial ring in 3 variables over cyclotomic field of order 3)\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/#Semi-invariants-/-relative-invariants","page":"Invariants of Finite Groups","title":"Semi-invariants / relative invariants","text":"","category":"section"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"semi_invariants(IR::InvRing, chi::GAPGroupClassFunction)","category":"page"},{"location":"InvariantTheory/finite_groups/#semi_invariants-Tuple{Oscar.InvRing, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"semi_invariants","text":"semi_invariants(IR::InvRing, chi::GAPGroupClassFunction)\nrelative_invariants(IR::InvRing, chi::GAPGroupClassFunction)\n\nGiven an irreducible character chi of the underlying group, return a system of semi-invariants (or relative invariants) with respect to chi. By this, we mean a set of free generators of the isotypic component of the of the polynomial ring with respect to chi as a module over the algebra generated by primary invariants for IR. See also Karin Gatermann (1996) and Richard P. Stanley (1979).\n\nnote: Note\nIf coefficient_ring(IR) does not contain all character values of chi, an error is raised.\n\nThis function is so far only implemented in the case of characteristic zero.\n\nExamples\n\njulia> S2 = symmetric_group(2);\n\njulia> RS2 = invariant_ring(S2);\n\njulia> F = abelian_closure(QQ)[1];\n\njulia> chi = Oscar.class_function(S2, [ F(sign(representative(c))) for c in conjugacy_classes(S2) ])\nclass_function(character table of group Sym( [ 1 .. 2 ] ), QQAbElem{nf_elem}[1, -1])\n\njulia> semi_invariants(RS2, chi)\n1-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x[1] - x[2]\n\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/finitefield/#Finite-fields","page":"Finite fields","title":"Finite fields","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Finite fields are provided in Nemo by Flint. This allows construction of finite fields of any characteristic and degree for which there are Conway polynomials. It is also possible for the user to specify their own irreducible polynomial generating a finite field.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Finite fields are constructed using the FlintFiniteField function. However, for convenience we define","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"FiniteField = FlintFiniteField","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"so that finite fields can be constructed using FiniteField rather than FlintFiniteField. Note that this is the name of the constructor, but not of finite field type.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"The types of finite field elements in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Library Field Element type Parent type\nFlint mathbbF_p^n (small p) fqPolyRepFieldElem fqPolyRepField\nFlint mathbbF_p^n (large p) FqPolyRepFieldElem FqPolyRepField","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"The only difference between the FqPolyRepFieldElem and fqPolyRepFieldElem types is the representation. The former is for finite fields with multiprecision characteristic and the latter is for characteristics that fit into a single unsigned machine word. The FlintFiniteField constructor automatically picks the correct representation for the user, and so the average user doesn't need to know about the actual types.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"All the finite field types belong to the FinField abstract type and the finite field element types belong to the FinFieldElem abstract type.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Since all the functionality for the FqPolyRepFieldElem finite field type is identical to that provided for the fqPolyRepFieldElem finite field type, we simply document the former.","category":"page"},{"location":"Nemo/finitefield/#Finite-field-functionality","page":"Finite fields","title":"Finite field functionality","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Finite fields in Nemo provide all the field functionality described in AbstractAlgebra:","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Below we describe the functionality that is provided in addition to this.","category":"page"},{"location":"Nemo/finitefield/#Constructors","page":"Finite fields","title":"Constructors","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"In order to construct finite field elements in Nemo, one must first construct the finite field itself. This is accomplished with one of the following constructors.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"FlintFiniteField","category":"page"},{"location":"Nemo/finitefield/#FlintFiniteField","page":"Finite fields","title":"FlintFiniteField","text":"FlintFiniteField(char::ZZRingElem, deg::Int, s::VarName; cached = true)\n\nReturns a tuple S x consisting of a finite field parent object S and generator x for the finite field of the given characteristic and degree. The string s is used to designate how the finite field generator will be printed. The characteristic must be prime. When a Conway polynomial is known, the field is generated using the Conway polynomial. Otherwise a random sparse, irreducible polynomial is used. The generator of the field is guaranteed to be a multiplicative generator only if the field is generated by a Conway polynomial. We require the degree to be positive.\n\n\n\n\n\nFlintFiniteField(pol::Union{ZZModPolyRingElem, FpPolyRingElem}, s::VarName; cached = true, check = true)\n\nReturns a tuple S x consisting of a finite field parent object S and generator x for the finite field over F_p defined by the given polynomial, i.e. mathbbF_pt(pol). The characteristic is specified by the modulus of pol. The polynomial is required to be irreducible, but this is not checked. The base ring of the polynomial is required to be a field, which is checked by default. Use check = false to disable the check. The string s is used to designate how the finite field generator will be printed. The generator will not be multiplicative in general.\n\n\n\n\n\nFlintFiniteField(F::FqPolyRepField, deg::Int, s::VarName; cached = true)\n\nReturn a finite field with the same type as F but with a possibly different degree deg over the prime subfield.\n\n\n\n\n\n","category":"function"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Here are some examples of creating finite fields and making use of the resulting parent objects to coerce various elements into those fields.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Examples","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"julia> R, x = FiniteField(7, 3, \"x\")\n(Finite field of degree 3 over GF(7), x)\n\njulia> S, y = FiniteField(ZZ(12431351431561), 2, \"y\")\n(Finite field of degree 2 over GF(12431351431561), y)\n\njulia> T, t = polynomial_ring(residue_ring(ZZ, 12431351431561), \"t\")\n(Univariate polynomial ring in t over ZZ/(12431351431561), t)\n\njulia> U, z = FiniteField(t^2 + 7, \"z\")\n(Finite field of degree 2 over GF(12431351431561), z)\n\njulia> a = R(5)\n5\n\njulia> b = R(x)\nx\n\njulia> c = S(ZZ(11))\n11\n\njulia> d = U(7)\n7","category":"page"},{"location":"Nemo/finitefield/#Basic-manipulation","page":"Finite fields","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"gen(::FqPolyRepField)","category":"page"},{"location":"Nemo/finitefield/#gen-Tuple{FqPolyRepField}","page":"Finite fields","title":"gen","text":"gen(a::FqPolyRepField)\n\nReturn the generator of the finite field. Note that this is only guaranteed to be a multiplicative generator if the finite field is generated by a Conway polynomial automatically.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"is_gen(::FqPolyRepFieldElem)","category":"page"},{"location":"Nemo/finitefield/#is_gen-Tuple{FqPolyRepFieldElem}","page":"Finite fields","title":"is_gen","text":"is_gen(a::FqPolyRepFieldElem)\n\nReturn true if the given finite field element is the generator of the finite field, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"coeff(::FqPolyRepFieldElem, ::Int)","category":"page"},{"location":"Nemo/finitefield/#coeff-Tuple{FqPolyRepFieldElem, Int64}","page":"Finite fields","title":"coeff","text":"coeff(x::FqPolyRepFieldElem, n::Int)\n\nReturn the degree n coefficient of the polynomial representing the given finite field element.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"degree(::FqPolyRepField)","category":"page"},{"location":"Nemo/finitefield/#degree-Tuple{FqPolyRepField}","page":"Finite fields","title":"degree","text":"degree(a::FqPolyRepField)\n\nReturn the degree of the given finite field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"modulus(::FqPolyRepField)","category":"page"},{"location":"Nemo/finitefield/#modulus-Tuple{FqPolyRepField}","page":"Finite fields","title":"modulus","text":"modulus(k::FqPolyRepField, var::VarName=:T)\n\nReturn the modulus defining the finite field k.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Examples","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"julia> R, x = FiniteField(ZZ(7), 5, \"x\")\n(Finite field of degree 5 over GF(7), x)\n\njulia> c = gen(R)\nx\n\njulia> d = characteristic(R)\n7\n\njulia> f = order(R)\n16807\n\njulia> g = degree(R)\n5\n\njulia> n = is_gen(x)\ntrue","category":"page"},{"location":"Nemo/finitefield/#Special-functions","page":"Finite fields","title":"Special functions","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Various special functions with finite field specific behaviour are defined.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"tr(::FqPolyRepFieldElem)","category":"page"},{"location":"Nemo/finitefield/#tr-Tuple{FqPolyRepFieldElem}","page":"Finite fields","title":"tr","text":"tr(x::FqPolyRepFieldElem)\n\nReturn the trace of x. This is an element of mathbbF_p, but the value returned is this value embedded in the original finite field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"norm(::FqPolyRepFieldElem)","category":"page"},{"location":"Nemo/finitefield/#norm-Tuple{FqPolyRepFieldElem}","page":"Finite fields","title":"norm","text":"norm(x::FqPolyRepFieldElem)\n\nReturn the norm of x. This is an element of mathbbF_p, but the value returned is this value embedded in the original finite field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"frobenius(::FqPolyRepFieldElem, ::Int)","category":"page"},{"location":"Nemo/finitefield/#frobenius-Tuple{FqPolyRepFieldElem, Int64}","page":"Finite fields","title":"frobenius","text":"frobenius(x::FqPolyRepFieldElem, n = 1)\n\nReturn the iterated Frobenius sigma_p^n(x) where sigma_p is the Frobenius map sending the element a to a^p in the finite field of characteristic p. By default the Frobenius map is applied n = 1 times if n is not specified.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"pth_root(::FqPolyRepFieldElem)","category":"page"},{"location":"Nemo/finitefield/#pth_root-Tuple{FqPolyRepFieldElem}","page":"Finite fields","title":"pth_root","text":"pth_root(x::FqPolyRepFieldElem)\n\nReturn the p-th root of x in the finite field of characteristic p. This is the inverse operation to the Frobenius map sigma_p.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Examples","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"julia> R, x = FiniteField(ZZ(7), 5, \"x\")\n(Finite field of degree 5 over GF(7), x)\n\njulia> a = x^4 + 3x^2 + 6x + 1\nx^4 + 3*x^2 + 6*x + 1\n\njulia> b = tr(a)\n1\n\njulia> c = norm(a)\n4\n\njulia> d = frobenius(a)\nx^4 + 2*x^3 + 3*x^2 + 5*x + 1\n\njulia> f = frobenius(a, 3)\n3*x^4 + 3*x^3 + 3*x^2 + x + 4\n\njulia> g = pth_root(a)\n4*x^4 + 3*x^3 + 4*x^2 + 5*x + 2","category":"page"},{"location":"Nemo/finitefield/#Lift","page":"Finite fields","title":"Lift","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"lift(::FpPolyRing, ::FqPolyRepFieldElem)","category":"page"},{"location":"Nemo/finitefield/#lift-Tuple{FpPolyRing, FqPolyRepFieldElem}","page":"Finite fields","title":"lift","text":"lift(R::FpPolyRing, x::FqPolyRepFieldElem)\n\nLift the finite field element x to a polynomial over the prime field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Examples","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"julia> R, x = FiniteField(23, 2, \"x\")\n(Finite field of degree 2 over GF(23), x)\n\njulia> S, y = polynomial_ring(GF(23), \"y\")\n(Univariate polynomial ring in y over GF(23), y)\n\njulia> f = 8x + 9\n8*x + 9\n\njulia> lift(S, f)\n8*y + 9","category":"page"},{"location":"Nemo/finitefield/#Uniform-finite-fields","page":"Finite fields","title":"Uniform finite fields","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"An (experimental) uniform finite field interface is provided by the type FqField. Such a finite field can be constructed as an extension of a prime field mathbfF_p (an absolute extension) or of another finite field (a relative extension). The field over which the extension is constructed is referred to as the base field and field theoretic properties like the degree of an extension or the trace of an element are understood with respect to the base field. The corresponding functionality for the implicit absolute extension over the prime field is available by methods with the prefix absolute_.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Note that all finite fields are simple extension kt(f) of their base field k. The irreducible polynomial f in kt is the defining polynomial and the class of t is referred to as the generator of the extension.","category":"page"},{"location":"Nemo/finitefield/#Construction-of-finite-fields","page":"Finite fields","title":"Construction of finite fields","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Nemo._FiniteField\nNemo._GF","category":"page"},{"location":"Nemo/finitefield/#_FiniteField","page":"Finite fields","title":"_FiniteField","text":"_FiniteField(q::IntegerUnion, s::String; cached::Bool, check::Bool)\n_FiniteField(p::IntegerUnion, d::Int, s::String; cached::Bool, check::Bool)\n_FiniteField(f::FqPolyRingElem; s::String; cached::Bool, check::Bool)\n\nReturn a tuple S x consisting of a finite field S of order q = p^d and algebra generator x. The string s is used to designate how the finite field generator will be printed.\n\nIf a polynomial f in kt over a finite field k is specified, the finite field S = kt(f) will be constructed as a finite field with base field k.\n\n\n\n\n\n","category":"function"},{"location":"Nemo/finitefield/#_GF","page":"Finite fields","title":"_GF","text":"_GF(q::IntegerUnion, s::String; cached::Bool, check::Bool)\n_GF(p::IntegerUnion, d::Int, s::String; cached::Bool, check::Bool)\n_GF(f::FqPolyRingElem; s::String; cached::Bool, check::Bool)\n\nReturn a finite field S of order q = p^d. The string s is used to designate how the finite field generator will be printed.\n\nIf a polynomial f in kt over a finite field k is specified, the finite field S = kt(f) will be constructed as a finite field with base field k.\n\n\n\n\n\n","category":"function"},{"location":"Nemo/finitefield/#Field-properties","page":"Finite fields","title":"Field properties","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"base_field(::FqField)\nprime_field(::FqField)\ndegree(::FqField)\nabsolute_degree(::FqField)\nis_absolute(::FqField)\ndefining_polynomial(::FqPolyRing, ::FqField)","category":"page"},{"location":"Nemo/finitefield/#base_field-Tuple{FqField}","page":"Finite fields","title":"base_field","text":"base_field(F::FqField)\n\nReturn the base field of F.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#prime_field-Tuple{FqField}","page":"Finite fields","title":"prime_field","text":"prime_field(F::FqField)\n\nReturn the prime field of F.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#degree-Tuple{FqField}","page":"Finite fields","title":"degree","text":"degree(a::FqField)\n\nReturn the degree of the given finite field over the base field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#absolute_degree-Tuple{FqField}","page":"Finite fields","title":"absolute_degree","text":"absolute_degree(a::FqField)\n\nReturn the degree of the given finite field over the prime field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#is_absolute-Tuple{FqField}","page":"Finite fields","title":"is_absolute","text":"is_absolute(F::FqField)\n\nReturn whether the base field of F is a prime field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#defining_polynomial-Tuple{FqPolyRing, FqField}","page":"Finite fields","title":"defining_polynomial","text":"defining_polynomial([R::FqPolyRing], L::FqField)\n\nReturn the defining polynomial of L as a polynomial over the base field of L.\n\nIf the polynomial ring R is specified, the polynomial will be an element of R.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#Element-properties","page":"Finite fields","title":"Element properties","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"tr(::FqFieldElem)\nabsolute_tr(::FqFieldElem)\nnorm(::FqFieldElem)\nabsolute_norm(::FqFieldElem)\nlift(::FqPolyRing, ::FqFieldElem)","category":"page"},{"location":"Nemo/finitefield/#tr-Tuple{FqFieldElem}","page":"Finite fields","title":"tr","text":"tr(x::FqFieldElem)\n\nReturn the trace of x. This is an element of the base field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#absolute_tr-Tuple{FqFieldElem}","page":"Finite fields","title":"absolute_tr","text":"absolute_tr(x::FqFieldElem)\n\nReturn the absolute trace of x. This is an element of the prime field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#norm-Tuple{FqFieldElem}","page":"Finite fields","title":"norm","text":"norm(x::FqFieldElem)\n\nReturn the norm of x. This is an element of the base field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#absolute_norm-Tuple{FqFieldElem}","page":"Finite fields","title":"absolute_norm","text":"absolute_norm(x::FqFieldElem)\n\nReturn the absolute norm of x. This is an element of the prime field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#lift-Tuple{FqPolyRing, FqFieldElem}","page":"Finite fields","title":"lift","text":"lift(R::FqPolyRing, a::FqFieldElem) -> FqPolyRingElem\n\nGiven a polynomial ring over the base field of the parent of a, return a lift such that parent(a)(lift(R, a)) == a is true.\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/printing_details/#Details-on-printing-in-Oscar","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"The following dection contains more details and examples on how to implement Oscar's 2+1 printing modes. The specifications and a minimal example may be found in the Developer Style Guide.","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Implementing-show-functions","page":"Details on printing in Oscar","title":"Implementing show functions","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"Here is the translation between :detail, one line and :supercompact.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"print(io, \"text/plain\", x) # detailed printing\nprint(io, x) # one line printing\nprint(IOContext(:supercompact => true), x) # supercompact printing","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"For reference, string interpolation \"$(x)\" will also use print(io, x).","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Mockup","page":"Details on printing in Oscar","title":"Mockup","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/#Detailed-printing-with-a-new-line","page":"Details on printing in Oscar","title":"Detailed printing with a new line","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"struct NewRing\n base_ring\nend\n\nbase_ring(R::NewRing) = R.base_ring","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"The following is a template for detailed printing. Note that at least one new line is needed for technical reasons. see below why.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"function Base.show(io::IO, ::MIME\"text/plain\", R::NewRing)\n println(io, \"I am a new ring\") # at least one new line is needed\n println(io, \"I print with newlines\")\n print(io, base_ring(R)) # the last print statement must not add a new line\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"The following is a template for one line and :supercompact printing.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"function Base.show(io::IO, R::NewRing)\n if get(io, :supercompact, false)\n # no nested printing\n print(io, \"supercompact printing of newring \")\n else\n # nested printing allowed, preferably supercompact\n print(io, \"one line printing of newring with \")\n print(IOContext(io, :supercompact => true), \"supercompact \", base_ring(R))\n end\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"And this is how it looks like:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"julia> R = NewRing(QQ)\nI am a new ring\nI print with newlines\nQQ\n\njulia> [R,R]\n2-element Vector{NewRing}:\n one line printing of newring with supercompact QQ\n one line printing of newring with supercompact QQ\n","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Detailed-printing-in-a-single-line","page":"Details on printing in Oscar","title":"Detailed printing in a single line","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"This version needs to be used in case the detailed printing does not contain newlines. Then detailed and one line printing agree. The if clause takes care of supercompact printing as well.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"struct NewRing2\n base_ring\nend\n\nbase_ring(R::NewRing2) = R.base_ring\n\nfunction Base.show(io::IO, R::NewRing2)\n if get(io, :supercompact, false)\n # no nested printing\n print(io, \"supercompact printing of newring\")\n else\n # nested printing allowed, preferably supercompact\n print(io, \"I am a new ring and always print in one line \" )\n print(IOContext(io, :supercompact => true), base_ring(R))\n end\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"And this is how it looks like:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"julia> R = NewRing2(QQ)\nI am a new ring and always print in one line QQ\n\njulia> [R,R]\n2-element Vector{NewRing2}:\n I am a new ring and always print in one line Rational Field\n I am a new ring and always print in one line Rational Field\n\njulia> print(IOContext(Base.stdout, :supercompact => true) ,R)\nsupercompact printing of newring","category":"page"},{"location":"DeveloperDocumentation/printing_details/#The-following-is-not-working-as-expected-and-should-not-be-used","page":"Details on printing in Oscar","title":"The following is not working as expected and should not be used","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"This example does not work correctly because the detailed printing does not include a newline, which is expected by the Julia printing system. To correctly support single line detailed printing, read the preceding section.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"function Base.show(io::IO, ::MIME\"text/plain\", R::NewRing) # do not implement me like this\n print(io, \"I am a new ring with a detailed printing of one line\")\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"Then the following will not be used for array/tuple printing. It will be used for print(io, R::NewRing) though.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"function Base.show(io::IO, R::NewRing)\n if get(io, :supercompact, false)\n print(io, \"supercompact printing of newring\")\n else # this is what we call one line\n print(io, \"one line printing of newring with \")\n print(IOContext(io, :supercompact => true), \"supercompact \", R.base_ring)\n end\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"This example illustrates the unexpected behavior.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"julia> R = NewRing(1)\n\njulia> R\nI am a new ring with a detailed printing of one line\n\njulia> [R,R] # one line printing is ignored\n2-element Vector{NewRing}:\n I am a new ring with a detailed printing of one line\n I am a new ring with a detailed printing of one line\n\njulia> print(Base.stdout, R)\none line printing of newring with supercompact QQ","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Advanced-printing-functionality","page":"Details on printing in Oscar","title":"Advanced printing functionality","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"To facilitate printing of nested mathematical structures, we provide a modified IOCustom object, that supports indentation and decapitalization.","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Example","page":"Details on printing in Oscar","title":"Example","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"We illustrate this with an example","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"struct A{T}\n x::T\nend\n\nfunction Base.show(io::IO, a::A)\n io = AbstractAlgebra.pretty(io)\n println(io, \"Something of type A\")\n print(io, AbstractAlgebra.Indent(), \"over \", AbstractAlgebra.Lowercase(), a.x)\n print(io, AbstractAlgebra.Dedent()) # don't forget to undo the indentation!\nend\n\nstruct B\nend\n\nfunction Base.show(io::IO, b::B)\n io = AbstractAlgebra.pretty(io)\n print(io, LowercaseOff(), \"Hilbert thing\")\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"At the REPL, this will then be printed as follows:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"julia> A(2)\nSomething of type A\n over 2\n\njulia> A(A(2))\nSomething of type A\n over something of type A\n over 2\n\njulia> A(B())\nSomething of type A\n over Hilbert thing","category":"page"},{"location":"DeveloperDocumentation/printing_details/#LaTeX-and-Unicode-printing","page":"Details on printing in Oscar","title":"LaTeX and Unicode printing","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/#LaTeX-output","page":"Details on printing in Oscar","title":"LaTeX output","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"Some types support LaTeX output.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"julia> Qx, x = QQ[\"x\"];\n\njulia> show(stdout, \"text/latex\", x^2 + 2x + x^10)\nx^{10} + x^{2} + 2 x\n\njulia> show(stdout, \"text/latex\", Qx[x x^2; 1 1])\n\\begin{array}{cc}\nx & x^{2} \\\\\n1 & 1\n\\end{array}","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"Base.show(io::IOContext, ::MIME\"text/latex\")","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Unicode-printing","page":"Details on printing in Oscar","title":"Unicode printing","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"Per default output should be ASCII only (no Unicode). Implementors of Base.show and related functions can branch on the output of Oscar.is_unicode_allowed() to display objects using non-ASCII characters. This will then be used for users which enabled Unicode using allow_unicode(true). Note that","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"there must be a default ASCII only output, since this is the default setting for new users, and\nOSCAR library code is not allowed to call Oscar.allow_unicode.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":"Here is an example with and without output using Unicode:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Details on printing in Oscar","title":"Details on printing in Oscar","text":" struct AtoB\n end\n\n function Base.show(io::IO, ::AtoB)\n if Oscar.is_unicode_allowed()\n print(io, \"A→B\")\n else\n print(io, \"A->B\")\n end\n end","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Affine-Algebraic-Sets","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Introduction","page":"Affine Algebraic Sets","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Let mathbbA^n(k)=k^n be the affine space of dimension n over a field k. For finitely many multivariate polynomials f_1 dots f_r in kx_1dots x_n and I = (f_1 dots f_r) subseteq kx_1dots x_n the ideal they generate, we denote by X = V(I) the (affine) algebraic set defined by the ideal I and call k its base field.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"If k subseteq K is any field extension, we denote the set of K-points of X by","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"beginalignedX(K) = P in mathbbA^n(K) mid f_1(P)=dots = f_n(P)=0=P in mathbbA^n(K) mid forall fin I f(P)=0endaligned","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Most properties of the algebraic set X refer to X(K) where K is an algebraically closed field. For instance is_empty returns whether X(K) = emptyset.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Exceptions to the rule, that we refer to X(K), are documented in the respective methods. For example the property of being irreducible depends on k: The algebraic set X = V(x^2+y^2) subseteq mathbbA^2 is irreducible over k = mathbbR. But it is the union of two lines over K = mathbbC, i.e. X is irreducible but geometrically reducible. See is_irreducible(X::AbsSpec{<:Field, <:MPolyAnyRing}) for details.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Rational-points","page":"Affine Algebraic Sets","title":"Rational points","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"To study the k-points, also called k-rational points, of the algebraic set X one first considers the solutions X(K) over an algebraically closed field extension K of k. Then in a second step one studies X(k) as a subset of X(K).","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"The first step involves calculations with ideals. For instance Hilbert's Nullstellensatz implies that X(K) is empty if and only if the ideal I=(1). This is decided by an ideal membership test relying on a Gröbner basis computation of I and can be carried out in kx_1dots x_n without taking any field extensions.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"The second step involves methods from number theory (if k is a number field) or from real algebraic geometry (if k = mathbbR).","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Algebraic sets in Oscar are designed for the first step. Most of their properfties should be interpreted as properties of the set X(K) of their K-points over an algebraic closure K.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Relation-to-Schemes","page":"Affine Algebraic Sets","title":"Relation to Schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"One may view an (affine) algebraic set as a geometrically reduced (affine) scheme over a field k.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Many constructions involving varieties lead naturally to schemes. For instance the intersection of X = V(x^2 - y) and Y = V(y) as sets is the point (00)=V(xy). As a scheme the intersection is defined by the ideal (x^2 y) which can be interpreted as a point of multiplicity 2 and contains the information that the intersection of X and Y is tangential in (00).","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Therefore we have two methods","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"set_theoretic_intersection(::AbsAffineAlgebraicSet) which can be thought of as X(K)cap Y(K)\nintersection(::AbsAffineAlgebraicSet) which is the scheme theoretic intersection","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"note: Note\nIf a construction returns a scheme Z, but you want to ignore the scheme structure, call the function algebraic_set(Z) to convert the scheme Z to an affine algebraic set.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"For example algebraic_set(intersection(X, Y)) is equivalent to set_theoretic_intersection(X, Y).","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Internally an AffineAlgebraicSet is constructed from a possibly non-reduced affine scheme, which we call the fat_scheme of X as opposed to the reduced_scheme of X which we refer to as the underlying_scheme.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"fat_ideal(X::AffineAlgebraicSet{<:Field})\nfat_scheme(X::AffineAlgebraicSet)\nunderlying_scheme(X::AffineAlgebraicSet)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#fat_ideal-Tuple{AffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"fat_ideal","text":"fat_ideal(X::AbsAffineAlgebraicSet) -> Ideal\n\nReturn an ideal whose radical is the vanishing ideal of X.\n\nIf X is constructed from an ideal I this returns I.\n\njulia> A2 = affine_space(QQ, [:x,:y])\nAffine space of dimension 2\n over rational field\nwith coordinates [x, y]\n\njulia> (x, y) = coordinates(A2);\n\njulia> I = ideal([x^2, y]);\n\njulia> X = algebraic_set(I)\nAffine algebraic set\n in affine 2-space over QQ with coordinates [x, y]\ndefined by ideal(x^2, y)\n\njulia> fat_ideal(X) === I\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#fat_scheme-Tuple{AffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"fat_scheme","text":"fat_scheme(X::AffineAlgebraicSet) -> AbsSpec\n\nReturn a scheme whose reduced subscheme is X.\n\nThis does not trigger any computation and is therefore cheap. Use this instead of underlying_scheme when possible.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#underlying_scheme-Tuple{AffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"underlying_scheme","text":"underlying_scheme(X::AffineAlgebraicSet) -> AbsSpec\n\nReturn the underlying reduced scheme defining X.\n\nThis is used to forward the AbsSpec functionality to X, but may trigger the computation of a radical ideal. Hence this can be expensive.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#More-general-affine-algebraic-sets","page":"Affine Algebraic Sets","title":"More general affine algebraic sets","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"By abuse of terminology we say that a scheme is an affine algebraic set if it is isomorphic to one. For example a hypersurface complement is an affine algebraic set. In particular, we allow affine algebraic sets which are not necessarily Zariski closed in their ambient affine space.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"AbsAffineAlgebraicSet","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#AbsAffineAlgebraicSet","page":"Affine Algebraic Sets","title":"AbsAffineAlgebraicSet","text":"AbsAffineAlgebraicSet <: AbsSpec\n\nAn affine, geometrically reduced subscheme of an affine space over a field.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Constructors","page":"Affine Algebraic Sets","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"One can create an algebraic set from an ideal or a multivariate polynomial.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"algebraic_set(I::MPolyIdeal{<:MPolyElem}; check::Bool=true)\nalgebraic_set(f::MPolyElem; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#algebraic_set-Tuple{MPolyIdeal{<:MPolyRingElem}}","page":"Affine Algebraic Sets","title":"algebraic_set","text":"algebraic_set(I::MPolyIdeal; is_radical::Bool=false, check::Bool=true)\n\nReturn the affine algebraic set defined I.\n\nIf is_radical is set, assume that I is a radical ideal.\n\njulia> R, (x,y) = GF(2)[:x,:y];\n\njulia> X = algebraic_set(ideal([y^2+y+x^3+1,x]))\nAffine algebraic set\n in affine 2-space over GF(2) with coordinates [x, y]\ndefined by ideal(x^3 + y^2 + y + 1, x)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#algebraic_set-Tuple{MPolyRingElem}","page":"Affine Algebraic Sets","title":"algebraic_set","text":"algebraic_set(p::MPolyRingElem)\n\nReturn the affine algebraic set defined by the multivariate polynomial p.\n\njulia> R, (x,y) = QQ[:x,:y];\n\njulia> X = algebraic_set((y^2+y+x^3+1)*x^2)\nAffine algebraic set\n in affine 2-space over QQ with coordinates [x, y]\ndefined by ideal(x^5 + x^2*y^2 + x^2*y + x^2)\n\njulia> R, (x,y) = GF(2)[:x,:y];\n\njulia> X = algebraic_set((y^2+y+x^3+1)*x^2)\nAffine algebraic set\n in affine 2-space over GF(2) with coordinates [x, y]\ndefined by ideal(x^5 + x^2*y^2 + x^2*y + x^2)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Convert an affine scheme to an affine algebraic set in order to ignore its (non-reduced) scheme structure.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"algebraic_set(X::Spec; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#algebraic_set-Tuple{Spec}","page":"Affine Algebraic Sets","title":"algebraic_set","text":"algebraic_set(X::Spec; is_reduced=false, check=true) -> AffineAlgebraicSet\n\nConvert X to an AffineAlgebraicSet by considering its reduced structure.\n\nIf is_reduced is set, assume that X is already reduced. If is_reduced and check are set, check that X is actually geometrically reduced as claimed.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"set_theoretic_intersection(X::AbsAffineAlgebraicSet, Y::AbsAffineAlgebraicSet)\nclosure(X::AbsAffineAlgebraicSet{<:Field})","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#set_theoretic_intersection-Tuple{AbsAffineAlgebraicSet, AbsAffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"set_theoretic_intersection","text":"set_theoretic_intersection(X::AbsAffineAlgebraicSet, Y::AbsAffineAlgebraicSet)\n\nReturn the set theoretic intersection of X and Y as an algebraic set.\n\njulia> A = affine_space(QQ, [:x,:y])\nAffine space of dimension 2\n over rational field\nwith coordinates [x, y]\n\njulia> (x, y) = coordinates(A)\n2-element Vector{QQMPolyRingElem}:\n x\n y\n\njulia> X = algebraic_set(ideal([y - x^2]))\nAffine algebraic set\n in affine 2-space over QQ with coordinates [x, y]\ndefined by ideal(-x^2 + y)\n\njulia> Y = algebraic_set(ideal([y]))\nAffine algebraic set\n in affine 2-space over QQ with coordinates [x, y]\ndefined by ideal(y)\n\njulia> Zred = set_theoretic_intersection(X, Y)\nAffine algebraic set\n in affine 2-space over QQ with coordinates [x, y]\ndefined by ideal(-x^2 + y, y)\n\n\n\nNote that the set theoretic intersection forgets the intersection multiplicities which the scheme theoretic intersection remembers. Therefore they are different.\n\njulia> Z = intersect(X, Y) # a non reduced scheme\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables over QQ\n by ideal(x^2 - y, y)\n\njulia> Zred == Z\nfalse\n\njulia> Zred == reduced_scheme(Z)[1]\ntrue\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#closure-Tuple{AbsAffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"closure","text":"closure(X::AbsAffineAlgebraicSet)\n\nReturn the closure of X in its ambient affine space.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Attributes","page":"Affine Algebraic Sets","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"In addition to the attributes inherited from Affine schemes the following are available.","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"irreducible_components(X::AbsAffineAlgebraicSet)\ngeometric_irreducible_components(X::AbsAffineAlgebraicSet)\nvanishing_ideal(X::AbsAffineAlgebraicSet)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#irreducible_components-Tuple{AbsAffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"irreducible_components","text":"irreducible_components(X::AbsAffineAlgebraicSet) -> Vector{AffineVariety}\n\nReturn the irreducible components of X defined over the base field of X.\n\nNote that they may be reducible over the algebraic closure. See also geometric_irreducible_components.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#geometric_irreducible_components-Tuple{AbsAffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"geometric_irreducible_components","text":"geometric_irreducible_components(X::AbsAffineAlgebraicSet)\n\nReturn the geometrically irreducible components of X.\n\nThey are the irreducible components V_ij of X seen over an algebraically closed field and given as a vector of tuples (A_i V_ij d_ij), say, where A_i is an algebraic set which is irreducible over the base field of X and V_ij represents a corresponding class of galois conjugated geometrically irreducible components of A_i defined over a number field of degree d_ij whose generator prints as _a.\n\nThis is expensive and involves taking field extensions.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#vanishing_ideal-Tuple{AbsAffineAlgebraicSet}","page":"Affine Algebraic Sets","title":"vanishing_ideal","text":"vanishing_ideal(X::AbsAffineAlgebraicSet) -> Ideal\n\nReturn the ideal of all polynomials vanishing in X.\n\nBy Hilbert's Nullstellensatz this is a radical ideal.\n\nnote: Note\nThis triggers the computation of a radical, which is expensive.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Methods","page":"Affine Algebraic Sets","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Inherited from Affine schemes","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#Properties","page":"Affine Algebraic Sets","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/","page":"Affine Algebraic Sets","title":"Affine Algebraic Sets","text":"Inherited from Affine schemes","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#GR-Algebras:-Quotients-of-PBW-Algebras","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"In analogy to the affine algebras section in the commutative algebra chapter, we describe OSCAR functionality for dealing with quotients of PBW-algebras modulo two-sided ideals.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"note: Note\nQuotients of PBW-algebras modulo two-sided ideals are also known as GR-algebras (here, GR stands for Gröbner-Ready; see Viktor Levandovskyy (2005)).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Types","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Types","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"GR-algebras are modelled by objects of type PBWAlgQuo{T, S} <: NCRing, their elements are objects of type PBWAlgQuoElem{T, S} <: NCRingElem. Here, T is the element type of the field over which the GR-algebra is defined (the type S is added for internal use).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Constructors","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Constructors","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"quo(A::PBWAlgRing, I::PBWAlgIdeal)","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#quo-Tuple{PBWAlgRing, Oscar.PBWAlgIdeal}","page":"GR-Algebras: Quotients of PBW-Algebras","title":"quo","text":"quo(A::PBWAlgRing, I::PBWAlgIdeal)\n\nGiven a two-sided ideal I of A, create the quotient algebra AI and return the new algebra together with the quotient map Ato AI.\n\nExamples\n\njulia> R, (x, y, z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [-x*y, -x*z, -y*z];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)))\n(PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z, PBWAlgElem{QQFieldElem, Singular.n_Q}[x, y, z])\n\njulia> I = two_sided_ideal(A, [x^2, y^2, z^2])\ntwo_sided_ideal(x^2, y^2, z^2)\n\njulia> Q, q = quo(A, I);\n\njulia> Q\n(PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z)/two_sided_ideal(x^2, y^2, z^2)\n\njulia> q\nMap from\nPBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z to (PBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z)/two_sided_ideal(x^2, y^2, z^2) defined by a julia-function with inverse\n\nnote: Note\nThe example above, shows one way of constructing the exterior algebra on the variables x, y, z over mathbb Q. For reasons of efficiency, it is recommended to use the built-in constructor exterior_algebra when working with exterior algebras in OSCAR.\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Exterior-Algebras","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Exterior Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"The n-th exterior algebra over a field K is the quotient of the PBW-algebra","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"A=K langle e_1dots e_n mid e_i e_j = - e_j e_i text for ineq jrangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"modulo the two-sided ideal","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"langle e_1^2dots e_n^2rangle","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":" exterior_algebra","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#exterior_algebra","page":"GR-Algebras: Quotients of PBW-Algebras","title":"exterior_algebra","text":"exterior_algebra(K::Field, numVars::Int)\nexterior_algebra(K::Field, listOfVarNames::AbstractVector{<:VarName})\n\nThe first form returns an exterior algebra with coefficient field K and numVars variables: numVars must be positive, and the variables are called e1, e2, ....\n\nThe second form returns an exterior algebra with coefficient field K, and variables named as specified in listOfVarNames (which must be non-empty).\n\nNOTE: Creating an exterior_algebra with many variables will create an object occupying a lot of memory (probably cubic in numVars).\n\nExamples\n\njulia> ExtAlg, (e1,e2) = exterior_algebra(QQ, 2);\n\njulia> e2*e1\n-e1*e2\n\njulia> (e1+e2)^2 # result is automatically reduced!\n0\n\njulia> ExtAlg, (x,y) = exterior_algebra(QQ, [\"x\",\"y\"]);\n\njulia> y*x\n-x*y\n\n\n\n\n\n","category":"function"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Data-Associated-to-Affine-GR-Algebras","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Data Associated to Affine GR-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Basic-Data","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Basic Data","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"If Q=A/I is the quotient ring of a PBW-algebra A modulo a two-sided ideal I of A, then","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"base_ring(Q) refers to A,\nmodulus(Q) to I,\ngens(Q) to the generators of Q,\nngens(Q) to the number of these generators, and\ngen(Q, i) as well as Q[i] to the i-th such generator.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Examples","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Examples","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"julia> R, (x, y, z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [-x*y, -x*z, -y*z];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)));\n\njulia> I = two_sided_ideal(A, [x^2, y^2, z^2]);\n\njulia> Q, q = quo(A, I);\n\njulia> base_ring(Q)\nPBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z\n\njulia> modulus(Q)\ntwo_sided_ideal(x^2, y^2, z^2)\n\njulia> gens(Q)\n3-element Vector{PBWAlgQuoElem{QQFieldElem, Singular.n_Q}}:\n x\n y\n z\n\njulia> ngens(Q)\n3\n\njulia> gen(Q, 2)\ny","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Elements-of-GR-Algebras","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Elements of GR-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Types-2","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Types","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"The OSCAR type for elements of quotient rings of multivariate polynomial rings PBW-algebras is of parametrized form PBWAlgQuoElem{T, S}, where T is the element type of the field over which the GR-algebra is defined (the type S is added for internal use).","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Creating-Elements-of-GR-Algebras","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Creating Elements of GR-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"Elements of a GR-algebra Q = AI are created as images of elements of A under the projection map or by directly coercing elements of A into Q. The function simplify reduces a given element with regard to the modulus I.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Examples-2","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Examples","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"julia> R, (x, y, z) = QQ[\"x\", \"y\", \"z\"];\n\njulia> L = [-x*y, -x*z, -y*z];\n\njulia> REL = strictly_upper_triangular_matrix(L);\n\njulia> A, (x, y, z) = pbw_algebra(R, REL, deglex(gens(R)));\n\njulia> I = two_sided_ideal(A, [x^2, y^2, z^2]);\n\njulia> Q, q = quo(A, I);\n\njulia> f = q(y*x+z^2)\n-x*y + z^2\n\njulia> typeof(f)\nPBWAlgQuoElem{QQFieldElem, Singular.n_Q}\n\njulia> simplify(f);\n\njulia> f\n-x*y\n\njulia> g = Q(y*x+x^2)\nx^2 - x*y\n\njulia> f == g\ntrue","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Data-associated-to-Elements-of-GR-Algebras","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Data associated to Elements of GR-Algebras","text":"","category":"section"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"Given an element f of an affine GR-algebra Q, ","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/","page":"GR-Algebras: Quotients of PBW-Algebras","title":"GR-Algebras: Quotients of PBW-Algebras","text":"parent(f) refers to Q.","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#Ideals-in-GR-Algebras","page":"GR-Algebras: Quotients of PBW-Algebras","title":"Ideals in GR-Algebras","text":"","category":"section"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"LinearAlgebra/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"The linear algebra part of OSCAR provides functionality for handling","category":"page"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"vectors and matrices\nmodules and vector spaces,\nvector spaces over fields\nmatrix spaces and matrix algebras","category":"page"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"...","category":"page"},{"location":"LinearAlgebra/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Claus Fieker,\nTommy Hofmann.","category":"page"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"LinearAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Matrix-Interface","page":"Matrix Interface","title":"Matrix Interface","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Generic matrices are supported in AbstractAlgebra.jl. Both the space of mtimes n matrices and the algebra (ring) of mtimes m matrices are supported.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"As the space of mtimes n matrices over a commutative ring is not itself a commutative ring, not all of the Ring interface needs to be implemented for such matrices in.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"In particular, the following functions do not need to be implemented: is_domain_type, and divexact. The canonical_unit function should be implemented, but simply needs to return the corresponding value for entry 1 1 (the function is never called on empty matrices).","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"For matrix algebras, all of the ring interface must be implemented.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"note: Note\nAbstractAlgebra.jl matrices are not the same as Julia matrices. We store a base ring in our matrix and matrices are row major instead of column major in order to support the numerous large C libraries that use this convention.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"All AbstractAlgebra.jl matrices are assumed to be mutable. This is usually critical to performance.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Types-and-parents","page":"Matrix Interface","title":"Types and parents","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"AbstractAlgebra provides two abstract types for matrix spaces and their elements:","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"MatSpace{T} is the abstract type for matrix space parent types\nMatElem{T} is the abstract type for matrix types belonging to a matrix space","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"It also provides two abstract types for matrix algebras and their elements:","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"MatAlgebra{T} is the abstract type for matrix algebra parent types\nMatAlgElem{T} is the abstract type for matrix types belonging to a matrix algebra","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Note that these abstract types are parameterised. The type T should usually be the type of elements of the matrices.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Matrix spaces and matrix algebras should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Matrix spaces and algebras should at least be distinguished based on their base (coefficient) ring and the dimensions of the matrices in the space.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Required-functionality-for-matrices","page":"Matrix Interface","title":"Required functionality for matrices","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"In addition to the required (relevant) functionality for the Ring interface (see above), the following functionality is required for the Matrix interface.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"We suppose that R is a fictitious base ring (coefficient ring) and that S is a space of mtimes n matrices over R, or algebra of mtimes m matrices with parent object S of type MyMatSpace{T} or MyMatAlgebra{T}, respectively. We also assume the matrices in the space have type MyMat{T}, where T is the type of elements of the base (element) ring.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Note that the type T must (transitively) belong to the abstract type RingElem.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Currently only matrices over commutative rings are supported.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Constructors","page":"Matrix Interface","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"In addition to the standard constructors, the following constructors, taking an array of elements, must be available.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"(S::MyMatSpace{T})(A::Matrix{T}) where T <: RingElem\n(S::MyMatAlgebra{T})(A::Matrix{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Create the matrix in the given space/algebra whose (i j) entry is given by A[i, j].","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"(S::MyMatSpace{T})(A::Matrix{S}) where {S <: RingElem, T <: RingElem}\n(S::MyMatAlgebra{T})(A::Matrix{S}) where {S <: RingElem, T <: RingElem}","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Create the matrix in the given space/algebra whose (i j) entry is given by A[i, j], where S is the type of elements that can be coerced into the base ring of the matrix.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"(S::MyMatSpace{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}\n(S::MyMatAlgebra{T})(A::Vector{S}) where {S <: RingElem, T <: RingElem}","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Create the matrix in the given space/algebra of matrices (with dimensions mtimes n say), whose (i j) entry is given by A[i*(n - 1) + j] and where S is the type of elements that can be coerced into the base ring of the matrix.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"It is also possible to create matrices (in a matrix space only) directly, without first creating the corresponding matrix space (the inner constructor being called directly). Note that to support this, matrix space parent objects don't contain a reference to their parent. Instead, parents are constructed on-the-fly if requested. (The same strategy is used for matrix algebras.)","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"matrix(R::Ring, arr::Matrix{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Given an mtimes n Julia matrix of entries, construct the corresponding AbstractAlgebra.jl matrix over the given ring R, assuming all the entries can be coerced into R.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"matrix(R::Ring, r::Int, c::Int, A::Vector{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Construct the given rtimes c AbstractAlgebra.jl matrix over the ring R whose (i j) entry is given by A[c*(i - 1) + j], assuming that all the entries can be coerced into R.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"zero_matrix(R::Ring, r::Int, c::Int)","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Construct the rtimes c AbstractAlgebra.jl zero matrix over the ring R.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Views","page":"Matrix Interface","title":"Views","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Just as Julia supports views of matrices, AbstractAlgebra requires all matrix types to support views. These allow one to work with a submatrix of a given matrix. Modifying the submatrix also modifies the original matrix.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Note that deepcopy of a view type must return the same type, but it should return a view into a deepcopy of the original matrix. Julia enforces this for consistency.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"To support views, generic matrices in AbstractAlgebra of type Generic.MatSpaceElem have an associated Generic.MatSpaceView type. Both belong to the Generic.Mat abstract type, so that one can work with that in functions that can accept both views and actual matrices.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"The syntax for views is as for Julia's own views.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Note that the parent_type function returns the same type for a view as for the original matrix type. This could potentially cause a problem if the elem_type function is applied to the return value of parent_type and then used in a type assertion. For this reason, there may be some limitations on the use of views.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"The similar function also returns a matrix of type MatSpaceElem when applied to a view, rather than another view.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Basic-manipulation-of-matrices","page":"Matrix Interface","title":"Basic manipulation of matrices","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"dense_matrix_type(::Type{T}) where T<:NCRingElement\ndense_matrix_type(::T) where T<:NCRingElement\ndense_matrix_type(::Type{S}) where S<:NCRing\ndense_matrix_type(::S) where S<:NCRing","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the type of dense matrices whose entries have type T respectively elem_type(S). It suffices to provide a method with the first signature. For the other three signatures, the default methods dispatch to the first. E.g. in Nemo, which depends on AbstractAlgebra, we define dense_matrix_type(::Type{ZZRingElem}) = ZZMatrix.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"nrows(M::MyMatSpace{T}) where T <: RingElem\nnrows(M::MyMatAlgebra{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the number of rows of matrices in the matrix space.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"ncols(M:MyMatSpace{T}) where T <: RingElem\nncols(M:MyMatAlgebra{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the number of columns of matrices in the matrix space.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"nrows(f::MyMat{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the number of rows of the given matrix.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"ncols(f::MyMat{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the number of columns of the given matrix.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"getindex(M::MyMat{T}, r::Int, c::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the (i j)-th entry of the matrix M.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"setindex!(M::MyMat{T}, d::T, r::Int, c::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Set the (i j)-th entry of the matrix M to d, which is assumed to be in the base ring of the matrix. The matrix must have such an entry and the matrix is mutated in place and not returned from the function.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Transpose","page":"Matrix Interface","title":"Transpose","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"transpose(::MyMat{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the transpose of the given matrix.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Optional-functionality-for-matrices","page":"Matrix Interface","title":"Optional functionality for matrices","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Especially when wrapping C libraries, some functions are best implemented directly, rather than relying on the generic functionality. The following are all provided by the AbstractAlgebra.jl generic code, but can optionally be implemented directly for performance reasons.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Optional-submatrices","page":"Matrix Interface","title":"Optional submatrices","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"The following are only available for matrix spaces, not for matrix algebras.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Base.getindex(M::MyMat, rows::AbstractVector{Int}, cols::AbstractVector{Int})","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return a new matrix with the same entries as the submatrix with the given range of rows and columns.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Optional-row-swapping","page":"Matrix Interface","title":"Optional row swapping","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"swap_rows!(M::MyMat{T}, i::Int, j::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Swap the rows of M in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Optional-concatenation","page":"Matrix Interface","title":"Optional concatenation","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"The following are only available for matrix spaces, not for matrix algebras.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"hcat(M::MyMat{T}, N::MyMat{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the horizontal concatenation of M and N. It is assumed that the number of rows of M and N are the same.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"vcat(M::MyMat{T}, N::MyMat{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return the vertical concatenation of M and N. It is assumed that the number of columns of M and N are the same.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Optional-zero-tests","page":"Matrix Interface","title":"Optional zero tests","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"The following functions are available for matrices in both matrix algebras and matrix spaces.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"is_zero_entry(M::MatrixElem{T}, i::Int, j::Int) where T <: NCRingElement\nis_zero_row(M::MatrixElem{T}, i::Int) where T <: NCRingElement\nis_zero_column(M::MatrixElem{T}, j::Int) where T <: NCRingElement","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Optional-similar-and-zero","page":"Matrix Interface","title":"Optional similar and zero","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"The following functions are available for matrices in both matrix algebras and matrix spaces. Both similar and zero construct new matrices, with the same methods, but the entries are either undefined with similar or zero-initialized with zero.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"similar(x::MyMat{T}, R::Ring=base_ring(x)) where T <: RingElem\nzero(x::MyMat{T}, R::Ring=base_ring(x)) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Construct the matrix with the same dimensions as the given matrix, and the same base ring unless explicitly specified.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"similar(x::MyMat{T}, R::Ring, r::Int, c::Int) where T <: RingElem\nsimilar(x::MyMat{T}, r::Int, c::Int) where T <: RingElem\nzero(x::MyMat{T}, R::Ring, r::Int, c::Int) where T <: RingElem\nzero(x::MyMat{T}, r::Int, c::Int) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Construct the rtimes c matrix with R as base ring (which defaults to the base ring of the the given matrix). If x belongs to a matrix algebra and r neq c, an exception is raised, and it's also possible to specify only one Int as the order (e.g. similar(x, n)).","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Custom matrices and rings may choose which specific matrix type is best-suited to return for the given ring and dimensionality. If they do not specialize these functions, the default is a Generic.MatSpaceElem matrix, or Generic.MatAlgElem for matrix algebras. The default implementation of zero calls out to similar, so it's generally sufficient to specialize only similar. For both similar and zero, only the most general method has to be implemented (e.g. similar(x::MyMat, R::Ring, r::Int, c::Int), as all other methods (which have defaults) call out to this more general method.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Base.isassigned(M::MyMat, i, j)","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Test whether the given matrix has a value associated with indices i and j. It is recommended to overload this method for custom matrices.","category":"page"},{"location":"AbstractAlgebra/matrix_interface/#Optional-symmetry-test","page":"Matrix Interface","title":"Optional symmetry test","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"is_symmetric(a::MatrixElem)","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"Return true if the given matrix is symmetric with respect to its main diagonal, otherwise return false.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#Constructions","page":"Constructions","title":"Constructions","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"The standard way to define a polyhedron is by either giving a V-representation or an H-representation. But polyhedra may also be constructed through other means: by name, via operations on other polyhedra, or from other objects in OSCAR.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#H-and-V-representations","page":"Constructions","title":"H- and V-representations","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#Intersecting-halfspaces:-H-representation","page":"Constructions","title":"Intersecting halfspaces: H-representation","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"polyhedron(::Type{T}, A::AnyVecOrMat, b::AbstractVector) where T<:scalar_types\npolyhedron(::Type{T}, I::Union{Nothing, AbstractCollection[AffineHalfspace]}, E::Union{Nothing, AbstractCollection[AffineHyperplane]} = nothing) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#polyhedron-Union{Tuple{T}, Tuple{Type{T}, Union{MatElem, AbstractVecOrMat}, AbstractVector}} where T<:Union{Float64, FieldElem}","page":"Constructions","title":"polyhedron","text":"polyhedron([::Union{Type{T}, Field},] A::AnyVecOrMat, b) where T<:scalar_types\n\nThe (convex) polyhedron defined by\n\nP(Ab) = x Ax b \n\nsee Def. 3.35 and Section 4.1. of Michael Joswig, Thorsten Theobald (2013)\n\nThe first argument either specifies the Type of its coefficients or their parent Field.\n\nExamples\n\nThe following lines define the square 01^2 subset mathbbR^2:\n\njulia> A = [1 0; 0 1; -1 0 ; 0 -1];\n\njulia> b = [1, 1, 0, 0];\n\njulia> polyhedron(A,b)\nPolyhedron in ambient dimension 2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#polyhedron-Union{Tuple{T}, Tuple{Type{T}, Union{Nothing, Tuple{Union{MatElem, AbstractVecOrMat}, Any}, AbstractVector{<:Halfspace}}}, Tuple{Type{T}, Union{Nothing, Tuple{Union{MatElem, AbstractVecOrMat}, Any}, AbstractVector{<:Halfspace}}, Union{Nothing, Tuple{Union{MatElem, AbstractVecOrMat}, Any}, AbstractVector{<:Hyperplane}}}} where T<:Union{Float64, FieldElem}","page":"Constructions","title":"polyhedron","text":"polyhedron(::Union{Type{T}, Field}, I::Union{Nothing, AbstractCollection[AffineHalfspace]}, E::Union{Nothing, AbstractCollection[AffineHyperplane]} = nothing) where T<:scalar_types\n\nThe (convex) polyhedron obtained intersecting the halfspaces I (inequalities) and the hyperplanes E (equations). The first argument either specifies the Type of its coefficients or their parent Field.\n\nExamples\n\nThe following lines define the square 01^2 subset mathbbR^2:\n\njulia> A = [1 0; 0 1; -1 0 ; 0 -1];\n\njulia> b = [1, 1, 0, 0];\n\njulia> polyhedron((A,b))\nPolyhedron in ambient dimension 2\n\nAs an example for a polyhedron constructed from both inequalities and equations, we construct the polytope 01times0subsetmathbbR^2\n\njulia> P = polyhedron(([-1 0; 1 0], [0,1]), ([0 1], [0]))\nPolyhedron in ambient dimension 2\n\njulia> is_feasible(P)\ntrue\n\njulia> dim(P)\n1\n\njulia> vertices(P)\n2-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 0]\n [0, 0]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"The complete H-representation can be retrieved using facets and affine_hull:","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"julia> P = polyhedron(([-1 0; 1 0], [0,1]), ([0 1], [0]))\nPolyhedron in ambient dimension 2\n\njulia> facets(P)\n2-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^2 described by:\n-x₁ ≦ 0\nx₁ ≦ 1\n\n\njulia> affine_hull(P)\n1-element SubObjectIterator{AffineHyperplane{QQFieldElem}} over the Hyperplanes of R^2 described by:\nx₂ = 0\n\n\njulia> Q0 = polyhedron(facets(P))\nPolyhedron in ambient dimension 2\n\njulia> P == Q0\nfalse\n\njulia> Q1 = polyhedron(facets(P), affine_hull(P))\nPolyhedron in ambient dimension 2\n\njulia> P == Q1\ntrue","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#Computing-convex-hulls:-V-representation","page":"Constructions","title":"Computing convex hulls: V-representation","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"convex_hull(::Type{T}, ::AnyVecOrMat; non_redundant::Bool=false) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#convex_hull-Union{Tuple{T}, Tuple{Type{T}, Union{MatElem, AbstractVecOrMat}}} where T<:Union{Float64, FieldElem}","page":"Constructions","title":"convex_hull","text":"convex_hull([::Union{Type{T}, Field} = QQFieldElem,] V [, R [, L]]; non_redundant::Bool = false)\n\nConstruct the convex hull of the vertices V, rays R, and lineality L. If R or L are omitted, then they are assumed to be zero.\n\nArguments\n\nThe first argument either specifies the Type of its coefficients or their\n\nparent Field.\n\nV::AbstractCollection[PointVector]: Points whose convex hull is to be computed.\nR::AbstractCollection[RayVector]: Rays completing the set of points.\nL::AbstractCollection[RayVector]: Generators of the Lineality space.\n\nIf an argument is given as a matrix, its content has to be encoded row-wise.\n\nR can be given as an empty matrix or as nothing if the user wants to compute the convex hull only from V and L.\n\nIf it is known that V and R only contain extremal points and that the description of the lineality space is complete, set non_redundant = true to avoid unnecessary redundancy checks.\n\nSee Def. 2.11 and Def. 3.1 of Michael Joswig, Thorsten Theobald (2013).\n\nExamples\n\nThe following lines define the square 01^2 subset mathbbR^2:\n\njulia> Square = convex_hull([0 0; 0 1; 1 0; 1 1])\nPolyhedron in ambient dimension 2\n\nTo construct the positive orthant, rays have to be passed:\n\njulia> V = [0 0];\n\njulia> R = [1 0; 0 1];\n\njulia> PO = convex_hull(V, R)\nPolyhedron in ambient dimension 2\n\nThe closed-upper half plane can be constructed by passing rays and a lineality space:\n\njulia> V = [0 0];\n\njulia> R = [0 1];\n\njulia> L = [1 0];\n\njulia> UH = convex_hull(V, R, L)\nPolyhedron in ambient dimension 2\n\nTo obtain the x-axis in mathbbR^2:\n\njulia> V = [0 0];\n\njulia> R = nothing;\n\njulia> L = [1 0];\n\njulia> XA = convex_hull(V, R, L)\nPolyhedron in ambient dimension 2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"This is a standard triangle, defined via a (redundant) V-representation and its unique minimal H-representation:","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"julia> T = convex_hull([ 0 0 ; 1 0 ; 0 1; 0 1/2 ])\nPolyhedron in ambient dimension 2\n\njulia> halfspace_matrix_pair(facets(T))\n(A = [-1 0; 0 -1; 1 1], b = QQFieldElem[0, 0, 1])\n","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"The complete V-representation can be retrieved using minimal_faces, rays_modulo_lineality and lineality_space:","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"julia> P = convex_hull([0 0], [1 0], [0 1])\nPolyhedron in ambient dimension 2\n\njulia> Q0 = convex_hull(vertices(P))\nPolyhedron in ambient dimension 2\n\njulia> P == Q0\nfalse\n\njulia> mfP = minimal_faces(P)\n(base_points = PointVector{QQFieldElem}[[0, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])\n\njulia> rmlP = rays_modulo_lineality(P)\n(rays_modulo_lineality = RayVector{QQFieldElem}[[1, 0]], lineality_basis = RayVector{QQFieldElem}[[0, 1]])\n\njulia> Q1 = convex_hull(mfP.base_points, rmlP.rays_modulo_lineality)\nPolyhedron in ambient dimension 2\n\njulia> P == Q1\nfalse\n\njulia> Q0 == Q1\nfalse\n\njulia> Q2 = convex_hull(mfP.base_points, rmlP.rays_modulo_lineality, lineality_space(P))\nPolyhedron in ambient dimension 2\n\njulia> P == Q2\ntrue","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#Regular-polytopes","page":"Constructions","title":"Regular polytopes","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"A polytope is regular, in the strict sense, if it admits a flag-transtive group of (linear) automorphisms. There are three infinite families of regular polytopes which exist in each dimension: the (regular) simplices, cubes and cross polytopes. In addition there are two exceptional regular 3-polytopes (dodecahedron and icosahedron) plus three exceptional regular 4-polytopes (24-cell, 120-cell and 600-cell).","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"The regular 3-polytopes are also known as the Platonic solids. Here we also list the Archimedean, Catalan and Johnson solids, which form various generalizations of the Platonic solids. However, here we implement \"disjoint families\", i.e., the proper Archimedean solids exclude the Platonic solids; similarly, the proper Johnson solids exclude the Archmidean solids.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"simplex\ncross_polytope\ncube\ntetrahedron\ndodecahedron\nicosahedron\nplatonic_solid\narchimedean_solid\njohnson_solid\ncatalan_solid\nregular_24_cell\nregular_120_cell\nregular_600_cell","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#simplex","page":"Constructions","title":"simplex","text":"simplex([::Union{Type{T}, Field} = QQFieldElem,] d::Int [,n])\n\nConstruct the simplex which is the convex hull of the standard basis vectors along with the origin in mathbbR^d, scaled by n. The first argument either specifies the Type of its coefficients or their parent Field.\n\nExamples\n\nHere we take a look at the facets of the 7-simplex and a scaled 7-simplex:\n\njulia> s = simplex(7)\nPolyhedron in ambient dimension 7\n\njulia> facets(s)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^7 described by:\n-x₁ ≦ 0\n-x₂ ≦ 0\n-x₃ ≦ 0\n-x₄ ≦ 0\n-x₅ ≦ 0\n-x₆ ≦ 0\n-x₇ ≦ 0\nx₁ + x₂ + x₃ + x₄ + x₅ + x₆ + x₇ ≦ 1\n\njulia> t = simplex(7, 5)\nPolyhedron in ambient dimension 7\n\njulia> facets(t)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^7 described by:\n-x₁ ≦ 0\n-x₂ ≦ 0\n-x₃ ≦ 0\n-x₄ ≦ 0\n-x₅ ≦ 0\n-x₆ ≦ 0\n-x₇ ≦ 0\nx₁ + x₂ + x₃ + x₄ + x₅ + x₆ + x₇ ≦ 5\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#cross_polytope","page":"Constructions","title":"cross_polytope","text":"cross_polytope([::Union{Type{T}, Field} = QQFieldElem,] d::Int [,n])\n\nConstruct a d-dimensional cross polytope around origin with vertices located at pm e_i for each unit vector e_i of R^d, scaled by n. The first argument either specifies the Type of its coefficients or their parent Field.\n\nExamples\n\nHere we print the facets of a non-scaled and a scaled 3-dimensional cross polytope:\n\njulia> C = cross_polytope(3)\nPolyhedron in ambient dimension 3\n\njulia> facets(C)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:\nx₁ + x₂ + x₃ ≦ 1\n-x₁ + x₂ + x₃ ≦ 1\nx₁ - x₂ + x₃ ≦ 1\n-x₁ - x₂ + x₃ ≦ 1\nx₁ + x₂ - x₃ ≦ 1\n-x₁ + x₂ - x₃ ≦ 1\nx₁ - x₂ - x₃ ≦ 1\n-x₁ - x₂ - x₃ ≦ 1\n\njulia> D = cross_polytope(3, 2)\nPolyhedron in ambient dimension 3\n\njulia> facets(D)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the Halfspaces of R^3 described by:\nx₁ + x₂ + x₃ ≦ 2\n-x₁ + x₂ + x₃ ≦ 2\nx₁ - x₂ + x₃ ≦ 2\n-x₁ - x₂ + x₃ ≦ 2\nx₁ + x₂ - x₃ ≦ 2\n-x₁ + x₂ - x₃ ≦ 2\nx₁ - x₂ - x₃ ≦ 2\n-x₁ - x₂ - x₃ ≦ 2\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#cube","page":"Constructions","title":"cube","text":"cube([::Union{Type{T}, Field} = QQFieldElem,] d::Int , [l::Rational = -1, u::Rational = 1])\n\nConstruct the lu-cube in dimension d. The first argument either specifies the Type of its coefficients or their parent Field.\n\nExamples\n\nIn this example the 5-dimensional unit cube is constructed to ask for one of its properties:\n\njulia> C = cube(5,0,1);\n\njulia> normalized_volume(C)\n120\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#tetrahedron","page":"Constructions","title":"tetrahedron","text":"tetrahedron()\n\nConstruct the regular tetrahedron, one of the Platonic solids.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#dodecahedron","page":"Constructions","title":"dodecahedron","text":"dodecahedron()\n\nConstruct the regular dodecahedron, one out of two Platonic solids.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#icosahedron","page":"Constructions","title":"icosahedron","text":"icosahedron()\n\nConstruct the regular icosahedron, one out of two exceptional Platonic solids.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#platonic_solid","page":"Constructions","title":"platonic_solid","text":"platonic_solid(s)\n\nConstruct a Platonic solid with the name given by String s from the list below.\n\nArguments\n\ns::String: The name of the desired Archimedean solid. Possible values:\n\"tetrahedron\" : Tetrahedron. Regular polytope with four triangular facets.\n\"cube\" : Cube. Regular polytope with six square facets.\n\"octahedron\" : Octahedron. Regular polytope with eight triangular facets.\n\"dodecahedron\" : Dodecahedron. Regular polytope with 12 pentagonal facets.\n\"icosahedron\" : Icosahedron. Regular polytope with 20 triangular facets.\n\nExamples\n\njulia> T = platonic_solid(\"icosahedron\")\nPolyhedron in ambient dimension 3 with EmbeddedElem{nf_elem} type coefficients\n\njulia> nfacets(T)\n20\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#archimedean_solid","page":"Constructions","title":"archimedean_solid","text":"archimedean_solid(s)\n\nConstruct an Archimedean solid with the name given by String s from the list below. The polytopes are realized with floating point numbers and thus not exact; Vertex-facet-incidences are correct in all cases.\n\nArguments\n\ns::String: The name of the desired Archimedean solid. Possible values:\n\"truncated_tetrahedron\" : Truncated tetrahedron. Regular polytope with four triangular and four hexagonal facets.\n\"cuboctahedron\" : Cuboctahedron. Regular polytope with eight triangular and six square facets.\n\"truncated_cube\" : Truncated cube. Regular polytope with eight triangular and six octagonal facets.\n\"truncated_octahedron\" : Truncated Octahedron. Regular polytope with six square and eight hexagonal facets.\n\"rhombicuboctahedron\" : Rhombicuboctahedron. Regular polytope with eight triangular and 18 square facets.\n\"truncated_cuboctahedron\" : Truncated Cuboctahedron. Regular polytope with 12 square, eight hexagonal and six octagonal facets.\n\"snub_cube\" : Snub Cube. Regular polytope with 32 triangular and six square facets. The vertices are realized as floating point numbers. This is a chiral polytope.\n\"icosidodecahedron\" : Icosidodecahedon. Regular polytope with 20 triangular and 12 pentagonal facets.\n\"truncated_dodecahedron\" : Truncated Dodecahedron. Regular polytope with 20 triangular and 12 decagonal facets.\n\"truncated_icosahedron\" : Truncated Icosahedron. Regular polytope with 12 pentagonal and 20 hexagonal facets.\n\"rhombicosidodecahedron\" : Rhombicosidodecahedron. Regular polytope with 20 triangular, 30 square and 12 pentagonal facets.\n\"truncated_icosidodecahedron\" : Truncated Icosidodecahedron. Regular polytope with 30 square, 20 hexagonal and 12 decagonal facets.\n\"snub_dodecahedron\" : Snub Dodecahedron. Regular polytope with 80 triangular and 12 pentagonal facets. The vertices are realized as floating point numbers. This is a chiral polytope.\n\nExamples\n\njulia> T = archimedean_solid(\"cuboctahedron\")\nPolyhedron in ambient dimension 3\n\njulia> sum([nvertices(F) for F in faces(T, 2)] .== 3)\n8\n\njulia> sum([nvertices(F) for F in faces(T, 2)] .== 4)\n6\n\njulia> nfacets(T)\n14\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#johnson_solid","page":"Constructions","title":"johnson_solid","text":"johnson_solid(i::Int)\n\nConstruct the i-th proper Johnson solid.\n\nA Johnson solid is a 3-polytope whose facets are regular polygons, of various gonalities. It is proper if it is not an Archimedean solid. Up to scaling there are exactly 92 proper Johnson solids.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#catalan_solid","page":"Constructions","title":"catalan_solid","text":"catalan_solid(s::String)\n\nConstruct a Catalan solid with the name s from the list below. The polytopes are realized with floating point coordinates and thus are not exact. However, vertex-facet-incidences are correct in all cases.\n\nArguments\n\ns::String: The name of the desired Archimedean solid. Possible values:\n\"triakis_tetrahedron\" : Triakis Tetrahedron. Dual polytope to the Truncated Tetrahedron, made of 12 isosceles triangular facets.\n\"triakis_octahedron\" : Triakis Octahedron. Dual polytope to the Truncated Cube, made of 24 isosceles triangular facets.\n\"rhombic_dodecahedron\" : Rhombic dodecahedron. Dual polytope to the cuboctahedron, made of 12 rhombic facets.\n\"tetrakis_hexahedron\" : Tetrakis hexahedron. Dual polytope to the truncated octahedron, made of 24 isosceles triangluar facets.\n\"disdyakis_dodecahedron\" : Disdyakis dodecahedron. Dual polytope to the truncated cuboctahedron, made of 48 scalene triangular facets.\n\"pentagonal_icositetrahedron\" : Pentagonal Icositetrahedron. Dual polytope to the snub cube, made of 24 irregular pentagonal facets. The vertices are realized as floating point numbers.\n\"pentagonal_hexecontahedron\" : Pentagonal Hexecontahedron. Dual polytope to the snub dodecahedron, made of 60 irregular pentagonal facets. The vertices are realized as floating point numbers.\n\"rhombic_triacontahedron\" : Rhombic triacontahedron. Dual polytope to the icosidodecahedron, made of 30 rhombic facets.\n\"triakis_icosahedron\" : Triakis icosahedron. Dual polytope to the icosidodecahedron, made of 30 rhombic facets.\n\"deltoidal_icositetrahedron\" : Deltoidal Icositetrahedron. Dual polytope to the rhombicubaoctahedron, made of 24 kite facets.\n\"pentakis_dodecahedron\" : Pentakis dodecahedron. Dual polytope to the truncated icosahedron, made of 60 isosceles triangular facets.\n\"deltoidal_hexecontahedron\" : Deltoidal hexecontahedron. Dual polytope to the rhombicosidodecahedron, made of 60 kite facets.\n\"disdyakis_triacontahedron\" : Disdyakis triacontahedron. Dual polytope to the truncated icosidodecahedron, made of 120 scalene triangular facets.\n\nExamples\n\njulia> T = catalan_solid(\"triakis_tetrahedron\");\n\njulia> count(F -> nvertices(F) == 3, faces(T, 2))\n12\n\njulia> nfacets(T)\n12\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#regular_24_cell","page":"Constructions","title":"regular_24_cell","text":"regular_24_cell()\n\nConstruct the regular 24-cell, one out of three exceptional regular 4-polytopes.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#regular_120_cell","page":"Constructions","title":"regular_120_cell","text":"regular_120_cell()\n\nConstruct the regular 120-cell, one out of three exceptional regular 4-polytopes.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#regular_600_cell","page":"Constructions","title":"regular_600_cell","text":"regular_600_cell()\n\nConstruct the regular 600-cell, one out of three exceptional regular 4-polytopes.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#Other-polytope-constructions","page":"Constructions","title":"Other polytope constructions","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"billera_lee_polytope\nbirkhoff_polytope\ncyclic_polytope\ndel_pezzo_polytope\nfano_simplex\nfractional_cut_polytope\nfractional_matching_polytope\ngelfand_tsetlin_polytope\nnewton_polytope\norbit_polytope\nperles_nonrational_8_polytope\nrand_spherical_polytope\nrand_subpolytope","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#billera_lee_polytope","page":"Constructions","title":"billera_lee_polytope","text":"billera_lee_polytope(h::AbstractVector)\n\nConstruct a simplicial polytope whose h-vector is h. The corresponding g-vector must be an M-sequence. The ambient dimension equals the length of h, and the polytope lives in codimension one.\n\nLouis J. Billera, Carl W. Lee (1981)\n\nExamples\n\njulia> BL = billera_lee_polytope([1,3,3,1])\nPolyhedron in ambient dimension 4\n\njulia> f_vector(BL)\n3-element Vector{ZZRingElem}:\n 6\n 12\n 8\n\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#birkhoff_polytope","page":"Constructions","title":"birkhoff_polytope","text":"birkhoff_polytope(n::Integer, even::Bool = false)\n\nConstruct the Birkhoff polytope of dimension n^2.\n\nThis is the polytope of n times n stochastic matrices (encoded as row vectors of length n^2), i.e., the matrices with non-negative real entries whose row and column entries sum up to one. Its vertices are the permutation matrices.\n\nUse even = true to get the vertices only for the even permutation matrices.\n\nExamples\n\njulia> b = birkhoff_polytope(3)\nPolyhedron in ambient dimension 9\n\njulia> vertices(b)\n6-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 0, 0, 0, 1, 0, 0, 0, 1]\n [0, 1, 0, 1, 0, 0, 0, 0, 1]\n [0, 0, 1, 1, 0, 0, 0, 1, 0]\n [1, 0, 0, 0, 0, 1, 0, 1, 0]\n [0, 1, 0, 0, 0, 1, 1, 0, 0]\n [0, 0, 1, 0, 1, 0, 1, 0, 0]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#cyclic_polytope","page":"Constructions","title":"cyclic_polytope","text":"cyclic_polytope(d::Int, n::Int)\n\nConstruct the cyclic polytope that is the convex hull of n points on the moment curve in dimension d.\n\nExamples\n\njulia> cp = cyclic_polytope(3, 20)\nPolyhedron in ambient dimension 3\n\njulia> nvertices(cp)\n20\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#del_pezzo_polytope","page":"Constructions","title":"del_pezzo_polytope","text":"del_pezzo_polytope(d::Int)\n\nProduce the d-dimensional del Pezzo polytope, which is the convex hull of the cross polytope together with the all-ones and minus all-ones vector.\n\nExamples\n\njulia> DP = del_pezzo_polytope(4)\nPolyhedron in ambient dimension 4\n\njulia> f_vector(DP)\n4-element Vector{ZZRingElem}:\n 10\n 40\n 60\n 30\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#fano_simplex","page":"Constructions","title":"fano_simplex","text":"fano_simplex(d::Int)\n\nConstruct a lattice simplex such that the origin is the unique interior lattice point. The normal toric variety associated with its face fan is smooth.\n\nExamples\n\njulia> S = fano_simplex(3)\nPolyhedron in ambient dimension 3\n\njulia> X = normal_toric_variety(face_fan(S))\nNormal toric variety\n\njulia> is_smooth(X)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#fractional_cut_polytope","page":"Constructions","title":"fractional_cut_polytope","text":"fractional_cut_polytope(G::Graph{Undirected})\n\nConstruct the fractional cut polytope of the graph G.\n\nExamples\n\njulia> G = complete_graph(4);\n\njulia> fractional_cut_polytope(G)\nPolyhedron in ambient dimension 6\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#fractional_matching_polytope","page":"Constructions","title":"fractional_matching_polytope","text":"fractional_matching_polytope(G::Graph{Undirected})\n\nConstruct the fractional matching polytope of the graph G.\n\nExamples\n\njulia> G = complete_graph(4);\n\njulia> fractional_matching_polytope(G)\nPolyhedron in ambient dimension 6\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#gelfand_tsetlin_polytope","page":"Constructions","title":"gelfand_tsetlin_polytope","text":"gelfand_tsetlin_polytope(lambda::AbstractVector)\n\nConstruct the Gelfand-Tsetlin polytope indexed by a weakly decreasing vector lambda.\n\nExamples\n\njulia> P = gelfand_tsetlin_polytope([5,3,2])\nPolyhedron in ambient dimension 6\n\njulia> is_fulldimensional(P)\nfalse\n\njulia> p = project_full(P)\nPolyhedron in ambient dimension 3\n\njulia> is_fulldimensional(p)\ntrue\n\njulia> volume(p)\n3\n\n\n\n\n\ngelfand_tsetlin_polytope(lambda::AbstractVector, sigma::PermGroupElem)\n\nConstruct the generalized Gelfand-Tsetlin polytope indexed by a weakly decreasing vector lambda and a permutation sigma. \n\nAlexander Postnikov, Richard P. Stanley (2009)\n\njulia> P = gelfand_tsetlin_polytope([5,3,2], @perm (1,3,2))\nPolyhedron in ambient dimension 6\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#newton_polytope","page":"Constructions","title":"newton_polytope","text":"newton_polytope(poly::Polynomial)\n\nCompute the Newton polytope of the multivariate polynomial poly.\n\nExamples\n\njulia> S, (x, y) = polynomial_ring(ZZ, [\"x\", \"y\"])\n(Multivariate polynomial ring in 2 variables over ZZ, ZZMPolyRingElem[x, y])\n\njulia> f = x^3*y + 3x*y^2 + 1\nx^3*y + 3*x*y^2 + 1\n\njulia> NP = newton_polytope(f)\nPolyhedron in ambient dimension 2\n\njulia> vertices(NP)\n3-element SubObjectIterator{PointVector{QQFieldElem}}:\n [3, 1]\n [1, 2]\n [0, 0]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#orbit_polytope","page":"Constructions","title":"orbit_polytope","text":"orbit_polytope(V::AbstractCollection[PointVector], G::PermGroup)\n\nConstruct the convex hull of the orbit of one or several points (given row-wise in V) under the action of G.\n\nExamples\n\nThis will construct the 3-dimensional permutahedron:\n\njulia> V = [1 2 3];\n\njulia> G = symmetric_group(3);\n\njulia> P = orbit_polytope(V, G)\nPolyhedron in ambient dimension 3\n\njulia> vertices(P)\n6-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 2, 3]\n [1, 3, 2]\n [2, 1, 3]\n [2, 3, 1]\n [3, 1, 2]\n [3, 2, 1]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#perles_nonrational_8_polytope","page":"Constructions","title":"perles_nonrational_8_polytope","text":"perles_nonrational_8_polytope()\n\nConstruct an 8-dimensional polytope with 12 vertices which is not combinatorially equivalent to any rational polytope.\n\nBranko Grünbaum (2003), p.94f\n\nExamples\n\njulia> perles_nonrational_8_polytope()\nPolyhedron in ambient dimension 8 with EmbeddedElem{nf_elem} type coefficients\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand_spherical_polytope","page":"Constructions","title":"rand_spherical_polytope","text":"rand_spherical_polytope([rng::AbstractRNG,] d::Int, n::Int;\ndistribution=:uniform, precision=nothing, seed=nothing)\n\nConstruct the convex hull of n points on the unit sphere in mathbbR^d. Almost surely this is a simplicial polytope.\n\nKeywords\n\ndistribution::Symbol: One of the following two options:\n:uniform (default): Use intermediate floating point numbers for an almost uniform distribution on the sphere. The points will not be exactly on the sphere.\n:exact: Create exact rational points on the unit sphere, this works at the expense of both uniformity and log-height of the points.\nprecision::Int64: Precision in bits during floating point approximation for uniform distribution.\nseed::Int64: Seed for random number generation. Cannot be used together with the AbstractRNG argument.\n\nExamples\n\njulia> rsph = rand_spherical_polytope(3, 20)\nPolyhedron in ambient dimension 3\n\njulia> is_simplicial(rsph)\ntrue\n\njulia> rsph = rand_spherical_polytope(3, 4; precision=5, seed=132)\nPolyhedron in ambient dimension 3\n\njulia> map(x->dot(x,x), vertices(rsph))\n4-element Vector{QQFieldElem}:\n 4306545//4194304\n 15849//16384\n 4165//4096\n 8281//8192\n\njulia> rsph = rand_spherical_polytope(3, 4; distribution=:exact)\nPolyhedron in ambient dimension 3\n\njulia> map(x->dot(x,x), vertices(rsph))\n4-element Vector{QQFieldElem}:\n 1\n 1\n 1\n 1\n\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand_subpolytope","page":"Constructions","title":"rand_subpolytope","text":"rand_subpolytope(P::Polyhedron, n::Int; seed=nothing)\n\nConstruct a subpolytope of P as the convex hull of n vertices, chosen uniformly at random. The polyhedron P must be bounded, and the number n must not exceed the number of vertices.\n\nKeywords\n\nseed::Int64: Seed for random number generation.\n\nExamples\n\njulia> nvertices(rand_subpolytope(cube(3), 5))\n5\n\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#Operations-on-polyhedra","page":"Constructions","title":"Operations on polyhedra","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"Polyhedra can be produced through operations on other polyhedra. For example, they can be added using Minkowski addition or scaled; each of which results in a new polyhedron.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"+(::Polyhedron{T}, ::Polyhedron{U}) where {T<:scalar_types, U<:scalar_types}\n*(::Number, ::Polyhedron{T}) where T<:scalar_types\n*(::Polyhedron{T}, ::Polyhedron{U}) where {T<:scalar_types, U<:scalar_types}\nbipyramid\nintersect(::Polyhedron...)\npyramid","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#+-Union{Tuple{U}, Tuple{T}, Tuple{Polyhedron{T}, Polyhedron{U}}} where {T<:Union{Float64, FieldElem}, U<:Union{Float64, FieldElem}}","page":"Constructions","title":"+","text":"+(P::Polyhedron, Q::Polyhedron)\n\nReturn the Minkowski sum P + Q = x+y xP yQ of P and Q (see also minkowski_sum).\n\nExamples\n\nThe Minkowski sum of a square and the 2-dimensional cross-polytope is an octagon:\n\njulia> P = cube(2);\n\njulia> Q = cross_polytope(2);\n\njulia> M = minkowski_sum(P, Q)\nPolyhedron in ambient dimension 2\n\njulia> nvertices(M)\n8\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#*-Union{Tuple{T}, Tuple{Number, Polyhedron{T}}} where T<:Union{Float64, FieldElem}","page":"Constructions","title":"*","text":"*(k::Union{Number, FieldElem}, Q::Polyhedron)\n\nReturn the scaled polyhedron kQ = kx xQ.\n\nNote that k*Q = Q*k.\n\nExamples\n\nScaling an n-dimensional bounded polyhedron by the factor k results in the volume being scaled by k^n. This example confirms the statement for the 6-dimensional cube and k = 2.\n\njulia> C = cube(6);\n\njulia> SC = 2*C\nPolyhedron in ambient dimension 6\n\njulia> volume(SC)//volume(C)\n64\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#*-Union{Tuple{U}, Tuple{T}, Tuple{Polyhedron{T}, Polyhedron{U}}} where {T<:Union{Float64, FieldElem}, U<:Union{Float64, FieldElem}}","page":"Constructions","title":"*","text":"*(P::Polyhedron, Q::Polyhedron)\n\nReturn the Cartesian product of P and Q (see also product).\n\nExamples\n\nThe Cartesian product of a triangle and a line segment is a triangular prism.\n\njulia> T=simplex(2)\nPolyhedron in ambient dimension 2\n\njulia> S=cube(1)\nPolyhedron in ambient dimension 1\n\njulia> length(vertices(T*S))\n6\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#bipyramid","page":"Constructions","title":"bipyramid","text":"bipyramid(P::Polyhedron, z::Union{Number, FieldElem} = 1, z_prime::Union{Number, FieldElem} = -z)\n\nMake a bipyramid over a pointed polyhedron P.\n\nThe bipyramid is the convex hull of the input polyhedron P and two apexes (v, z), (v, z_prime) on both sides of the affine span of P. For bounded polyhedra, the projections of the apexes v to the affine span of P is the vertex barycenter of P.\n\nExamples\n\njulia> c = cube(2)\nPolyhedron in ambient dimension 2\n\njulia> vertices(bipyramid(c,2))\n6-element SubObjectIterator{PointVector{QQFieldElem}}:\n [-1, -1, 0]\n [1, -1, 0]\n [-1, 1, 0]\n [1, 1, 0]\n [0, 0, 2]\n [0, 0, -2]\n\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#intersect-Tuple{Vararg{Polyhedron}}","page":"Constructions","title":"intersect","text":"intersect(P::Polyhedron...)\n\nReturn the intersection bigcaplimits_p in P p.\n\nExamples\n\nThe positive orthant of the plane is the intersection of the two halfspaces with x0 and y0 respectively.\n\njulia> UH1 = convex_hull([0 0],[1 0],[0 1]);\n\njulia> UH2 = convex_hull([0 0],[0 1],[1 0]);\n\njulia> PO = intersect(UH1, UH2)\nPolyhedron in ambient dimension 2\n\njulia> rays(PO)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [0, 1]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#pyramid","page":"Constructions","title":"pyramid","text":"pyramid(P::Polyhedron, z::Union{Number, FieldElem} = 1)\n\nMake a pyramid over the given polyhedron P.\n\nThe pyramid is the convex hull of the input polyhedron P and a point v outside the affine span of P. For bounded polyhedra, the projection of v to the affine span of P coincides with the vertex barycenter of P. The scalar z is the distance between the vertex barycenter and v.\n\nExamples\n\njulia> c = cube(2)\nPolyhedron in ambient dimension 2\n\njulia> vertices(pyramid(c,5))\n5-element SubObjectIterator{PointVector{QQFieldElem}}:\n [-1, -1, 0]\n [1, -1, 0]\n [-1, 1, 0]\n [1, 1, 0]\n [0, 0, 5]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"The convex hull of two polytopes can be computed via convex_hull.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"convex_hull(::Polyhedron...)","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#convex_hull-Tuple{Vararg{Polyhedron}}","page":"Constructions","title":"convex_hull","text":"convex_hull(P::Polyhedron, Q::Polyhedron)\n\nReturn the convex_hull of P and Q.\n\nExamples\n\nThe convex hull of the following two line segments in R^3 is a tetrahedron.\n\njulia> L₁ = convex_hull([-1 0 0; 1 0 0])\nPolyhedron in ambient dimension 3\n\njulia> L₂ = convex_hull([0 -1 0; 0 1 0])\nPolyhedron in ambient dimension 3\n\njulia> T=convex_hull(L₁,L₂);\n\njulia> f_vector(T)\n2-element Vector{ZZRingElem}:\n 4\n 4\n\n\n\n\n\n","category":"method"},{"location":"StraightLinePrograms/gapslps/#GAP's-SLPs","page":"GAP's SLPs","title":"GAP's SLPs","text":"","category":"section"},{"location":"StraightLinePrograms/gapslps/","page":"GAP's SLPs","title":"GAP's SLPs","text":"There are two other available SLP types: GAPSLProgram and AtlasSLProgram, and related GAPSLDecision and AtlasSLDecision, which are constructed similarly as in GAP:","category":"page"},{"location":"StraightLinePrograms/gapslps/","page":"GAP's SLPs","title":"GAP's SLPs","text":"julia> prg = GAPSLProgram( [ [1,2,2,3], [3,-1] ], 2 )\n# input:\nr = [ g1, g2 ]\n# program:\nr[3] = r[1]^2*r[2]^3\nr[4] = r[3]^-1\n# return value:\nr[4]\n\njulia> SLP.evaluate(prg, [perm1, perm2])\n(1,3,4,2)\n\njulia> SLP.evaluate(prg, [x, y])\n#1 = ^ x 2 ==> x^2\n#2 = ^ y 3 ==> y^3\n#3 = * #1 #2 ==> (x^2y^3)\n#4 = ^ #3 -1 ==> (x^2y^3)^-1\nreturn: #4\n\njulia> SLProgram(prg) # direct compilation (with room for optimizations obviously)\n#1 = x ==> x\n#2 = y ==> y\n#3 = ^ #1 2 ==> x^2\n#4 = ^ #2 3 ==> y^3\n#5 = * #3 #4 ==> (x^2y^3)\n#3 = #5 ==> (x^2y^3)\nkeep: #1..#3\n#4 = ^ #3 -1 ==> (x^2y^3)^-1\nkeep: #1..#4\nreturn: #4\n\njulia> GAPSLProgram( [ [2,3], [ [3,1,1,4], [1,2,3,1] ] ], 2 )\n# input:\nr = [ g1, g2 ]\n# program:\nr[3] = r[2]^3\n# return values:\n[ r[3]*r[1]^4, r[1]^2*r[3] ]\n\njulia> GAPSLDecision([ [ [ 1, 1, 2, 1 ], 3 ], [ \"Order\", 1, 2 ], [ \"Order\", 2, 3 ], [ \"Order\", 3, 5 ] ] )\n# input:\nr = [ g1, g2 ]\n# program:\nr[3] = r[1]*r[2]\norder( r[1] ) == 2 || return false\norder( r[2] ) == 3 || return false\norder( r[3] ) == 5 || return false\n# return value:\ntrue\n\njulia> SLProgram(ans)\n#1 = x ==> x\n#2 = y ==> y\n#3 = * #1 #2 ==> (xy)\nkeep: #1..#3\ntest: order(#1) == 2 || return false\ntest: order(#2) == 3 || return false\ntest: order(#3) == 5 || return false\nreturn: true\n\njulia> d = AtlasSLDecision(\"inp 2\\nchor 1 2\\nchor 2 3\\nmu 1 2 3\\nchor 3 5\")\ninp 2\nchor 1 2\nchor 2 3\nmu 1 2 3\nchor 3 5\n\n376> SLP.evaluate(d, [perm1, perm2])\nfalse\n\njulia> GAPSLDecision(d)\n# input:\nr = [ g1, g2 ]\n# program:\norder( r[1] ) == 2 || return false\norder( r[2] ) == 3 || return false\nr[3] = r[1]*r[2]\norder( r[3] ) == 5 || return false\n# return value:\ntrue\n\njulia> SLProgram(d)\n#1 = x ==> x\n#2 = y ==> y\ntest: order(#1) == 2 || return false\ntest: order(#2) == 3 || return false\n#3 = * #1 #2 ==> (xy)\nkeep: #1..#3\ntest: order(#3) == 5 || return false\nreturn: true","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#Complex-embedding","page":"Complex embedding","title":"Complex embedding","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"We describe functionality for complex embeddings of arbitrary number fields. Note that a complex embeddding of a number field L is a morphism iota colon L to mathbfC. Such an embedding is called real if operatornameim(iota) subseteq mathbfR and imaginary otherwise.","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#Construction-of-complex-embeddings","page":"Complex embedding","title":"Construction of complex embeddings","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"complex_embeddings(::NumField)\nreal_embeddings(::NumField)","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#complex_embeddings-Tuple{NumField}","page":"Complex embedding","title":"complex_embeddings","text":"complex_embeddings(K::NumField; conjugates::Bool = true) -> Vector{NumFieldEmb}\n\nReturn the complex embeddings of K. If conjugates is false, only one imaginary embedding per conjugated pairs is returned.\n\nExamples\n\njulia> K, a = quadratic_field(-3);\n\njulia> complex_embeddings(K)\n2-element Vector{Hecke.NumFieldEmbNfAbs}:\n Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field defined by x^2 + 3\n Complex embedding corresponding to 0.00 - 1.73 * i of imaginary quadratic field defined by x^2 + 3\n\njulia> complex_embeddings(K, conjugates = false)\n1-element Vector{Hecke.NumFieldEmbNfAbs}:\n Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field defined by x^2 + 3\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#real_embeddings-Tuple{NumField}","page":"Complex embedding","title":"real_embeddings","text":"real_embeddings(K::NumField) -> Vector{NumFieldEmb}\n\nReturn the real embeddings of K.\n\nExamples\n\njulia> K, a = quadratic_field(3);\n\njulia> real_embeddings(K)\n2-element Vector{Hecke.NumFieldEmbNfAbs}:\n Embedding corresponding to ≈ -1.73\n Embedding corresponding to ≈ 1.73\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#Properties","page":"Complex embedding","title":"Properties","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"number_field(::NumFieldEmb)\nis_real(::NumFieldEmb)\nis_imaginary(::NumFieldEmb)","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#number_field-Tuple{Hecke.NumFieldEmb}","page":"Complex embedding","title":"number_field","text":"number_field(f::NumFieldEmb) -> NumField\n\nReturn the corresponding number field of the embedding f.\n\nExamples\n\njulia> K, a = quadratic_field(-3); e = complex_embeddings(K)[1];\n\njulia> number_field(e)\nImaginary quadratic field defined by x^2 + 3\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#is_real-Tuple{Hecke.NumFieldEmb}","page":"Complex embedding","title":"is_real","text":"is_real(f::NumFieldEmb) -> Bool\n\nReturn true if the embedding is real.\n\nExamples\n\njulia> K, a = quadratic_field(3); e = complex_embeddings(K)[1];\n\njulia> is_real(e)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#is_imaginary-Tuple{Hecke.NumFieldEmb}","page":"Complex embedding","title":"is_imaginary","text":"is_imaginary(f::NumFieldEmb) -> Bool\n\nReturns true if the embedding is imaginary, that is, not real.\n\nExamples\n\njulia> K, a = quadratic_field(-3); e = complex_embeddings(K)[1];\n\njulia> is_imaginary(e)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#Conjugated-embedding","page":"Complex embedding","title":"Conjugated embedding","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"conj(::NumFieldEmb)","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#conj-Tuple{Hecke.NumFieldEmb}","page":"Complex embedding","title":"conj","text":"conj(f::NumFieldEmb) -> NumFieldEmb\n\nReturns the conjugate embedding of f.\n\nExamples\n\njulia> K, a = quadratic_field(-3); e = complex_embeddings(K);\n\njulia> conj(e[1]) == e[2]\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#Evaluating-elements-at-complex-embeddings","page":"Complex embedding","title":"Evaluating elements at complex embeddings","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"Given an embedding f colon K to mathbfC and an element x of K, the image f(x) of x under f can be constructed as follows.","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":" (f::NumFieldEmb)(x::NumFieldElem, prec::Int = 32) -> acb","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"Note that the return type will be a complex ball of type acb. The radius r of the ball is guaranteed to satisfy r < 2^(-prec).\nIf the embedding is real, then the value c will satisfy is_real(c) == true.","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"For convenience, we also provide the following function to quickly create a corresponding anonymous function:","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"evaluation_function(e::NumFieldEmb, prec::Int)","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#evaluation_function-Tuple{Hecke.NumFieldEmb, Int64}","page":"Complex embedding","title":"evaluation_function","text":"evaluation_function(e::NumFieldEmb, prec::Int) -> Function\n\nReturn the anonymous function x -> e(x, prec).\n\nExamples\n\njulia> K, a = quadratic_field(-3);\n\njulia> e = complex_embeddings(K)[1];\n\njulia> fn = evaluation_function(e, 64);\n\njulia> fn(a)\n[+/- 3.99e-77] + [1.73205080756887729353 +/- 5.41e-21]*im\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#Logarithmic-embedding","page":"Complex embedding","title":"Logarithmic embedding","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"Given an object e representing an embedding iota colon L to mathbfC, the corresponding logarithmic embedding L to mathbfR x mapsto log(lvert iota(x) rvert) can be constructed as log(abs(e)).","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"julia> K, a = quadratic_field(2);\n\njulia> e = complex_embedding(K, 1.41)\nEmbedding of\nReal quadratic field defined by x^2 - 2\ncorresponding to ≈ 1.41\n\njulia> log(abs(e))(a, 128)\n[0.346573590279972654708616060729088284037750067180127627 +/- 4.62e-55]\n\njulia> log(abs(e(a)))\n[0.346573590 +/- 2.99e-10]","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#Restriction","page":"Complex embedding","title":"Restriction","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"Given a subfield iota colon k to K, any embedding f colon K to mathbfC naturally restricts to a complex embedding of K. Computing this restriction is supported in case k appears as a base field of (a base field) of K or iota is provided:","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"restrict(::NumFieldEmb, ::NumField)\nrestrict(::NumFieldEmb, ::NumFieldMor)","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#restrict-Tuple{Hecke.NumFieldEmb, NumField}","page":"Complex embedding","title":"restrict","text":"restrict(f::NumFieldEmb, K::NumField)\n\nGiven an embedding f of a number field L and a number field K appearing as a base field of L, return the restriction of f to K.\n\nExamples\n\njulia> K, a = quadratic_field(3);\n\njulia> L, b = number_field(polynomial(K, [1, 0, 1]), \"b\");\n\njulia> e = complex_embeddings(L);\n\njulia> restrict(e[1], K)\nComplex embedding corresponding to -1.73\n of number field with defining polynomial x^2 - 3\n over rational field\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#restrict-Tuple{Hecke.NumFieldEmb, Hecke.NumFieldMor}","page":"Complex embedding","title":"restrict","text":"restrict(f::NumFieldEmb, g::NumFieldMor)\n\nGiven an embedding f of a number field L and a morphism g colon K to L, return the embedding g circ f of K.\n\nThis is the same as g * f.\n\nExamples\n\njulia> K, a = CyclotomicField(5, \"a\");\n\njulia> k, ktoK = Hecke.subfield(K, [a + inv(a)]);\n\njulia> e = complex_embeddings(K);\n\njulia> restrict(e[1], ktoK)\nComplex embedding corresponding to 0.62\n of number field with defining polynomial x^2 + x - 1\n over rational field\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#Extension","page":"Complex embedding","title":"Extension","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"Given a complex embedding f colon k to mathbfC and a morphism iota colon k to K, an embedding g colon K to mathbfC is extension of f, if g restricts to f. Given an embedding and a morphism, all extensions can be computed as follows:","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"extend(::NumFieldEmb, ::NumFieldMor)","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#extend-Tuple{Hecke.NumFieldEmb, Hecke.NumFieldMor}","page":"Complex embedding","title":"extend","text":"extend(e::NumFieldEmb, f::NumFieldMor)\n\nGiven an embedding e of k and a morphism f colon k to K, determine all embedings of K which restrict to e along f.\n\nExample\n\njulia> K, a = CyclotomicField(5, \"a\");\n\njulia> k, ktoK = Hecke.subfield(K, [a + inv(a)]);\n\njulia> e = complex_embeddings(k)[1];\n\njulia> extend(e, ktoK)\n2-element Vector{Hecke.NumFieldEmbNfAbs}:\n Complex embedding corresponding to -0.81 + 0.59 * i of cyclotomic field of order 5\n Complex embedding corresponding to -0.81 - 0.59 * i of cyclotomic field of order 5\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#positivity_and_signs","page":"Complex embedding","title":"Positivity & Signs","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"sign(::NumFieldElem, ::NumFieldEmb)\nsigns(::NumFieldElem, ::Vector{NumFieldEmb})\nis_positive(::NumFieldElem, ::NumFieldEmb)\nis_positive(::NumFieldElem, ::Vector{NumFieldEmb})\nis_totally_positive(::NumFieldElem)\nis_negative(::NumFieldElem, ::NumFieldEmb)\nis_negative(::NumFieldElem, ::Vector{NumFieldEmb})","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/#sign-Tuple{NumFieldElem, Hecke.NumFieldEmb}","page":"Complex embedding","title":"sign","text":"sign(x::NumFieldElem, e::NumFieldEmb) -> Int\n\nGiven a number field element x and a complex embedding e, return 1, -1 or 0 depending on whether e(x) is positive, negative, or zero.\n\nExamples\n\njulia> K, a = quadratic_field(3);\n\njulia> e = complex_embedding(K, 1.7);\n\njulia> sign(a, e)\n1\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#signs-Tuple{NumFieldElem, Vector{Hecke.NumFieldEmb}}","page":"Complex embedding","title":"signs","text":"signs(a::NumFieldElem, [embs::Vector{NumFieldEmb} = real_embeddings(K)])\n -> Dict{NumFieldEmb, Int}\n\nReturn the signs of a at the real embeddings in embs as a dictionary, which are by default all real embeddings of the number field.\n\nExamples\n\njulia> K, a = quadratic_field(3);\n\njulia> signs(a)\nDict{Hecke.NumFieldEmbNfAbs, Int64} with 2 entries:\n Complex embedding corresponding to -1.73 of real quadratic field define… => -1\n Complex embedding corresponding to 1.73 of real quadratic field defined… => 1\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#is_positive-Tuple{NumFieldElem, Hecke.NumFieldEmb}","page":"Complex embedding","title":"is_positive","text":"is_positive(a::NumFieldElem, e::NumFieldEmb) -> Bool\n\nGiven a number field element a and a real embedding e, return whether a is positive at e.\n\nExamples\n\njulia> K, a = quadratic_field(5);\n\njulia> e = complex_embedding(K, 2.1);\n\njulia> is_positive(a, e)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#is_positive-Tuple{NumFieldElem, Vector{Hecke.NumFieldEmb}}","page":"Complex embedding","title":"is_positive","text":"is_positive(a::NumFieldElem, embs::Vector{NumFieldEmb}) -> Bool\n\nReturn whether the element a is positive at all embeddings of embs. All embeddings in embs must be real.\n\njulia> K, a = quadratic_field(5);\n\njulia> e = complex_embedding(K, 2.1);\n\njulia> e(a)\n[2.236067977 +/- 5.02e-10]\n\njulia> is_positive(a, [e])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#is_totally_positive-Tuple{NumFieldElem}","page":"Complex embedding","title":"is_totally_positive","text":"is_totally_positive(a::NumFieldElem) -> Bool\n\nReturn whether the element a is totally positive, that is, whether it is positive at all real embeddings of the ambient number field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#is_negative-Tuple{NumFieldElem, Hecke.NumFieldEmb}","page":"Complex embedding","title":"is_negative","text":"is_negative(a::NumFieldElem, e::NumFieldEmb) -> Bool\n\nGiven a number field element a and a real embedding e, return whether a is positive at e.\n\nExamples\n\njulia> K, a = quadratic_field(5);\n\njulia> e = complex_embedding(K, 2.1);\n\njulia> is_negative(a, e)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#is_negative-Tuple{NumFieldElem, Vector{Hecke.NumFieldEmb}}","page":"Complex embedding","title":"is_negative","text":"is_negative(a::NumFieldElem, embs::Vector{NumFieldEmb}) -> Bool\n\nReturn whether the element a is positive at all embeddings of embs. All embeddings in embs must be real.\n\nExamples\n\njulia> K, a = quadratic_field(5);\n\njulia> e = complex_embedding(K, -2.1);\n\njulia> e(a)\n[-2.236067977 +/- 5.02e-10]\n\njulia> is_negative(a, [e])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/complex_embeddings/#Example","page":"Complex embedding","title":"Example","text":"","category":"section"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"As mentioned, this functionality works for all types of number fields. Here is an example of an absolute non-simple number field.","category":"page"},{"location":"Hecke/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"julia> Qx, x = QQ[\"x\"];\n\njulia> K, a = number_field([x^2 + 1, x^3 + 2], \"a\");\n\njulia> emb = complex_embeddings(K)\n6-element Vector{Hecke.NumFieldEmbNfAbsNS}:\n Complex embedding corresponding to [1.00 * i, -1.26] of non-simple number field\n Complex embedding corresponding to [1.00 * i, 0.63 + 1.09 * i] of non-simple number field\n Complex embedding corresponding to [-1.00 * i, 0.63 + 1.09 * i] of non-simple number field\n Complex embedding corresponding to [-1.00 * i, -1.26] of non-simple number field\n Complex embedding corresponding to [-1.00 * i, 0.63 - 1.09 * i] of non-simple number field\n Complex embedding corresponding to [1.00 * i, 0.63 - 1.09 * i] of non-simple number field\n\njulia> k, b = quadratic_field(-1);\n\njulia> i = hom(k, K, a[1]);\n\njulia> restrict(emb[1], i)\nComplex embedding corresponding to 1.00 * i\n of number field with defining polynomial x^2 + 1\n over rational field\n\njulia> restrict(emb[3], i)\nComplex embedding corresponding to -1.00 * i\n of number field with defining polynomial x^2 + 1\n over rational field","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/functional_map/#Functional-maps","page":"Functional maps","title":"Functional maps","text":"","category":"section"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"A functional map in AbstractAlgebra is a map which can be applied by evaluating a Julia function or closure. It is represented by a map object that contains such a function/closure, usually in a field called image_fn.","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"All functional maps belong to the map class FunctionalMap.","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"A generic concrete type Generic.FunctionalMap is provided by the Generic module to implement a generic functional map type. This allows for functional maps that contain no extra data, other than a Julia function/closure.","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"Custom map types can also be defined which have map class FunctionalMap.","category":"page"},{"location":"AbstractAlgebra/functional_map/#Functional-map-interface","page":"Functional maps","title":"Functional map interface","text":"","category":"section"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"All functional map types must define their supertypes as in the following example:","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"mutable struct MyFunctionalMap{D, C} <: Map{D, C, FunctionalMap, MyFunctionalMap}\n # some fields\n image_fn::Function\nend","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"Of course MyFunctionalMap need not be parameterised if the types D and C of the domain and codomain objects are known.","category":"page"},{"location":"AbstractAlgebra/functional_map/#Required-functions-for-functional-maps","page":"Functional maps","title":"Required functions for functional maps","text":"","category":"section"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"The following functions must be defined for all functional map types or classes:","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"image_fn(M::Map(MyFunctionalMap))","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"Return the Julia function or closure that corresponds to application of the map M. This function only needs to be provided if this function is not stored in an image_fn field of the MyFunctionalMap type.","category":"page"},{"location":"AbstractAlgebra/functional_map/#Generic-functional-maps","page":"Functional maps","title":"Generic functional maps","text":"","category":"section"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"The Generic module provides a concrete type FunctionalMap which merely keeps track of a Julia function/closure implementing the map.","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"Such maps can be constructed using the following function:","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"map_from_func(f::Function, R, S)","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"Construct the generic functional map with domain and codomain given by the parent objects R and S corresponding to the Julia function f.","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"Examples","category":"page"},{"location":"AbstractAlgebra/functional_map/","page":"Functional maps","title":"Functional maps","text":"julia> f = map_from_func(x -> x + 1, ZZ, ZZ)\nMap with the following data\n\nDomain:\n=======\nIntegers\n\nCodomain:\n========\nIntegers\n\njulia> f(ZZ(2))\n3","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend\nDocTestFilters = r\"[0-9\\.]+ seconds \\(.*\\)\"","category":"page"},{"location":"AbstractAlgebra/ytabs/#Partitions-and-Young-tableaux","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"AbstractAlgebra.jl provides basic support for computations with Young tableaux, skew diagrams and the characters of permutation groups (implemented src/generic/YoungTabs.jl). All functionality of permutations is accessible in the Generic submodule.","category":"page"},{"location":"AbstractAlgebra/ytabs/#Partitions","page":"Partitions and Young tableaux","title":"Partitions","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"The basic underlying object for those concepts is Partition of a number n, i.e. a sequence of positive integers n_1 ldots n_k which sum to n. Partitions in AbstractAlgebra.jl are represented internally by non-increasing Vectors of Ints. Partitions are printed using the standard notation, i.e. 9 = 4 + 2 + 1 + 1 + 1 is shown as 4_1 2_1 1_3 with the subscript indicating the count of a summand in the partition.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic.Partition","category":"page"},{"location":"AbstractAlgebra/ytabs/#Partition","page":"Partitions and Young tableaux","title":"Partition","text":"Partition(part::Vector{<:Integer}[, check::Bool=true]) <: AbstractVector{Int}\n\nRepresent integer partition in the non-increasing order.\n\npart will be sorted, if necessary. Checks for validity of input can be skipped by calling the (inner) constructor with false as the second argument.\n\nFunctionally Partition is a thin wrapper over Vector{Int}.\n\nFieldnames:\n\nn::Int - the partitioned number\npart::Vector{Int} - a non-increasing sequence of summands of n.\n\nExamples\n\njulia> p = Partition([4,2,1,1,1])\n4₁2₁1₃\n\njulia> p.n == sum(p.part)\ntrue\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/ytabs/#Array-interface","page":"Partitions and Young tableaux","title":"Array interface","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Partition is a concrete (immutable) subtype of AbstractVector{Integer} and implements the standard Array interface.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"size(::Generic.Partition)\ngetindex(::Generic.Partition, i::Integer)","category":"page"},{"location":"AbstractAlgebra/ytabs/#size-Tuple{AbstractAlgebra.Generic.Partition}","page":"Partitions and Young tableaux","title":"size","text":"size(p::Partition)\n\nReturn the size of the vector which represents the partition.\n\nExamples\n\njulia> p = Partition([4,3,1]); size(p)\n(3,)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#getindex-Tuple{AbstractAlgebra.Generic.Partition, Integer}","page":"Partitions and Young tableaux","title":"getindex","text":"getindex(p::Partition, i::Integer)\n\nReturn the i-th part (in non-increasing order) of the partition.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"These functions work on the level of p.part vector.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"One can easily iterate over all partitions of n using the Generic.partitions function.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic.partitions","category":"page"},{"location":"AbstractAlgebra/ytabs/#partitions","page":"Partitions and Young tableaux","title":"partitions","text":"partitions(n::Integer)\n\nReturn the vector of all permutations of n. For an unsafe generator version see partitions!.\n\nExamples\n\njulia> Generic.partitions(5)\n7-element Vector{AbstractAlgebra.Generic.Partition{Int64}}:\n 1₅\n 2₁1₃\n 3₁1₂\n 2₂1₁\n 4₁1₁\n 3₁2₁\n 5₁\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"You may also have a look at JuLie.jl package for more utilities related to partitions.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"The number of all partitions can be computed by the hidden function _numpart. Much faster implementation is available in Nemo.jl.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic._numpart","category":"page"},{"location":"AbstractAlgebra/ytabs/#_numpart","page":"Partitions and Young tableaux","title":"_numpart","text":"_numpart(n::Integer)\n\nReturn the number of all distinct integer partitions of n. The function uses Euler pentagonal number theorem for recursive formula. For more details see OEIS sequence A000041. Note that _numpart(0) = 1 by convention.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Since Partition is a subtype of AbstractVector generic functions which operate on vectors should work in general. However the meaning of conj has been changed to agree with the traditional understanding of conjugation of Partitions:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"conj(::Generic.Partition)\nconj(::Generic.Partition, v::Vector)","category":"page"},{"location":"AbstractAlgebra/ytabs/#conj-Tuple{AbstractAlgebra.Generic.Partition}","page":"Partitions and Young tableaux","title":"conj","text":"conj(part::Partition)\n\nReturn the conjugated partition of part, i.e. the partition corresponding to the Young diagram of part reflected through the main diagonal.\n\nExamples\n\njulia> p = Partition([4,2,1,1,1])\n4₁2₁1₃\n\njulia> conj(p)\n5₁2₁1₂\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#conj-Tuple{AbstractAlgebra.Generic.Partition, Vector}","page":"Partitions and Young tableaux","title":"conj","text":"conj(part::Partition, v::Vector)\n\nReturn the conjugated partition of part together with permuted vector v.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#Young-Diagrams-and-Young-Tableaux","page":"Partitions and Young tableaux","title":"Young Diagrams and Young Tableaux","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Mathematically speaking Young diagram is a diagram which consists of rows of square boxes such that the number of boxes in each row is no less than the number of boxes in the previous row. For example partition 4_1 3_2 1 represents the following diagram.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"┌───┬───┬───┬───┐\n│ │ │ │ │\n├───┼───┼───┼───┘\n│ │ │ │\n├───┼───┼───┤\n│ │ │ │\n├───┼───┴───┘\n│ │\n└───┘","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Young Tableau is formally a bijection between the set of boxes of a Young Diagram and the set 1 ldots n. If a bijection is increasing along rows and columns of the diagram it is referred to as standard. For example","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┼───┤\n│ 8 │ 9 │10 │\n├───┼───┴───┘\n│11 │\n└───┘","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"is a standard Young tableau of 4_1 3_2 1 where the bijection assigns consecutive natural numbers to consecutive (row-major) cells.","category":"page"},{"location":"AbstractAlgebra/ytabs/#Constructors","page":"Partitions and Young tableaux","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"In AbstractAlgebra.jl Young tableau are implemented as essentially row-major sparse matrices, i.e. YoungTableau <: AbstractMatrix{Int} but only the defining Partition and the (row-major) fill-vector is stored.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic.YoungTableau","category":"page"},{"location":"AbstractAlgebra/ytabs/#YoungTableau","page":"Partitions and Young tableaux","title":"YoungTableau","text":"YoungTableau(part::Partition[, fill::Vector{Int}=collect(1:sum(part))]) <: AbstractMatrix{Int}\n\nReturn the Young tableaux of partition part, filled linearly by fill vector. Note that fill vector is in row-major format.\n\nFields:\n\npart - the partition defining Young diagram\nfill - the row-major fill vector: the entries of the diagram.\n\nExamples\n\njulia> p = Partition([4,3,1]); y = YoungTableau(p)\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> y.part\n4₁3₁1₁\n\njulia> y.fill\n8-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"For convenience there exists an alternative constructor of YoungTableau, which accepts a vector of integers and constructs Partition internally.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"YoungTableau(p::Vector{Integer}[, fill=collect(1:sum(p))])","category":"page"},{"location":"AbstractAlgebra/ytabs/#Array-interface-2","page":"Partitions and Young tableaux","title":"Array interface","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"To make YoungTableaux array-like we implement the following functions:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"size(::Generic.YoungTableau)\ngetindex(::Generic.YoungTableau, n::Integer)","category":"page"},{"location":"AbstractAlgebra/ytabs/#size-Tuple{AbstractAlgebra.Generic.YoungTableau}","page":"Partitions and Young tableaux","title":"size","text":"size(Y::YoungTableau)\n\nReturn size of the smallest array containing Y, i.e. the tuple of the number of rows and the number of columns of Y.\n\nExamples\n\njulia> y = YoungTableau([4,3,1]); size(y)\n(3, 4)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#getindex-Tuple{AbstractAlgebra.Generic.YoungTableau, Integer}","page":"Partitions and Young tableaux","title":"getindex","text":"getindex(Y::YoungTableau, n::Integer)\n\nReturn the column-major linear index into the size(Y)-array. If a box is outside of the array return 0.\n\nExamples\n\njulia> y = YoungTableau([4,3,1])\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> y[1]\n1\n\njulia> y[2]\n5\n\njulia> y[4]\n2\n\njulia> y[6]\n0\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Also the double-indexing corresponds to (row, column) access to an abstract array.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"julia> y = YoungTableau([4,3,1])\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> y[1,2]\n2\n\njulia> y[2,3]\n7\n\njulia> y[3,2]\n0","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Functions defined for AbstractArray type based on those (e.g. length) should work. Again, as in the case of Partition the meaning of conj is altered to reflect the usual meaning for Young tableaux:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"conj(::Generic.YoungTableau)","category":"page"},{"location":"AbstractAlgebra/ytabs/#conj-Tuple{AbstractAlgebra.Generic.YoungTableau}","page":"Partitions and Young tableaux","title":"conj","text":"conj(Y::YoungTableau)\n\nReturn the conjugated tableau, i.e. the tableau reflected through the main diagonal.\n\nExamples\n\njulia> y = YoungTableau([4,3,1])\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> conj(y)\n┌───┬───┬───┐\n│ 1 │ 5 │ 8 │\n├───┼───┼───┘\n│ 2 │ 6 │\n├───┼───┤\n│ 3 │ 7 │\n├───┼───┘\n│ 4 │\n└───┘\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#Pretty-printing","page":"Partitions and Young tableaux","title":"Pretty-printing","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Similarly to permutations we have two methods of displaying Young Diagrams:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic.setyoungtabstyle","category":"page"},{"location":"AbstractAlgebra/ytabs/#setyoungtabstyle","page":"Partitions and Young tableaux","title":"setyoungtabstyle","text":"setyoungtabstyle(format::Symbol)\n\nSelect the style in which Young tableaux are displayed (in REPL or in general as string). This can be either\n\n:array - as matrices of integers, or\n:diagram - as filled Young diagrams (the default).\n\nThe difference is purely esthetical.\n\nExamples\n\njulia> Generic.setyoungtabstyle(:array)\n:array\n\njulia> p = Partition([4,3,1]); YoungTableau(p)\n 1 2 3 4\n 5 6 7\n 8\n\njulia> Generic.setyoungtabstyle(:diagram)\n:diagram\n\njulia> YoungTableau(p)\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/#Ulitility-functions","page":"Partitions and Young tableaux","title":"Ulitility functions","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"matrix_repr(::Generic.YoungTableau)\nfill!(::Generic.YoungTableau, ::AbstractVector{<:Integer})","category":"page"},{"location":"AbstractAlgebra/ytabs/#matrix_repr-Tuple{AbstractAlgebra.Generic.YoungTableau}","page":"Partitions and Young tableaux","title":"matrix_repr","text":"matrix_repr(a::Perm)\n\nReturn the permutation matrix as a sparse matrix representing a via natural embedding of the permutation group into the general linear group over mathbbZ.\n\nExamples\n\njulia> p = Perm([2,3,1])\n(1,2,3)\n\njulia> matrix_repr(p)\n3×3 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n ⋅ 1 ⋅\n ⋅ ⋅ 1\n 1 ⋅ ⋅\n\njulia> Array(ans)\n3×3 Matrix{Int64}:\n 0 1 0\n 0 0 1\n 1 0 0\n\n\n\n\n\nmatrix_repr(Y::YoungTableau)\n\nConstruct sparse integer matrix representing the tableau.\n\nExamples\n\njulia> y = YoungTableau([4,3,1]);\n\n\njulia> matrix_repr(y)\n3×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 8 stored entries:\n 1 2 3 4\n 5 6 7 ⋅\n 8 ⋅ ⋅ ⋅\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#fill!-Tuple{AbstractAlgebra.Generic.YoungTableau, AbstractVector{<:Integer}}","page":"Partitions and Young tableaux","title":"fill!","text":"fill!(Y::YoungTableaux, V::Vector{<:Integer})\n\nReplace the fill vector Y.fill by V. No check if the resulting tableau is standard (i.e. increasing along rows and columns) is performed.\n\nExamples\n\njulia> y = YoungTableau([4,3,1])\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> fill!(y, [2:9...])\n┌───┬───┬───┬───┐\n│ 2 │ 3 │ 4 │ 5 │\n├───┼───┼───┼───┘\n│ 6 │ 7 │ 8 │\n├───┼───┴───┘\n│ 9 │\n└───┘\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#Characters-of-permutation-groups","page":"Partitions and Young tableaux","title":"Characters of permutation groups","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Irreducible characters (at least over field of characteristic 0) of the full group of permutations S_n correspond via Specht modules to partitions of n.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"character(::Generic.Partition)\ncharacter(lambda::Generic.Partition, p::Generic.Perm)\ncharacter(lambda::Generic.Partition, mu::Generic.Partition)","category":"page"},{"location":"AbstractAlgebra/ytabs/#character-Tuple{AbstractAlgebra.Generic.Partition}","page":"Partitions and Young tableaux","title":"character","text":"character(lambda::Partition)\n\nReturn the lambda-th irreducible character of permutation group on sum(lambda) symbols. The returned character function is of the following signature:\n\nchi(p::Perm[, check::Bool=true]) -> BigInt\n\nThe function checks (if p belongs to the appropriate group) can be switched off by calling chi(p, false). The values computed by chi are cached in look-up table.\n\nThe computation follows the Murnaghan-Nakayama formula: chi_lambda(sigma) = sum_textrimhook xisubset lambda(-1)^ll(lambdabackslashxi) chi_lambda backslashxi(tildesigma) where lambdabackslashxi denotes the skew diagram of lambda with xi removed, ll denotes the leg-length (i.e. number of rows - 1) and tildesigma is permutation obtained from sigma by the removal of the longest cycle.\n\nFor more details see e.g. Chapter 2.8 of Group Theory and Physics by S.Sternberg.\n\nExamples\n\njulia> G = SymmetricGroup(4)\nFull symmetric group over 4 elements\n\njulia> chi = character(Partition([3,1])); # character of the regular representation\n\n\njulia> chi(one(G))\n3\n\njulia> chi(perm\"(1,3)(2,4)\")\n-1\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#character-Tuple{AbstractAlgebra.Generic.Partition, Perm}","page":"Partitions and Young tableaux","title":"character","text":"character(lambda::Partition, p::Perm, check::Bool=true) -> BigInt\n\nReturn the value of lambda-th irreducible character of the permutation group on permutation p.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#character-Tuple{AbstractAlgebra.Generic.Partition, AbstractAlgebra.Generic.Partition}","page":"Partitions and Young tableaux","title":"character","text":"character(lambda::Partition, mu::Partition, check::Bool=true) -> BigInt\n\nReturn the value of lambda-th irreducible character on the conjugacy class represented by partition mu.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"The values computed by characters are cached in an internal dictionary Dict{Tuple{BitVector,Vector{Int}}, BigInt}. Note that all of the above functions return BigInts. If you are sure that the computations do not overflow, variants of the last two functions using Int are available:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"character(::Type{Int}, lambda::Partition, p::Perm[, check::Bool=true])\ncharacter(::Type{Int}, lambda::Partition, mu::Partition[, check::Bool=true])","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"The dimension dim lambda of the irreducible module corresponding to partition lambda can be computed using Hook length formula","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic.rowlength\nGeneric.collength\nhooklength\ndim(::Generic.YoungTableau)","category":"page"},{"location":"AbstractAlgebra/ytabs/#rowlength","page":"Partitions and Young tableaux","title":"rowlength","text":"rowlength(Y::YoungTableau, i, j)\n\nReturn the row length of Y at box (i,j), i.e. the number of boxes in the i-th row of the diagram of Y located to the right of the (i,j)-th box.\n\nExamples\n\njulia> y = YoungTableau([4,3,1])\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> Generic.rowlength(y, 1,2)\n2\n\njulia> Generic.rowlength(y, 2,3)\n0\n\njulia> Generic.rowlength(y, 3,3)\n0\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/#collength","page":"Partitions and Young tableaux","title":"collength","text":"collength(Y::YoungTableau, i, j)\n\nReturn the column length of Y at box (i,j), i.e. the number of boxes in the j-th column of the diagram of Y located below of the (i,j)-th box.\n\nExamples\n\njulia> y = YoungTableau([4,3,1])\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> Generic.collength(y, 1,1)\n2\n\njulia> Generic.collength(y, 1,3)\n1\n\njulia> Generic.collength(y, 2,4)\n0\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/#hooklength","page":"Partitions and Young tableaux","title":"hooklength","text":"hooklength(Y::YoungTableau, i, j)\n\nReturn the hook-length of an element in Y at position (i,j), i.e the number of cells in the i-th row to the right of (i,j)-th box, plus the number of cells in the j-th column below the (i,j)-th box, plus 1.\n\nReturn 0 for (i,j) not in the tableau Y.\n\nExamples\n\njulia> y = YoungTableau([4,3,1])\n┌───┬───┬───┬───┐\n│ 1 │ 2 │ 3 │ 4 │\n├───┼───┼───┼───┘\n│ 5 │ 6 │ 7 │\n├───┼───┴───┘\n│ 8 │\n└───┘\n\njulia> hooklength(y, 1,1)\n6\n\njulia> hooklength(y, 1,3)\n3\n\njulia> hooklength(y, 2,4)\n0\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/#dim-Tuple{AbstractAlgebra.Generic.YoungTableau}","page":"Partitions and Young tableaux","title":"dim","text":"dim(Y::YoungTableau) -> BigInt\n\nReturn the dimension (using hook-length formula) of the irreducible representation of permutation group S_n associated the partition Y.part.\n\nSince the computation overflows easily BigInt is returned. You may perform the computation of the dimension in different type by calling dim(Int, Y).\n\nExamples\n\njulia> dim(YoungTableau([4,3,1]))\n70\n\njulia> dim(YoungTableau([3,1])) # the regular representation of S_4\n3\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"The character associated with Y.part can also be used to compute the dimension, but as it is expected the Murnaghan-Nakayama is much slower even though (due to caching) consecutive calls are fast:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"julia> λ = Partition(collect(12:-1:1))\n12₁11₁10₁9₁8₁7₁6₁5₁4₁3₁2₁1₁\n\njulia> @time dim(YoungTableau(λ))\n 0.224430 seconds (155.77 k allocations: 7.990 MiB)\n9079590132732747656880081324531330222983622187548672000\n\njulia> @time dim(YoungTableau(λ))\n 0.000038 seconds (335 allocations: 10.734 KiB)\n9079590132732747656880081324531330222983622187548672000\n\njulia> G = SymmetricGroup(sum(λ))\nFull symmetric group over 78 elements\n\njulia> @time character(λ, one(G))\n 0.000046 seconds (115 allocations: 16.391 KiB)\n9079590132732747656880081324531330222983622187548672000\n\njulia> @time character(λ, one(G))\n 0.001439 seconds (195 allocations: 24.453 KiB)\n9079590132732747656880081324531330222983622187548672000","category":"page"},{"location":"AbstractAlgebra/ytabs/#Low-level-functions-and-characters","page":"Partitions and Young tableaux","title":"Low-level functions and characters","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"As mentioned above character functions use the Murnaghan-Nakayama rule for evaluation. The implementation follows","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Dan Bernstein, The computational complexity of rules for the character table of S_n Journal of Symbolic Computation, 37 (6), 2004, p. 727-748,","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"implementing the following functions. For precise definitions and meaning please consult the paper cited.","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic.partitionseq\nis_rimhook(::BitVector, ::Int, ::Int)\nGeneric.MN1inner","category":"page"},{"location":"AbstractAlgebra/ytabs/#partitionseq","page":"Partitions and Young tableaux","title":"partitionseq","text":"partitionseq(lambda::Partition)\n\nReturn a sequence (as BitVector) of falses and trues constructed from lambda: tracing the lower contour of the Young Diagram associated to lambda from left to right a true is inserted for every horizontal and false for every vertical step. The sequence always starts with true and ends with false.\n\n\n\n\n\npartitionseq(seq::BitVector)\n\nReturn the essential part of the sequence seq, i.e. a subsequence starting at first true and ending at last false.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/#is_rimhook-Tuple{BitVector, Int64, Int64}","page":"Partitions and Young tableaux","title":"is_rimhook","text":"is_rimhook(R::BitVector, idx::Integer, len::Integer)\n\nR[idx:idx+len] forms a rim hook in the Young Diagram of partition corresponding to R iff R[idx] == true and R[idx+len] == false.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#MN1inner","page":"Partitions and Young tableaux","title":"MN1inner","text":"MN1inner(R::BitVector, mu::Partition, t::Integer, charvals)\n\nReturn the value of lambda-th irreducible character on conjugacy class of permutations represented by partition mu, where R is the (binary) partition sequence representing lambda. Values already computed are stored in charvals::Dict{Tuple{BitVector,Vector{Int}}, Int}. This is an implementation (with slight modifications) of the Murnaghan-Nakayama formula as described in\n\nDan Bernstein,\n\"The computational complexity of rules for the character table of Sn\"\n_Journal of Symbolic Computation_, 37(6), 2004, p. 727-748.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/#Skew-Diagrams","page":"Partitions and Young tableaux","title":"Skew Diagrams","text":"","category":"section"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Skew diagrams are formally differences of two Young diagrams. Given lambda and mu, two partitions of n+m and m (respectively). Suppose that each of cells of mu is a cell of lambda (i.e. parts of mu are no greater than the corresponding parts of lambda). Then the skew diagram denoted by lambdamu is the set theoretic difference the of sets of boxes, i.e. is a diagram with exactly n boxes:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"Generic.SkewDiagram","category":"page"},{"location":"AbstractAlgebra/ytabs/#SkewDiagram","page":"Partitions and Young tableaux","title":"SkewDiagram","text":"SkewDiagram(lambda::Partition, mu::Partition) <: AbstractMatrix{Int}\n\nImplements a skew diagram, i.e. a difference of two Young diagrams represented by partitions lambda and mu. (below dots symbolise the removed entries)\n\nExamples\n\njulia> l = Partition([4,3,2])\n4₁3₁2₁\n\njulia> m = Partition([3,1,1])\n3₁1₂\n\njulia> xi = SkewDiagram(l,m)\n3×4 AbstractAlgebra.Generic.SkewDiagram{Int64}:\n ⋅ ⋅ ⋅ 1\n ⋅ 1 1\n ⋅ 1\n\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"SkewDiagram implements array interface with the following functions:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"size(xi::Generic.SkewDiagram)\nin(t::Tuple{Integer,Integer}, xi::Generic.SkewDiagram)\ngetindex(xi::Generic.SkewDiagram, n::Integer)","category":"page"},{"location":"AbstractAlgebra/ytabs/#size-Tuple{AbstractAlgebra.Generic.SkewDiagram}","page":"Partitions and Young tableaux","title":"size","text":"size(xi::SkewDiagram)\n\nReturn the size of array where xi is minimally contained. See size(Y::YoungTableau) for more details.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#in-Tuple{Tuple{Integer, Integer}, AbstractAlgebra.Generic.SkewDiagram}","page":"Partitions and Young tableaux","title":"in","text":"in(t::Tuple{Integer,Integer}, xi::SkewDiagram)\n\nCheck if box at position (i,j) belongs to the skew diagram xi.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#getindex-Tuple{AbstractAlgebra.Generic.SkewDiagram, Integer}","page":"Partitions and Young tableaux","title":"getindex","text":"getindex(xi::SkewDiagram, n::Integer)\n\nReturn 1 if linear index n corresponds to (column-major) entry in xi.lam which is not contained in xi.mu. Otherwise return 0.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"The support for skew diagrams is very rudimentary. The following functions are available:","category":"page"},{"location":"AbstractAlgebra/ytabs/","page":"Partitions and Young tableaux","title":"Partitions and Young tableaux","text":"is_rimhook(::Generic.SkewDiagram)\nleglength\nmatrix_repr(::Generic.SkewDiagram)","category":"page"},{"location":"AbstractAlgebra/ytabs/#is_rimhook-Tuple{AbstractAlgebra.Generic.SkewDiagram}","page":"Partitions and Young tableaux","title":"is_rimhook","text":"is_rimhook(xi::SkewDiagram)\n\nCheck if xi represents a rim-hook diagram, i.e. its diagram is edge-connected and contains no 2times 2 squares.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ytabs/#leglength","page":"Partitions and Young tableaux","title":"leglength","text":"leglength(xi::SkewDiagram[, check::Bool=true])\n\nCompute the leglength of a rim-hook xi, i.e. the number of rows with non-zero entries minus one. If check is false function will not check whether xi is actually a rim-hook.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ytabs/#matrix_repr-Tuple{AbstractAlgebra.Generic.SkewDiagram}","page":"Partitions and Young tableaux","title":"matrix_repr","text":"matrix_repr(xi::SkewDiagram)\n\nReturn a sparse representation of the diagram xi, i.e. a sparse array A where A[i,j] == 1 if and only if (i,j) is in xi.lam but not in xi.mu.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/visualizing_types/#Visualization-of-the-types-of-AbstractAlgebra.jl","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"AbstractAlgebra.jl implements a couple of abstract types which can be extended.","category":"page"},{"location":"AbstractAlgebra/visualizing_types/#Abstract-parents","page":"Visualization of the types of AbstractAlgebra.jl","title":"Abstract parents","text":"","category":"section"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"The following diagram shows a complete list of all abstract types in AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"(Image: Diagram of parent types)","category":"page"},{"location":"AbstractAlgebra/visualizing_types/#Abstract-elements","page":"Visualization of the types of AbstractAlgebra.jl","title":"Abstract elements","text":"","category":"section"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"Similarly the following diagram shows a complete list of all abstract types in AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"(Image: Diagram of element types)","category":"page"},{"location":"AbstractAlgebra/visualizing_types/#Concrete-types-in-AbstractAlgebra.jl","page":"Visualization of the types of AbstractAlgebra.jl","title":"Concrete types in AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"Until now we have discussed the abstract types of AbstractAlgebra.jl. Under this subsection we will instead give some examples of concrete types in AbstractAlgebra.jl.","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"In parentheses we put the types of the corresponding parent objects.","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"Perm{<:Integer} (SymmetricGroup{<:Integer})\nGFElem{<:Integer} (GFField{<:Integer})","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"We also think of various Julia types as though they were AbstractAlgebra.jl types:","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"BigInt (Integers{BigInt})\nRational{BigInt} (Rationals{BigInt})","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"Then there are various types for generic constructions over a base ring. They are all parameterised by a type T which is the type of the elements of the base ring they are defined over.","category":"page"},{"location":"AbstractAlgebra/visualizing_types/","page":"Visualization of the types of AbstractAlgebra.jl","title":"Visualization of the types of AbstractAlgebra.jl","text":"Generic.Poly{T} (Generic.PolyRing{T})\nGeneric.MPoly{T} (Generic.MPolyRing{T})\nGeneric.RelSeries{T} (Generic.RelPowerSeriesRing{T})\nGeneric.AbsSeries{T} (Generic.AbsPowerSeriesRing{T})\nGeneric.LaurentSeriesRingElem{T} (Generic.LaurentSeriesRing{T})\nGeneric.LaurentSeriesFieldElem{T} (Generic.LaurentSeriesField{T})\nGeneric.ResidueRingElem{T} (Generic.ResidueRing{T})\nGeneric.Frac{T} (Generic.FracField{T})\nGeneric.Mat{T} (Generic.MatSpace{T})","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"The commutative algebra part of OSCAR provides functionality for dealing with","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"multivariate polynomial rings and their ideals,\nquotients of multivariate polynomial rings modulo ideals and ideals of such quotients,\nlocalizations of the above rings and ideals of such localizations, and \nmodules over all rings above.","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"We use affine algebra as a synonym for quotient of a multivariate polynomial ring modulo an ideal.","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Fundamental to computational commutative algebra is the concept of standard bases. Each such basis is defined relative to a monomial ordering. If this ordering is a well-ordering, a standard basis is also called a Gröbner basis. We refer to the corresponding section in this chapter for details.","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nEach multivariate polynomial ring in OSCAR comes equipped with a monomial ordering according to which the polynomials are stored and displayed. Independently of this ordering, standard bases can be computed with respect to any monomial ordering: The groebner_basis and standard_basis functions provided by OSCAR allow one to specify the desired monomial ordering as a key word argument. Typically, however, the user does not have to worry about Gröbner (standard) bases: The functions discussed in this chapter compute such bases behind the scenes when needed. Once computed, each such basis is cached for later reuse.","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nIn Oscar, it is possible to equip multivariate polynomial rings with gradings by finitely presented groups. Most functions discussed in this chapter apply to both ungraded and graded polynomial rings. However, for simplicity of the presentation, in this documentation, the functions are often only illustrated by examples with focus on the former case, but work similarly for homogeneous ideals and graded modules in the latter case.","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nOur main focus in this chapter is on multivariate polynomial rings over fields (exact fields supported by OSCAR). Where not indicated otherwise, the presented functions also apply to polynomial rings over mathbb Z. ","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include: ","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Gert-Martin Greuel, Gerhard Pfister (2008)\nWolfram Decker, Christoph Lossen (2006)\nWolfram Decker, Gerhard Pfister (2013)","category":"page"},{"location":"CommutativeAlgebra/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Wolfram Decker.","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/","page":"Operations on Module Maps","title":"Operations on Module Maps","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/#Operations-on-Module-Maps","page":"Operations on Module Maps","title":"Operations on Module Maps","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/","page":"Operations on Module Maps","title":"Operations on Module Maps","text":"If module homomorphisms a and b with codomain(a) === domain(b) are given, then compose(a, b) refers to the composition b circ a. If an isomorphism of modules a is given, then inv(a) refers to its inverse.","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/","page":"Operations on Module Maps","title":"Operations on Module Maps","text":"hom_product(M::ModuleFP, N::ModuleFP, A::Matrix{<: ModuleFPHom})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/#hom_product-Tuple{ModuleFP, ModuleFP, Matrix{<:ModuleFPHom}}","page":"Operations on Module Maps","title":"hom_product","text":"hom_product(M::ModuleFP, N::ModuleFP, A::Matrix{<:ModuleFPHom})\n\nGiven modules M, N which are products with the same number of factors, say M = prod_i=1^r M_i, N = prod_j=1^r N_j, and given a matrix A of homomorphisms a_ij M_i to N_j, return the homomorphism M to N with ij-components a_ij.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/","page":"Operations on Module Maps","title":"Operations on Module Maps","text":"hom_tensor(M::ModuleFP, N::ModuleFP, V::Vector{ <: ModuleFPHom})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/#hom_tensor-Tuple{ModuleFP, ModuleFP, Vector{<:ModuleFPHom}}","page":"Operations on Module Maps","title":"hom_tensor","text":"hom_tensor(M::ModuleFP, N::ModuleFP, V::Vector{ <: ModuleFPHom})\n\nGiven modules M, N which are tensor products with the same number of factors, say M = M_1 otimes cdots otimes M_r, N = N_1 otimes cdots otimes N_r, and given a vector V of homomorphisms a_i M_i to N_i, return a_1 otimes cdots otimes a_r.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/","page":"Operations on Module Maps","title":"Operations on Module Maps","text":"lift_homomorphism_contravariant(Hom_MP::ModuleFP, Hom_NP::ModuleFP, phi:: ModuleFPHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/#lift_homomorphism_contravariant-Tuple{ModuleFP, ModuleFP, ModuleFPHom}","page":"Operations on Module Maps","title":"lift_homomorphism_contravariant","text":"lift_homomorphism_contravariant(Hom_MP::ModuleFP, Hom_NP::ModuleFP, a::ModuleFPHom)\n\nGiven modules of homomorphism, say, Hom_MP = textHom(MP) and Hom_NP = textHom(NP), and given a homomorphism a N to M, return the induced homomorphism textHom(MP) to textHom(NP).\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/","page":"Operations on Module Maps","title":"Operations on Module Maps","text":"lift_homomorphism_covariant(Hom_PM::ModuleFP, Hom_PN::ModuleFP, phi:: ModuleFPHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/#lift_homomorphism_covariant-Tuple{ModuleFP, ModuleFP, ModuleFPHom}","page":"Operations on Module Maps","title":"lift_homomorphism_covariant","text":"lift_homomorphism_covariant(Hom_PM::ModuleFP, Hom_PN::ModuleFP, a::ModuleFPHom)\n\nGiven modules of homomorphism, say, Hom_PM = textHom(PM) and Hom_PN = textHom(PN), and given a homomorphism a M to N, return the induced homomorphism textHom(PM) to textHom(PN).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/non_plane_curves/","page":"Projective Curves","title":"Projective Curves","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/PlaneCurve/non_plane_curves/#Projective-Curves","page":"Projective Curves","title":"Projective Curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/non_plane_curves/","page":"Projective Curves","title":"Projective Curves","text":"We consider projective curves in projective spaces of arbitrary dimension.","category":"page"},{"location":"Experimental/PlaneCurve/non_plane_curves/#Constructors","page":"Projective Curves","title":"Constructors","text":"","category":"section"},{"location":"Experimental/PlaneCurve/non_plane_curves/","page":"Projective Curves","title":"Projective Curves","text":"We define a projective curve by an ideal of homogeneous polynomials.","category":"page"},{"location":"Experimental/PlaneCurve/non_plane_curves/","page":"Projective Curves","title":"Projective Curves","text":"ProjCurve","category":"page"},{"location":"Experimental/PlaneCurve/non_plane_curves/#ProjCurve","page":"Projective Curves","title":"ProjCurve","text":"ProjCurve(I::MPolyIdeal)\n\nGiven a homogeneous ideal I of Krull dimension 2, return the projective curve defined by I.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [\"w\", \"x\", \"y\", \"z\"]);\n\njulia> M = matrix(R, 2, 3, [w x y; x y z])\n[w x y]\n[x y z]\n\njulia> V = minors(M, 2)\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n w*y - x^2\n w*z - x*y\n x*z - y^2\n\njulia> I = ideal(R, V);\n\njulia> TC = ProjCurve(I)\nProjective curve defined by the ideal(w*y - x^2, w*z - x*y, x*z - y^2)\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PlaneCurve/non_plane_curves/#General-functions-for-curves","page":"Projective Curves","title":"General functions for curves","text":"","category":"section"},{"location":"Experimental/PlaneCurve/non_plane_curves/","page":"Projective Curves","title":"Projective Curves","text":"defining_ideal(C::ProjCurve)\nin(P::Oscar.Geometry.ProjSpcElem, C::ProjCurve)\ncurve_components(C::ProjCurve)\nis_irreducible(C::ProjCurve)\nreduction(C::ProjCurve)\njacobi_ideal(C::ProjCurve)\ninvert_birational_map(phi::Vector{T}, C::ProjCurve) where {T <: MPolyRingElem}","category":"page"},{"location":"Experimental/PlaneCurve/non_plane_curves/#defining_ideal-Tuple{ProjCurve}","page":"Projective Curves","title":"defining_ideal","text":"defining_ideal(C::ProjCurve)\n\nReturn the defining ideal of the projective curve C.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/non_plane_curves/#in-Tuple{Oscar.Geometry.ProjSpcElem, ProjCurve}","page":"Projective Curves","title":"in","text":"in(P::Oscar.Geometry.ProjSpcElem, C::ProjCurve)\n\nReturn true if the point P is on the curve C, and false otherwise.\n\nExamples\n\njulia> S, (x, y, z, t) = polynomial_ring(QQ, [\"x\", \"y\", \"z\", \"t\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])\n\njulia> I = ideal(T, [x^2, y^2*z, z^2])\nideal(x^2, y^2*z, z^2)\n\njulia> C = Oscar.ProjCurve(I)\nProjective curve defined by the ideal(x^2, y^2*z, z^2)\n\n\njulia> PP = proj_space(QQ, 3)\n(Projective space of dim 3 over Rational field\n, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[0], x[1], x[2], x[3]])\n\njulia> P = Oscar.Geometry.ProjSpcElem(PP[1], [QQ(0), QQ(2), QQ(0), QQ(5)])\n(0 : 2 : 0 : 5)\n\njulia> P in C\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/non_plane_curves/#curve_components-Tuple{ProjCurve}","page":"Projective Curves","title":"curve_components","text":"curve_components(C::ProjCurve)\n\nReturn a dictionary containing the irreducible components of C and the corresponding reduced curve.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/non_plane_curves/#is_irreducible-Tuple{ProjCurve}","page":"Projective Curves","title":"is_irreducible","text":"is_irreducible(C::ProjCurve)\n\nReturn true if C is irreducible, and false otherwise.\n\nExamples\n\njulia> S, (x, y, z, t) = polynomial_ring(QQ, [\"x\", \"y\", \"z\", \"t\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])\n\njulia> I = ideal(T, [x^2, y^2*z, z^2])\nideal(x^2, y^2*z, z^2)\n\njulia> C = Oscar.ProjCurve(I)\nProjective curve defined by the ideal(x^2, y^2*z, z^2)\n\njulia> Oscar.is_irreducible(C)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/non_plane_curves/#reduction-Tuple{ProjCurve}","page":"Projective Curves","title":"reduction","text":"reduction(C::ProjCurve)\n\nReturn the projective curve defined by the radical of the defining ideal of C.\n\nExamples\n\njulia> S, (x, y, z, t) = polynomial_ring(QQ, [\"x\", \"y\", \"z\", \"t\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])\n\njulia> I = ideal(T, [x^2, y^2*z, z^2])\nideal(x^2, y^2*z, z^2)\n\njulia> C = Oscar.ProjCurve(I)\nProjective curve defined by the ideal(x^2, y^2*z, z^2)\n\njulia> Oscar.reduction(C)\nProjective curve defined by the ideal(z, x)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/non_plane_curves/#jacobi_ideal-Tuple{ProjCurve}","page":"Projective Curves","title":"jacobi_ideal","text":"jacobi_ideal(C::ProjCurve)\n\nReturn the Jacobian ideal of the defining ideal of C.\n\nExamples\n\njulia> S, (x, y, z, t) = polynomial_ring(QQ, [\"x\", \"y\", \"z\", \"t\"])\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, t])\n\njulia> T, _ = grade(S)\n(Graded multivariate polynomial ring in 4 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z, t])\n\njulia> I = ideal(T, [x^2, y^2*z, z^2])\nideal(x^2, y^2*z, z^2)\n\njulia> C = Oscar.ProjCurve(I)\nProjective curve defined by the ideal(x^2, y^2*z, z^2)\n\njulia> Oscar.jacobi_ideal(C)\nideal(4*x*y*z, 2*x*y^2, 4*x*z, 4*y*z^2)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PlaneCurve/non_plane_curves/#invert_birational_map-Union{Tuple{T}, Tuple{Vector{T}, ProjCurve}} where T<:MPolyRingElem","page":"Projective Curves","title":"invert_birational_map","text":"invert_birational_map(phi::Vector{T}, C::ProjCurve) where {T <: MPolyRingElem}\n\nReturn a dictionary where image represents the image of the birational map given by phi, and inverse represents its inverse, where phi is a birational map of the projective curve C to its image in the projective space of dimension size(phi) - 1. Note that the entries of inverse should be considered as representatives of elements in R/image, where R is the basering.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = :(using AbstractAlgebra)","category":"page"},{"location":"AbstractAlgebra/map_interface/#Map-Interface","page":"Map Interface","title":"Map Interface","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Maps in AbstractAlgebra can be constructed from Julia functions, or they can be represented by some other kind of data, e.g. a matrix, or built up from other maps.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"In the following, we will always use the word \"function\" to mean a Julia function, and reserve the word \"map\" for a map on sets, whether mathematically, or as an object in the system.","category":"page"},{"location":"AbstractAlgebra/map_interface/#Parent-objects","page":"Map Interface","title":"Parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Maps in AbstractAlgebra currently don't have parents. This will change later when AbstractAlgebra has a category system, so that the parent of a map can be some sort of Hom set.","category":"page"},{"location":"AbstractAlgebra/map_interface/#Map-classes","page":"Map Interface","title":"Map classes","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"All maps in AbstractAlgebra belong to a class of maps. The classes are modeled as abstract types that lie in a hierarchy, inheriting from SetMap at the top of the hierarchy. Other classes that inherit from SetMap are FunctionalMap for maps that are constructed from a Julia function (or closure), and IdentityMap for the class of the identity maps within the system.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"One might naturally assume that map types belong directly to these classes in the way that types of other objects in the system belong to abstract types in the AbstractAlgebra type hierarchy. However, in order to provide an extensible system, this is not the case.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Instead, a map type MyMap will belong to an abstract type of the form Map{D, C, T, MyMap}, where D is the type of the object representing the domain of the map type (this can also be an abstract type, such as Group), C is the type of the object representing the codomain of the map type and T is the map class that MyMap belongs to, e.g. SetMap or FunctionalMap.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Because a four parameter type system becomes quite cumbersome to use, we provide a number of functions for referring to collections of map types.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"If writing a function that accepts any map type, one makes the type of its argument belong to Map. For example f(M::Map) = 1.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"If writing a function that accepts any map from a domain of type D to a codomain of type C, one makes writes for example f(M::Map{D, C}) = 2. Note that D and C can be abstract types, such as Group, but otherwise must be the types of the parent objects representing the domain and codomain.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"A function that accepts any map belonging to a given map class might be written as f(M::Map(FunctionalMap)) = 3 or f(M::Map(FunctionalMap){D, C}) = 4 for example, where D and C are the types of the parent objects for the domain and codomain.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Finally, if a function should only work for a map of a given map type MyMap, say, one writes this f(M::Map(MyMap)) or f(M::Map(MyMap){D, C}, where as usual D and C are the types of the domain and codomain parent objects.","category":"page"},{"location":"AbstractAlgebra/map_interface/#Implementing-new-map-types","page":"Map Interface","title":"Implementing new map types","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"There are two common kinds of map type that developers will need to write. The first has a fixed domain and codomain, and the second is a type parameterised by the types of the domain and codomain. We give two simple examples here of how this might look.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"In the case of fixed domain and codomain, e.g. Integers{BigInt}, we would write it as follows:","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"mutable struct MyMap <: Map{Integers{BigInt}, Integers{BigInt}, SetMap, MyMap}\n # some data fields\nend","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"In the case of parameterisation by the type of the domain and codomain:","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"mutable struct MyMap{D, C} <: Map{D, C, SetMap, MyMap}\n # some data fields\nend","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"As mentioned above, to write a function that only accepts maps of type MyMap, one writes the functions as follows:","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"function my_fun(M::Map(MyMap))","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"The Map function then computes the correct type to use, which is actually not MyMap if all features of the generic Map infrastructure are required. It is bad practice to write functions for MyMap directly instead of Map(MyMap), since other users will be unable to use generic constructions over the map type MyMap.","category":"page"},{"location":"AbstractAlgebra/map_interface/#Required-functionality-for-maps","page":"Map Interface","title":"Required functionality for maps","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"All map types must implement a standard interface, which we specify here.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"We will define this interface for a custom map type MyMap belonging to Map(SetMap), SetMap being the map class that all maps types belong to.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Note that map types do not need to contain any specific fields, but must provide accessor functions (getters and setters) in the manner described above.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"The required accessors for map types of class SetMap are as follows.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"domain(M::Map(MyMap))\ncodomain(M::Map(MyMap))","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Return the domain and codomain parent objects respectively, for the map M. It is only necessary to define these functions if the map type MyMap does not contain fields domain and codomain containing these parent objects.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"It is also necessary to be able to apply a map. This amounts to overloading the call method for objects belonging to Map(MyMap).","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"(M::Map(MyMap)(a))","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Apply the map M to the element a of the domain of M. Note that it is usual to add a type assertion to the return value of this function, asserting that the return value has type elem_type(C) where C is the type of the codomain parent object.","category":"page"},{"location":"AbstractAlgebra/map_interface/#Optional-functionality-for-maps","page":"Map Interface","title":"Optional functionality for maps","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"The Generic module in AbstractAlgebra automatically provides certain functionality for map types, assuming that they satisfy the full interface described above.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"However, certain map types or map classes might like to provide their own implementation of this functionality, overriding the generic functionality.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"We describe this optional functionality here.","category":"page"},{"location":"AbstractAlgebra/map_interface/#Show-method","page":"Map Interface","title":"Show method","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Custom map types may like to provide a custom show method if the default of displaying the domain and codomain of the map is not sufficient.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"show(io::IO, M::Map(MyMap))","category":"page"},{"location":"AbstractAlgebra/map_interface/#Identity-maps","page":"Map Interface","title":"Identity maps","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"There is a concrete map type Generic.IdentityMap{D} for the identity map on a given domain. Here D is the type of the object representing that domain.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Generic.IdentityMap belongs to the supertype Map{D, C, AbstractAlgebra.IdentityMap, IdentityMap}.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Note that the map class is also called IdentityMap. It is an abstract type, whereas Generic.IdentityMap is a concrete type in the Generic module.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"An identity map has the property that when composed with any map whose domain or codomain is compatible, that map will be returned as the composition. Identity maps can therefore serve as a starting point when building up a composition of maps, starting an identity map.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"We do not cached identity maps in the system, so that if more than one is created on the same domain, there will be more than one such map in the system. This underscores the fact that there is in general no way for the system to know if two maps compose to give an identity map, and therefore the only two maps that can be composed to give an identity map are identity maps on the same domain.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"To construct an identity map for a given domain, specified by a parent object R, say, we have the following function.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"identity_map(R::Set)","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Return an identity map on the domain R.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Of course there is nothing stopping a map type or class from implementing its own identity map type, and defining composition of maps of the same kind with such an identity map. In such a case, the class of such an identity map type must belong to IdentityMap so that composition with other map types still works.","category":"page"},{"location":"AbstractAlgebra/map_interface/#Composition-of-maps","page":"Map Interface","title":"Composition of maps","text":"","category":"section"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Any two compatible maps in AbstractAlgebra can be composed and any composition can be applied.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"In order to facilitate this, the Generic module provides a type Generic.CompositeMap{D, C}, which contains two maps map1 and map2, corresponding to the two maps to be applied in a composition, in the order they should be applied.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"To construct a composition map from two existing maps, we have the following function:","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"compose(f::Map{D, U}, g::Map{U, C}) where {D, U, C}","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Compose the two maps f and g, i.e. return the map h such that h(x) = g(f(x)).","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"As a shortcut for this function we have the following operator:","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"*(f::Map{D, U}, g::Map{U, C}) where {D, U, C} = compose(f, g)","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Note the order of composition. If we have maps f X to Y, g Y to Z the correct order of the maps in this operator is f*g, so that (f*g)(x) = g(f(x)).","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"This is chosen so that for left R-module morphisms represented by a matrix, the order of matrix multiplication will match the order of composition of the corresponding morphisms.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Of course, a custom map type or class of maps can implement its own composition type and compose function.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"This is the case with the FunctionalMap class for example, which caches the Julia function/closure corresponding to the composition of two functional maps. As this cached function needs to be stored inside the composition, a special type is necessary for the composition of two functional maps.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"By default, compose will check that the two maps are composable, i.e. the codomain of the first map matches the domain of the second map. This is implemented by the following function:","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"check_composable(f::Map{D, U}, g::Map{U, C})","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Raise an exception if the codomain of f doesn't match the domain of g.","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Note that composite maps should keep track of the two maps they were constructed from. To access these maps, the following functions are provided:","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"map1(f::CompositeMap)\nmap2(f::CompositeMap)","category":"page"},{"location":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"Any custom composite map type must also provide these functions for that map type, even if there exist fields with those names. This is because there is no common map class for all composite map types. Therefore the Generic system cannot provide fallbacks for all such composite map types.","category":"page"},{"location":"AbstractAlgebra/matrix_introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AbstractAlgebra/matrix_introduction/","page":"Introduction","title":"Introduction","text":"AbstractAlgebra provides matrix spaces (mxn matrices) and matrix algebras (nxn matrices) over a ring. Whilst both types of matrix provide matrix multiplication for matrices whose dimensions are compatible for multiplication, only the latter kind of matrices form rings in the system.","category":"page"},{"location":"AbstractAlgebra/matrix_introduction/","page":"Introduction","title":"Introduction","text":"Matrix spaces provide a large number of linear algebra operations, including linear solving, elementary row operations, various canonical forms. The system also provides characteristic and minimal polynomial computations, LU decomposition, determinant, matrix inverse, kernel computations.","category":"page"},{"location":"AbstractAlgebra/matrix_introduction/","page":"Introduction","title":"Introduction","text":"There is also code for computation of the Hermite and Smith normal forms over Euclidean domains and Popov form for matrices over polynomial rings over a field.","category":"page"},{"location":"AbstractAlgebra/matrix_introduction/","page":"Introduction","title":"Introduction","text":"Most of this generic functionality is provided for arbitrary matrix types that satisfy the AbstractAlgebra matrix interface.","category":"page"},{"location":"Experimental/LinearQuotients/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/LinearQuotients/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/LinearQuotients/introduction/","page":"Introduction","title":"Introduction","text":"Linear quotients are orbit spaces of the action of a finite group G on a finite-dimensional vector space V over mathbb C. Formally, we define VG = operatornameSpecmathbb CV^G. Notice that the invariant ring mathbb CV^G is an affine algebra by a theorem of Hilbert-Noether.","category":"page"},{"location":"Experimental/LinearQuotients/introduction/#Status","page":"Introduction","title":"Status","text":"","category":"section"},{"location":"Experimental/LinearQuotients/introduction/","page":"Introduction","title":"Introduction","text":"This part of OSCAR is in an experimental state; please see Adding new projects to experimental for what this means. See also the dedicated README.md for details.","category":"page"},{"location":"Experimental/LinearQuotients/introduction/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Experimental/LinearQuotients/introduction/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/LinearQuotients/introduction/","page":"Introduction","title":"Introduction","text":"Johannes Schmitt","category":"page"},{"location":"Experimental/LinearQuotients/introduction/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Experimental/LinearQuotients/introduction/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/#Noncommutative-ring-Interface","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"","category":"section"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"AbstractAlgebra.jl supports commutative rings through its Ring interface. In this section we describe the corresponding interface for noncommutative rings. The two interfaces are very similar in terms of required functionality, and so we mainly document the differences here.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"Noncommutative rings can be supported through the abstract types NCRing and NCRingElem. Note that we have Ring <: NCRing, etc., so the interface here should more correctly be called the Not-necessarily-Commutative-ring interface.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"However, the fact remains that if one wishes to implement a noncommutative ring, one should make its type belong to NCRing but not to Ring. Therefore it is not too much of a mistake to think of the NCRing interface as being for noncommutative rings.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/#Types","page":"Noncommutative ring Interface","title":"Types","text":"","category":"section"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"As for the Ring interface, most noncommutative rings must supply two types:","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"a type for the parent object (representing the ring itself)\na type for elements of that ring","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"The parent type must belong to NCRing and the element type must belong to NCRingElem. Of course, the types may belong to these abstract types transitively via an intermediate abstract type.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"Also as for the Ring interface, it is advised to make the types of generic parameterised rings that belong to NCRing and NCRingElem depend on the type of the elements of that parameter ring.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/#NCRingElement-type-union","page":"Noncommutative ring Interface","title":"NCRingElement type union","text":"","category":"section"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"As for the Ring interface, the NCRing interface provides a union type NCRingElement in src/julia/JuliaTypes.jl which is a union of NCRingElem and the Julia types Integer, Rational and AbstractFloat.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"Most of the generic code in AbstractAlgebra for general rings makes use of the union type NCRingElement instead of NCRingElem so that the generic functions also accept the Julia Base ring types.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"As per usual, one may need to implement one ad hoc binary operation for each concrete type belonging to NCRingElement to avoid ambiguity warnings.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/#Parent-object-caches","page":"Noncommutative ring Interface","title":"Parent object caches","text":"","category":"section"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"Parent object caches for the NCRing interface operate as per the Ring interface.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/#Required-functions-for-all-rings","page":"Noncommutative ring Interface","title":"Required functions for all rings","text":"","category":"section"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"Generic functions may only rely on required functionality for the NCRing interface, which must be implemented by all noncommutative rings.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"Most of this required functionality is the same as for the Ring interface, so we refer the reader there for details, with the following modifications.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"We give this interface for fictitious types MyParent for the type of the ring parent object R and MyElem for the type of the elements of the ring.","category":"page"},{"location":"AbstractAlgebra/ncring_interface/#Exact-division","page":"Noncommutative ring Interface","title":"Exact division","text":"","category":"section"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"divexact_left(f::MyElem, g::MyElem)\ndivexact_right(f::MyElem, g::MyElem)","category":"page"},{"location":"AbstractAlgebra/ncring_interface/","page":"Noncommutative ring Interface","title":"Noncommutative ring Interface","text":"If f = ga for some a in the ring, the function divexact_left(f, g) returns a. If f = ag then divexact_right(f, g) returns a. A DivideError() should be thrown if division is by zero. If no exact quotient exists or an impossible inverse is unavoidably encountered, an error should be thrown.","category":"page"},{"location":"Nemo/about/#About-Nemo","page":"About Nemo","title":"About Nemo","text":"","category":"section"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"Nemo is a library for fast basic arithmetic in various commonly used rings, for the Julia programming language. Our aim is to provide a highly performant package covering","category":"page"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"Commutative Algebra\nNumber Theory\nGroup Theory","category":"page"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"Nemo consists of wrappers of specialised C/C++ libraries:","category":"page"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"Flint http://flintlib.org/\nArb https://arblib.org/\nAntic https://github.com/wbhart/antic/\nCalcium https://fredrikj.net/calcium/","category":"page"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"Nemo also uses AbstractAlgebra.jl to provide generic constructions over the basic rings provided by the above packages.","category":"page"},{"location":"Nemo/about/#Why-Julia?","page":"About Nemo","title":"Why Julia?","text":"","category":"section"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"Julia is a sophisticated, modern programming language which is designed to be both performant and flexible. It was written by mathematicians, for mathematicians.","category":"page"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"The benefits of Julia include","category":"page"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"Familiar imperative syntax\nJIT compilation (provides near native performance, even for highly generic code)\nREPL console (cuts down on development time)\nParametric types (allows for fast generic constructions over other data types)\nPowerful metaprogramming facilities\nOperator overloading\nMultiple dispatch (dispatch on every argument of a function)\nEfficient native C interface (little or no wrapper overhead)\nExperimental C++ interface\nDynamic type inference\nBuilt-in bignums\nAble to be embedded in C programs\nHigh performance collection types (dictionaries, iterators, arrays, etc.)\nJupyter support (for web based notebooks)","category":"page"},{"location":"Nemo/about/","page":"About Nemo","title":"About Nemo","text":"The main benefits for Nemo are the parametric type system and JIT compilation. The former allows us to model many mathematical types, e.g. generic polynomial rings over an arbitrary base ring. The latter speeds up the runtime performance, even of highly generic mathematical procedures.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/complex/#Arbitrary-precision-complex-balls","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Arbitrary precision complex ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Complex numbers are represented in rectangular form a+bi where ab are arb balls.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"The corresponding field is constructed using the ComplexField constructor. This constructs the parent object for the Arb complex field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"The types of complex boxes in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Library Field Element type Parent type\nArb mathbbC (boxes) ComplexFieldElem ComplexField","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"All the complex field types belong to the Field abstract type and the types of elements in this field, i.e. complex boxes in this case, belong to the FieldElem abstract type.","category":"page"},{"location":"Nemo/complex/#Complex-ball-functionality","page":"Arbitrary precision complex balls","title":"Complex ball functionality","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"The complex balls in Nemo provide all the field functionality defined by AbstractAlgebra:.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Below, we document the additional functionality provided for complex balls.","category":"page"},{"location":"Nemo/complex/#Precision-management","page":"Arbitrary precision complex balls","title":"Precision management","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"See Precision management.","category":"page"},{"location":"Nemo/complex/#Complex-field-constructors","page":"Arbitrary precision complex balls","title":"Complex field constructors","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"In order to construct complex boxes in Nemo, one must first construct the Arb complex field itself. This is accomplished with the following constructor.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"ComplexField(prec::Int)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Here is an example of creating an Arb complex field and using the resulting parent object to coerce values into the resulting field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\n\na = CC(\"0.25\")\nb = CC(\"0.1\")\nc = CC(0.5)\nd = CC(12)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Note that whilst one can coerce double precision floating point values into an Arb complex field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb complex field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.","category":"page"},{"location":"Nemo/complex/#Constructors","page":"Arbitrary precision complex balls","title":"Constructors","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"onei(::ComplexField)","category":"page"},{"location":"Nemo/complex/#onei-Tuple{ComplexField}","page":"Arbitrary precision complex balls","title":"onei","text":"onei(r::ComplexField)\n\nReturn exact one times i in the given Arb complex field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\n\nc = onei(CC)","category":"page"},{"location":"Nemo/complex/#Basic-functionality","page":"Arbitrary precision complex balls","title":"Basic functionality","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"The following basic functionality is provided by the default Arb complex field implementation in Nemo, to support construction of generic rings over complex fields. Any custom complex field implementation in Nemo should provide analogues of these functions along with the usual arithmetic operations.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"parent_type(::Type{ComplexFieldElem})","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Gives the type of the parent object of an Arb complex field element.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"elem_type(R::ComplexField)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Given the parent object for an Arb complex field, return the type of elements of the field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"mul!(c::ComplexFieldElem, a::ComplexFieldElem, b::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Multiply a by b and set the existing Arb complex field element c to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"addeq!(c::ComplexFieldElem, a::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"In-place addition adds a to c and sets c to the result. This function is provided for performance reasons as it saves allocating a new object for the result and eliminates associated garbage collection.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"deepcopy(a::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Return a copy of the Arb complex field element a, recursively copying the internal data. Arb complex field elements are mutable in Nemo so a shallow copy is not sufficient.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Given the parent object R for an Arb complex field, the following coercion functions are provided to coerce various elements into the Arb complex field. Developers provide these by overloading the call operator for the complex field parent objects.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"R()","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Coerce zero into the Arb complex field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"R(n::Integer)\nR(f::ZZRingElem)\nR(q::QQFieldElem)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Coerce an integer or rational value into the Arb complex field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"R(f::Float64)\nR(f::BigFloat)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Coerce the given floating point number into the Arb complex field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"R(f::AbstractString)\nR(f::AbstractString, g::AbstractString)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Coerce the decimal number, given as a string, into the Arb complex field. In each case f is the real part and g is the imaginary part.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"R(f::arb)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Coerce the given Arb real ball into the Arb complex field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"R(f::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Take an Arb complex field element that is already in an Arb field and simply return it. A copy of the original is not made.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Here are some examples of coercing elements into the Arb complex field.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"RR = RealField(64)\nCC = ComplexField(64)\n\na = CC(3)\nb = CC(QQ(2,3))\nc = CC(\"3 +/- 0.0001\")\nd = CC(\"-1.24e+12345\")\nf = CC(\"nan +/- inf\")\ng = CC(RR(3))","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"In addition to the above, developers of custom complex field types must ensure that they provide the equivalent of the function base_ring(R::ComplexField) which should return Union{}. In addition to this they should ensure that each complex field element contains a field parent specifying the parent object of the complex field element, or at least supply the equivalent of the function parent(a::ComplexFieldElem) to return the parent object of a complex field element.","category":"page"},{"location":"Nemo/complex/#Basic-manipulation","page":"Arbitrary precision complex balls","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"isfinite(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#isfinite-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"isfinite","text":"isfinite(x::ComplexFieldElem)\n\nReturn true if x is finite, i.e. its real and imaginary parts have finite midpoint and radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"is_exact(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#is_exact-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"is_exact","text":"is_exact(x::ComplexFieldElem)\n\nReturn true if x is exact, i.e. has its real and imaginary parts have zero radius, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"isinteger(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#isinteger-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"isinteger","text":"isinteger(x::ComplexFieldElem)\n\nReturn true if x is an exact integer, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"accuracy_bits(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#accuracy_bits-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"accuracy_bits","text":"accuracy_bits(x::ComplexFieldElem)\n\nReturn the relative accuracy of x measured in bits, capped between typemax(Int) and -typemax(Int).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\n\na = CC(\"1.2 +/- 0.001\")\nb = CC(3)\n\nisreal(a)\nisfinite(b)\nisinteger(b)\nc = real(a)\nd = imag(b)\nf = accuracy_bits(a)","category":"page"},{"location":"Nemo/complex/#Containment","page":"Arbitrary precision complex balls","title":"Containment","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"It is often necessary to determine whether a given exact value or box is contained in a given complex box or whether two boxes overlap. The following functions are provided for this purpose.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"overlaps(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#overlaps-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"overlaps","text":"overlaps(x::ComplexFieldElem, y::ComplexFieldElem)\n\nReturns true if any part of the box x overlaps any part of the box y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"contains(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#contains-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"contains","text":"contains(x::ComplexFieldElem, y::ComplexFieldElem)\n\nReturns true if the box x contains the box y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"contains(::ComplexFieldElem, ::Integer)\ncontains(::ComplexFieldElem, ::ZZRingElem)\ncontains(::ComplexFieldElem, ::QQFieldElem)","category":"page"},{"location":"Nemo/complex/#contains-Tuple{ComplexFieldElem, Integer}","page":"Arbitrary precision complex balls","title":"contains","text":"contains(x::ComplexFieldElem, y::Integer)\n\nReturns true if the box x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/#contains-Tuple{ComplexFieldElem, ZZRingElem}","page":"Arbitrary precision complex balls","title":"contains","text":"contains(x::ComplexFieldElem, y::ZZRingElem)\n\nReturns true if the box x contains the given integer value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/#contains-Tuple{ComplexFieldElem, QQFieldElem}","page":"Arbitrary precision complex balls","title":"contains","text":"contains(x::ComplexFieldElem, y::QQFieldElem)\n\nReturns true if the box x contains the given rational value, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"The following functions are also provided for determining if a box intersects a certain part of the complex number plane.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"contains_zero(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#contains_zero-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"contains_zero","text":"contains_zero(x::ComplexFieldElem)\n\nReturns true if the box x contains zero, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\nx = CC(\"1 +/- 0.001\")\ny = CC(\"3\")\n\noverlaps(x, y)\ncontains(x, y)\ncontains(y, 3)\ncontains(x, ZZ(1)//2)\ncontains_zero(x)","category":"page"},{"location":"Nemo/complex/#Comparison","page":"Arbitrary precision complex balls","title":"Comparison","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Nemo provides a full range of comparison operations for Arb complex boxes. ","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"In addition to the standard comparisons, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"isequal(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#isequal-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"isequal","text":"isequal(x::ComplexFieldElem, y::ComplexFieldElem)\n\nReturn true if the boxes x and y are precisely equal, i.e. their real and imaginary parts have the same midpoints and radii.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"A full range of ad hoc comparison operators is provided. These are implemented directly in Julia, but we document them as though only == were provided.","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Function\n==(x::ComplexFieldElem, y::Integer)\n==(x::Integer, y::ComplexFieldElem)\n==(x::ComplexFieldElem, y::ZZRingElem)\n==(x::ZZRingElem, y::ComplexFieldElem)\n==(x::arb, y::ZZRingElem)\n==(x::ZZRingElem, y::arb)\n==(x::ComplexFieldElem, y::Float64)\n==(x::Float64, y::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\nx = CC(\"1 +/- 0.001\")\ny = CC(\"3\")\nz = CC(\"4\")\n\nisequal(x, deepcopy(x))\nx == 3\nZZ(3) == z\nx != 1.23","category":"page"},{"location":"Nemo/complex/#Absolute-value","page":"Arbitrary precision complex balls","title":"Absolute value","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\nx = CC(\"-1 +/- 0.001\")\n\na = abs(x)","category":"page"},{"location":"Nemo/complex/#Shifting","page":"Arbitrary precision complex balls","title":"Shifting","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\nx = CC(\"-3 +/- 0.001\")\n\na = ldexp(x, 23)\nb = ldexp(x, -ZZ(15))","category":"page"},{"location":"Nemo/complex/#Miscellaneous-operations","page":"Arbitrary precision complex balls","title":"Miscellaneous operations","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"trim(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#trim-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"trim","text":"trim(x::ComplexFieldElem)\n\nReturn an acb box containing x but which may be more economical, by rounding off insignificant bits from midpoints.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"unique_integer(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#unique_integer-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"unique_integer","text":"unique_integer(x::ComplexFieldElem)\n\nReturn a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the box x contains a unique integer. If this is the case, the second return value is set to this unique integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\nx = CC(\"-3 +/- 0.001\", \"0.1\")\n\na = trim(x)\nb, c = unique_integer(x)\nd = conj(x)\nf = angle(x)","category":"page"},{"location":"Nemo/complex/#Constants","page":"Arbitrary precision complex balls","title":"Constants","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"const_pi(::ComplexField)","category":"page"},{"location":"Nemo/complex/#const_pi-Tuple{ComplexField}","page":"Arbitrary precision complex balls","title":"const_pi","text":"const_pi(r::ComplexField)\n\nReturn pi = 314159ldots as an element of r.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(200)\n\na = const_pi(CC)","category":"page"},{"location":"Nemo/complex/#Mathematical-and-special-functions","page":"Arbitrary precision complex balls","title":"Mathematical and special functions","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"rsqrt(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#rsqrt-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"rsqrt","text":"rsqrt(x::ComplexFieldElem)\n\nReturn the reciprocal of the square root of x, i.e. 1sqrtx.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"cispi(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#cispi-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"cispi","text":"cispi(x::ComplexFieldElem)\n\nReturn the exponential of pi i x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"root_of_unity(::ComplexField, k::Int)","category":"page"},{"location":"Nemo/complex/#root_of_unity-Tuple{ComplexField, Int64}","page":"Arbitrary precision complex balls","title":"root_of_unity","text":"root_of_unity(C::ComplexField, k::Int)\n\nReturn exp(2pi ik).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"log_sinpi(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#log_sinpi-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"log_sinpi","text":"log_sinpi(x::ComplexFieldElem)\n\nReturn logsin(pi x), constructed without branch cuts off the real line.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"gamma(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#gamma-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"gamma","text":"gamma(x::ComplexFieldElem)\n\nReturn the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"lgamma(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#lgamma-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"lgamma","text":"lgamma(x::ComplexFieldElem)\n\nReturn the logarithm of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"rgamma(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#rgamma-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"rgamma","text":"rgamma(x::ComplexFieldElem)\n\nReturn the reciprocal of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"digamma(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#digamma-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"digamma","text":"digamma(x::ComplexFieldElem)\n\nReturn the logarithmic derivative of the gamma function evaluated at x, i.e. psi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"zeta(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#zeta-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"zeta","text":"zeta(x::ComplexFieldElem)\n\nReturn the Riemann zeta function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"barnes_g(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#barnes_g-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"barnes_g","text":"barnes_g(x::ComplexFieldElem)\n\nReturn the Barnes G-function, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"log_barnes_g(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#log_barnes_g-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"log_barnes_g","text":"log_barnes_g(x::ComplexFieldElem)\n\nReturn the logarithm of the Barnes G-function, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"erf(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#erf-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"erf","text":"erf(x::ComplexFieldElem)\n\nReturn the error function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"erfi(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#erfi-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"erfi","text":"erfi(x::ComplexFieldElem)\n\nReturn the imaginary error function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"exp_integral_ei(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#exp_integral_ei-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"exp_integral_ei","text":"exp_integral_ei(x::ComplexFieldElem)\n\nReturn the exponential integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"sin_integral(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#sin_integral-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"sin_integral","text":"sin_integral(x::ComplexFieldElem)\n\nReturn the sine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"cos_integral(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#cos_integral-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"cos_integral","text":"cos_integral(x::ComplexFieldElem)\n\nReturn the exponential cosine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"sinh_integral(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#sinh_integral-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"sinh_integral","text":"sinh_integral(x::ComplexFieldElem)\n\nReturn the hyperbolic sine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"cosh_integral(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#cosh_integral-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"cosh_integral","text":"cosh_integral(x::ComplexFieldElem)\n\nReturn the hyperbolic cosine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"dedekind_eta(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#dedekind_eta-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"dedekind_eta","text":"dedekind_eta(x::ComplexFieldElem)\n\nReturn the Dedekind eta function eta(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"modular_weber_f(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#modular_weber_f-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"modular_weber_f","text":"modular_weber_f(x::ComplexFieldElem)\n\nReturn the modular Weber function mathfrakf(tau) = fraceta^2(tau)eta(tau2)eta(2tau) at x in the complex upper half plane.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"modular_weber_f1(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#modular_weber_f1-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"modular_weber_f1","text":"modular_weber_f1(x::ComplexFieldElem)\n\nReturn the modular Weber function mathfrakf_1(tau) = fraceta(tau2)eta(tau) at x in the complex upper half plane.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"modular_weber_f2(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#modular_weber_f2-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"modular_weber_f2","text":"modular_weber_f2(x::ComplexFieldElem)\n\nReturn the modular Weber function mathfrakf_2(tau) = fracsqrt2eta(2tau)eta(tau) at x in the complex upper half plane.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"j_invariant(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#j_invariant-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"j_invariant","text":"j_invariant(x::ComplexFieldElem)\n\nReturn the j-invariant j(tau) at tau = x.\n\n\n\n\n\nj_invariant(E::ProjEllipticCurve{S}) where S <: FieldElem\n\nReturn the j-invariant of the projective elliptic curve E.\n\n\n\n\n\nj_invariant(E::EllCrv) -> FieldElem\n\nCompute the j-invariant of E.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"modular_lambda(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#modular_lambda-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"modular_lambda","text":"modular_lambda(x::ComplexFieldElem)\n\nReturn the modular lambda function lambda(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"modular_delta(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#modular_delta-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"modular_delta","text":"modular_delta(x::ComplexFieldElem)\n\nReturn the modular delta function Delta(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"eisenstein_g(::Int, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#eisenstein_g-Tuple{Int64, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"eisenstein_g","text":"eisenstein_g(k::Int, x::ComplexFieldElem)\n\nReturn the non-normalized Eisenstein series G_k(tau) of mathrmSL_2(mathbbZ). Also defined for tau = i infty.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"hilbert_class_polynomial(::Int, ::ZZPolyRing)","category":"page"},{"location":"Nemo/complex/#hilbert_class_polynomial-Tuple{Int64, ZZPolyRing}","page":"Arbitrary precision complex balls","title":"hilbert_class_polynomial","text":"hilbert_class_polynomial(D::Int, R::ZZPolyRing)\n\nReturn in the ring R the Hilbert class polynomial of discriminant D, which is only defined for D 0 and D equiv 0 1 pmod 4.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"elliptic_k(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#elliptic_k-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"elliptic_k","text":"elliptic_k(x::ComplexFieldElem)\n\nReturn the complete elliptic integral K(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"elliptic_e(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#elliptic_e-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"elliptic_e","text":"elliptic_e(x::ComplexFieldElem)\n\nReturn the complete elliptic integral E(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"agm(::ComplexFieldElem)\nagm(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#agm-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"agm","text":"agm(x::ComplexFieldElem)\n\nReturn the arithmetic-geometric mean of 1 and x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/#agm-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"agm","text":"agm(x::ComplexFieldElem, y::ComplexFieldElem)\n\nReturn the arithmetic-geometric mean of x and y.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"polygamma(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#polygamma-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"polygamma","text":"polygamma(s::ComplexFieldElem, a::ComplexFieldElem)\n\nReturn the generalised polygamma function psi(sz).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"zeta(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#zeta-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"zeta","text":"zeta(s::ComplexFieldElem, a::ComplexFieldElem)\n\nReturn the Hurwitz zeta function zeta(sa).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"rising_factorial(::ComplexFieldElem, ::Int)","category":"page"},{"location":"Nemo/complex/#rising_factorial-Tuple{ComplexFieldElem, Int64}","page":"Arbitrary precision complex balls","title":"rising_factorial","text":"rising_factorial(x::ComplexFieldElem, n::Int)\n\nReturn the rising factorial x(x + 1)ldots (x + n - 1) as an Acb.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"rising_factorial2(::ComplexFieldElem, ::Int)","category":"page"},{"location":"Nemo/complex/#rising_factorial2-Tuple{ComplexFieldElem, Int64}","page":"Arbitrary precision complex balls","title":"rising_factorial2","text":"rising_factorial2(x::ComplexFieldElem, n::Int)\n\nReturn a tuple containing the rising factorial x(x + 1)ldots (x + n - 1) and its derivative.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"polylog(::Union{ComplexFieldElem,Int}, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#polylog-Tuple{Union{Int64, ComplexFieldElem}, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"polylog","text":"polylog(s::Union{ComplexFieldElem,Int}, a::ComplexFieldElem)\n\nReturn the polylogarithm Li_s(a).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"log_integral(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#log_integral-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"log_integral","text":"log_integral(x::ComplexFieldElem)\n\nReturn the logarithmic integral, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"log_integral_offset(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#log_integral_offset-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"log_integral_offset","text":"log_integral_offset(x::ComplexFieldElem)\n\nReturn the offset logarithmic integral, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"exp_integral_e(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#exp_integral_e-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"exp_integral_e","text":"exp_integral_e(s::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the generalised exponential integral E_s(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"gamma(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#gamma-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"gamma","text":"gamma(s::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the upper incomplete gamma function Gamma(sx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"gamma_regularized(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#gamma_regularized-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"gamma_regularized","text":"gamma_regularized(s::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the regularized upper incomplete gamma function Gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"gamma_lower(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#gamma_lower-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"gamma_lower","text":"gamma_lower(s::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"gamma_lower_regularized(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#gamma_lower_regularized-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"gamma_lower_regularized","text":"gamma_lower_regularized(s::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the regularized lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"airy_ai(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#airy_ai-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"airy_ai","text":"airy_ai(x::ComplexFieldElem)\n\nReturn the Airy function operatornameAi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"airy_ai_prime(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#airy_ai_prime-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"airy_ai_prime","text":"airy_ai_prime(x::ComplexFieldElem)\n\nReturn the derivative of the Airy function operatornameAi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"airy_bi(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#airy_bi-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"airy_bi","text":"airy_bi(x::ComplexFieldElem)\n\nReturn the Airy function operatornameBi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"airy_bi_prime(::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#airy_bi_prime-Tuple{ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"airy_bi_prime","text":"airy_bi_prime(x::ComplexFieldElem)\n\nReturn the derivative of the Airy function operatornameBi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"bessel_j(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#bessel_j-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"bessel_j","text":"bessel_j(nu::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the Bessel function J_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"bessel_y(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#bessel_y-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"bessel_y","text":"bessel_y(nu::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the Bessel function Y_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"bessel_i(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#bessel_i-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"bessel_i","text":"bessel_i(nu::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the Bessel function I_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"bessel_k(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#bessel_k-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"bessel_k","text":"bessel_k(nu::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the Bessel function K_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"hypergeometric_1f1(::ComplexFieldElem, ::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#hypergeometric_1f1-Tuple{ComplexFieldElem, ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"hypergeometric_1f1","text":"hypergeometric_1f1(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the confluent hypergeometric function _1F_1(abx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"hypergeometric_1f1_regularized(::ComplexFieldElem, ::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#hypergeometric_1f1_regularized-Tuple{ComplexFieldElem, ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"hypergeometric_1f1_regularized","text":"hypergeometric_1f1_regularized(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the regularized confluent hypergeometric function _1F_1(abx) Gamma(b).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"hypergeometric_u(::ComplexFieldElem, ::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#hypergeometric_u-Tuple{ComplexFieldElem, ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"hypergeometric_u","text":"hypergeometric_u(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)\n\nReturn the confluent hypergeometric function U(abx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"hypergeometric_2f1(::ComplexFieldElem, ::ComplexFieldElem, ::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#hypergeometric_2f1-NTuple{4, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"hypergeometric_2f1","text":"hypergeometric_2f1(a::ComplexFieldElem, b::ComplexFieldElem, c::ComplexFieldElem, x::ComplexFieldElem; flags=0)\n\nReturn the Gauss hypergeometric function _2F_1(abcx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"jacobi_theta(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#jacobi_theta-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"jacobi_theta","text":"jacobi_theta(z::ComplexFieldElem, tau::ComplexFieldElem)\n\nReturn a tuple of four elements containing the Jacobi theta function values theta_1 theta_2 theta_3 theta_4 evaluated at z tau.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"weierstrass_p(::ComplexFieldElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/complex/#weierstrass_p-Tuple{ComplexFieldElem, ComplexFieldElem}","page":"Arbitrary precision complex balls","title":"weierstrass_p","text":"weierstrass_p(z::ComplexFieldElem, tau::ComplexFieldElem)\n\nReturn the Weierstrass elliptic function wp(ztau).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(64)\n\ns = CC(1, 2)\nz = CC(\"1.23\", \"3.45\")\n\na = sin(z)^2 + cos(z)^2\nb = zeta(z)\nc = bessel_j(s, z)\nd = hypergeometric_1f1(s, s+1, z)","category":"page"},{"location":"Nemo/complex/#Linear-dependence","page":"Arbitrary precision complex balls","title":"Linear dependence","text":"","category":"section"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"lindep(::Vector{ComplexFieldElem}, n::Int)","category":"page"},{"location":"Nemo/complex/#lindep-Tuple{Vector{ComplexFieldElem}, Int64}","page":"Arbitrary precision complex balls","title":"lindep","text":"lindep(A::Vector{ComplexFieldElem}, bits::Int)\n\nFind a small linear combination of the entries of the array A that is small (using LLL). The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find linear dependence between a list of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"lindep(A::Matrix{ComplexFieldElem}, bits::Int)","category":"page"},{"location":"Nemo/complex/#lindep-Tuple{Matrix{ComplexFieldElem}, Int64}","page":"Arbitrary precision complex balls","title":"lindep","text":"lindep(A::Matrix{ComplexFieldElem}, bits::Int)\n\nFind a (common) small linear combination of the entries in each row of the array A, that is small (using LLL). It is assumed that the complex numbers in each row of the array share the same linear combination. The entries are first scaled by the given number of bits before truncating the real and imaginary parts to integers for use in LLL. This function can be used to find a common linear dependence shared across a number of lists of complex numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the common linear combination.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/complex/","page":"Arbitrary precision complex balls","title":"Arbitrary precision complex balls","text":"CC = ComplexField(128)\n\n# These are two of the roots of x^5 + 3x + 1\na = CC(1.0050669478588622428791051888364775253, - 0.93725915669289182697903585868761513585)\nb = CC(-0.33198902958450931620250069492231652319)\n\n# We recover the polynomial from one root....\nV1 = [CC(1), a, a^2, a^3, a^4, a^5];\nW = lindep(V1, 20)\n\n# ...or from two\nV2 = [CC(1), b, b^2, b^3, b^4, b^5];\nVs = [V1 V2]\nX = lindep(Vs, 20)","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Rings/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"The rings part of OSCAR provides functionality for handling various kinds of rings: ","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"the ring of integers\npolynomial rings (univariate and multivariate, see Generic univariate polynomial types and Generic sparse distributed multivariable polynomial types),\norders in number fields\nseries rings","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"...","category":"page"},{"location":"Rings/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"Claus Fieker,\nTommy Hofmann.","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"PolyhedralGeometry/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"The polyhedral geometry part of OSCAR provides functionality for handling","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"convex polytopes, unbounded polyhedra and cones\npolyhedral fans\nlinear programs","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Michael Joswig, Thorsten Theobald (2013)\nGünter M. Ziegler (1995)","category":"page"},{"location":"PolyhedralGeometry/intro/#Scalar-types","page":"Introduction","title":"Scalar types","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"The objects from polyhedral geometry operate on a given type, which (usually) resembles a field. This is indicated by the template parameter, e.g. the properties of a Polyhedron{QQFieldElem} are rational numbers of type QQFieldElem, if applicable. Supported scalar types are FieldElem and Float64, but some functionality might not work properly if the parent Field does not satisfy certain mathematic conditions, like being ordered. When constructing a polyhedral object from scratch, for the \"simpler\" types QQFieldElem and Float64 it suffices to pass the Type, but more complex FieldElems require a parent Field object. This can be set by either passing the desired Field instead of the type, or by inserting the type and have a matching FieldElem in your input data. If no type or field is given, the scalar type defaults to QQFieldElem.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"The parent Field of the coefficients of an object O with coefficients of type T can be retrieved with the coefficient_field function, and it holds elem_type(coefficient_field(O)) == T.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"coefficient_field(x::PolyhedralObject)","category":"page"},{"location":"PolyhedralGeometry/intro/#coefficient_field-Tuple{Oscar.PolyhedralObject}","page":"Introduction","title":"coefficient_field","text":"coefficient_field(P::Union{Polyhedron{T}, Cone{T}, PolyhedralFan{T}, PolyhedralComplex{T}) where T<:scalar_types\n\nReturn the parent Field of the coefficients of P.\n\nExamples\n\njulia> c = cross_polytope(2)\nPolyhedron in ambient dimension 2\n\njulia> coefficient_field(c)\nRational field\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"warning: Warning\nSupport for fields other than the rational numbers is currently in an experimental stage.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"These three lines result in the same polytope over rational numbers. Besides the general support mentioned above, naming a Field explicitly is encouraged because it allows user control and increases efficiency.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"julia> P = convex_hull(QQ, [1 0 0; 0 0 1]) # passing a `Field` always works\nPolyhedron in ambient dimension 3\n\njulia> P == convex_hull(QQFieldElem, [1 0 0; 0 0 1]) # passing the type works for `QQFieldElem` and `Float64` only\ntrue\n\njulia> P == convex_hull([1 0 0; 0 0 1]) # `Field` defaults to `QQ`\ntrue\n","category":"page"},{"location":"PolyhedralGeometry/intro/#Type-compatibility","page":"Introduction","title":"Type compatibility","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"When working in polyhedral geometry it can prove advantageous to have various input formats for the same kind of re-occurring quantitative input information. This example shows three different ways to write the points whose convex hull is to be computed, all resulting in identical Polyhedron objects:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"julia> P = convex_hull([1 0 0; 0 0 1])\nPolyhedron in ambient dimension 3\n\njulia> P == convex_hull([[1, 0, 0], [0, 0, 1]])\ntrue\n\njulia> P == convex_hull(vertices(P))\ntrue","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"convex_hull is only one of many functions and constructors supporting this behavior, and there are also more types that can be described this way besides PointVector. Whenever the docs state an argument is required to be of type AbstractCollection[ElType] (where ElType is the Oscar type of single instances described in this collection), the user can choose the input to follow any of the corresponding notions below.","category":"page"},{"location":"PolyhedralGeometry/intro/#Vectors","page":"Introduction","title":"Vectors","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"While RayVectors can not be used do describe PointVectors (and vice versa), matrices are generally allowed.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"AbstractCollection[PointVector] can be given as:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Type A PointVector corresponds to...\nAbstractVector{<:ṔointVector} an element of the vector.\nAbstractVector{<:AbstractVector} an element of the vector.\nAbstractMatrix/MatElem a row of the matrix.\nAbstractVector/PointVector the vector itself (only one PointVector is described).\nSubObjectIterator{<:PointVector} an element of the iterator.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"AbstractCollection[RayVector] can be given as:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Type A RayVector corresponds to...\nAbstractVector{<:RayVector} an element of the vector.\nAbstractVector{<:AbstractVector} an element of the vector.\nAbstractMatrix/MatElem a row of the matrix.\nAbstractVector/RayVector the vector itself (only one RayVector is described).\nSubObjectIterator{<:RayVector} an element of the iterator.","category":"page"},{"location":"PolyhedralGeometry/intro/#Halfspaces-and-Hyperplanes","page":"Introduction","title":"Halfspaces and Hyperplanes","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"These collections allow to mix up affine halfspaces/hyperplanes and their linear counterparts, but note that an error will be produced when trying to convert an affine description with bias not equal to zero to a linear description.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"AbstractCollection[LinearHalfspace] can be given as:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Type A LinearHalfspace corresponds to...\nAbstractVector{<:Halfspace} an element of the vector.\nAbstractMatrix/MatElem A the halfspace with normal vector A[i, :].\nAbstractVector{<:AbstractVector} A the halfspace with normal vector A[i].\nSubObjectIterator{<:Halfspace} an element of the iterator.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"AbstractCollection[LinearHyperplane] can be given as:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Type A LinearHyperplane corresponds to...\nAbstractVector{<:Hyperplane} an element of the vector.\nAbstractMatrix/MatElem A the hyperplane with normal vector A[i, :].\nAbstractVector{<:AbstractVector} A the hyperplane with normal vector A[i].\nSubObjectIterator{<:Hyperplane} an element of the iterator.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"AbstractCollection[AffineHalfspace] can be given as:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Type An AffineHalfspace corresponds to...\nAbstractVector{<:Halfspace} an element of the vector.\nTuple over matrix A and vector b the affine halfspace with normal vector A[i, :] and bias b[i].\nSubObjectIterator{<:Halfspace} an element of the iterator.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"AbstractCollection[AffineHyperplane] can be given as:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Type An AffineHyperplane corresponds to...\nAbstractVector{<:Hyperplane} an element of the vector.\nTuple over matrix A and vector b the affine hyperplane with normal vector A[i, :] and bias b[i].\nSubObjectIterator{<:Hyperplane} an element of the iterator.","category":"page"},{"location":"PolyhedralGeometry/intro/#IncidenceMatrix","page":"Introduction","title":"IncidenceMatrix","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Some methods will require input or return output in form of an IncidenceMatrix.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"IncidenceMatrix","category":"page"},{"location":"PolyhedralGeometry/intro/#IncidenceMatrix","page":"Introduction","title":"IncidenceMatrix","text":" IncidenceMatrix\n\nA matrix with boolean entries. Each row corresponds to a fixed element of a collection of mathematical objects and the same holds for the columns and a second (possibly equal) collection. A 1 at entry (i, j) is interpreted as an incidence between object i of the first collection and object j of the second one.\n\nExamples\n\nNote that the input and print of an IncidenceMatrix lists the non-zero indices for each row.\n\njulia> IM = IncidenceMatrix([[1,2,3],[4,5,6]])\n2×6 IncidenceMatrix\n[1, 2, 3]\n[4, 5, 6]\n\n\njulia> IM[1, 2]\ntrue\n\njulia> IM[2, 3]\nfalse\n\njulia> IM[:, 4]\n2-element SparseVectorBool\n[2]\n\n\n\n\n\n","category":"type"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"From the example it can be seen that this type supports julia's matrix functionality. There are also functions to retrieve specific rows or columns as a Set over the non-zero indices.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"row(i::IncidenceMatrix, n::Int)\ncolumn(i::IncidenceMatrix, n::Int)","category":"page"},{"location":"PolyhedralGeometry/intro/#row-Tuple{IncidenceMatrix, Int64}","page":"Introduction","title":"row","text":" row(i::IncidenceMatrix, n::Int)\n\nReturn the indices where the n-th row of i is true, as a Set{Int}.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[4,5,6]])\n2×6 IncidenceMatrix\n[1, 2, 3]\n[4, 5, 6]\n\n\njulia> row(IM, 2)\nSet{Int64} with 3 elements:\n 5\n 4\n 6\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/intro/#column-Tuple{IncidenceMatrix, Int64}","page":"Introduction","title":"column","text":" column(i::IncidenceMatrix, n::Int)\n\nReturn the indices where the n-th column of i is true, as a Set{Int}.\n\nExamples\n\njulia> IM = IncidenceMatrix([[1,2,3],[4,5,6]])\n2×6 IncidenceMatrix\n[1, 2, 3]\n[4, 5, 6]\n\n\njulia> column(IM, 5)\nSet{Int64} with 1 element:\n 2\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"A typical application is the assignment of rays to the cones of a polyhedral fan for its construction, see polyhedral_fan.","category":"page"},{"location":"PolyhedralGeometry/intro/#Visualization","page":"Introduction","title":"Visualization","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Lower dimensional polyhedral objects can be visualized through polymake's backend.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"visualize(P::PolyhedralObject{T}) where T<:Union{QQFieldElem, Float64}","category":"page"},{"location":"PolyhedralGeometry/intro/#visualize-Union{Tuple{Oscar.PolyhedralObject{T}}, Tuple{T}} where T<:Union{Float64, QQFieldElem}","page":"Introduction","title":"visualize","text":"visualize(P::Union{Polyhedron{T}, Cone{T}, PolyhedralFan{T}, PolyhedralComplex{T}}) where T<:Union{QQFieldElem, Float64}\n\nVisualize a polyhedral object of dimension at most four (in 3-space). In dimensions up to 3 a usual embedding is shown. Four-dimensional polytopes are visualized as a Schlegel diagram, which is a projection onto one of the facets; e.g., see Chapter 5 of Günter M. Ziegler (1995).\n\nIn higher dimensions there is no standard method; use projections to lower dimensions or try ideas from Ewgenij Gawrilow, Michael Joswig, Thilo Rörig, Nikolaus Witte (2010).\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/intro/#Serialization","page":"Introduction","title":"Serialization","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Most objects from the polyhedral geometry section can be saved through the polymake interface in the background. These functions are documented in the subsections on the different objects. The format of the files is JSON and you can find details of the specification here.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"More details on the serialization, albeit concerning the older XML format, can be found in Ewgenij Gawrilow, Simon Hampe, Michael Joswig (2016). Even though the underlying format changed to JSON, the abstract mathematical structure of the data files is still the same.","category":"page"},{"location":"PolyhedralGeometry/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Taylor Brysiewicz,\nMichael Joswig,\nLars Kastner,\nBenjamin Lorenz.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"#Welcome-to-OSCAR","page":"Welcome to OSCAR","title":"Welcome to OSCAR","text":"","category":"section"},{"location":"","page":"Welcome to OSCAR","title":"Welcome to OSCAR","text":"OSCAR is a new computer algebra system. OSCAR features functions for groups, rings, and fields as well as linear and commutative algebra, number theory, algebraic and polyhedral geometry, and more. It is built upon several well established systems for mathematical research joined via the Julia programming language. Have a look at our Architecture page for a detailed overview and at our installation instructions for installing OSCAR.","category":"page"},{"location":"","page":"Welcome to OSCAR","title":"Welcome to OSCAR","text":"If you have questions about OSCAR, please have a look at our Frequently Asked Questions and feel free to contact us under the channels mentioned on our community page. Our main communication channels are Slack and Github.","category":"page"},{"location":"","page":"Welcome to OSCAR","title":"Welcome to OSCAR","text":"If you are a new developer or interested in developing OSCAR, have a look at our Introduction for new developers.","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/#Subdivisions-of-Points","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"","category":"section"},{"location":"PolyhedralGeometry/subdivisions_of_points/#Introduction","page":"Subdivisions of Points","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"Let mathbbF be an ordered field; the default is that mathbbF=mathbbQ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"A subdivision of points consists of","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"a finite set mathcalPsubseteqmathbbF^n of points; and\na finite set of cells mathcalSsubseteq 2^mathcalP.","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"The cells are only allowed to intersect in common faces. In contrast to the maximal cones of a polyhedral fan or the maximal polytopes of a polyhedral complex, cells are allowed to have interior points here, i.e. they are not given in terms of their vertices.","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/#Construction","page":"Subdivisions of Points","title":"Construction","text":"","category":"section"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"There are two ways to construct a subdivision of points. First, one can specify the cells directly. Second, one can assign a weight or height to every point, take the convex hull and take the cells corresponding to facets visible from below (\"lower envelope\"). Not every subdivision of points comes from a weight vector, but if it does, it is called regular.","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"subdivision_of_points(::Type{T}, Points::Union{Oscar.MatElem,AbstractMatrix}, Incidence::IncidenceMatrix) where T<:scalar_types\nsubdivision_of_points(::Type{T}, Points::Union{Oscar.MatElem,AbstractMatrix}, Weights::AbstractVector) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/#subdivision_of_points-Union{Tuple{T}, Tuple{Type{T}, Union{MatElem, AbstractMatrix}, IncidenceMatrix}} where T<:Union{Float64, FieldElem}","page":"Subdivisions of Points","title":"subdivision_of_points","text":"subdivision_of_points([f = QQFieldElem,] points, cells)\n\nArguments\n\nf::Union{Type{T}, Field}: either specifies the Type of its coefficients or their\n\nparent Field.\n\npoints::AbstractCollection[PointVector]: Points generating the cells of the subdivision; encoded row-wise as representative vectors.\ncells::IncidenceMatrix: An incidence matrix; there is a 1 at position (i,j) if cell i contains point j, and 0 otherwise.\n\nA subdivision of points formed from points and cells made of these points. The cells are given as an IncidenceMatrix, where the columns represent the points and the rows represent the cells.\n\nExamples\n\nThe following is the famous \"mother of all examples\" (MOAE) non-regular triangulation.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);\n\njulia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0)\nSubdivision of points in ambient dimension 3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/subdivisions_of_points/#subdivision_of_points-Union{Tuple{T}, Tuple{Type{T}, Union{MatElem, AbstractMatrix}, AbstractVector}} where T<:Union{Float64, FieldElem}","page":"Subdivisions of Points","title":"subdivision_of_points","text":"subdivision_of_points([f = QQFieldElem,] points, weights)\n\nArguments\n\nf::Union{Type{T}, Field}: either specifies the Type of its coefficients or their\n\nparent Field.\n\npoints::AbstractCollection[PointVector]: Points generating the cells of the subdivision; encoded row-wise as representative vectors.\nweights::AbstractVector: A vector with one entry for every point indicating the height of this point.\n\nA subdivision of points formed by placing every point at the corresponding height, then taking the convex hull and then only considering those cells corresponding to faces visible from below (\"lower envelope\").\n\nExamples\n\nWe use the MOAE points, but give a weight vector instead of cells:\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1])\nSubdivision of points in ambient dimension 3\n\njulia> n_maximal_cells(SOP)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"From a subdivision of points one can construct the secondary_cone(SOP::SubdivisionOfPoints), i.e. the cone that is the closure of the set of all weight vectors realizing that subdivision.","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/#Auxiliary-functions","page":"Subdivisions of Points","title":"Auxiliary functions","text":"","category":"section"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"ambient_dim(SOP::SubdivisionOfPoints)\nis_regular(SOP::SubdivisionOfPoints)\nmaximal_cells\nmin_weights\nn_maximal_cells(SOP::SubdivisionOfPoints)\npoints(SOP::SubdivisionOfPoints)\nsecondary_cone","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/#ambient_dim-Tuple{SubdivisionOfPoints}","page":"Subdivisions of Points","title":"ambient_dim","text":"ambient_dim(SOP::SubdivisionOfPoints)\n\nReturn the ambient dimension SOP, which is the dimension of the embedding space.\n\nExamples\n\nThe ambient dimension of the MOAE is 3, independent of the subdivision chosen.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);\n\njulia> ambient_dim(SOP)\n3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/subdivisions_of_points/#is_regular-Tuple{SubdivisionOfPoints}","page":"Subdivisions of Points","title":"is_regular","text":"is_regular(SOP::SubdivisionOfPoints)\n\nDetermine whether SOP is regular, i.e. can be given via a height function.\n\nExamples\n\nThis is the so-called \"mother of all examples\", a very famous non-regular triangulation of six points.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);\n\njulia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0);\n\njulia> is_regular(MOAE)\nfalse\n\njulia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);\n\njulia> is_regular(SOP)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/subdivisions_of_points/#maximal_cells","page":"Subdivisions of Points","title":"maximal_cells","text":"maximal_cells(SOP::SubdivisionOfPoints)\n\nReturn an iterator over the maximal cells of SOP.\n\nExamples\n\nDisplay the cells of the \"mother of all examples\" non-regular triangulation.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2]\n6×3 Matrix{Int64}:\n 4 0 0\n 0 4 0\n 0 0 4\n 2 1 1\n 1 2 1\n 1 1 2\n\njulia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]])\n7×6 IncidenceMatrix\n[4, 5, 6]\n[1, 2, 4]\n[2, 4, 5]\n[2, 3, 5]\n[3, 5, 6]\n[1, 3, 6]\n[1, 4, 6]\n\n\njulia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0);\n\njulia> maximal_cells(MOAE)\n7-element SubObjectIterator{Vector{Int64}}:\n [4, 5, 6]\n [1, 2, 4]\n [2, 4, 5]\n [2, 3, 5]\n [3, 5, 6]\n [1, 3, 6]\n [1, 4, 6]\n\n\n\n\n\nmaximal_cells(IncidenceMatrix, SOP::SubdivisionOfPoints)\n\nReturn the maximal cells of SOP as an incidence matrix.\n\nThe rows of the output correspond to the maximal cells and the columns correspond to the cells.\n\nExamples\n\nIf we give all points the same weight there is only one cell containing all points.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2]\n6×3 Matrix{Int64}:\n 4 0 0\n 0 4 0\n 0 0 4\n 2 1 1\n 1 2 1\n 1 1 2\n\njulia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1])\nSubdivision of points in ambient dimension 3\n\njulia> maximal_cells(IncidenceMatrix, SOP)\n1×6 IncidenceMatrix\n[1, 2, 3, 4, 5, 6]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/subdivisions_of_points/#min_weights","page":"Subdivisions of Points","title":"min_weights","text":"min_weights(SOP::SubdivisionOfPoints)\n\nReturn the minimal weights inducing a subdivision of points. This method will give an error if the input subdivision is non-regular.\n\nExamples\n\nIf all points have the same weight, then the 0-vector is minimal.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);\n\njulia> min_weights(SOP)\n6-element Vector{Int64}:\n 0\n 0\n 0\n 0\n 0\n 0\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/subdivisions_of_points/#n_maximal_cells-Tuple{SubdivisionOfPoints}","page":"Subdivisions of Points","title":"n_maximal_cells","text":"n_maximal_cells(SOP::SubdivisionOfPoints)\n\nReturn the number of maximal cells of SOP.\n\nExamples\n\nIf all points have the same weight, there is only one cell.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> SOP = subdivision_of_points(moaepts, [1,1,1,1,1,1]);\n\njulia> n_maximal_cells(SOP)\n1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/subdivisions_of_points/#points-Tuple{SubdivisionOfPoints}","page":"Subdivisions of Points","title":"points","text":"points(SOP::SubdivisionOfPoints)\n\nReturn the points of the subdivision of points, SOP.\n\nExamples\n\nDisplay the points of the \"mother of all examples\" non-regular triangulation.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);\n\njulia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0);\n\njulia> points(MOAE)\n6-element SubObjectIterator{PointVector{QQFieldElem}}:\n [4, 0, 0]\n [0, 4, 0]\n [0, 0, 4]\n [2, 1, 1]\n [1, 2, 1]\n [1, 1, 2]\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/subdivisions_of_points/#secondary_cone","page":"Subdivisions of Points","title":"secondary_cone","text":"secondary_cone(SOP::SubdivisionOfPoints)\n\nReturn the secondary cone of a subdivision of points, the closure of all the weight vectors inducing the given subdivision of points.\n\nExamples\n\nFor a non-regular subdivision, the secondary cone can still contain non-trivial weights, but it will not be full-dimensional.\n\njulia> moaepts = [4 0 0; 0 4 0; 0 0 4; 2 1 1; 1 2 1; 1 1 2];\n\njulia> moaeimnonreg0 = IncidenceMatrix([[4,5,6],[1,4,2],[2,4,5],[2,3,5],[3,5,6],[1,3,6],[1,4,6]]);\n\njulia> MOAE = subdivision_of_points(moaepts, moaeimnonreg0)\nSubdivision of points in ambient dimension 3\n\njulia> C = secondary_cone(MOAE)\nPolyhedral cone in ambient dimension 6\n\njulia> dim(C)\n4\n\n\n\n\n\n","category":"function"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Rings/rational/#Rationals","page":"Rationals","title":"Rationals","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Fractions are created in Julia with the double slash operator //. If a fraction is created from Julia integers, a Julia fraction results, and if either the numerator or denominator is an OSCAR integer of type ZZRingElem, an OSCAR fraction of type QQFieldElem results.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Julia has its own parameterised type Rational{T} for its own fractions, where T is the integer type of the numerator and denominator, e.g. Rational{Int} and Rational{BigInt}. Unlike with Int, all of the basic arithmetic operations on Julia's Rational{Int} are checked for overflow in the numerator and denominator.","category":"page"},{"location":"Rings/rational/#The-field-of-rationals","page":"Rationals","title":"The field of rationals","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"The parent of an OSCAR rational number is the field of rationals. It can be constructed from the ring of integers ZZ using the fraction_field constructor.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"For convenience, QQ is already defined to be the field of rational numbers.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> S = fraction_field(ZZ)\nRational field\n\njulia> QQ\nRational field\n","category":"page"},{"location":"Rings/rational/#Integer-constructors","page":"Rationals","title":"Integer constructors","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"OSCAR rationals can be created using QQ. Two arguments can be passed to specify numerator and denominator. If a single argument is passed, the denominator is set to 1.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"For convenience, QQ also accepts Julia integers and rationals, but will always construct an OSCAR rational.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Naturally, Julia's double slash operator can also be used to construct fractions. However, unlike QQ, the double slash operator only constructs an OSCAR rational if either the numerator or denominator is an OSCAR integer.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"An exception is raised if a fraction is constructed with denominator zero.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> QQ(1, 2)\n1//2\n\njulia> QQ(5)\n5\n\njulia> ZZ(3)//5\n3//5\n\njulia> 1//ZZ(7)\n1//7\n\njulia> QQ(2//3)\n2//3\n\njulia> ZZ(3)//0\nERROR: DivideError: integer division error\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"One can also construct the rational number 0 with the empty constructor:","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> QQ()\n0\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"The following special constructors are also provided:","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"zero(QQ)\none(QQ)","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> zero(QQ)\n0\n\njulia> one(QQ)\n1\n","category":"page"},{"location":"Rings/rational/#Predicates","page":"Rationals","title":"Predicates","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"iszero(n::QQFieldElem) -> Bool\nisone(n::QQFieldElem) -> Bool\nis_unit(n::QQFieldElem) -> Bool","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"The is_unit function will return true iff n neq 0.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> iszero(QQ())\ntrue\n\njulia> isone(one(QQ))\ntrue\n\njulia> is_unit(QQ(-2, 3))\ntrue\n","category":"page"},{"location":"Rings/rational/#Properties","page":"Rationals","title":"Properties","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"numerator(n::QQFieldElem) -> ZZRingElem\ndenominator(n::QQFieldElem) -> ZZRingElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the numerator and denominator respectively, of n.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"sign(n::QQFieldElem) -> QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the sign of n, i.e. nn if n neq 0, or 0 otherwise.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> sign(QQ(2, 3))\n1\n\njulia> sign(QQ())\n0\n\njulia> sign(QQ(-1))\n-1\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"abs(n::QQFieldElem) -> QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the absolute value of n, i.e. n if n geq 0 and -n otherwise.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> abs(QQ(-3, 2))\n3//2\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"height(n::QQFieldElem) -> ZZRingElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the maximum of the absolute values of the numerator and denominator of n.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> height(QQ(324987329, -8372492324))\n8372492324\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"floor(n::QQFieldElem) -> QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the greatest integer m (as a rational number) such that m leq n.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"ceil(n::QQFieldElem) -> QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the least integer m (as a rational number) such that m geq n.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> floor(QQ(-2, 3))\n-1\n\njulia> ceil(QQ(7, 2))\n4\n\njulia> typeof(ans)\nQQFieldElem\n\njulia> ceil(QQ(5))\n5\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"floor(ZZRingElem, n::QQFieldElem) -> ZZRingElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the greatest integer m such that m leq n.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"ceil(ZZRingElem, n::QQFieldElem) -> ZZRingElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the least integer m such that m geq n.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> floor(ZZRingElem, QQ(-2, 3))\n-1\n\njulia> ceil(ZZRingElem, QQ(7, 2))\n4\n\njulia> typeof(ans)\nZZRingElem\n\njulia> ceil(ZZRingElem, QQ(5))\n5\n","category":"page"},{"location":"Rings/rational/#Basic-arithmetic","page":"Rationals","title":"Basic arithmetic","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"OSCAR provides the basic arithmetic operations +, - and * and comparison operators ==, !=, <, <=, >, >=, including mixed operations between Julia and OSCAR rationals and integers.","category":"page"},{"location":"Rings/rational/#[Exact-Division]","page":"Rationals","title":"[Exact Division]","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"divexact(a::QQFieldElem, b::QQFieldElem) -> QQFieldElem\ndivexact(a::QQFieldElem, b::Union{ZZRingElem,Base.Integer,Base.Rational}) -> QQFieldElem\ndivexact(a::Union{ZZRingElem,Base.Integer,Base.Rational}, b::QQFieldElem) -> QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the quotient of a by b. Exact division raises an exception if division by zero is attempted.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> divexact(QQ(2, 3), QQ(3, 5))\n10//9\n\njulia> divexact(QQ(1, 3), ZZ(0))\nERROR: DivideError: integer division error\n\njulia> divexact(QQ(3, 4), ZZ(5))\n3//20\n\njulia> divexact(ZZ(6), QQ(2, 3))\n9\n\njulia> divexact(QQ(1, 3), 5)\n1//15\n","category":"page"},{"location":"Rings/rational/#Powering","page":"Rationals","title":"Powering","text":"","category":"section"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"^(a::QQFieldElem, b::Int) -> QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Return the result of powering a by b.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> QQ(5, 7)^32\n23283064365386962890625//1104427674243920646305299201\n\njulia> QQ(1, 2)^(-2)\n4\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"The following is allowed for convenience.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> QQ(0)^0\n1\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"note: Note\nIn Julia, the rational number 01 when raised to a negative power returns 10 to indicate that the value is undefined. OSCAR raises an exception.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> QQ(0)^-2\nERROR: DivideError: integer division error\n","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"is_power(a::QQFieldElem, b::Int) -> Bool, QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Test if a is an n-th power. If so, return true and the root, false and any rational otherwise.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"is_power(a::QQFieldElem) -> Int, QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Find the largest n such that a is an n-th power. Return n and the root.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"root(a::QQFieldElem, b::Int) -> QQFieldElem","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"Compute an n-th root of a, raises an error if a is not an n-th power.","category":"page"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"julia> is_power(QQ(8), 3)\n(true, 2)\n\njulia> is_power(QQ(8), 2)\n(false, 8)\n\njulia> is_power(QQ(9//16))\n(2, 3//4)\n\njulia> root(QQ(25//9), 2)\n5//3\n","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#Automorphism-Groups-of-K3-surfaces","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"A complex K3 surface is a compact complex surface X with vanishing irregularity h^1(X mathcalO_X)=0 and trivial canonical bundle mathcalO_Xcong omega_X.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"Much of the theory of (complex) K3 surfaces is governed by its Hodge structure and the mathbbZ-lattices NS(X) subseteq H^2(X mathbbZ).","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"See Daniel Huybrechts (2016) for the theory of K3 surfaces.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#Automorphisms","page":"Automorphism Groups of K3 surfaces","title":"Automorphisms","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"K3_surface_automorphism_group(S::ZZLat)\nborcherds_method\nK3Chamber\nchamber(data::BorcherdsCtx, weyl_vector::ZZMatrix, parent_wall::ZZMatrix=zero_matrix(ZZ, 0, 0))\nweyl_vector(D::K3Chamber)\nwalls(::K3Chamber)\ninner_point(::K3Chamber)\nrays(::K3Chamber)\naut(::K3Chamber)\nhom(::K3Chamber,::K3Chamber)\nadjacent_chamber(D::K3Chamber, v::ZZMatrix)\nseparating_hyperplanes(S::ZZLat, v::QQMatrix, h::QQMatrix, d)\nhas_zero_entropy","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#K3_surface_automorphism_group-Tuple{ZZLat}","page":"Automorphism Groups of K3 surfaces","title":"K3_surface_automorphism_group","text":"K3_surface_automorphism_group(S::ZZLat [, ample_class]) -> generators, rational curves, chambers\n\nCompute the automorphism group of a very-general S-polarized K3 surface.\n\nFurther return representatives of the mathrmAut(X)-orbits of (-2)-curves on X and a fundamental domain for the action of mathrmAut(X) on the set of nef L|S chambers. This is almost a fundamental domain for mathrmAut(X) on the nef cone.\n\nHere very general means that Num(X) is isomorphic to S and the image of mathrmAut(X) to H^0(XOmega^2_X) is $ \\pm 1$.\n\nThe function returns generators for the image of\n\nfcolon mathrmAut(X) to O(Num(X))\n\nThe output is represented with respect to the basis of S.\n\nNote that under our genericity assumptions the kernel of f is of order at most 2 and it is equal to 2 if and only if S is 2-elementary. If an ample class is given, then the generators returned preserve it.\n\nThis kind of computation can be very expensive. To print progress information use set_verbose_level(:K3Auto, 2) or higher.\n\nInput\n\nS: a hyperbolic lattice\nample: a row matrix or a vector given with respect to the ambient space of S.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#borcherds_method","page":"Automorphism Groups of K3 surfaces","title":"borcherds_method","text":"borcherds_method(S::ZZLat, n::Integer; compute_OR=true, entropy_abort=false, max_nchambers=-1)\nborcherds_method(L::ZZLat, S::ZZLat, w::QQMatrix; compute_OR=true, entropy_abort=false, max_nchambers=-1)\n\nCompute the symmetry group of a Weyl chamber up to finite index.\n\nArguments\n\nw: initial Weyl row vector represented with respect to the basis of L;\nL: even, unimodular, hyperbolic lattice of rank n=10,18 or 26;\nS: a primitive sublattice of L;\ncompute_OR=true: if false take as G all isometries of S extending to L;\nmax_nchambers: break the computation after max_nchambers are found;\nentropy_abort abort if an automorphism of positive entropy is found.\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#K3Chamber","page":"Automorphism Groups of K3 surfaces","title":"K3Chamber","text":"K3Chamber\n\nThe LS chamber induced from a Weyl vector in L.\n\nLet L be an even, unimodular and hyperbolic lattice of rank 10, 18 or 26 and S be a primitive sublattice. Any Weyl vector w of L defines a Weyl chamber C(w) in the positive cone of L. The Weyl chamber is a rational locally polyhedral cone with infinitely many facets, i.e. walls. It is the intersection of the positive half-spaces defined by Delta_L(w) = r in L r^2=-2 rw = 1. We have\n\nC(w)=x in mathcalP_L forall r in Delta_L(w) xr geq 0\n\nThe Weyl chamber is a fundamental domain for the action of the Weyl group on the positive cone. We say that S otimes mathbbR cap C(w) is the LS-chamber induced by w.\n\nNote that two Weyl vectors induce the same chamber if and only if their orthogonal projections to S coincide.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#chamber","page":"Automorphism Groups of K3 surfaces","title":"chamber","text":"chamber(data::BorcherdsCtx, weyl_vector::ZZMatrix, [parent_wall::ZZMatrix, walls::Vector{ZZMatrix}])\n\nReturn the LS-chamber with the given Weyl vector.\n\nThe lattices L and S are stored in data. Via the parent walls we can obtain a spanning tree of the chamber graph.\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#weyl_vector-Tuple{K3Chamber}","page":"Automorphism Groups of K3 surfaces","title":"weyl_vector","text":"weyl_vector(D::K3Chamber) -> ZZMatrix\n\nReturn the Weyl vector defining this chamber.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#walls-Tuple{K3Chamber}","page":"Automorphism Groups of K3 surfaces","title":"walls","text":"walls(D::K3Chamber) -> Vector{ZZMatrix}\n\nReturn the walls of the chamber D, i.e. its facets.\n\nThe corresponding half space of the wall defined by v in walls(D) is\n\nx in S otimes mathbbR langle xv rangle geq 0\n\nv is given with respect to the basis of S and is primitive in S.\n\nNote that Ichiro Shimada (2015) follows a different convention and takes v primitive in S^\\vee.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#inner_point-Tuple{K3Chamber}","page":"Automorphism Groups of K3 surfaces","title":"inner_point","text":"inner_point(L::ZZLat, S::ZZLat, w::QQMatrix)\ninner_point(C::K3Chamber)\n\nReturn a reasonably small integer inner point of the given L|S chamber.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#rays-Tuple{K3Chamber}","page":"Automorphism Groups of K3 surfaces","title":"rays","text":"rays(D::K3Chamber)\n\nReturn the rays of the chamber D.\n\nThey are represented as primitive row vectors with respect to the basis of S.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#aut-Tuple{K3Chamber}","page":"Automorphism Groups of K3 surfaces","title":"aut","text":"aut(E::K3Chamber) -> Vector{ZZMatrix}\n\nReturn the stabilizer mathrmAut_G(E) of E in G.\n\nThe elements are represented with respect to the basis of S.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#hom-Tuple{K3Chamber, K3Chamber}","page":"Automorphism Groups of K3 surfaces","title":"hom","text":"hom(D::K3Chamber, E::K3Chamber) -> Vector{ZZMatrix}\n\nReturn the set mathrmHom_G(D E) of elements of G mapping D to E.\n\nThe elements are represented with respect to the basis of S.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#adjacent_chamber-Tuple{K3Chamber, ZZMatrix}","page":"Automorphism Groups of K3 surfaces","title":"adjacent_chamber","text":"adjacent_chamber(D::K3Chamber, v::ZZMatrix) -> K3Chamber\n\nReturn return the LS chamber adjacent to D via the wall defined by v.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#separating_hyperplanes-Tuple{ZZLat, QQMatrix, QQMatrix, Any}","page":"Automorphism Groups of K3 surfaces","title":"separating_hyperplanes","text":"separating_hyperplanes(S::ZZLat, v::QQMatrix, h::QQMatrix, d)\n\nReturn x in S x^2=d xv0 xh0.\n\nArguments\n\nS: a hyperbolic lattice\nd: a negative integer\nv,h: vectors of positive square\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#has_zero_entropy","page":"Automorphism Groups of K3 surfaces","title":"has_zero_entropy","text":"has_zero_entropy(S::ZZLat; rank_unimod=26) ->\n\nCompute if the symmetry group of a Weyl chamber is elliptic, parabolic or hyperbolic.\n\nOutput\n\n1 - elliptic – the symmetry group is finite\n0 - parabolic – there is a unique cusp with infinite stabilizer\n-1 - hyperbolic – positive entropy\n\nThis calls borcherds_method and breaks the computation as soon as a symmetry of a Weyl chamber with positive entrop is found.\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/#Contact","page":"Automorphism Groups of K3 surfaces","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"Simon Brandhorst.\nMatthias Zach,","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/K3Surfaces/","page":"Automorphism Groups of K3 surfaces","title":"Automorphism Groups of K3 surfaces","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/ring/#Ring-functionality","page":"Ring functionality","title":"Ring functionality","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"AbstractAlgebra has both commutative and noncommutative rings. Together we refer to them below as rings.","category":"page"},{"location":"AbstractAlgebra/ring/#Abstract-types-for-rings","page":"Ring functionality","title":"Abstract types for rings","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"All commutative ring types in AbstractAlgebra belong to the Ring abstract type and commutative ring elements belong to the RingElem abstract type.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Noncommutative ring types belong to the NCRing abstract type and their elements to NCRingElem.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"As Julia types cannot belong to our RingElem type hierarchy, we also provide the union type RingElement which includes RingElem in union with the Julia types Integer, Rational and AbstractFloat.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Similarly NCRingElement includes the Julia types just mentioned in union with NCRingElem.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Note that","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Ring <: NCRing\nRingElem <: NCRingElem\nRingElement <: NCRingElement","category":"page"},{"location":"AbstractAlgebra/ring/#Functions-for-types-and-parents-of-rings","page":"Ring functionality","title":"Functions for types and parents of rings","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"parent_type(::Type{T}) where T <: NCRingElement\nelem_type(::Type{T}) where T <: NCRing","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Return the type of the parent (resp. element) type corresponding to the given ring element (resp. parent) type.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"base_ring(R::NCRing)\nbase_ring(a::NCRingElement)","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"For generic ring constructions over a base ring (e.g. polynomials over a coefficient ring), return the parent object of that base ring.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"parent(a::NCRingElement)","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Return the parent of the given ring element.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"is_domain_type(::Type{T}) where T <: NCRingElement\nis_exact_type(::Type{T}) where T <: NCRingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Return true if the given ring element type can only belong to elements of an integral domain or exact ring respectively. (An exact ring is one whose elements are represented exactly in the system without approximation.)","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"The following function is implemented where mathematically and algorithmically possible.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"characteristic(R::NCRing)","category":"page"},{"location":"AbstractAlgebra/ring/#Constructors","page":"Ring functionality","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"If R is a parent object of a ring in AbstractAlgebra, it can always be used to construct certain objects in that ring.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"(R::NCRing)() # constructs zero\n(R::NCRing)(c::Integer)\n(R::NCRing)(c::elem_type(R))\n(R::NCRing{T})(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ring/#Basic-functions","page":"Ring functionality","title":"Basic functions","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"All rings in AbstractAlgebra are expected to implement basic ring operations, unary minus, binary addition, subtraction and multiplication, equality testing, powering.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"In addition, the following are implemented for parents/elements just as they would be in Julia for types/objects.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"zero(R::NCRing)\none(R::NCRing)\niszero(a::NCRingElement)\nisone(a::NCRingElement)","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"In addition, the following are implemented where it is mathematically/algorithmically viable to do so.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"is_unit(a::NCRingElement)\nis_zero_divisor(a::NCRingElement)\nis_zero_divisor_with_annihilator(a::NCRingElement)","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"The following standard Julia functions are also implemented for all ring elements.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"hash(f::RingElement, h::UInt)\ndeepcopy_internal(a::RingElement, dict::IdDict)\nshow(io::IO, R::NCRing)\nshow(io::IO, a::NCRingElement)","category":"page"},{"location":"AbstractAlgebra/ring/#Basic-functionality-for-inexact-rings-only","page":"Ring functionality","title":"Basic functionality for inexact rings only","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"By default, inexact ring elements in AbstractAlgebra compare equal if they are the same to the minimum precision of the two elements. However, we also provide the following more strict notion of equality, which also requires the precisions to be the same.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"isequal(a::T, b::T) where T <: NCRingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"For floating point and ball arithmetic it is sometimes useful to be able to check if two elements are approximately equal, e.g. to suppress numerical noise in comparisons. For this, the following are provided.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"isapprox(a::T, b::T; atol::Real=sqrt(eps())) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Similarly, for a parameterised ring with type MyElem{T} over such an inexact ring we have the following.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"isapprox(a::MyElem{T}, b::T; atol::Real=sqrt(eps())) where T <: RingElement\nisapprox(a::T, b::MyElem{T}; atol::Real=sqrt(eps())) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"These notionally perform a coercion into the parameterised ring before doing the approximate equality test.","category":"page"},{"location":"AbstractAlgebra/ring/#Basic-functionality-for-commutative-rings-only","page":"Ring functionality","title":"Basic functionality for commutative rings only","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"divexact(a::T, b::T) where T <: RingElement\ninv(a::T)","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Return a/b or 1/a respectively, where the slash here refers to the mathematical notion of division in the ring, not Julia's floating point division operator.","category":"page"},{"location":"AbstractAlgebra/ring/#Basic-functionality-for-noncommutative-rings-only","page":"Ring functionality","title":"Basic functionality for noncommutative rings only","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"divexact_left(a::T, b::T) where T <: NCRingElement\ndivexact_right(a::T, b::T) where T <: NCRingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"As per divexact above, except that division by b happens on the left or right, respectively, of a.","category":"page"},{"location":"AbstractAlgebra/ring/#Unsafe-ring-operators","page":"Ring functionality","title":"Unsafe ring operators","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"To speed up polynomial arithmetic, various unsafe operators are provided, which mutate the output rather than create a new object.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"zero!(a::NCRingElement)\nmul!(a::T, b::T, c::T) where T <: NCRingElement\nadd!(a::T, b::T, c::T) where T <: NCRingElement\naddeq!(a::T, b::T) where T <: NCRingElement\naddmul!(a::T, b::T, c::T, t::T) where T <: NCRingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"In each case the mutated object is the leftmost parameter.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"The addeq!(a, b) operation does the same thing as add!(a, a, b). The optional addmul!(a, b, c, t) operation does the same thing as mul!(t, b, c); addeq!(a, t) where t is a temporary which can be mutated so that an addition allocation is not needed.","category":"page"},{"location":"AbstractAlgebra/ring/#Random-generation","page":"Ring functionality","title":"Random generation","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"The Julia random interface is implemented for all ring parents (instead of for types). The exact interface differs depending on the ring, but the parameters supplied are usually ranges, e.g. -1:10 for the range of allowed degrees for a univariate polynomial.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"rand(R::NCRing, v...)","category":"page"},{"location":"AbstractAlgebra/ring/#Factorization","page":"Ring functionality","title":"Factorization","text":"","category":"section"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"For commutative rings supporting factorization and irreducibility testing, the following optional functions may be implemented.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"is_irreducible(a::T) where T <: RingElement\nis_squarefree(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Decide whether a is irreducible or squarefree, respectively.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"factor(a::T) where T <: RingElement\nfactor_squarefree(a::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Return a factorization into irreducible or squarefree elements, respectively. The return is an object of type Fac{T}.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","text":"Fac\nunit(a::Fac)\nevaluate(a::Fac)\ngetindex(a::Fac, b)\nsetindex!(a::Fac{Int}, c::Int, b::Int)","category":"page"},{"location":"AbstractAlgebra/ring/#Fac","page":"Ring functionality","title":"Fac","text":"Fac{T <: RingElement}\n\nType for factored ring elements. The structure holds a unit of type T and is an iterable collection of T => Int pairs for the factors and exponents.\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/ring/#unit-Tuple{Fac}","page":"Ring functionality","title":"unit","text":"unit(a::Fac{T}) -> T\n\nReturn the unit of the factorization.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ring/#evaluate-Tuple{Fac}","page":"Ring functionality","title":"evaluate","text":"evaluate(a::Fac{T}) -> T\n\nMultiply out the factorization into a single element.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ring/#getindex-Tuple{Fac, Any}","page":"Ring functionality","title":"getindex","text":"getindex(a::Fac, b) -> Int\n\nIf b is a factor of a, the corresponding exponent is returned. Otherwise an error is thrown.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ring/#setindex!-Tuple{Fac{Int64}, Int64, Int64}","page":"Ring functionality","title":"setindex!","text":"setindex!(a::Fac{T}, c::Int, b::T)\n\nIf b is a factor of a, the corresponding entry is set to c.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LinearQuotients/cox_rings/","page":"Cox rings","title":"Cox rings","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/LinearQuotients/cox_rings/#Cox-rings","page":"Cox rings","title":"Cox rings","text":"","category":"section"},{"location":"Experimental/LinearQuotients/cox_rings/#Cox-rings-of-linear-quotients","page":"Cox rings","title":"Cox rings of linear quotients","text":"","category":"section"},{"location":"Experimental/LinearQuotients/cox_rings/","page":"Cox rings","title":"Cox rings","text":"By a theorem of Arzhantsev and Gaifullin Ivan V. Arzhantsev, Sergei A. Gaǐfullin (2010), the Cox ring of a linear quotient VG is graded isomorphic to the invariant ring KV^GG, where GG is the derived subgroup of G. This functionality is so far only available if the group does not contain any reflections.","category":"page"},{"location":"Experimental/LinearQuotients/cox_rings/","page":"Cox rings","title":"Cox rings","text":"cox_ring(L::LinearQuotient)","category":"page"},{"location":"Experimental/LinearQuotients/cox_rings/#cox_ring-Tuple{Oscar.LinearQuotient}","page":"Cox rings","title":"cox_ring","text":"cox_ring(L::LinearQuotient)\n\nReturn the Cox ring of the linear quotient L in a presentation as a graded affine algebra (MPolyQuoRing) and an injective map from this ring into a polynomial ring.\n\nBy a theorem of Arzhantsev–Gaifullin Ivan V. Arzhantsev, Sergei A. Gaǐfullin (2010) the Cox ring is graded isomorphic to the invariant ring of the derived subgroup of group(L). We use ideas from Maria Donten-Bury, Simon Keicher (2017) to find homogeneous generators of the invariant ring. To get a map from group(G) to the grading group of the returned ring, use class_group.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LinearQuotients/cox_rings/#Cox-rings-of-\\mathbb-Q-factorial-terminalizations","page":"Cox rings","title":"Cox rings of mathbb Q-factorial terminalizations","text":"","category":"section"},{"location":"Experimental/LinearQuotients/cox_rings/","page":"Cox rings","title":"Cox rings","text":"We provide an experimental algorithm to compute the Cox ring of a mathbb Q-factorial terminalization Xto VG of a linear quotient due to Ryo Yamagishi (2018).","category":"page"},{"location":"Experimental/LinearQuotients/cox_rings/","page":"Cox rings","title":"Cox rings","text":"cox_ring_of_qq_factorial_terminalization(L::LinearQuotient)","category":"page"},{"location":"Experimental/LinearQuotients/cox_rings/#cox_ring_of_qq_factorial_terminalization-Tuple{Oscar.LinearQuotient}","page":"Cox rings","title":"cox_ring_of_qq_factorial_terminalization","text":"cox_ring_of_qq_factorial_terminalization(L::LinearQuotient)\n\nReturn the Cox ring of a QQ-factorial terminalization of the linear quotient L in a presentation as a graded affine algebra (MPolyQuoRing) and an injective map from this ring into a Laurent polynomial ring using the algorithm from Ryo Yamagishi (2018).\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/tableaux/#Tableaux","page":"Tableaux","title":"Tableaux","text":"","category":"section"},{"location":"Combinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"Tableau","category":"page"},{"location":"Combinatorics/tableaux/#Tableau","page":"Tableaux","title":"Tableau","text":"Tableau{T} <: AbstractVector{AbstractVector{T}}\n\nA Young diagram is a diagram of finitely many empty \"boxes\" arranged in left-justified rows, with the row lengths in non-increasing order. The box in row i and and column j has the coordinates (i,j). Listing the number of boxes in each row gives a partition λ of a non-negative integer n (the total number of boxes of the diagram). The diagram is then said to be of shape λ. Conversely, one can associate to any partition λ a Young diagram in the obvious way, so Young diagrams are just another way to look at partitions.\n\nA Young tableau of shape λ is a filling of the boxes of the Young diagram of λ with elements from some set. After relabeling we can (and will) assume that we fill from a set of integers from 1 up to some number, which in applications is often equal to n. We encode a tableau as an array of arrays and we have implemented an own type Tableau{T} as subtype of AbstractVector{AbstractVector{T}} to work with tableaux. As for partitions, you may increase performance by casting into smaller integer types, e.g.\n\nFor efficiency, we do not check whether the given array is really a tableau, i.e. whether the structure of the array defines a partition.\n\nExamples\n\njulia> tab=Tableau([[1,2,3],[4,5],[6]])\n[[1, 2, 3], [4, 5], [6]]\n\njulia> tab=Tableau(Vector{Int8}[[2,1], [], [3,2,1]]) #Using 8 bit integers\nVector{Int8}[[2, 1], [], [3, 2, 1]]\n\nReferences\n\nWikipedia, Young tableau.\n\n\n\n\n\n","category":"type"},{"location":"Combinatorics/tableaux/#Operations","page":"Tableaux","title":"Operations","text":"","category":"section"},{"location":"Combinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"hook_length\nhook_lengths\nshape\nweight\nreading_word","category":"page"},{"location":"Combinatorics/tableaux/#hook_length","page":"Tableaux","title":"hook_length","text":"hook_length(lambda::Partition, i::Integer, j::Integer)\n\nConsider the Young diagram of a partition λ. The hook length of a box, is the number of boxes to the right in the same row + the number of boxes below in the same column + 1. The function returns the hook length of the box with coordinates (i,j). The functions assumes that the box exists.\n\n\n\n\n\nhook_length(tab::Tableau, i::Integer, j::Integer)\n\nShortcut for hook_length(shape(tab), i, j).\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#hook_lengths","page":"Tableaux","title":"hook_lengths","text":"hook_lengths(lambda::Partition)\n\nReturn the tableau of shape λ in which the entry at position (i,j) is equal to the hook length of the corresponding box.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#shape","page":"Tableaux","title":"shape","text":"shape(tab::Tableau{T})\n\nReturn the shape of a tableau, i.e. the partition given by the lengths of the rows of the tableau.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#weight","page":"Tableaux","title":"weight","text":"weight(tab::Tableau)\n\nThe weight of a tableau is the number of times each number appears in the tableau. The return value is an array whose i-th element gives the number of times the integer i appears in the tableau.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#reading_word","page":"Tableaux","title":"reading_word","text":"reading_word(tab::Tableau)\n\nThe reading word of a tableau is the word obtained by concatenating the fillings of the rows, starting from the bottom row. The word is here returned as an array.\n\nExamples\n\njulia> reading_word(Tableau([ [1,2,3] , [4,5] , [6] ]))\n6-element Vector{Int64}:\n 6\n 4\n 5\n 1\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#Semistandard-tableaux","page":"Tableaux","title":"Semistandard tableaux","text":"","category":"section"},{"location":"Combinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"is_semistandard\nsemistandard_tableaux","category":"page"},{"location":"Combinatorics/tableaux/#is_semistandard","page":"Tableaux","title":"is_semistandard","text":"is_semistandard(tab::Tableau)\n\nA tableau is called semistandard if the entries weakly increase along each row and strictly increase down each column.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#semistandard_tableaux","page":"Tableaux","title":"semistandard_tableaux","text":"semistandard_tableaux(shape::Partition{T}, max_val::T=sum(shape)) where T<:Integer\n\nReturn a list of all semistandard tableaux of given shape and filling elements bounded by max_val. By default, max_val is equal to the sum of the shape partition (the number of boxes in the Young diagram). The list of tableaux is in lexicographic order from left to right and top to bottom.\n\n\n\n\n\nsemistandard_tableaux(shape::Partition{T}, max_val::T=sum(shape)) where T<:Integer\n\nShortcut for semistandard_tableaux(Partition(shape), max_val).\n\n\n\n\n\nsemistandard_tableaux(box_num::T, max_val::T=box_num) where T<:Integer\n\nReturn a list of all semistandard tableaux consisting of box_num boxes and filling elements bounded by max_val.\n\n\n\n\n\nsemistandard_tableaux(s::Vector{T}, weight::Vector{T}) where T<:Integer\n\nReturn a list of all semistandard tableaux with shape s and given weight. This requires that sum(s) = sum(weight).\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#Standard-tableaux","page":"Tableaux","title":"Standard tableaux","text":"","category":"section"},{"location":"Combinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"is_standard\nstandard_tableaux\nnum_standard_tableaux\nschensted\nbump!","category":"page"},{"location":"Combinatorics/tableaux/#is_standard","page":"Tableaux","title":"is_standard","text":"is_standard(tab::Tableau)\n\nA tableau is called standard if it is semistandard and the entries are in bijection with 1n, where n is the number of boxes.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#standard_tableaux","page":"Tableaux","title":"standard_tableaux","text":"standard_tableaux(s::Partition)\nstandard_tableaux(s::Vector{Integer})\n\nReturn a list of all standard tableaux of a given shape.\n\n\n\n\n\nstandard_tableaux(n::Integer)\n\nReturn a list of all standard tableaux with n boxes.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#num_standard_tableaux","page":"Tableaux","title":"num_standard_tableaux","text":"num_standard_tableaux(lambda::Partition)\n\nReturn the number f^λ of standard tableaux of shape λ using the hook length formula\n\nf^λ = fracnprod_ij h_λ(ij)\n\nwhere the product is taken over all boxes in the Young diagram of λ and h_λ denotes the hook length of the box (i,j).\n\nReferences\n\nWikipedia, Hook length formula.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#schensted","page":"Tableaux","title":"schensted","text":"schensted(sigma::Vector{Integer})\nschensted(sigma::Perm{T})\n\nThe Robinson–Schensted correspondence is a bijection between permutations and pairs of standard Young tableaux of the same shape. For a permutation sigma (given as an array), this function performs the Schnested algorithm and returns the corresponding pair of standard tableaux (the insertion and recording tableaux).\n\nExamples\n\njulia> P,Q = schensted([3,1,6,2,5,4]);\n\njulia> P\n[[1, 2, 4], [3, 5], [6]]\n\njulia> Q\n[[1, 3, 5], [2, 4], [6]]\n\nReferences\n\nWikipedia, Robinson–Schensted correspondence\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/tableaux/#bump!","page":"Tableaux","title":"bump!","text":"bump!(tab::Tableau, x::Int)\n\nInserts the integer x into the tableau tab according to the bumping algorithm by applying the Schensted insertion.\n\nReferences\n\nWolfram MathWorld, Bumping Algorithm\n\n\n\n\n\nbump!(tab::Tableau, x::Integer, Q::Tableau, y::Integer)\n\nInserts x into tab according to the bumping algorithm by applying the Schensted insertion. Traces the change with Q by inserting y at the same position in Q as x in tab.\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Operations-on-Modules","page":"Operations on Modules","title":"Operations on Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Subquotients-Related-to-Homomorphisms","page":"Operations on Modules","title":"Subquotients Related to Homomorphisms","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Kernel","page":"Operations on Modules","title":"Kernel","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"kernel(a::ModuleFPHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#kernel-Tuple{ModuleFPHom}","page":"Operations on Modules","title":"kernel","text":"kernel(a::ModuleFPHom)\n\nReturn the kernel of a as an object of type SubquoModule.\n\nAdditionally, if K denotes this object, return the inclusion map K to domain(a).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 3);\n\njulia> G = free_module(R, 2);\n\njulia> W = R[y 0; x y; 0 z]\n[y 0]\n[x y]\n[0 z]\n\njulia> a = hom(F, G, W);\n\njulia> K, incl = kernel(a);\n\njulia> K\nSubmodule with 1 generator\n1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]\nrepresented as subquotient with no relations.\n\njulia> incl\nMap with following data\nDomain:\n=======\nSubmodule with 1 generator\n1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]\nrepresented as subquotient with no relations.\nCodomain:\n=========\nFree module of rank 3 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x*N[2]]\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x*y^2*e[1]\n x*y*e[1]\n\njulia> a = hom(M, N, V);\n\njulia> K, incl = kernel(a);\n\njulia> K\nSubquotient of Submodule with 3 generators\n1 -> (-x + y^2)*e[1]\n2 -> x*y*e[1]\n3 -> -x*y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> incl\nMap with following data\nDomain:\n=======\nSubquotient of Submodule with 3 generators\n1 -> (-x + y^2)*e[1]\n2 -> x*y*e[1]\n3 -> -x*y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> Z = abelian_group(0)\nGrpAb: Z\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> kernel(a)\n(Graded subquotient of submodule of F generated by\n1 -> -y*e[1]\n2 -> (x^2 - y^2)*e[1]\n3 -> -x*y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Graded subquotient of submodule of F generated by\n1 -> -y*e[1]\n2 -> (x^2 - y^2)*e[1]\n3 -> -x*y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> M\n-y*e[1] -> -y*e[1]\n(x^2 - y^2)*e[1] -> (x^2 - y^2)*e[1]\n-x*y*e[1] -> -x*y*e[1]\nHomogeneous module homomorphism)\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Image","page":"Operations on Modules","title":"Image","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"image(a::ModuleFPHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#image-Tuple{ModuleFPHom}","page":"Operations on Modules","title":"image","text":"image(a::ModuleFPHom)\n\nReturn the image of a as an object of type SubquoModule.\n\nAdditionally, if I denotes this object, return the inclusion map I to codomain(a).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 3);\n\njulia> G = free_module(R, 2);\n\njulia> W = R[y 0; x y; 0 z]\n[y 0]\n[x y]\n[0 z]\n\njulia> a = hom(F, G, W);\n\njulia> I, incl = image(a);\n\njulia> I\nSubmodule with 3 generators\n1 -> y*e[1]\n2 -> x*e[1] + y*e[2]\n3 -> z*e[2]\nrepresented as subquotient with no relations.\n\njulia> incl\nMap with following data\nDomain:\n=======\nSubmodule with 3 generators\n1 -> y*e[1]\n2 -> x*e[1] + y*e[2]\n3 -> z*e[2]\nrepresented as subquotient with no relations.\nCodomain:\n=========\nFree module of rank 2 over Multivariate polynomial ring in 3 variables over QQ\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x*N[2]]\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x*y^2*e[1]\n x*y*e[1]\n\njulia> a = hom(M, N, V);\n\njulia> I, incl = image(a);\n\njulia> I\nSubquotient of Submodule with 2 generators\n1 -> x*y^2*e[1]\n2 -> x*y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> incl\nMap with following data\nDomain:\n=======\nSubquotient of Submodule with 2 generators\n1 -> x*y^2*e[1]\n2 -> x*y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\nCodomain:\n=========\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> Z = abelian_group(0)\nGrpAb: Z\n\njulia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> F = graded_free_module(Rg, 1);\n\njulia> A = Rg[x; y];\n\njulia> B = Rg[x^2; y^3; z^4];\n\njulia> M = SubquoModule(F, A, B)\nGraded subquotient of submodule of F generated by\n1 -> x*e[1]\n2 -> y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x^2*N[2]];\n\njulia> a = hom(M, N, V)\nM -> M\nx*e[1] -> x*y^2*e[1]\ny*e[1] -> x^2*y*e[1]\nGraded module homomorphism of degree [2]\n\njulia> image(a)\n(Graded subquotient of submodule of F generated by\n1 -> x*y^2*e[1]\n2 -> x^2*y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1], Graded subquotient of submodule of F generated by\n1 -> x*y^2*e[1]\n2 -> x^2*y*e[1]\nby submodule of F generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1] -> M\nx*y^2*e[1] -> x*y^2*e[1]\nx^2*y*e[1] -> x^2*y*e[1]\nHomogeneous module homomorphism)\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Cokernel","page":"Operations on Modules","title":"Cokernel","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"cokernel(a::ModuleFPHom)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#cokernel-Tuple{ModuleFPHom}","page":"Operations on Modules","title":"cokernel","text":"cokernel(a::ModuleFPHom)\n\nReturn the cokernel of a as an object of type SubquoModule.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 3);\n\njulia> G = free_module(R, 2);\n\njulia> W = R[y 0; x y; 0 z]\n[y 0]\n[x y]\n[0 z]\n\njulia> a = hom(F, G, W);\n\njulia> cokernel(a)\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 3 generators\n1 -> y*e[1]\n2 -> x*e[1] + y*e[2]\n3 -> z*e[2]\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = free_module(R, 1);\n\njulia> A = R[x; y]\n[x]\n[y]\n\njulia> B = R[x^2; y^3; z^4]\n[x^2]\n[y^3]\n[z^4]\n\njulia> M = SubquoModule(F, A, B)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 3 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n\njulia> N = M;\n\njulia> V = [y^2*N[1], x*N[2]]\n2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:\n x*y^2*e[1]\n x*y*e[1]\n\njulia> a = hom(M, N, V);\n\njulia> cokernel(a)\nSubquotient of Submodule with 2 generators\n1 -> x*e[1]\n2 -> y*e[1]\nby Submodule with 5 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n4 -> x*y^2*e[1]\n5 -> x*y*e[1]\n\njulia> R, _ = polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> Z = abelian_group(0);\n\njulia> Rg, (x, y, z) = grade(R,[Z[1], Z[1], Z[1]]);\n\njulia> F = graded_free_module(Rg, 3);\n\njulia> G = graded_free_module(Rg, 2);\n\njulia> W = Rg[y 0; x y; 0 z]\n[y 0]\n[x y]\n[0 z]\n\njulia> a = hom(F, G, W)\nF -> G\ne[1] -> y*e[1]\ne[2] -> x*e[1] + y*e[2]\ne[3] -> z*e[2]\nGraded module homomorphism of degree [1]\n\njulia> M = cokernel(a)\nGraded subquotient of submodule of G generated by\n1 -> e[1]\n2 -> e[2]\nby submodule of G generated by\n1 -> y*e[1]\n2 -> x*e[1] + y*e[2]\n3 -> z*e[2]\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Direct-Sums-and-Products","page":"Operations on Modules","title":"Direct Sums and Products","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#direct_sum-Union{Tuple{Vararg{ModuleFP{T}}}, Tuple{T}} where T","page":"Operations on Modules","title":"direct_sum","text":"direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T\n\nGiven modules M_1dots M_n, say, return the direct sum bigoplus_i=1^n M_i. \n\nAdditionally, return \n\na vector containing the canonical injections M_itobigoplus_i=1^n M_i if task = :sum (default),\na vector containing the canonical projections bigoplus_i=1^n M_ito M_i if task = :prod,\ntwo vectors containing the canonical injections and projections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#direct_product-Union{Tuple{Vararg{ModuleFP{T}}}, Tuple{T}} where T","page":"Operations on Modules","title":"direct_product","text":"direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T\n\nGiven modules M_1dots M_n, say, return the direct product prod_i=1^n M_i.\n\nAdditionally, return\n\na vector containing the canonical projections prod_i=1^n M_ito M_i if task = :prod (default),\na vector containing the canonical injections M_itoprod_i=1^n M_i if task = :sum,\ntwo vectors containing the canonical projections and injections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Truncation","page":"Operations on Modules","title":"Truncation","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"truncate(M::ModuleFP, g::GrpAbFinGenElem, task::Symbol = :with_morphism)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#truncate","page":"Operations on Modules","title":"truncate","text":"truncate(M::ModuleFP, g::GrpAbFinGenElem, task::Symbol = :with_morphism)\n\nGiven a finitely presented graded module M over a mathbb Z-graded multivariate polynomial ring with positive weights, return the truncation of M at degree g.\n\nPut more precisely, return the truncation as an object of type SubquoModule. \n\nAdditionally, if N denotes this object,\n\nreturn the inclusion map N to M if task = :with_morphism (default),\nreturn and cache the inclusion map N to M if task = :cache_morphism,\ndo none of the above if task = :none.\n\nIf task = :only_morphism, return only the inclusion map.\n\ntruncate(M::ModuleFP, d::Int, task::Symbol = :with_morphism)\n\nGiven a module M as above, and given an integer d, convert d into an element g of the grading group of base_ring(I) and proceed as above.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [\"x\", \"y\", \"z\"]);\n\njulia> F = graded_free_module(R, 1)\nGraded free module R^1([0]) of rank 1 over R\n\njulia> V = [x*F[1]; y^4*F[1]; z^5*F[1]];\n\njulia> M, _ = quo(F, V);\n\njulia> M[1]\ne[1]\n\njulia> MT = truncate(M, 3);\n\njulia> MT[1]\nGraded subquotient of submodule of F generated by\n1 -> z^3*e[1]\n2 -> y*z^2*e[1]\n3 -> y^2*z*e[1]\n4 -> y^3*e[1]\n5 -> x*z^2*e[1]\n6 -> x*y*z*e[1]\n7 -> x*y^2*e[1]\n8 -> x^2*z*e[1]\n9 -> x^2*y*e[1]\n10 -> x^3*e[1]\nby submodule of F generated by\n1 -> x*e[1]\n2 -> y^4*e[1]\n3 -> z^5*e[1]\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/styleguide/#Developer-Style-Guide","page":"Developer Style Guide","title":"Developer Style Guide","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"In general we aim to follow the Julia Style Guide but there are some exceptions due to our specific needs and a different background.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"The content of this page are merely guidelines. There may be good reasons to deviate from them in some cases; in that case just do so.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#General-styleguide","page":"Developer Style Guide","title":"General styleguide","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Use Julia conventions where applicable and when they don't contradict our own rules above.\nUnless really really necessary, don't add new dependencies. Every new dependency complicates the development workflow, in that we will need to stay compatible with this package. \nIf already existing types in OSCAR are almost what you need, consider improving them instead of writing your own. While it might be tempting to create a new polynomial ring type for the new application because some feature is missing, it causes a lot of work and compatibility issues: Will the new type support\nnormal functions (gcd, factor),\nquotient fields,\nmodules and residue rings,\nconversion to and from other already existing types?\nWhenever functions return the same mathematical object, but in different mathematical categories, the first argument should be the desired return type. One example is projective_space(NormalToricVariety, *) vs projective_space(ProjectiveScheme, *). However, if the return type is different, even if the result describes the same mathematical object, it should be indicated in the function name, for example automorphism_group vs automorphism_group_generators vs automorphism_list.\nFollow the mathematics. If your function needs a list of points, you should create a point-type (or use the one already there) and then use this. For user-facing functions, please do not use re-purposed lists, arrays, matrices...","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Naming-conventions","page":"Developer Style Guide","title":"Naming conventions","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"The usual Julia naming conventions apply to OSCAR, too (that said, for various reasons our code still violates quite some of them; but in general we strive to reduce these). Here is a summary of the naming convention followed in OSCAR:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Use CamelCase for types and snake_case for everything else. (Internal functions do not have to follow these rules.) Types (and their constructor) tend to be in CamelCase. However, please also provide the constructor (or a constructor) in snake_case. As a user one usually does not know if something is a constructor or a function.\nFor filenames we recommend using snake_case.jl.\nNoteworthy difference to Julia base is that we do not have exceptions for is* or has* as prefix. It is is_foo instead of isfoo and has_bar instead of hasbar. The main reason is to avoid awkward constructions like isvery_ample, while also being consistent. For compatibility with standard Julia, while staying consistent internally, we also provide aliases (using AbstractAlgebra.@alias) for various standard Julia functions, e.g. is_one as alias for isone\nFor generic concepts choose generic names, based on general algebraic concepts, preferably not special names from your area of speciality.\nAvoid direct access to members of our objects. This means, do not use something like A.foo, instead use a suitable getter get_foo(A), and if there is none, please write one or request that one be written. Internal member names are free to change at any time, but functions can be deprecated properly.\nIn Julia we have multiple dispatch, so we do not need functions like point_from_matrix as the \"from\" part is clear by the type of the argument. It should be called points(T::Matrix) in some variation. Similarly for matrix_to_points. Of course it is fine to use them internally, where useful.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Code-formatting","page":"Developer Style Guide","title":"Code formatting","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/#Editor-configuration","page":"Developer Style Guide","title":"Editor configuration","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Please check if your editor can be configured to honor our .editorconfig file, see https://editorconfig.org for more information about this.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Unicode","page":"Developer Style Guide","title":"Unicode","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"As most modern programming languages, Julia allows the use of Unicode, e.g., α, in the REPL as well as in source code. As this reduces accessibility to various groups of users and developers, the use of Unicode should be kept to a minimum. Here is a general principle:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Do not use Unicode characters inside functions. See below for the exception concerning printing.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Whitespace","page":"Developer Style Guide","title":"Whitespace","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Do not use tabs.\nDo not put spaces \"inside\" parenthesis.\nDo put spaces after commas.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Good example:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"f(x, y) = x + 1\nprint(f(1, 2))","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Bad example:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"f( x,y ) = x + 1\nprint( f ( 1,2 ) )","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Loops-and-other-control-structures","page":"Developer Style Guide","title":"Loops and other control structures","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"for loops should use in not =\ndon't put spaces around the : in a range","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Good example:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"for i in 1:3\n println(i)\nend","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Bad example:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"for i = 1 : 3\n println(i)\nend","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Code-structure","page":"Developer Style Guide","title":"Code structure","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"do not nest loops and if clauses too deeply; if you are using 5 or more levels, then in general that's a hint that you should refactor; e.g.\nby moving parts of the code into a separate function\nby replacing guard constructs like\nfor i in A\n if flag\n ...\n end\nend\nby\nfor i in A\n if !flag\n continue\n end\n ...\nend\nor\nfor i in A\n flag ||continue\n ...\nend\nby merging loops: you can replace\nfor i in A\n for j in B\n ...\n end\nend\nby\nfor i in A, j in B\n ...\nend\nFunctions should not have too many arguments. If you need a bunch arguments, chances are that introducing a new type makes it more readable.\nFunctions should not be too long; very long functions are in general harder to understand; it is also more difficult to see all the code at once. Consider splitting the function into multiple ones, if it is sensibly possible.\nEvery export statement must be confined to a single line; the intention is to make it easy to use tools like git grep to find exports. In general it is recommended export exactly one identifier per export statement. Exceptions may be made for certain tightly related identifiers, e.g. is_finite, set_is_finite and has_is_finite could be put on a single line. In general if multiple export statements appear in sequence, they must be sorted alphabetically.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"However, as always, rules sometimes should be broken.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Documentation","page":"Developer Style Guide","title":"Documentation","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"In general we try to follow the list of recommendations in the Documentation section of the Julia manual.\nVia the MathJax integration it is possible to use LaTeX code, and this is the preferred way to denote the mathematical symbols in the docstrings.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Printing-in-Oscar","page":"Developer Style Guide","title":"Printing in Oscar","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/#The-2-1-print-modes-of-Oscar","page":"Developer Style Guide","title":"The 2 + 1 print modes of Oscar","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Oscar has two user print modes detailed and one line and one internal print mode :supercompact. The latter is for use during recursion, e.g. to print the base_ring(X) when in one line mode. It exists to make sure that one line stays compact and human readable.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Top-level REPL printing of an object will use detailed mode by default","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"julia> X\ndetailed","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Inside nested structures, e.g. inside a Vector, the one line mode is used.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"julia> [X,X]\n3-element Vector{TypeofX{T}}\none line\none line\none line","category":"page"},{"location":"DeveloperDocumentation/styleguide/#An-Example-for-the-2-1-print-modes","page":"Developer Style Guide","title":"An Example for the 2 + 1 print modes","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"# detailed\nGeneral linear group of degree 24\n over Finite field of degree 7 over GF(29)\n\n# one line\nGeneral linear group of degree 24 over GF(29^7)\n\n# supercompact\nGeneral linear group","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"The print modes are specified as follows","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Detailed-printing","page":"Developer Style Guide","title":"Detailed printing","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"the output must make sense as a standalone without context to non-specialists\nthe number of output lines should fit in the terminal\nif the object is simple enough use only one line\nuse indentation and (usually) one line to print substructures","category":"page"},{"location":"DeveloperDocumentation/styleguide/#One-line-printing","page":"Developer Style Guide","title":"One line printing","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"the output must print in one line\nshould make sense as a standalone without context\nvariable names/generators/relations should not be printed only their number.\nOnly the first word is capitalized e.g. Polynomial ring\none should use :supercompact for nested printing in compact\nnested calls to one line (if you think them really necessary) should be at the end, so that one can read sequentially. Calls to :supercompact can be anywhere.\ncommas must be enclosed in brackets so that printing tuples stays unambiguous","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Super-compact-printing","page":"Developer Style Guide","title":"Super compact printing","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"a user readable version of the main (mathematical) type.\na single term or a symbol/letter mimicking mathematical notation\nshould usually only depend on the type and not of the type parameters or of the concrete instance - exceptions of this rule are possible e.g. for GF(2)\nno nested printing. In particular variable names and base_ring must not be displayed. This ensures that one line and :supercompact stay compact even for complicated things. If you want nested printing use one line or detailed.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"For further information and examples we refer you to our section Details on printing in Oscar.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Deprecating-functions","page":"Developer Style Guide","title":"Deprecating functions","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Sometimes it is necessary to rename a function or otherwise change it. To allow for backwards compatibility, please then introduce a new line in the file src/deprecations.jl. The syntax is as follows:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"# Deprecated after CURRENT_RELEASE_VERSION\n@deprecate old_function(args) new_function(args)","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"It is possible to transform the args too, if the syntax has changed. If this process needs an auxiliary function, which otherwise is unnecessary, please add it above:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"# Deprecated after CURRENT_RELEASE_VERSION\nfunction transform_args_for_new_function(args)\n # Do something\n return new_args\nend\n@deprecate old_function(args) new_function(transform_args_for_new_function(args))","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"The comment about the version number is only necessary if you are the first one adding to deprecations.jl after a release, otherwise please add to the existing block.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"note: Note\nPlease make sure to change to the new function everywhere in the existing OSCAR code base. Even if you think, you were the only one using the function, run a quick grep to make sure. When you are done, deprecations.jl should be the only place mentioning old_function. To make sure, you can start Julia with --depwarn=yes or even --depwarn=error and then run the tests.","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Approved-abbreviations","page":"Developer Style Guide","title":"Approved abbreviations","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Types for rings/groups/ideals/modules/... end with Ring/Group/Ideal/Module/...\nTypes for elements should have the same name as the type of the parent with Elem added;\nException: MatrixSpace elements end with Matrix.\nWe abbreviate certain parts of type names, according to a fixed set of substitutions; further abbreviations should be carefully decided upon.\nEvery abbreviation must be unique; e.g. Abs stands for Absolute, and so must not be used for e.g. Abstract.\nList of approved abbreviations\nabsolute -> Abs\nabstract -> Abstract\ndecorated -> Dec\ngroup -> Group\nideal -> Ideal\nlocalized -> Loc\nmatrix -> Matrix\nmodule -> Module\nmultivariate polynomial -> MPoly\npolynomial -> Poly\nquotient -> Quo\nrelative -> Rel\nring ->Ring\nsubquotient -> Subquo\nIf a type comes in sparse and dense variants, then call the dense type T and the sparse one SparseT.","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#Morphisms-of-projective-schemes","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":"Let Q = By_0 dots y_nJ and P = Ax_0dotsx_mI be graded affine algebras over base_rings A and B, respectively. A morphism varphi mathrmProj(Q) to mathrmProj(P) is modeled via a morphism of graded algebras varphi^* P to Q. In the case of A != B, this involves a non-trivial morphism of rings A to B.","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#Abstract-types-and-basic-interface","page":"Morphisms of projective schemes","title":"Abstract types and basic interface","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":"At the moment we have no abstract type for such morphisms and no interface spelled out. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#Types","page":"Morphisms of projective schemes","title":"Types","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":" ProjectiveSchemeMor","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#ProjectiveSchemeMor","page":"Morphisms of projective schemes","title":"ProjectiveSchemeMor","text":"ProjectiveSchemeMor\n\nA morphism of projective schemes\n\n ℙˢ(B) ℙʳ(A)\n ∪ ∪\n P → Q\n ↓ ↓\n Spec(B) → Spec(A)\n\ngiven by means of a commutative diagram of homomorphisms of graded rings\n\n A[v₀,…,vᵣ] → B[u₀,…,uₛ]\n ↑ ↑\n A → B\n\nIf no morphism A → B of the base rings is specified, then both P and Q are assumed to be defined in relative projective space over the same ring with the identity on the base.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#Constructors","page":"Morphisms of projective schemes","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":" morphism_of_projective_schemes(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map; check::Bool=true )\n morphism_of_projective_schemes(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map, h::SchemeMor; check::Bool=true )\n morphism_of_projective_schemes(X::AbsProjectiveScheme, Y::AbsProjectiveScheme, a::Vector{<:RingElem})","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#morphism_of_projective_schemes-Tuple{AbsProjectiveScheme, AbsProjectiveScheme, Map}","page":"Morphisms of projective schemes","title":"morphism_of_projective_schemes","text":"morphism_of_projective_schemes(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map; check::Bool=true )\n\nGiven a morphism f T S of the homogeneous_coordinate_rings of Q and P, respectively, construct the associated morphism of projective schemes.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#morphism_of_projective_schemes-Tuple{AbsProjectiveScheme, AbsProjectiveScheme, Map, SchemeMor}","page":"Morphisms of projective schemes","title":"morphism_of_projective_schemes","text":"morphism_of_projective_schemes(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map, h::SchemeMor; check::Bool=true )\n\nSuppose P ℙʳ_A and Q ℙˢ_B are projective schemes, h Spec(A) Spec(B) is a morphism of their base_schemes, and f T S a morphism of the homogeneous_coordinate_rings of Q and P over h^* B A. This constructs the associated morphism of projective schemes.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#morphism_of_projective_schemes-Tuple{AbsProjectiveScheme, AbsProjectiveScheme, Vector{<:RingElem}}","page":"Morphisms of projective schemes","title":"morphism_of_projective_schemes","text":"morphism_of_projective_schemes(X::AbsProjectiveScheme, Y::AbsProjectiveScheme, a::Vector{<:RingElem})\n\nSuppose X ℙʳ and Y ℙˢ are projective schemes over the same base_scheme. Construct the morphism of projective schemes associated to the morphism of graded rings which takes the generators of the homogeneous_coordinate_ring of Y to the elements in a of the homogeneous_coordinate_ring of X.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#Attributes","page":"Morphisms of projective schemes","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":"As every instance of Map, a morphism of projective schemes can be asked for its (co-)domain:","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":" domain(phi::ProjectiveSchemeMor) \n codomain(phi::ProjectiveSchemeMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":"Moreover, we provide getters for the associated morphisms of rings:","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":" pullback(phi::ProjectiveSchemeMor)\n base_ring_morphism(phi::ProjectiveSchemeMor) \n base_map(phi::ProjectiveSchemeMor)\n map_on_affine_cones(phi::ProjectiveSchemeMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#pullback-Tuple{ProjectiveSchemeMor}","page":"Morphisms of projective schemes","title":"pullback","text":" pullback(phi::ProjectiveSchemeMor)\n\nFor a morphism phi of projective schemes, this returns the associated morphism of graded affine algebras.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#base_ring_morphism-Tuple{ProjectiveSchemeMor}","page":"Morphisms of projective schemes","title":"base_ring_morphism","text":"base_ring_morphism(phi::ProjectiveSchemeMor)\n\nFor a morphism phi : P → Q of relative projective spaces over psi : Spec(A) → Spec(B) this returns the associated map B → A.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#base_map-Tuple{ProjectiveSchemeMor}","page":"Morphisms of projective schemes","title":"base_map","text":"base_map(phi::ProjectiveSchemeMor)\n\nFor a morphism phi : P → Q of relative projective spaces over psi : Spec(A) → Spec(B) this returns psi.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#map_on_affine_cones-Tuple{ProjectiveSchemeMor}","page":"Morphisms of projective schemes","title":"map_on_affine_cones","text":"map_on_affine_cones(phi::ProjectiveSchemeMor)\n\nFor a morphism phi : X → Y this returns the associated morphism of the affine_cones C(X) C(Y).\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#Methods","page":"Morphisms of projective schemes","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/","page":"Morphisms of projective schemes","title":"Morphisms of projective schemes","text":" covered_scheme_morphism(f::ProjectiveSchemeMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#covered_scheme_morphism-Tuple{ProjectiveSchemeMor}","page":"Morphisms of projective schemes","title":"covered_scheme_morphism","text":"covered_scheme_morphism(f::ProjectiveSchemeMor)\n\nGiven a morphism of ProjectiveSchemes f X Y, construct and return the same morphism as a CoveredSchemeMorphism of the covered_schemes of X and Y, respectively.\n\nExamples\n\njulia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> I = ideal([x^3-y^2*z]);\n\njulia> Y = projective_scheme(P, I);\n\njulia> f = identity_map(Y)\nMorphism\n from projective scheme in IP^2 over QQ\n to projective scheme in IP^2 over QQ\n\njulia> fcov = covered_scheme_morphism(f);\n\njulia> codomain(fcov)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: spec of quotient of multivariate polynomial ring\n 2: spec of quotient of multivariate polynomial ring\n 3: spec of quotient of multivariate polynomial ring\n in the coordinate(s)\n 1: [(y//x), (z//x)]\n 2: [(x//y), (z//y)]\n 3: [(x//z), (y//z)]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Nongeneral-Type-Surfaces-in-\\mathbb-P4","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"Every smooth, projective surface can be embedded in mathbb P^5, but there are constraints on the numerical invariants of a smooth surface in mathbb P^4: The invariants of each such surface S satisfy the double point formula","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"d^2-5d-10(pi-1)+2(chi(mathcal O_S)-K_S^2) = 0","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"Here, d is the degree of S, pi its sectional genus, chi(mathcal O_S) its Euler-Poincare characteristic, and K_S its canonical class. The double point formula is a key ingredient in the proof of a theorem of Ellingsrud and Peskine which states that there are only finitely many families of smooth surfaces in mathbb P^4 which are not of general type. That is, the degree of such surfaces in bounded from above. The best bound known so far is 52, while examples exist up to degree 15.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"For details, we refer to","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"Wolfram Decker, Lawrence Ein, Frank-Olaf Schreyer (1993)\nSorin Popescu (1993)\nWolfram Decker, Frank-Olaf Schreyer (2000)","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"and the references given there.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"Below, we present functions which return one hard coded example for each family presented in the first two papers above. Based on these papers, the existence of further families has been shown. Explicit examples to be included here are under construction.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"note: Note\nTo ease subsequent computations, all hard coded examples are defined over a finite prime field.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Rational-Surfaces","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Rational Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d3,-\\pi0","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=3, pi=0","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"cubic_scroll()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#cubic_scroll-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"cubic_scroll","text":"cubic_scroll()\n\nReturn a smooth rational surface in mathbb P^4 with degree 3 and sectional genus 0.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d4,-\\pi0","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=4, pi=0","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"veronese()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#veronese-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"veronese","text":"veronese()\n\nReturn a smooth rational surface in mathbb P^4 with degree 4 and sectional genus 0.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d5,-\\pi2","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=5, pi=2","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"castelnuovo()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#castelnuovo-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"castelnuovo","text":"castelnuovo()\n\nReturn a smooth rational surface in mathbb P^4 with degree 5 and sectional genus 2.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d6,-\\pi3","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=6, pi=3","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"bordiga()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#bordiga-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"bordiga","text":"bordiga()\n\nReturn a smooth rational surface in mathbb P^4 with degree 6 and sectional genus 3.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d7,-\\pi4","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=7, pi=4","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d7_pi4()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d7_pi4-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d7_pi4","text":"rational_d7_pi4()\n\nReturn a smooth rational surface in mathbb P^4 with degree 7 and sectional genus 4.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d8,-\\pi5","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=8, pi=5","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d8_pi5()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d8_pi5-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d8_pi5","text":"rational_d8_pi5()\n\nReturn a smooth rational surface in mathbb P^4 with degree 8 and sectional genus 5.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d8,-\\pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=8, pi=6","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d8_pi6()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d8_pi6-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d8_pi6","text":"rational_d8_pi6()\n\nReturn a smooth rational surface in mathbb P^4 with degree 8 and sectional genus 6.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d9,-\\pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=9, pi=6","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d9_pi6()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d9_pi6-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d9_pi6","text":"rational_d9_pi6()\n\nReturn a smooth rational surface in mathbb P^4 with degree 9 and sectional genus 6.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d9,-\\pi7","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=9, pi=7","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d9_pi7()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d9_pi7-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d9_pi7","text":"rational_d9_pi7()\n\nReturn a smooth rational surface in mathbb P^4 with degree 9 and sectional genus 7.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d10,-\\pi8","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=10, pi=8","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d10_pi8()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d10_pi8-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d10_pi8","text":"rational_d10_pi8()\n\nReturn a smooth rational surface in mathbb P^4 with degree 10 and sectional genus 8.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d10,-\\pi9-which-is-Contained-in-one-Quartic","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=10, pi=9 which is Contained in one Quartic","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d10_pi9_quart_1()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d10_pi9_quart_1-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d10_pi9_quart_1","text":"rational_d10_pi9_quart_1()\n\nReturn a smooth rational surface in mathbb P^4 with degree 10 and sectional genus 9 which is contained in precisely one quartic.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d10,-\\pi9-which-is-Contained-in-a-Pencil-of-Quartics","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=10, pi=9 which is Contained in a Pencil of Quartics","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d10_pi9_quart_2()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d10_pi9_quart_2-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d10_pi9_quart_2","text":"rational_d10_pi9_quart_2()\n\nReturn a smooth rational surface in mathbb P^4 with degree 10 and sectional genus 9 which is contained in a pencil of quartics.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d11,-\\pi11,-and-no-6-Secant","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=11, pi=11, and no 6-Secant","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d11_pi11_ss_0()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d11_pi11_ss_0-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d11_pi11_ss_0","text":"rational_d11_pi11_ss_0()\n\nReturn a smooth rational surface in mathbb P^4 with degree 11, sectional genus 11, and no 6-secant.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d11,-\\pi11,-and-one-6-Secant","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=11, pi=11, and one 6-Secant","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d11_pi11_ss_1()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d11_pi11_ss_1-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d11_pi11_ss_1","text":"rational_d11_pi11_ss_1()\n\nReturn a smooth rational surface in mathbb P^4 with degree 11, sectional genus 11, and one 6-secant.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Rational-Surface-with-d11,-\\pi11,-and-Infinitely-Many-6-Secants","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Rational Surface with d=11, pi=11, and Infinitely Many 6-Secants","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"rational_d11_pi11_ss_inf()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#rational_d11_pi11_ss_inf-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"rational_d11_pi11_ss_inf","text":"rational_d11_pi11_ss_inf()\n\nReturn a smooth rational surface in mathbb P^4 with degree 11, sectional genus 11, and infinitely many 6-secants.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Ruled-Surfaces","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Ruled Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Ruled-Surface-with-d5,-\\pi1","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Ruled Surface with d=5, pi=1","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"quintic_elliptic_scroll()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#quintic_elliptic_scroll-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"quintic_elliptic_scroll","text":"quintic_elliptic_scroll()\n\nReturn a smooth ruled surface in mathbb P^4 with degree 5 and sectional genus 1.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Enriques-Surfaces","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Enriques Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Enriques-Surface-with-d9,-\\pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Enriques Surface with d=9, pi=6","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"enriques_d9_pi6()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#enriques_d9_pi6-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"enriques_d9_pi6","text":"enriques_d9_pi6()\n\nReturn a smooth Enriques surface in mathbb P^4 with degree 9 and sectional genus 6.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Enriques-Surface-with-d10,-\\pi8","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Enriques Surface with d=10, pi=8","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"enriques_d10_pi8()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#enriques_d10_pi8-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"enriques_d10_pi8","text":"enriques_d10_pi8()\n\nReturn a smooth Enriques surface in mathbb P^4 with degree 10 and sectional genus 8.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Enriques-Surface-with-d11,-\\pi10","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Enriques Surface with d=11, pi=10","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"enriques_d11_pi10()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#enriques_d11_pi10-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"enriques_d11_pi10","text":"enriques_d11_pi10()\n\nReturn a smooth Enriques surface in mathbb P^4 with degree 11 and sectional genus 10.\n\nThe returned surface is defined over a prime field of characteristic 43.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Enriques-Surface-with-d13,-\\pi16","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Enriques Surface with d=13, pi=16","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"enriques_d13_pi16()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#enriques_d13_pi16-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"enriques_d13_pi16","text":"enriques_d13_pi16()\n\nReturn a smooth Enriques surface in mathbb P^4 with degree 13 and sectional genus 16.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Enriques-Surface-with-d13,-\\pi16-2","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Enriques Surface with d=13, pi=16","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"enriques_d13_pi16_two()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#enriques_d13_pi16_two-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"enriques_d13_pi16_two","text":"enriques_d13_pi16_two()\n\nReturn a smooth Enriques surface in mathbb P^4 with degree 13 and sectional genus 16.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#K3-Surfaces","page":"Nongeneral Type Surfaces in mathbb P^4","title":"K3 Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d7,-\\pi5","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=7, pi=5","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d7_pi5","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d7_pi5","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d7_pi5","text":"k3_d7_pi5()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 7 and sectional genus 5.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d8,-\\pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=8, pi=6","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d8_pi6","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d8_pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d8_pi6","text":"k3_d8_pi6()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 8 and sectional genus 6.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d9,-\\pi8","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=9, pi=8","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d9_pi8","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d9_pi8","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d9_pi8","text":"k3_d9_pi8()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 9 and sectional genus 8.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d10,-\\pi9-which-is-Contained-in-one-Quartic","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=10, pi=9 which is Contained in one Quartic","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d10_pi9_quart_1()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d10_pi9_quart_1-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d10_pi9_quart_1","text":"k3_d10_pi9_quart_1()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 10 and sectional genus 9 which is contained in precisely one quartic.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d10,-\\pi9-which-is-Contained-in-a-Pencil-of-Quartics","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=10, pi=9 which is Contained in a Pencil of Quartics","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d10_pi9_quart_2()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d10_pi9_quart_2-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d10_pi9_quart_2","text":"k3_d10_pi9_quart_2()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 10 and sectional genus 9 which is contained in a pencil of quartics.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d11,-\\pi11-and-no-6-Secant","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=11, pi=11 and no 6-Secant","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d11_pi11_ss_0()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d11_pi11_ss_0-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d11_pi11_ss_0","text":"k3_d11_pi11_ss_0()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 11, sectional genus 11, and no 6-secant.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d11,-\\pi11-and-one-6-Secant","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=11, pi=11 and one 6-Secant","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d11_pi11_ss_1()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d11_pi11_ss_1-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d11_pi11_ss_1","text":"k3_d11_pi11_ss_1()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 11, sectional genus 11, and one 6-secant.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d11,-\\pi11-and-two-6-Secants","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=11, pi=11 and two 6-Secants","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d11_pi11_ss_2()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d11_pi11_ss_2-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d11_pi11_ss_2","text":"k3_d11_pi11_ss_2()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 11, sectional genus 11, and two 6-secants.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d11,-\\pi11-and-three-6-Secants","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=11, pi=11 and three 6-Secants","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d11_pi11_ss_3()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d11_pi11_ss_3-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d11_pi11_ss_3","text":"k3_d11_pi11_ss_3()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 11, sectional genus 11, and three 6-secants.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d11,-\\pi12","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=11, pi=12","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d11_pi12()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d11_pi12-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d11_pi12","text":"k3_d11_pi12()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 11 and sectional genus 12.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d12,-\\pi14","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=12, pi=14","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d12_pi14()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d12_pi14-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d12_pi14","text":"k3_d12_pi14()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 12 and sectional genus 14.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d13,-\\pi16","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=13, pi=16","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d13_pi16()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d13_pi16-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d13_pi16","text":"k3_d13_pi16()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 13 and sectional genus 16.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-K3-Surface-with-d14,-\\pi19","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A K3 Surface with d=14, pi=19","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"k3_d14_pi19()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#k3_d14_pi19-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"k3_d14_pi19","text":"k3_d14_pi19()\n\nReturn a smooth K3 surface in mathbb P^4 with degree 14 and sectional genus 19.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Bielliptic-Surfaces","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Bielliptic Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Bielliptic-Surface-with-d10,-\\pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Bielliptic Surface with d=10, pi=6","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"bielliptic_d10_pi6()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#bielliptic_d10_pi6-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"bielliptic_d10_pi6","text":"bielliptic_d10_pi6()\n\nReturn a smooth bielliptic surface in mathbb P^4 with degree 10 and sectional genus 6.\n\nThe returned surface is defined over a prime field of characteristic 911.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#A-Bielliptic-Surface-with-d15,-\\pi21","page":"Nongeneral Type Surfaces in mathbb P^4","title":"A Bielliptic Surface with d=15, pi=21","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"bielliptic_d15_pi21()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#bielliptic_d15_pi21-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"bielliptic_d15_pi21","text":"bielliptic_d15_pi21()\n\nReturn a smooth bielliptic surface in mathbb P^4 with degree 15 and sectional genus 21.\n\nThe returned surface is defined over a prime field of characteristic 911.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Abelian-Surfaces","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Abelian Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Abelian-Surface-with-d10,-\\pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Abelian Surface with d=10, pi=6","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"abelian_d10_pi6()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#abelian_d10_pi6-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"abelian_d10_pi6","text":"abelian_d10_pi6()\n\nReturn a smooth abelian surface in mathbb P^4 with degree 10 and sectional genus 6.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Abelian-Surface-with-d15,-\\pi21-which-is-Contained-in-a-Net-of-Quintics","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Abelian Surface with d=15, pi=21 which is Contained in a Net of Quintics","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"abelian_d15_pi21_quintic_3()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#abelian_d15_pi21_quintic_3-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"abelian_d15_pi21_quintic_3","text":"abelian_d15_pi21_quintic_3()\n\nReturn a smooth abelian surface in mathbb P^4 with degree 15 and sectional genus 21 which is contained in a net of quintics.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Abelian-Surface-with-d15,-\\pi21-which-is-Contained-in-one-Quintic","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Abelian Surface with d=15, pi=21 which is Contained in one Quintic","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"abelian_d15_pi21_quintic_1()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#abelian_d15_pi21_quintic_1-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"abelian_d15_pi21_quintic_1","text":"abelian_d15_pi21_quintic_1()\n\nReturn a smooth abelian surface in mathbb P^4 with degree 15 and sectional genus 21 which is contained in precisely one quintic.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Elliptic-Surfaces","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Elliptic Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d7,-\\pi6","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=7, pi=6","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d7_pi6()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d7_pi6-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d7_pi6","text":"elliptic_d7_pi6()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 7 and sectional genus 6.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d8,-\\pi7","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=8, pi=7","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d8_pi7()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d8_pi7-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d8_pi7","text":"elliptic_d8_pi7()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 8 and sectional genus 7.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d9,-\\pi7","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=9, pi=7","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d9_pi7()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d9_pi7-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d9_pi7","text":"elliptic_d9_pi7()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 9 and sectional genus 7.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d10,-\\pi9","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=10, pi=9","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d10_pi9()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d10_pi9-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d10_pi9","text":"elliptic_d10_pi9()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 10 and sectional genus 9.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d10,-\\pi10","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=10, pi=10","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d10_pi10()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d10_pi10-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d10_pi10","text":"elliptic_d10_pi10()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 10 and sectional genus 10.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d11,-\\pi12","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=11, pi=12","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d11_pi12()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d11_pi12-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d11_pi12","text":"elliptic_d11_pi12()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 11 and sectional genus 12.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d12,-\\pi13","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=12, pi=13","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d12_pi13()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d12_pi13-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d12_pi13","text":"elliptic_d12_pi13()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 12 and sectional genus 13.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d12,-\\pi14-and-no-6-Secant","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=12, pi=14 and no 6-Secant","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d12_pi14_ss_0()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d12_pi14_ss_0-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d12_pi14_ss_0","text":"elliptic_d12_pi14_ss_0()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 12, sectional genus 14, and no 6-secant.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#An-Elliptic-Surface-with-d12,-\\pi14,-and-Infinitely-Many-6-Secants","page":"Nongeneral Type Surfaces in mathbb P^4","title":"An Elliptic Surface with d=12, pi=14, and Infinitely Many 6-Secants","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"elliptic_d12_pi14_ss_inf()","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#elliptic_d12_pi14_ss_inf-Tuple{}","page":"Nongeneral Type Surfaces in mathbb P^4","title":"elliptic_d12_pi14_ss_inf","text":"elliptic_d12_pi14_ss_inf()\n\nReturn a smooth elliptic surface in mathbb P^4 with degree 12, sectional genus 14, and infinitely many 6-secants.\n\nThe returned surface is defined over a prime field of characteristic 31991.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/#Contact","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"Wolfram Decker.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/SurfacesP4/","page":"Nongeneral Type Surfaces in mathbb P^4","title":"Nongeneral Type Surfaces in mathbb P^4","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AbstractAlgebra/module_introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AbstractAlgebra/module_introduction/","page":"Introduction","title":"Introduction","text":"As with many generic constructions in AbstractAlgebra, the modules that are provided in AbstractAlgebra itself work over a Euclidean domain. Moreover, they are limited to finitely presented modules.","category":"page"},{"location":"AbstractAlgebra/module_introduction/","page":"Introduction","title":"Introduction","text":"Free modules and vector spaces are provided over Euclidean domains and fields respectively and then submodule, quotient module and direct sum module constructions are possible recursively over these.","category":"page"},{"location":"AbstractAlgebra/module_introduction/","page":"Introduction","title":"Introduction","text":"It's also possible to compute an invariant decomposition using the Smith Normal Form.","category":"page"},{"location":"AbstractAlgebra/module_introduction/","page":"Introduction","title":"Introduction","text":"The system also provides module homomorphisms and isomorphisms, building on top of the map interface.","category":"page"},{"location":"AbstractAlgebra/module_introduction/","page":"Introduction","title":"Introduction","text":"As for rings and fields, modules follow an interface which other modules are expected to follow. However, very little generic functionality is provided automatically once this interface is implemented by a new module type.","category":"page"},{"location":"AbstractAlgebra/module_introduction/","page":"Introduction","title":"Introduction","text":"The purpose of the module interface is simply to encourage uniformity in the module interfaces of systems that build on AbstractAlgebra. Of course modules are so diverse that this is a very loosely defined interface to accommodate the diversity of possible representations and implementations.","category":"page"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"The groups part of OSCAR provides functionality for handling","category":"page"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"Permutation groups\nMatrix groups\nFinitely presented groups\nPolycyclic groups\nProducts of groups\nGroups of automorphisms","category":"page"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"B. Huppert (1967)\nDerek F. Holt, Bettina Eick, Eamonn A. O'Brien (2005)","category":"page"},{"location":"Groups/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"Thomas Breuer,\nMax Horn.","category":"page"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Nemo/types/#Types-in-Nemo","page":"Types in Nemo","title":"Types in Nemo","text":"","category":"section"},{"location":"Nemo/types/","page":"Types in Nemo","title":"Types in Nemo","text":"Nemo is fully compatible with AbstractAlgebra.jl, but specialises implementations of various commonly used rings with a highly optimised C implementation, provided by the C libraries wrapped by Nemo.","category":"page"},{"location":"Nemo/types/","page":"Types in Nemo","title":"Types in Nemo","text":"Below, we give a list of all of the specialised types available in Nemo that implement rings using a specialised C library. The types of elements of the respective rings and other mathematical structures are given, and in parentheses we list the types of the parent objects of the given rings and structures.","category":"page"},{"location":"Nemo/types/","page":"Types in Nemo","title":"Types in Nemo","text":"Flint\nZZRingElem (ZZRing)\nQQFieldElem (QQField)\nzzModRingElem (zzModRing)\nZZModRingElem (ZZModRing`)\nfqPolyRepFieldElem (fqPolyRepField)\nfpFieldElem (fpField)\nFpFieldElem (FpField)\nFqPolyRepFieldElem (FqPolyRepField)\npadic (FlintPadicField)\nqadic (FlintQadicField)\nZZPolyRingElem (ZZPolyRing)\nQQPolyRingElem (QQPolyRing)\nzzModPolyRingElem (zzModPolyRing)\nZZModPolyRingElem (ZZModPolyRing)\nFqPolyRepPolyRingElem (FqPolyRepPolyRing)\nfqPolyRepPolyRingElem (fqPolyRepPolyRing)\nZZMPolyRingElem (ZZMPolyRing)\nQQMPolyRingElem (QQMPolyRing)\nzzModMPolyRingElem (zzModMPolyRing)\nfqPolyRepMPolyRingElem (fqPolyRepMPolyRing`)\nfpPolyRingElem (fpPolyRing)\nFpPolyRingElem (FpPolyRing)\nZZRelPowerSeriesRingElem (ZZRelPowerSeriesRing)\nZZAbsPowerSeriesRingElem (ZZAbsPowerSeriesRing)\nQQRelPowerSeriesRingElem (QQRelPowerSeriesRing)\nQQAbsPowerSeriesRingElem (QQAbsPowerSeriesRing)\nZZModRelPowerSeriesRingElem (ZZModRelPowerSeriesRing)\nZZModAbsPowerSeriesRingElem (ZZModAbsPowerSeriesRing)\nzzModRelPowerSeriesRingElem (zzModRelPowerSeriesRing)\nzzModAbsPowerSeriesRingElem (zzModAbsPowerSeriesRing)\nfpRelPowerSeriesRingElem (fpRelPowerSeriesRing)\nfpAbsPowerSeriesRingElem (fpAbsPowerSeriesRing)\nFpRelPowerSeriesRingElem (FpRelPowerSeriesRing)\nFpAbsPowerSeriesRingElem (FpAbsPowerSeriesRing)\nfqPolyRepRelPowerSeriesRingElem (fqPolyRepRelPowerSeriesRing)\nfqPolyRepAbsPowerSeriesRingElem (fqPolyRepAbsPowerSeriesRing)\nFqPolyRepRelPowerSeriesRingElem (FqPolyRepRelPowerSeriesRing)\nFqPolyRepAbsPowerSeriesRingElem (FqPolyRepAbsPowerSeriesRing)\nZZMatrix (ZZMatrixSpace)\nQQMatrix (QQMatrixSpace)\nzzModMatrix (zzModMatrixSpace)\nZZModMatrix (ZZModMatrixSpace`)\nfqPolyRepMatrix (fqPolyRepMatrixSpace)\nFqPolyRepMatrix (FqPolyRepMatrixSpace)\nfpMatrix (fpMatrixSpace)\nperm (SymmetricGroup)\nAntic\nnf_elem (AnticNumberField)\nArb\narb (ArbField)\nacb (AcbField)\narb_poly (ArbPolyRing)\nacb_poly (AcbPolyRing)\narb_mat (ArbMatSpace)\nacb_mat (AcbMatSpace)\nCalcium\nqqbar (CalciumQQBarField)\nca (CalciumField)","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/misc/#Miscellaneous","page":"Miscellaneous","title":"Miscellaneous","text":"","category":"section"},{"location":"AbstractAlgebra/misc/#Printing-options","page":"Miscellaneous","title":"Printing options","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"AbstractAlgebra supports printing to LaTeX using the MIME type \"text/latex\". To enable LaTeX rendering in Jupyter notebooks and query for the current state, use the following functions:","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"set_html_as_latex\nget_html_as_latex","category":"page"},{"location":"AbstractAlgebra/misc/#set_html_as_latex","page":"Miscellaneous","title":"set_html_as_latex","text":"set_html_as_latex(fl::Bool)\n\nToggles whether MIME type text/html should be printed as text/latex. Note that this is a global option. The return value is the old value.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#get_html_as_latex","page":"Miscellaneous","title":"get_html_as_latex","text":"get_html_as_latex()\n\nReturns whether MIME type text/html is printed as text/latex.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#Updating-the-type-diagrams","page":"Miscellaneous","title":"Updating the type diagrams","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Updating the diagrams of the documentation can be done by modifying and running the script docs/create_type_diagrams.jl. Note that this requires the package Kroki.","category":"page"},{"location":"AbstractAlgebra/misc/#Attributes","page":"Miscellaneous","title":"Attributes","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Often it is desirable to have a flexible way to attach additional data to mathematical structures such as groups, rings, fields, etc. beyond what the original implementation covers. To facilitate this, we provide an attributes system: for objects of suitable types, one may use set_attribute! to attach key-value pairs to the object, and query them using has_attribute, get_attribute and get_attribute!.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Attributes are supported for all singletons (i.e., instances of an empty struct type), as well as for instances of mutable struct type for which attribute storage was enabled. There are two ways to enable attribute storage for such types:","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"By applying @attributes to a mutable struct declaration, storage is reserved inside that struct type itself (this increases the size of each struct by 8 bytes if no attributes are set).\nBy applying @attributes to the name of a mutable struct type, methods are installed which store attributes to instances of the type in a WeakKeyDict outside the struct.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"@attributes\n@attr\nhas_attribute\nget_attribute\nget_attribute!\nset_attribute!","category":"page"},{"location":"AbstractAlgebra/misc/#@attributes","page":"Miscellaneous","title":"@attributes","text":"@attributes typedef\n\nThis is a helper macro that ensures that there is storage for attributes in the type declared in the expression typedef, which must be either a mutable struct definition expression, or the name of a mutable struct type.\n\nThe latter variant is useful to enable attribute storage for types defined in other packages. Note that @attributes is idempotent: when applied to a type for which attribute storage is already available, it does nothing.\n\nFor singleton types, attribute storage is also supported, and in fact always enabled. Thus it is not necessary to apply this macro to such a type.\n\nnote: Note\nWhen applied to a struct definition this macro adds a new field to the struct. For structs without constructor, this will change the signature of the default inner constructor, which requires explicit values for every field, including the attribute storage field this macro adds. Usually it is thus preferable to add an explicit default constructor, as in the example below.\n\nExamples\n\nApplying the macro to a struct definition results in internal storage of the attributes:\n\njulia> @attributes mutable struct MyGroup\n order::Int\n MyGroup(order::Int) = new(order)\n end\n\njulia> G = MyGroup(5)\nMyGroup(5, #undef)\n\njulia> set_attribute!(G, :isfinite, :true)\n\njulia> get_attribute(G, :isfinite)\ntrue\n\nApplying the macro to a typename results in external storage of the attributes:\n\njulia> mutable struct MyOtherGroup\n order::Int\n MyOtherGroup(order::Int) = new(order)\n end\n\njulia> @attributes MyOtherGroup\n\njulia> G = MyOtherGroup(5)\nMyOtherGroup(5)\n\njulia> set_attribute!(G, :isfinite, :true)\n\njulia> get_attribute(G, :isfinite)\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"AbstractAlgebra/misc/#@attr","page":"Miscellaneous","title":"@attr","text":"@attr [RetType] funcdef\n\nThis macro is applied to the definition of a unary function, and enables caching (\"memoization\") of its return values based on the argument. This assumes the argument supports attribute storing (see @attributes) via get_attribute!.\n\nThe name of the function is used as name for the underlying attribute.\n\nEffectively, this turns code like this:\n\n@attr RetType function myattr(obj::Foo)\n # ... expensive computation\n return result\nend\n\ninto something essentially equivalent to this:\n\nfunction myattr(obj::Foo)\n return get_attribute!(obj, :myattr) do\n # ... expensive computation\n return result\n end::RetType\nend\n\nExamples\n\njulia> @attributes mutable struct Foo\n x::Int\n Foo(x::Int) = new(x)\n end;\n\njulia> @attr Int function myattr(obj::Foo)\n println(\"Performing expensive computation\")\n return factorial(obj.x)\n end;\n\njulia> obj = Foo(5);\n\njulia> myattr(obj)\nPerforming expensive computation\n120\n\njulia> myattr(obj) # second time uses the cached result\n120\n\n\n\n\n\n\n","category":"macro"},{"location":"AbstractAlgebra/misc/#has_attribute","page":"Miscellaneous","title":"has_attribute","text":"has_attribute(G::Any, attr::Symbol)\n\nReturn a boolean indicating whether G has a value stored for the attribute attr.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#get_attribute","page":"Miscellaneous","title":"get_attribute","text":"get_attribute(f::Function, G::Any, attr::Symbol)\n\nReturn the value stored for the attribute attr, or if no value has been set, return f().\n\nThis is intended to be called using do block syntax.\n\nget_attribute(obj, attr) do\n # default value calculated here if needed\n ...\nend\n\n\n\n\n\nget_attribute(G::Any, attr::Symbol, default::Any = nothing)\n\nReturn the value stored for the attribute attr, or if no value has been set, return default.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#get_attribute!","page":"Miscellaneous","title":"get_attribute!","text":"get_attribute!(f::Function, G::Any, attr::Symbol)\n\nReturn the value stored for the attribute attr of G, or if no value has been set, store key => f() and return f().\n\nThis is intended to be called using do block syntax.\n\nget_attribute!(obj, attr) do\n # default value calculated here if needed\n ...\nend\n\n\n\n\n\nget_attribute!(G::Any, attr::Symbol, default::Any)\n\nReturn the value stored for the attribute attr of G, or if no value has been set, store key => default, and return default.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#set_attribute!","page":"Miscellaneous","title":"set_attribute!","text":"set_attribute!(G::Any, data::Pair{Symbol, <:Any}...)\n\nAttach the given sequence of key=>value pairs as attributes of G.\n\n\n\n\n\nset_attribute!(G::Any, attr::Symbol, value::Any)\n\nAttach the given value as attribute attr of G.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"The attributes system can be utilized to change the way certain objects are printed. We provide macros @show_special and @show_name for this purpose, both are called with the same argument as show: an IO-object and the object itself. Both are supposed to be used within the usual show function:","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"function show(io::IO, A::MyObj)\n @show_name(io, A)\n @show_special(io, A)\n\n ... usual stuff","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"@show_special checks if an attribute :show_special is present. If so, it has to be a function taking IO and the object. This is then called instead of the usual show function.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"@show_name will check if there is a variable in global (Main module) namespace with value bound to the object. In compact printing mode, the name is then shown instead of the object.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Note: if the object is stored in several variable, the first one will be used. Also the name, once used for printing, is stored in the object - hence will not change anymore.","category":"page"},{"location":"AbstractAlgebra/misc/#Advanced-printing","page":"Miscellaneous","title":"Advanced printing","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"To facilitate printing of nested mathematical structures, we provide a modified IOCustom object, that supports indentation and decapitalization.","category":"page"},{"location":"AbstractAlgebra/misc/#Example","page":"Miscellaneous","title":"Example","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"We illustrate this with an example","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"struct A{T}\n x::T\nend\n\nfunction Base.show(io::IO, a::A)\n io = AbstractAlgebra.pretty(io)\n println(io, \"Something of type A\")\n print(io, AbstractAlgebra.Indent(), \"over \", AbstractAlgebra.Lowercase(), a.x)\n print(io, AbstractAlgebra.Dedent()) # don't forget to undo the indentation!\nend\n\nstruct B\nend\n\nfunction Base.show(io::IO, b::B)\n io = AbstractAlgebra.pretty(io)\n print(io, LowercaseOff(), \"Hilbert thing\")\nend","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"At the REPL, this will then be printed as follows:","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"julia> A(2)\nSomething of type A\n over 2\n\njulia> A(A(2))\nSomething of type A\n over something of type A\n over 2\n\njulia> A(B())\nSomething of type A\n over Hilbert thing","category":"page"},{"location":"AbstractAlgebra/misc/#Documentation","page":"Miscellaneous","title":"Documentation","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"AbstractAlgebra.pretty\nAbstractAlgebra.Indent\nAbstractAlgebra.Dedent\nAbstractAlgebra.Lowercase\nAbstractAlgebra.LowercaseOff","category":"page"},{"location":"AbstractAlgebra/misc/#pretty","page":"Miscellaneous","title":"pretty","text":"pretty(io::IO) -> IOCustom\n\nWrap io into an IOCustom object.\n\nExamples\n\njulia> io = AbstractAlgebra.pretty(stdout);\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#Indent","page":"Miscellaneous","title":"Indent","text":"Indent\n\nWhen printed to an IOCustom object, increases the indentation level by one.\n\nExamples\n\njulia> io = AbstractAlgebra.pretty(stdout);\n\njulia> print(io, AbstractAlgebra.Indent(), \"This is indented\")\n This is indented\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/misc/#Dedent","page":"Miscellaneous","title":"Dedent","text":"Dedent\n\nWhen printed to an IOCustom object, decreases the indentation level by one.\n\nExamples\n\njulia> io = AbstractAlgebra.pretty(stdout);\n\njulia> print(io, AbstractAlgebra.Indent(), AbstractAlgebra.Dedent(), \"This is indented\")\nThis is indented\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/misc/#Lowercase","page":"Miscellaneous","title":"Lowercase","text":"Lowercase\n\nWhen printed to an IOCustom object, the next letter printed will be lowercase.\n\nExamples\n\njulia> io = AbstractAlgebra.pretty(stdout);\n\njulia> print(io, AbstractAlgebra.Lowercase(), \"Foo\")\nfoo\n\n\n\n\n\n","category":"type"},{"location":"AbstractAlgebra/misc/#LowercaseOff","page":"Miscellaneous","title":"LowercaseOff","text":"LowercaseOff\n\nWhen printed to an IOCustom object, the case of the next letter will not be changed when printed.\n\nExamples\n\njulia> io = AbstractAlgebra.pretty(stdout);\n\njulia> print(io, AbstractAlgebra.Lowercase(), AbstractAlgebra.LowercaseOff(), \"Foo\")\nFoo\n\n\n\n\n\n","category":"type"},{"location":"General/complex/#Complex-Algorithms-in-OSCAR","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"","category":"section"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"On this page we will list some of the more involved algorithmic problems of OSCAR which you may encounter in the background. For larger examples these may not terminate, due to lack of memory or time. We will not go into the details of the respective complexity, as there is sufficient literature.","category":"page"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"Often there are several algorithms in OSCAR solving a particular problem, and trying different alternatives may be worthwhile, as some algorithms may not terminate, while others finish in an instant.","category":"page"},{"location":"General/complex/#Groebner-and-Standard-Bases","page":"Complex Algorithms in OSCAR","title":"Groebner and Standard Bases","text":"","category":"section"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"A standard basis of an ideal is a generating with special properties. A standard basis is necessary for many (mathematical) low level operations from commutative algebra.","category":"page"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"Ideal membership\nRadical of an ideal\nKernel of a ring homomorphism\nKrull dimension of an ideal","category":"page"},{"location":"General/complex/#Double-Description","page":"Complex Algorithms in OSCAR","title":"Double Description","text":"","category":"section"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"A polyhedron may be described as the convex hull of a finite set of points or as the intersection of finitely many halfspaces. We omit the more complex cases of unbounded or non-fulldimensional polyhedra here. Computing one description from the other is done via double description algorithms. Many simple algorithms on polyhedra need a double description.","category":"page"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"Equality of polyhedra\nFace lattice\nLattice points\nHilbert basis","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/finfield/#Finite-fields","page":"Finite fields","title":"Finite fields","text":"","category":"section"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"AbstractAlgebra.jl provides a module, implemented in src/julia/GF.jl for finite fields. The module is a naive implementation that supports only fields of degree 1 (prime fields). They are modelled as mathbbZpmathbbZ for p a prime.","category":"page"},{"location":"AbstractAlgebra/finfield/#Types-and-parent-objects","page":"Finite fields","title":"Types and parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"Finite fields have type GFField{T} where T is either Int or BigInt.","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"Elements of such a finite field have type GFElem{T}.","category":"page"},{"location":"AbstractAlgebra/finfield/#Finite-field-constructors","page":"Finite fields","title":"Finite field constructors","text":"","category":"section"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"In order to construct finite fields in AbstractAlgebra.jl, one must first construct the field itself. This is accomplished with the following constructors.","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"GF(p::T) where T <: Integer","category":"page"},{"location":"AbstractAlgebra/finfield/#GF-Tuple{T} where T<:Integer","page":"Finite fields","title":"GF","text":"GF(p::T; check::Bool=true) where T <: Integer\n\nReturn the finite field mathbbF_p, where p is a prime. By default, the integer p is checked with a probabilistic algorithm for primality. When check == false, no check is made, but the behaviour of the resulting object is undefined if p is composite.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"Here are some examples of creating a finite field and making use of the resulting parent object to coerce various elements into the field.","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"julia> F = GF(13)\nFinite field F_13\n\njulia> g = F(3)\n3\n\njulia> h = F(g)\n3\n\njulia> GF(4)\nERROR: DomainError with 4:\nCharacteristic is not prime in GF(p)\nStacktrace:\n[...]","category":"page"},{"location":"AbstractAlgebra/finfield/#Basic-field-functionality","page":"Finite fields","title":"Basic field functionality","text":"","category":"section"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"The finite field module in AbstractAlgebra.jl implements the full Field interface.","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"We give some examples of such functionality.","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"julia> F = GF(13)\nFinite field F_13\n\njulia> f = F(7)\n7\n\njulia> h = zero(F)\n0\n\njulia> k = one(F)\n1\n\njulia> isone(k)\ntrue\n\njulia> iszero(h)\ntrue\n\njulia> T = parent(h)\nFinite field F_13\n\njulia> h == deepcopy(h)\ntrue\n\njulia> h = h + 2\n2\n\njulia> m = inv(k)\n1\n","category":"page"},{"location":"AbstractAlgebra/finfield/#Basic-manipulation-of-fields-and-elements","page":"Finite fields","title":"Basic manipulation of fields and elements","text":"","category":"section"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"data(::GFElem)\nlift(::GFElem)","category":"page"},{"location":"AbstractAlgebra/finfield/#data-Tuple{AbstractAlgebra.GFElem}","page":"Finite fields","title":"data","text":"data(R::GFElem)\n\nReturn the internal data used to represent the finite field element. This coincides with lift except where the internal data ids a machine integer.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/finfield/#lift-Tuple{AbstractAlgebra.GFElem}","page":"Finite fields","title":"lift","text":"lift(R::GFElem)\n\nLift the finite field element to the integers. The result will be a multiprecision integer regardless of how the field element is represented internally.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"gen{T <: Integer}(F::GFField{T})","category":"page"},{"location":"AbstractAlgebra/finfield/#gen-Union{Tuple{AbstractAlgebra.GFField{T}}, Tuple{T}} where T<:Integer","page":"Finite fields","title":"gen","text":"gen(R::GFField{T}) where T <: Integer\n\nReturn a generator of the field. Currently this returns 1.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"order(F::GFField)","category":"page"},{"location":"AbstractAlgebra/finfield/#order-Tuple{AbstractAlgebra.GFField}","page":"Finite fields","title":"order","text":"order(R::GFField)\n\nReturn the order, i.e. the number of element in the given finite field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"degree(F::GFField)","category":"page"},{"location":"AbstractAlgebra/finfield/#degree-Tuple{AbstractAlgebra.GFField}","page":"Finite fields","title":"degree","text":"degree(R::GFField)\n\nReturn the degree of the given finite field.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"Examples","category":"page"},{"location":"AbstractAlgebra/finfield/","page":"Finite fields","title":"Finite fields","text":"julia> F = GF(13)\nFinite field F_13\n\njulia> d = degree(F)\n1\n\njulia> n = order(F)\n13\n\njulia> g = gen(F)\n1\n","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/developer/interfaces/#Interfaces","page":"Interfaces","title":"Interfaces","text":"","category":"section"},{"location":"Nemo/developer/interfaces/#Functionality-for-Generic-and-Abstract-Types","page":"Interfaces","title":"Functionality for Generic and Abstract Types","text":"","category":"section"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"As previously mentioned, Nemo provides various generic types, e.g. Poly{T} for generic univariate polynomials and Mat{T} for generic matrices over a base ring. These and other polynomial and matrix types belong in turn to abstract types or unions thereof, e.g. PolyRingElem{T} is an abstract type representing all univariate polynomial types and MatrixElem{T} is a union of all Nemo matrix types.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"When implementing generic functionality, one should usually implement it for the abstract types and unions thereof, since the new functionality will then work for all types of the specified kind, instead of just the generic types.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"In order for this to work in practice, such implementations can only use functions in the relevant official interface. These are the functions required to be implemented by all types of that kind. For example, matrix implementations make heavy use of addeq! and mul! to accumulate entries, but they cannot make use of functions such as subeq! as it is not part of the official interface.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"In addition to implementations for abstract types and their unions, one may also like to provide specialised implementations for the generic types e.g. Poly{T} and Mat{T} as one would for other specialised types. The generic types are based on Julia arrays internally, and so it makes perfect sense to implement lower level functionality for these types specifically, as this may lead to performance gains. Such specialised implementations can make use of any functions provided for the generic types, whether in the interface or not.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"For convenience we list the most important abstract types and their unions for which one should usually prefer to write generic implementations.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"PolyRingElem{T} : all univariate polynomial types\nMPolyRingElem{T} : all multivariate polynomial types (see note below)\nMatrixElem{T} : union of all matrix types including matrix algebras\nMatElem{T} : all matrix types not including matrix algebras\nAbsPowerSeriesRingElem{T} : all abstract series types\nRelPowerSeriesRingElem{T} : all relative series types\nLaurentSeriesElem{T} : union of all Laurent series over rings and fields\nPuiseuxSeriesElem{T} : union of all Puiseux series over rings and fields\nFPModule{T} : all finitely presented modules over a Euclidean domain\nFPModuleElem{T} : all elems of fin. presented modules over a Euc. domain\nFracElem{T} : all fractions\nResElem{T} : all elements of a residue ring\nResFieldElem{T} : all elements of a residue field\nMap{D, C} : all maps (see Maps developer docs for a description)","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"N.B: inside the Generic submodule of AbstractAlgebra some abstract types Blah are only accessible by writing AbstractAlgebra.Blah. The unions are directly accessible. There may be generic types and abstract types with the same name, so this is more than just a convention.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Note that multivariate polynomials tend to require very specialised implementations depending heavily on implementation details of the specific multivariate type. Therefore it is rare to write implementations for the abstract type MPolyRingElem{T}. Instead, implementations tend to be done for each concrete multivariate type separately.","category":"page"},{"location":"Nemo/developer/interfaces/#Generic-interfaces","page":"Interfaces","title":"Generic interfaces","text":"","category":"section"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"As mentioned above, the generic implementations in Nemo depend on carefully written interfaces for each of the abstract types provided by the system.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"These interfaces are spelled out in the AbstractAlgebra documentation. Note that a generic implementation may depend on functions in both the required and optional interfaces as the optional functions are all implemented with generic fallbacks in terms of the required functions.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"For convenience we provide here a list of interfaces that can be relied on in generic implementations, along with a description.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Ring : all commutative rings in the system\nField : all fields in the system\nNCRing : all rings in the system (not necessarily commutative)\nEuclidean Ring : Euclidean rings (see notes below)\nUnivariate Polynomial Ring : all dense univariate polynomials\nMultivariate Polynomial Ring : all sparse distributed multivariate polys.\nSeries Ring : all series, relative and absolute\nResidue Ring : all quotients of gcd domains with gcdx by a principal ideal\nFraction Field : all fractions over a gcd domain with gcdx\nModule : all finitely presented modules over a Euclidean domain\nMatrix : all matrices over a commutative ring\nMap : all (set) maps in the system","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Although we allow Z/nZ in our definition of Euclidean ring, much of the functionality in Nemo can be expected to misbehave (impossible inverses, etc.) when working with Euclidean rings that are not domains. In some cases the algorithms just don't exist, and in other cases we simply haven't implemented the required functionality to support all Euclidean rings for which computations can be done.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Whether a ring is a Euclidean domain or not cannot be encoded in the type. Thus there is no abstract type for Euclidean domains or their elements. Instead, generic functions rely on the existence of certain functions such as gcdx to implement functionality for Euclidean domains.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"There is also currently no way to define a Euclidean function for a given ring (which is known to be Euclidean) and have the system recognise the ring as such. This kind of Euclidean interface may be provided in a future version of Nemo.","category":"page"},{"location":"Nemo/developer/interfaces/#Julia-interfaces-we-support","page":"Interfaces","title":"Julia interfaces we support","text":"","category":"section"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Many Julia interfaces rely on being able to create zero and one elements given the type only. As we use the parent/element model (see developer notes on this topic) we cannot support all Julia interfaces fully.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"We do however partially implement some Julia interfaces.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Iteration : iterators are currently provided for multivariate polynomials to iterate over the coefficients, terms and monomials. Nemo matrices can also be iterated over. Iteration proceeds down each column in turn. One can also iterate over all permutations and partitions. Finally, all finite field types can be iterated over.\nViews : because C libraries cannot be expected to implement the full range of Julia view types, views of matrices in Nemo can only be constructed for submatrices consisting of contiguous blocks in the original matrix.\nmap and similar : we implement the map and similar interfaces with the caveat that we generally use parent objects where Julia would use types. See the specific documentation for the module of interest to see details.\nzero and one : these are implemented for parent types, which is not what Julia typically expects. Exceptions include the Flint ZZRingElem and QQFieldElem types, as their parents are not parameterised, which makes it possible to implement these functions for the types as well as the parents.\nrand : we have a Nemo specific rand interface, which passes the tail of a given rand invocation to the rand function for the base ring, e.g. to create random matrix elements or polynomial coefficients and so on. In addition to this custom rand interface, we also support much of the Julia rand interface, with the usual caveat that we use parent objects instead of types where necessary.\nserialisation : unfortunately this is currently NOT implemented by Nemo, but we would certainly like to see that done in the future. It's not automatic because of the C objects that underly many of our constructions.\nNumber : Nemo number types do NOT belong to Julia's Number hierarchy, as we must make all our ring element types belong to our RingElem abstract type. To make some Julia Number types cooperate with Nemo, we define the unions RingElement and FieldElement which include some Julia types, such as BigInt and Rational{BigInt}, etc. Note that fixed precision integer types cannot be expected to be well-behaved when they overflow. We recommend using Nemo integer types if one wants good performance for small machine word sized integers, but no overflow when the integer becomes large (Nemo integers are based on Flint's multiprecision ZZRingElem type).\nhash : we implement hash functions for all major element types in Nemo.\ngetindex/setindex!/typed_hvcat : we implement these to access elements of Nemo matrices, however see the note below on row major representation. In addition, we allow creation of matrices using the notation R[a b; c d] etc. This is done by overloading typed_hvcat for the parent object R instead of a type as Julia would normally expect. This produces a Nemo matrix rather than a Julia one. Note that when passed a type, Julia's typed_hvcat can only construct Julia matrices for Nemo types such as ZZRingElem and QQFieldElem where elements can be constructed from types alone.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Many other Julia interfaces are either not yet implemented or only very partially implemented.","category":"page"},{"location":"Nemo/developer/interfaces/#Column-major-vs-row-major-matrices","page":"Interfaces","title":"Column major vs row major matrices","text":"","category":"section"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"Whereas Julia uses column major representation for its matrices, Nemo follows the convention of the C libraries it wraps and uses row major representation. Although Julia 2-D arrays are used internally in Nemo's generic matrix type, the interface from the perspective of the user is still the Nemo row major convention, not the Julia column major convention.","category":"page"},{"location":"Nemo/developer/interfaces/","page":"Interfaces","title":"Interfaces","text":"In row major representation, some row operations may be able to be performed more cheaply than similar column operations. In column major representation the converse is true. This may mean that some Julia matrix implementations may perform more slowly if naively ported to Nemo matrices, unless suitably modified.","category":"page"},{"location":"AbstractAlgebra/field/#Field-functionality","page":"Field functionality","title":"Field functionality","text":"","category":"section"},{"location":"AbstractAlgebra/field/#Abstract-types-for-rings","page":"Field functionality","title":"Abstract types for rings","text":"","category":"section"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"All field types in AbstractAlgebra belong to the Field abstract type and field elements belong to the FieldElem abstract type.","category":"page"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"As Julia types cannot belong to our FieldElem type hierarchy, we also provide the union type FieldElement which includes FieldElem in union with the Julia types Rational and AbstractFloat.","category":"page"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"Note that","category":"page"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"Field <: Ring\nFieldElem <: RingElem\nFieldElement <: RingElement","category":"page"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"Of course all Ring functionality is available for AbstractAlgebra fields and their elements.","category":"page"},{"location":"AbstractAlgebra/field/#Functions-for-types-and-parents-of-fields","page":"Field functionality","title":"Functions for types and parents of fields","text":"","category":"section"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"characteristic(R::MyParent)","category":"page"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"Return the characteristic of the field. If the characteristic is not known, an exception is raised.","category":"page"},{"location":"AbstractAlgebra/field/#Basic-functions","page":"Field functionality","title":"Basic functions","text":"","category":"section"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"is_unit(f::MyElem)","category":"page"},{"location":"AbstractAlgebra/field/","page":"Field functionality","title":"Field functionality","text":"Return true if the given element is invertible, i.e. nonzero in the field.","category":"page"},{"location":"Combinatorics/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"Combinatorics/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Combinatorics/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Combinatorics/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Combinatorics/intro/","page":"Introduction","title":"Introduction","text":"Simplicial complexes: Michael Joswig,\nGraphs: Lars Kastner,\nMatroids:\nBenjamin Schröter\nLukas Kühne.","category":"page"},{"location":"Combinatorics/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Combinatorics/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Hecke/#Hecke","page":"Hecke","title":"Hecke","text":"","category":"section"},{"location":"Hecke/#About","page":"Hecke","title":"About","text":"","category":"section"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"Hecke is a software package for algebraic number theory maintained by Claus Fieker, Carlo Sircana and Tommy Hofmann. It is written in julia and is based on the computer algebra package Nemo.","category":"page"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"https://github.com/thofma/Hecke.jl (Source code)\nhttps://thofma.github.io/Hecke.jl/dev/ (Online documentation)","category":"page"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"So far, Hecke provides the following features:","category":"page"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"Orders (including element and ideal arithmetic) in number fields\nComputation of maximal orders\nVerified residue computations of Dedekind zeta functions\nClass and Unit group computation, S-units, PID testing\nLattice enumeration\nSparse linear algebra\nNormal forms for modules over maximal orders\nExtensions of number fields, non-simple extensions of number fields\nOrders and ideals in extensions of fields\nAbelian groups\nRay class groups, quotients of ray class groups\nInvariant subgroups\nClass Field Theory\nAssociative Algebras","category":"page"},{"location":"Hecke/#Installation","page":"Hecke","title":"Installation","text":"","category":"section"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"To use Hecke, a julia version of 1.6 is necessary (the latest stable julia version will do). Please see https://julialang.org/downloads/ for instructions on how to obtain julia for your system. Once a suitable julia version is installed, use the following steps at the julia prompt to install Hecke:","category":"page"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"julia> using Pkg\njulia> Pkg.add(\"Hecke\")","category":"page"},{"location":"Hecke/#Quick-start","page":"Hecke","title":"Quick start","text":"","category":"section"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"Here is a quick example of using Hecke:","category":"page"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"julia> using Hecke\n...\n\nWelcome to\n\n _ _ _\n | | | | | |\n | |__| | ___ ___| | _____\n | __ |/ _ \\/ __| |/ / _ \\\n | | | | __/ (__| < __/\n |_| |_|\\___|\\___|_|\\_\\___|\n\nVersion 0.9.0 ...\n ... which comes with absolutely no warranty whatsoever\n(c) 2015-2018 by Claus Fieker, Tommy Hofmann and Carlo Sircana\n\njulia> Qx, x = polynomial_ring(FlintQQ, \"x\");\njulia> f = x^3 + 2;\njulia> K, a = number_field(f, \"a\");\njulia> O = maximal_order(K);\njulia> O\nMaximal order of Number field over Rational Field with defining polynomial x^3 + 2\nwith basis [1,a,a^2]","category":"page"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"The documentation of the single functions can also be accessed at the julia prompt. Here is an example:","category":"page"},{"location":"Hecke/","page":"Hecke","title":"Hecke","text":"help?> signature\nsearch: signature\n\n ----------------------------------------------------------------------------\n\n signature(O::NfMaximalOrder) -> Tuple{Int, Int}\n\n | Returns the signature of the ambient number field of \\mathcal O.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Normal-Toric-Varieties","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Introduction","page":"Normal Toric Varieties","title":"Introduction","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"We introduce two main types of normal toric varieties, distinguishing between the affine and non-affine case:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"AffineNormalToricVariety is the type for toric varieties associated to a cone sigma, denoted by U_sigma in David A. Cox, John B. Little, Henry K. Schenck (2011)\nNormalToricVariety is the type for toric varieties associated to a polyhedral fan Sigma, denoted by X_Sigma in David A. Cox, John B. Little, Henry K. Schenck (2011)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"warning: Warning\nThe lattice is always assumed to be the standard lattice mathbbZ^n. Transformations for non-standard lattices will have to be done by the user.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Constructors","page":"Normal Toric Varieties","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"All of the constructors below accept as their last argument an optional boolean. This boolean set_attributes controls whether the constructors sets attributes for the constructed variety. The benefit of such setters is increased performance. However, as per usual, a shortcut comes at a price. In the case at hand, it might lead to possible inconsistencies, despite our best efforts to prevent this from happening.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"The default is set_attributes = true, that is our constructors set attributes upon construction. If not desired, it can be switched off by passing set_attributes = false as last argument. Note however, that the constructors of del_pezzo_surface, hirzebruch_surface, projective_space and weighted_projective_space always make a default/standard choice for the grading of the Cox ring.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Affine-Toric-Varieties","page":"Normal Toric Varieties","title":"Affine Toric Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"affine_normal_toric_variety(C::Cone; set_attributes::Bool = true)\nnormal_toric_variety(C::Cone; set_attributes::Bool = true)\naffine_normal_toric_variety(v::NormalToricVariety; set_attributes::Bool = true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#affine_normal_toric_variety-Tuple{Cone}","page":"Normal Toric Varieties","title":"affine_normal_toric_variety","text":"affine_normal_toric_variety(C::Cone; set_attributes::Bool = true)\n\nConstruct the affine normal toric variety U_C corresponding to a polyhedral cone C.\n\nExamples\n\nSet C to be the positive orthant in two dimensions.\n\njulia> C = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> antv = affine_normal_toric_variety(C)\nNormal, affine toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety-Tuple{Cone}","page":"Normal Toric Varieties","title":"normal_toric_variety","text":"normal_toric_variety(C::Cone; set_attributes::Bool = true)\n\nConstruct the (affine) normal toric variety X_Sigma corresponding to a polyhedral fan Sigma = C consisting only of the cone C.\n\nExamples\n\nSet C to be the positive orthant in two dimensions.\n\njulia> C = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> ntv = normal_toric_variety(C)\nNormal, affine toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#affine_normal_toric_variety-Tuple{NormalToricVariety}","page":"Normal Toric Varieties","title":"affine_normal_toric_variety","text":"affine_normal_toric_variety(v::NormalToricVariety; set_attributes::Bool = true)\n\nFor internal design, we make a strict distinction between normal toric varieties and affine toric varieties. Given an affine, normal toric variety v, this method turns it into an affine toric variety.\n\nExamples\n\njulia> v = normal_toric_variety(positive_hull([1 0; 0 1]))\nNormal, affine toric variety\n\njulia> affineVariety = affine_normal_toric_variety(v)\nNormal, affine toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Normal-Toric-Varieties-2","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"normal_toric_variety(rays::AbstractCollection[RayVector], max_cones::Vector{Vector{Int64}}; non_redundant::Bool = false)\nnormal_toric_variety(PF::PolyhedralFan)\nnormal_toric_variety(P::Polyhedron; set_attributes::Bool = true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety-Tuple{Union{MatElem, AbstractVecOrMat}, Vector{Vector{Int64}}}","page":"Normal Toric Varieties","title":"normal_toric_variety","text":"normal_toric_variety(rays::AbstractMatrix, max_cones::Vector{Vector{Int64}})\n\nConstruct a normal toric variety X by providing the rays and maximal cones as vector of vectors. By default, this method assumes that the input is not non-redundant (e.g. that a ray was entered twice by accident). If the user is certain that no redundancy exists in the entered information, one can pass non_redundant = true as third argument. This will bypass these consistency checks. In addition, this will ensure that the order of the rays is not altered by the constructor.\n\nExamples\n\njulia> ray_generators = [[1,0], [0, 1], [-1, 5], [0, -1]]\n4-element Vector{Vector{Int64}}:\n [1, 0]\n [0, 1]\n [-1, 5]\n [0, -1]\n\njulia> max_cones = [[1, 2], [2, 3], [3, 4], [4, 1]]\n4-element Vector{Vector{Int64}}:\n [1, 2]\n [2, 3]\n [3, 4]\n [4, 1]\n\njulia> normal_toric_variety(ray_generators, max_cones)\nNormal toric variety\n\njulia> normal_toric_variety(ray_generators, max_cones; non_redundant = true)\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety-Tuple{PolyhedralFan}","page":"Normal Toric Varieties","title":"normal_toric_variety","text":"normal_toric_variety(PF::PolyhedralFan)\n\nConstruct the normal toric variety X_PF corresponding to a polyhedral fan PF.\n\nExamples\n\nTake PF to be the normal fan of the square.\n\njulia> square = cube(2)\nPolyhedron in ambient dimension 2\n\njulia> nf = normal_fan(square)\nPolyhedral fan in ambient dimension 2\n\njulia> ntv = normal_toric_variety(nf)\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety-Tuple{Polyhedron}","page":"Normal Toric Varieties","title":"normal_toric_variety","text":"normal_toric_variety(P::Polyhedron; set_attributes::Bool = true)\n\nConstruct the normal toric variety X_Sigma_P corresponding to the normal fan Sigma_P of the given polyhedron P.\n\nNote that this only coincides with the projective variety associated to P from the affine relations of the lattice points in P, if P is very ample.\n\nExamples\n\nSet P to be a square.\n\njulia> square = cube(2)\nPolyhedron in ambient dimension 2\n\njulia> ntv = normal_toric_variety(square)\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Famous-Toric-Vareties","page":"Normal Toric Varieties","title":"Famous Toric Vareties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"affine_space(::Type{NormalToricVariety}, d::Int; set_attributes::Bool = true)\ndel_pezzo_surface(::Type{NormalToricVariety}, b::Int; set_attributes::Bool = true)\nhirzebruch_surface(::Type{NormalToricVariety}, r::Int; set_attributes::Bool = true)\nprojective_space(::Type{NormalToricVariety}, d::Int; set_attributes::Bool = true)\nweighted_projective_space(::Type{NormalToricVariety}, w::Vector{T}; set_attributes::Bool = true) where {T <: IntegerUnion}","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#affine_space-Tuple{Type{NormalToricVariety}, Int64}","page":"Normal Toric Varieties","title":"affine_space","text":"affine_space(::Type{NormalToricVariety}, d::Int; set_attributes::Bool = true)\n\nConstructs the (toric) affine space of dimension d.\n\nExamples\n\njulia> affine_space(NormalToricVariety, 2)\nNormal, affine, 2-dimensional toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#del_pezzo_surface-Tuple{Type{NormalToricVariety}, Int64}","page":"Normal Toric Varieties","title":"del_pezzo_surface","text":"del_pezzo_surface(::Type{NormalToricVariety}, b::Int; set_attributes::Bool = true)\n\nConstructs the del Pezzo surface with b blowups for b at most 3.\n\nExamples\n\njulia> del_pezzo_surface(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#hirzebruch_surface-Tuple{Type{NormalToricVariety}, Int64}","page":"Normal Toric Varieties","title":"hirzebruch_surface","text":"hirzebruch_surface(::Type{NormalToricVariety}, r::Int; set_attributes::Bool = true)\n\nConstructs the r-th Hirzebruch surface.\n\nExamples\n\njulia> hirzebruch_surface(NormalToricVariety, 5)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#projective_space-Tuple{Type{NormalToricVariety}, Int64}","page":"Normal Toric Varieties","title":"projective_space","text":"projective_space(::Type{NormalToricVariety}, d::Int; set_attributes::Bool = true)\n\nConstruct the projective space of dimension d.\n\nExamples\n\njulia> projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#weighted_projective_space-Union{Tuple{T}, Tuple{Type{NormalToricVariety}, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Normal Toric Varieties","title":"weighted_projective_space","text":"weighted_projective_space(::Type{NormalToricVariety}, w::Vector{T}; set_attributes::Bool = true) where {T <: IntegerUnion}\n\nConstruct the weighted projective space corresponding to the weights w.\n\nExamples\n\njulia> weighted_projective_space(NormalToricVariety, [2,3,1])\nNormal, non-affine, simplicial, projective, 2-dimensional toric variety without torusfactor\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Constructions-based-on-triangulations","page":"Normal Toric Varieties","title":"Constructions based on triangulations","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"It is possible to associate toric varieties to star triangulations of the lattice points of polyhedrons. Specifically, we can associate to any full star triangulation of the lattice points of the polyhedron in question a toric variety. For this task, we provide the following constructors.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"normal_toric_variety_from_star_triangulation(P::Polyhedron; set_attributes::Bool = true)\nnormal_toric_varieties_from_star_triangulations(P::Polyhedron; set_attributes::Bool = true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety_from_star_triangulation-Tuple{Polyhedron}","page":"Normal Toric Varieties","title":"normal_toric_variety_from_star_triangulation","text":"normal_toric_variety_from_star_triangulation(P::Polyhedron; set_attributes::Bool = true)\n\nReturns a toric variety that was obtained from a fine regular star triangulation of the lattice points of the polyhedron P. This is particularly useful when the lattice points of the polyhedron in question admit many triangulations.\n\nExamples\n\njulia> P = convex_hull([0 0 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1])\nPolyhedron in ambient dimension 3\n\njulia> v = normal_toric_variety_from_star_triangulation(P)\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_varieties_from_star_triangulations-Tuple{Polyhedron}","page":"Normal Toric Varieties","title":"normal_toric_varieties_from_star_triangulations","text":"normal_toric_varieties_from_star_triangulations(P::Polyhedron; set_attributes::Bool = true)\n\nReturns the list of toric varieties obtained from fine regular star triangulations of the polyhedron P. With this we can compute the two phases of the famous conifold transition.\n\nExamples\n\njulia> P = convex_hull([0 0 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1])\nPolyhedron in ambient dimension 3\n\njulia> (v1, v2) = normal_toric_varieties_from_star_triangulations(P)\n2-element Vector{NormalToricVariety}:\n Normal toric variety\n Normal toric variety\n\njulia> stanley_reisner_ideal(v1)\nideal(x1*x4)\n\njulia> stanley_reisner_ideal(v2)\nideal(x2*x3)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"An application of this functionality exists in the physics. Witten's Generalized-Sigma models (GLSM) Edward Witten (1988) originally sparked interest in the physics community in toric varieties. On a mathematical level, this establishes a construction of toric varieties for which a Z^n grading of the Cox ring is provided. See for example Huijun Fan, Tyler Jarvis, Yongbin Ruan (2017), which describes this as GIT construction David A. Cox, John B. Little, Henry K. Schenck (2011).","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"Explicitly, given the grading of the Cox ring, the map from the group of torus invariant Weil divisors to the class group is known. Under the assumption that the variety in question has no torus factor, we can then identify the map from the lattice to the group of torus invariant Weil divisors as the kernel of the map from the torus invariant Weil divisor to the class group. The latter is a map between free Abelian groups, i.e. is provided by an integer valued matrix. The rows of this matrix are nothing but the ray generators of the fan of the toric variety. It then remains to triangulate these rays, hence in general for a GLSM the toric variety is only unique up to fine regular star triangulations. We provide the following two constructors:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"normal_toric_variety_from_glsm(charges::ZZMatrix; set_attributes::Bool = true)\nnormal_toric_varieties_from_glsm(charges::ZZMatrix; set_attributes::Bool = true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety_from_glsm-Tuple{ZZMatrix}","page":"Normal Toric Varieties","title":"normal_toric_variety_from_glsm","text":"normaltoricvarietyfromglsm(charges::ZZMatrix; set_attributes::Bool = true)\n\nThis function returns one toric variety with the desired GLSM charges. This can be particularly useful provided that there are many such toric varieties.\n\nExamples\n\njulia> charges = [[1, 1, 1]]\n1-element Vector{Vector{Int64}}:\n [1, 1, 1]\n\njulia> normal_toric_variety_from_glsm(charges)\nNormal toric variety\n\nFor convenience, we also support:\n\nnormaltoricvarietyfromglsm(charges::Vector{Vector{Int}})\nnormaltoricvarietyfromglsm(charges::Vector{Vector{ZZRingElem}})\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_varieties_from_glsm-Tuple{ZZMatrix}","page":"Normal Toric Varieties","title":"normal_toric_varieties_from_glsm","text":"normal_toric_varieties_from_glsm(charges::ZZMatrix; set_attributes::Bool = true)\n\nThis function returns all toric variety with the desired GLSM charges. This computation may take a long time if there are many such toric varieties.\n\nExamples\n\njulia> charges = [[1, 1, 1]]\n1-element Vector{Vector{Int64}}:\n [1, 1, 1]\n\njulia> normal_toric_varieties_from_glsm(charges)\n1-element Vector{NormalToricVariety}:\n Normal toric variety\n\njulia> varieties = normal_toric_varieties_from_glsm(matrix(ZZ, [1 2 3 4 6 0; -1 -1 -2 -2 -3 1]))\n1-element Vector{NormalToricVariety}:\n Normal toric variety\n\njulia> cox_ring(varieties[1])\nMultivariate polynomial ring in 6 variables over QQ graded by \n x1 -> [1 -1]\n x2 -> [2 -1]\n x3 -> [3 -2]\n x4 -> [4 -2]\n x5 -> [6 -3]\n x6 -> [0 1]\n\nFor convenience, we also support:\n\nnormaltoricvarietiesfromglsm(charges::Vector{Vector{Int}})\nnormaltoricvarietiesfromglsm(charges::Vector{Vector{ZZRingElem}})\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Further-Constructions","page":"Normal Toric Varieties","title":"Further Constructions","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"blow_up(v::AbstractNormalToricVariety, I::MPolyIdeal; coordinate_name::String = \"e\", set_attributes::Bool = true)\nblow_up(v::AbstractNormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String = \"e\", set_attributes::Bool = true)\nblow_up(v::AbstractNormalToricVariety, n::Int; coordinate_name::String = \"e\", set_attributes::Bool = true)\nBase.:*(v::AbstractNormalToricVariety, w::AbstractNormalToricVariety; set_attributes::Bool = true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#blow_up-Tuple{Oscar.AbstractNormalToricVariety, MPolyIdeal}","page":"Normal Toric Varieties","title":"blow_up","text":"blow_up(v::AbstractNormalToricVariety, I::MPolyIdeal; coordinate_name::String = \"e\", set_attributes::Bool = true)\n\nBlow up the toric variety by subdividing the cone in the list of all cones of the fan of v which corresponds to the provided ideal I. Note that this cone need not be maximal.\n\nBy default, we pick \"e\" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor\n\njulia> (x1,x2,x3,x4) = gens(cox_ring(P3))\n4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n x4\n\njulia> I = ideal([x2,x3])\nideal(x2, x3)\n\njulia> bP3 = domain(blow_up(P3, I))\nNormal toric variety\n\njulia> cox_ring(bP3)\nMultivariate polynomial ring in 5 variables over QQ graded by\n x1 -> [1 0]\n x2 -> [0 1]\n x3 -> [0 1]\n x4 -> [1 0]\n e -> [1 -1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#blow_up-Tuple{Oscar.AbstractNormalToricVariety, AbstractVector{<:Union{Integer, ZZRingElem}}}","page":"Normal Toric Varieties","title":"blow_up","text":"blow_up(v::AbstractNormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String = \"e\", set_attributes::Bool = true)\n\nBlow up the toric variety by subdividing the fan of the variety with the provided new ray. Note that this ray must be a primitive element in the lattice Z^d, with d the dimension of the fan. This function returns the corresponding blowdown morphism.\n\nBy default, we pick \"e\" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor\n\njulia> blow_down_morphism = blow_up(P3, [0, 1, 1])\nA toric morphism\n\njulia> bP3 = domain(blow_down_morphism)\nNormal toric variety\n\njulia> cox_ring(bP3)\nMultivariate polynomial ring in 5 variables over QQ graded by\n x1 -> [1 0]\n x2 -> [0 1]\n x3 -> [0 1]\n x4 -> [1 0]\n e -> [1 -1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#blow_up-Tuple{Oscar.AbstractNormalToricVariety, Int64}","page":"Normal Toric Varieties","title":"blow_up","text":"blow_up(v::AbstractNormalToricVariety, n::Int; coordinate_name::String = \"e\", set_attributes::Bool = true)\n\nBlow up the toric variety by subdividing the n-th cone in the list of all cones of the fan of v. This cone need not be maximal. This function returns the corresponding blowdown morphism.\n\nBy default, we pick \"e\" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor\n\njulia> blow_down_morphism = blow_up(P3, 5)\nA toric morphism\n\njulia> bP3 = domain(blow_down_morphism)\nNormal toric variety\n\njulia> cox_ring(bP3)\nMultivariate polynomial ring in 5 variables over QQ graded by\n x1 -> [1 0]\n x2 -> [0 1]\n x3 -> [0 1]\n x4 -> [1 0]\n e -> [1 -1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#*-Tuple{Oscar.AbstractNormalToricVariety, Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"*","text":"Base.:*(v::AbstractNormalToricVariety, w::AbstractNormalToricVariety; set_attributes::Bool = true)\n\nReturn the Cartesian/direct product of two normal toric varieties v and w.\n\nBy default, we prepend an \"x\" to all homogeneous coordinate names of the first factor v and a \"y\" to all homogeneous coordinate names of the second factor w. This default can be overwritten by invoking set_coordinate_names after creating the variety (cf. set_coordinate_names(v::AbstractNormalToricVariety, coordinate_names::Vector{String})).\n\nImportant: Recall that the coordinate names can only be changed as long as the toric variety in question is not finalized (cf. is_finalized(v::AbstractNormalToricVariety)).\n\nCrucially, the order of the homogeneous coordinates is not shuffled. To be more specific, assume that v has n_1 and w has n_2 homogeneous coordinates. Then v * w has n_1 + n_2 homogeneous coordinates. The first n_1 of these coordinates are those of v and appear in the very same order as they do for v. The remaining n_2 homogeneous coordinates are those of w and appear in the very same order as they do for w.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> v1 = P2 * P2\nNormal toric variety\n\njulia> cox_ring(v1)\nMultivariate polynomial ring in 6 variables over QQ graded by\n xx1 -> [1 0]\n xx2 -> [1 0]\n xx3 -> [1 0]\n yx1 -> [0 1]\n yx2 -> [0 1]\n yx3 -> [0 1]\n\njulia> v2 = P2 * P2\nNormal toric variety\n\njulia> set_coordinate_names(v2, [\"x1\", \"x2\", \"x3\", \"y1\", \"y2\", \"y3\"])\n\n\njulia> cox_ring(v2)\nMultivariate polynomial ring in 6 variables over QQ graded by\n x1 -> [1 0]\n x2 -> [1 0]\n x3 -> [1 0]\n y1 -> [0 1]\n y2 -> [0 1]\n y3 -> [0 1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Properties-of-Toric-Varieties","page":"Normal Toric Varieties","title":"Properties of Toric Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"has_torusfactor(v::AbstractNormalToricVariety)\nis_affine(v::AbstractNormalToricVariety)\nis_complete(v::AbstractNormalToricVariety)\nis_fano(v::AbstractNormalToricVariety)\nis_gorenstein(v::AbstractNormalToricVariety)\nis_simplicial(v::AbstractNormalToricVariety)\nis_smooth(v::AbstractNormalToricVariety)\nis_normal(v::AbstractNormalToricVariety)\nis_orbifold(v::AbstractNormalToricVariety)\nis_projective(v::AbstractNormalToricVariety)\nis_projective_space(v::AbstractNormalToricVariety)\nis_q_gorenstein(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#has_torusfactor-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"has_torusfactor","text":"has_torusfactor(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v has a torus factor.\n\nExamples\n\njulia> has_torusfactor(projective_space(NormalToricVariety, 2))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_affine-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_affine","text":"is_affine(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is affine.\n\nExamples\n\njulia> is_affine(projective_space(NormalToricVariety, 2))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_complete-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_complete","text":"is_complete(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is complete.\n\nExamples\n\njulia> is_complete(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_fano-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_fano","text":"is_fano(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is fano.\n\nExamples\n\njulia> is_fano(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_gorenstein-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_gorenstein","text":"is_gorenstein(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is Gorenstein.\n\nExamples\n\njulia> is_gorenstein(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_simplicial-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_simplicial","text":"is_simplicial(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is simplicial. Hence, this function works just as is_orbifold. It is implemented for user convenience.\n\nExamples\n\njulia> is_simplicial(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_smooth-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_smooth","text":"is_smooth(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is smooth.\n\nExamples\n\njulia> is_smooth(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_normal-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_normal","text":"is_normal(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is normal. (This function is somewhat tautological at this point.)\n\nExamples\n\njulia> is_normal(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_orbifold-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_orbifold","text":"is_orbifold(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is an orbifold.\n\nExamples\n\njulia> is_orbifold(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_projective-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_projective","text":"is_projective(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is projective, i.e. if the fan of v is the the normal fan of a polytope.\n\nExamples\n\njulia> is_projective(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_projective_space-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_projective_space","text":"is_projective_space(v::AbstractNormalToricVariety)\n\nDecides if the normal toric varieties v is a projective space.\n\nExamples\n\njulia> F5 = hirzebruch_surface(NormalToricVariety, 5)\nNormal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor\n\njulia> is_projective_space(F5)\nfalse\n\njulia> is_projective_space(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_q_gorenstein-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_q_gorenstein","text":"is_q_gorenstein(v::AbstractNormalToricVariety)\n\nChecks if the normal toric variety v is Q-Gorenstein.\n\nExamples\n\njulia> is_q_gorenstein(projective_space(NormalToricVariety, 2))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Operations-for-Toric-Varieties","page":"Normal Toric Varieties","title":"Operations for Toric Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Affine-Open-Covering","page":"Normal Toric Varieties","title":"Affine Open Covering","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"affine_open_covering( v::AbstractNormalToricVariety )","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#affine_open_covering-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"affine_open_covering","text":"affine_open_covering(v::AbstractNormalToricVariety)\n\nCompute an affine open cover of the normal toric variety v, i.e. returns a list of affine toric varieties.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> affine_open_covering(p2)\n3-element Vector{AffineNormalToricVariety}:\n Normal, affine toric variety\n Normal, affine toric variety\n Normal, affine toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Characters,-Weil-Divisors,-Cartier-Divisors,-Class-Group-and-Picard-Group","page":"Normal Toric Varieties","title":"Characters, Weil Divisors, Cartier Divisors, Class Group and Picard Group","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"torusinvariant_cartier_divisor_group(v::AbstractNormalToricVariety)\ncharacter_lattice(v::AbstractNormalToricVariety)\nclass_group(v::AbstractNormalToricVariety)\nmap_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)\nmap_from_torusinvariant_cartier_divisor_group_to_picard_group(v::AbstractNormalToricVariety)\nmap_from_character_lattice_to_torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)\nmap_from_torusinvariant_weil_divisor_group_to_class_group(v::AbstractNormalToricVariety)\npicard_group(v::AbstractNormalToricVariety)\ntorusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)\ntorusinvariant_prime_divisors(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#torusinvariant_cartier_divisor_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"torusinvariant_cartier_divisor_group","text":"torusinvariant_cartier_divisor_group(v::AbstractNormalToricVariety)\n\nReturn the Cartier divisor group of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> torusinvariant_cartier_divisor_group(p2)\nGrpAb: Z^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#character_lattice-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"character_lattice","text":"character_lattice(v::AbstractNormalToricVariety)\n\nReturn the character lattice of a normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> character_lattice(p2)\nGrpAb: Z^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#class_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"class_group","text":"class_group(v::AbstractNormalToricVariety)\n\nReturn the class group of the normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> class_group(p2)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group","text":"map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)\n\nReturn the embedding of the group of Cartier divisors into the group of torus-invariant Weil divisors of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(p2)\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^3\nCodomain:\n=========\nAbelian group with structure: Z^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_torusinvariant_cartier_divisor_group_to_picard_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"map_from_torusinvariant_cartier_divisor_group_to_picard_group","text":"map_from_torusinvariant_cartier_divisor_group_to_picard_group(v::AbstractNormalToricVariety)\n\nReturn the map from the Cartier divisors to the Picard group of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> map_from_torusinvariant_cartier_divisor_group_to_picard_group(p2)\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^3\nCodomain:\n=========\nAbelian group with structure: Z\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_character_lattice_to_torusinvariant_weil_divisor_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"map_from_character_lattice_to_torusinvariant_weil_divisor_group","text":"map_from_character_lattice_to_torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)\n\nReturn the map from the character lattice to the group of principal divisors of a normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> map_from_character_lattice_to_torusinvariant_weil_divisor_group(p2)\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^2\nCodomain:\n=========\nAbelian group with structure: Z^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_torusinvariant_weil_divisor_group_to_class_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"map_from_torusinvariant_weil_divisor_group_to_class_group","text":"map_from_torusinvariant_weil_divisor_group_to_class_group(v::AbstractNormalToricVariety)\n\nReturn the map from the group of Weil divisors to the class of group of a normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> map_from_torusinvariant_weil_divisor_group_to_class_group(p2)\nMap with following data\nDomain:\n=======\nAbelian group with structure: Z^3\nCodomain:\n=========\nAbelian group with structure: Z\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#picard_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"picard_group","text":"picard_group(v::AbstractNormalToricVariety)\n\nReturn the Picard group of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> picard_group(p2)\nGrpAb: Z\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#torusinvariant_weil_divisor_group-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"torusinvariant_weil_divisor_group","text":"torusinvariant_weil_divisor_group(v::AbstractNormalToricVariety)\n\nReturn the torusinvariant divisor group of a normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> torusinvariant_weil_divisor_group(p2)\nGrpAb: Z^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#torusinvariant_prime_divisors-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"torusinvariant_prime_divisors","text":"torusinvariant_prime_divisors(v::AbstractNormalToricVariety)\n\nReturn the list of all torus invariant prime divisors in a normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> torusinvariant_prime_divisors(p2)\n3-element Vector{ToricDivisor}:\n Torus-invariant, prime divisor on a normal toric variety\n Torus-invariant, prime divisor on a normal toric variety\n Torus-invariant, prime divisor on a normal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Cones-and-Fans","page":"Normal Toric Varieties","title":"Cones and Fans","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"polyhedral_fan(v::AbstractNormalToricVariety)\ncone(v::AffineNormalToricVariety)\ndual_cone(v::AffineNormalToricVariety)\nhilbert_basis(v::AffineNormalToricVariety)\nmori_cone(v::NormalToricVariety)\nnef_cone(v::NormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#polyhedral_fan-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"polyhedral_fan","text":"polyhedral_fan(v::AbstractNormalToricVariety)\n\nReturn the fan of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> polyhedral_fan(p2)\nPolyhedral fan in ambient dimension 2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#cone-Tuple{AffineNormalToricVariety}","page":"Normal Toric Varieties","title":"cone","text":"cone(v::AffineNormalToricVariety)\n\nReturn the cone of the affine normal toric variety v.\n\nExamples\n\njulia> cone(affine_normal_toric_variety(Oscar.positive_hull([1 1; -1 1])))\nPolyhedral cone in ambient dimension 2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#dual_cone-Tuple{AffineNormalToricVariety}","page":"Normal Toric Varieties","title":"dual_cone","text":"dual_cone(v::AffineNormalToricVariety)\n\nReturn the dual cone of the affine normal toric variety v.\n\nExamples\n\njulia> C = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> antv = affine_normal_toric_variety(C)\nNormal, affine toric variety\n\njulia> dual_cone(antv)\nPolyhedral cone in ambient dimension 2\n\njulia> polarize(cone(antv)) == dual_cone(antv)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#hilbert_basis-Tuple{AffineNormalToricVariety}","page":"Normal Toric Varieties","title":"hilbert_basis","text":"hilbert_basis(v::AffineNormalToricVariety)\n\nFor an affine toric variety v, this returns the Hilbert basis of the cone dual to the cone of v.\n\nExamples\n\njulia> C = positive_hull([-1 1; 1 1])\nPolyhedral cone in ambient dimension 2\n\njulia> antv = affine_normal_toric_variety(C)\nNormal, affine toric variety\n\njulia> hilbert_basis(antv)\n[-1 1]\n[ 1 1]\n[ 0 1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#mori_cone-Tuple{NormalToricVariety}","page":"Normal Toric Varieties","title":"mori_cone","text":"mori_cone(v::NormalToricVariety)\n\nReturn the mori cone of the normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> mori = mori_cone(p2)\nPolyhedral cone in ambient dimension 1\n\njulia> dim(mori)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#nef_cone-Tuple{NormalToricVariety}","page":"Normal Toric Varieties","title":"nef_cone","text":"nef_cone(v::NormalToricVariety)\n\nReturn the nef cone of the normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor\n\njulia> nef = nef_cone(p2)\nPolyhedral cone in ambient dimension 1\n\njulia> dim(nef)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Dimensions","page":"Normal Toric Varieties","title":"Dimensions","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"dim(v::AbstractNormalToricVariety)\ndim_of_torusfactor(v::AbstractNormalToricVariety)\neuler_characteristic(v::AbstractNormalToricVariety)\nbetti_number(v::AbstractNormalToricVariety, i::Int)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#dim-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"dim","text":"dim(v::AbstractNormalToricVariety)\n\nReturn the dimension of the normal toric variety v.\n\nExamples\n\njulia> C = Oscar.positive_hull([1 0]);\n\njulia> antv = affine_normal_toric_variety(C);\n\njulia> dim(antv)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#dim_of_torusfactor-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"dim_of_torusfactor","text":"dim_of_torusfactor(v::AbstractNormalToricVariety)\n\nReturn the dimension of the torus factor of the normal toric variety v.\n\nExamples\n\njulia> C = Oscar.positive_hull([1 0]);\n\njulia> antv = affine_normal_toric_variety(C);\n\njulia> dim_of_torusfactor(antv)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#euler_characteristic-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"euler_characteristic","text":"euler_characteristic(v::AbstractNormalToricVariety)\n\nReturn the Euler characteristic of the normal toric variety v.\n\nExamples\n\njulia> C = Oscar.positive_hull([1 0]);\n\njulia> antv = affine_normal_toric_variety(C);\n\njulia> euler_characteristic(antv)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#betti_number-Tuple{Oscar.AbstractNormalToricVariety, Int64}","page":"Normal Toric Varieties","title":"betti_number","text":"betti_number(v::AbstractNormalToricVariety, i::Int)\n\nCompute the i-th Betti number of the normal toric variety v. Specifically, this method returns the dimension of the i-th simplicial homology group (with rational coefficients) of v. The employed algorithm is derived from theorem 12.3.12 in David A. Cox, John B. Little, Henry K. Schenck (2011). Note that this theorem requires that the normal toric variety v is both complete and simplicial.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal, non-affine, smooth, projective, gorenstein, fano, 3-dimensional toric variety without torusfactor\n\njulia> betti_number(P3,0)\n1\n\njulia> betti_number(P3, 1)\n0\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Rings-and-ideals","page":"Normal Toric Varieties","title":"Rings and ideals","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"We support the following rings and ideals for toric varieties:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"Cox ring (also termed the \"total coordinate ring\" in David A. Cox, John B. Little, Henry K. Schenck (2011)),\ncoordinate ring of torus,\ncohomology_ring,\nChow ring,\nirrelevant ideal,\nStanley-Reisner ideal,\nideal of linear relations,\ntoric ideal.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"Of course, for any of these coordinate names and the coefficient ring have to be chosen. The coefficient ring is fixed to Q. Therefore, the method coefficient_ring(v::AbstractNormalToricVariety) always return the field of rational numbers. For the coordinate names, we provide the following setter functions:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"set_coordinate_names(v::AbstractNormalToricVariety, coordinate_names::Vector{String})\nset_coordinate_names_of_torus(v::AbstractNormalToricVariety, coordinate_names::Vector{String})","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#set_coordinate_names-Tuple{Oscar.AbstractNormalToricVariety, Vector{String}}","page":"Normal Toric Varieties","title":"set_coordinate_names","text":"set_coordinate_names(v::AbstractNormalToricVariety, coordinate_names::Vector{String})\n\nAllows to set the names of the homogeneous coordinates as long as the toric variety in question is not yet finalized (cf. is_finalized(v::AbstractNormalToricVariety)).\n\nExamples\n\njulia> C = Oscar.positive_hull([1 0]);\n\njulia> antv = affine_normal_toric_variety(C);\n\njulia> set_coordinate_names(antv, [\"u\"])\n\njulia> coordinate_names(antv)\n1-element Vector{String}:\n \"u\"\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#set_coordinate_names_of_torus-Tuple{Oscar.AbstractNormalToricVariety, Vector{String}}","page":"Normal Toric Varieties","title":"set_coordinate_names_of_torus","text":"set_coordinate_names_of_torus(v::AbstractNormalToricVariety, coordinate_names::Vector{String})\n\nAllows to set the names of the coordinates of the torus.\n\nExamples\n\njulia> F3 = hirzebruch_surface(NormalToricVariety, 3);\n\njulia> set_coordinate_names_of_torus(F3, [\"u\", \"v\"])\n\njulia> coordinate_names_of_torus(F3)\n2-element Vector{String}:\n \"u\"\n \"v\"\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"The following methods allow to etract the chosen coordinates:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"coordinate_names(v::AbstractNormalToricVariety)\ncoordinate_names_of_torus(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#coordinate_names-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"coordinate_names","text":"coordinate_names(v::AbstractNormalToricVariety)\n\nReturn the names of the homogeneous coordinates of the normal toric variety v. The default is x1, ..., xn.\n\nExamples\n\njulia> C = Oscar.positive_hull([1 0]);\n\njulia> antv = affine_normal_toric_variety(C);\n\njulia> coordinate_names(antv)\n1-element Vector{String}:\n \"x1\"\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#coordinate_names_of_torus-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"coordinate_names_of_torus","text":"coordinate_names_of_torus(v::AbstractNormalToricVariety)\n\nReturn the names of the coordinates of the torus of the normal toric variety v. The default is x1, ..., xn.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"In order to efficiently construct algebraic cycles (elements of the Chox ring), cohomology classes (elements of the cohomology ring), or in order to compare ideals, it is imperative to fix choices of the coordinate names. The default value for coordinate names is [x1, x2, ... ]. The choice of coordinate names is fixed, once one of the above-mentioned rings is computed via one the following methods:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"cox_ring(v::AbstractNormalToricVariety)\nirrelevant_ideal(v::AbstractNormalToricVariety)\nideal_of_linear_relations(v::AbstractNormalToricVariety)\nstanley_reisner_ideal(v::AbstractNormalToricVariety)\ntoric_ideal(antv::AffineNormalToricVariety)\ncoordinate_ring_of_torus(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#cox_ring-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"cox_ring","text":"cox_ring(v::AbstractNormalToricVariety)\n\nComputes the Cox ring of the normal toric variety v. Note that David A. Cox, John B. Little, Henry K. Schenck (2011) refers to this ring as the \"total coordinate ring\".\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> set_coordinate_names(p2, [\"y1\", \"y2\", \"y3\"])\n\njulia> cox_ring(p2)\nMultivariate polynomial ring in 3 variables over QQ graded by\n y1 -> [1]\n y2 -> [1]\n y3 -> [1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#irrelevant_ideal-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"irrelevant_ideal","text":"irrelevant_ideal(v::AbstractNormalToricVariety)\n\nReturn the irrelevant ideal of a normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> length(gens(irrelevant_ideal(p2)))\n3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#ideal_of_linear_relations-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"ideal_of_linear_relations","text":"ideal_of_linear_relations(v::AbstractNormalToricVariety)\n\nReturn the ideal of linear relations of the simplicial and complete toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> ngens(ideal_of_linear_relations(p2))\n2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#stanley_reisner_ideal-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"stanley_reisner_ideal","text":"stanley_reisner_ideal(v::AbstractNormalToricVariety)\n\nReturn the Stanley-Reisner ideal of a normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> ngens(stanley_reisner_ideal(p2))\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#toric_ideal-Tuple{AffineNormalToricVariety}","page":"Normal Toric Varieties","title":"toric_ideal","text":"toric_ideal(antv::AffineNormalToricVariety)\n\nReturn the toric ideal defining the affine normal toric variety.\n\nExamples\n\nTake the cone over the square at height one. The resulting toric variety has one defining equation. In projective space this corresponds to mathbbP^1timesmathbbP^1. Note that this cone is self-dual, the toric ideal comes from the dual cone.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 1 0 1; 1 1 1])\nPolyhedral cone in ambient dimension 3\n\njulia> antv = affine_normal_toric_variety(C)\nNormal, affine toric variety\n\njulia> toric_ideal(antv)\nideal(-x1*x2 + x3*x4)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#coordinate_ring_of_torus-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"coordinate_ring_of_torus","text":"coordinate_ring_of_torus(v::AbstractNormalToricVariety)\n\nComputes the coordinate ring of the torus of the normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> set_coordinate_names_of_torus(p2, [\"y1\", \"y2\"])\n\njulia> coordinate_ring_of_torus(p2)\nQuotient\n of multivariate polynomial ring in 4 variables over QQ\n by ideal(y1*y1_ - 1, y2*y2_ - 1)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"One can check the status as follows:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"is_finalized(v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_finalized-Tuple{Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"is_finalized","text":"is_finalized(v::AbstractNormalToricVariety)\n\nChecks if the Cox ring, the coordinate ring of the torus, the cohomology_ring, the Chow ring, the Stanley-Reisner ideal, the irrelevant ideal, the ideal of linear relations or the toric ideal has been cached. If any of these has been cached, then this function returns true and otherwise false.\n\nExamples\n\njulia> is_finalized(del_pezzo_surface(NormalToricVariety, 3))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"After the variety finalized, one can enforce to obtain the above ideals in different rings. Also, one can opt to compute the above rings with a different choice of coordinate names and different coefficient ring. To this end, onc provides a custom ring (which reflects the desired choice of coordinate names and coefficient ring) as first argument. However, note that the cached ideals and rings are not altered.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"cox_ring(R::MPolyRing, v::AbstractNormalToricVariety)\nirrelevant_ideal(R::MPolyRing, v::AbstractNormalToricVariety)\nideal_of_linear_relations(R::MPolyRing, v::AbstractNormalToricVariety)\nstanley_reisner_ideal(R::MPolyRing, v::AbstractNormalToricVariety)\ntoric_ideal(R::MPolyRing, antv::AffineNormalToricVariety)\ncoordinate_ring_of_torus(R::MPolyRing, v::AbstractNormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#cox_ring-Tuple{MPolyRing, Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"cox_ring","text":"cox_ring(R::MPolyRing, v::AbstractNormalToricVariety)\n\nComputes the Cox ring of the normal toric variety v, in this case by adding the Cox grading to the given ring R. Note that David A. Cox, John B. Little, Henry K. Schenck (2011) refers to this ring as the \"total coordinate ring\".\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> R, _ = polynomial_ring(QQ, 3);\n\njulia> cox_ring(R, p2)\nMultivariate polynomial ring in 3 variables over QQ graded by\n x1 -> [1]\n x2 -> [1]\n x3 -> [1]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#irrelevant_ideal-Tuple{MPolyRing, Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"irrelevant_ideal","text":"irrelevant_ideal(R::MPolyRing, v::AbstractNormalToricVariety)\n\nReturn the irrelevant ideal of a normal toric variety v as an ideal in R.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> R, _ = polynomial_ring(QQ, 3);\n\njulia> length(gens(irrelevant_ideal(R, p2)))\n3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#ideal_of_linear_relations-Tuple{MPolyRing, Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"ideal_of_linear_relations","text":"ideal_of_linear_relations(R::MPolyRing, v::AbstractNormalToricVariety)\n\nReturn the ideal of linear relations of the simplicial and complete toric variety v in the ring R.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> R, _ = polynomial_ring(QQ, 3);\n\njulia> ngens(ideal_of_linear_relations(R, p2))\n2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#stanley_reisner_ideal-Tuple{MPolyRing, Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"stanley_reisner_ideal","text":"stanley_reisner_ideal(R::MPolyRing, v::AbstractNormalToricVariety)\n\nReturn the Stanley-Reisner ideal of a normal toric variety v as an ideal of R.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> R, _ = polynomial_ring(QQ, 3);\n\njulia> ngens(stanley_reisner_ideal(R, p2))\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#toric_ideal-Tuple{MPolyRing, AffineNormalToricVariety}","page":"Normal Toric Varieties","title":"toric_ideal","text":"toric_ideal(R::MPolyRing, antv::AffineNormalToricVariety)\n\nReturn the toric ideal defining the affine normal toric variety as an ideal in R.\n\nExamples\n\nTake the cone over the square at height one. The resulting toric variety has one defining equation. In projective space this corresponds to mathbbP^1timesmathbbP^1. Note that this cone is self-dual, the toric ideal comes from the dual cone.\n\njulia> C = positive_hull([1 0 0; 1 1 0; 1 0 1; 1 1 1])\nPolyhedral cone in ambient dimension 3\n\njulia> antv = affine_normal_toric_variety(C)\nNormal, affine toric variety\n\njulia> R, _ = polynomial_ring(QQ, 4);\n\njulia> toric_ideal(R, antv)\nideal(-x1*x2 + x3*x4)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#coordinate_ring_of_torus-Tuple{MPolyRing, Oscar.AbstractNormalToricVariety}","page":"Normal Toric Varieties","title":"coordinate_ring_of_torus","text":"coordinate_ring_of_torus(R::MPolyRing, v::AbstractNormalToricVariety)\n\nComputes the coordinate ring of the torus of the normal toric variety v in the given polynomial ring R.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"Along the same lines, characters can be turned into rational functions:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"character_to_rational_function(v::AbstractNormalToricVariety, character::Vector{ZZRingElem})\ncharacter_to_rational_function(R::MPolyRing, v::AbstractNormalToricVariety, character::Vector{ZZRingElem})","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#character_to_rational_function-Tuple{Oscar.AbstractNormalToricVariety, Vector{ZZRingElem}}","page":"Normal Toric Varieties","title":"character_to_rational_function","text":"character_to_rational_function(v::AbstractNormalToricVariety, character::Vector{ZZRingElem})\n\nComputes the rational function corresponding to a character of the normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> character_to_rational_function(p2, [-1, 2])\nx2^2*x1_\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#character_to_rational_function-Tuple{MPolyRing, Oscar.AbstractNormalToricVariety, Vector{ZZRingElem}}","page":"Normal Toric Varieties","title":"character_to_rational_function","text":"character_to_rational_function(R::MPolyRing, v::AbstractNormalToricVariety, character::Vector{ZZRingElem})\n\nComputes the rational function corresponding to a character of the normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2);\n\njulia> R, _ = polynomial_ring(QQ, 4);\n\njulia> character_to_rational_function(R, p2, [-1, 2])\nx2^2*x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Auxiliary-Methods","page":"Normal Toric Varieties","title":"Auxiliary Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"binomial_exponents_to_ideal(binoms::Union{AbstractMatrix, ZZMatrix})\ntoric_ideal(pts::ZZMatrix)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#binomial_exponents_to_ideal-Tuple{Union{ZZMatrix, AbstractMatrix}}","page":"Normal Toric Varieties","title":"binomial_exponents_to_ideal","text":"binomial_exponents_to_ideal(binoms::Union{AbstractMatrix, ZZMatrix})\n\nThis function converts the rows of a matrix to binomials. Each row r is written as r=u-v with u vge 0 by splitting into positive and negative entries. Then the row r corresponds to x^u-x^v. The resulting ideal is returned.\n\nExamples\n\njulia> A = [-1 -1 0 2; 2 3 -2 -1]\n2×4 Matrix{Int64}:\n -1 -1 0 2\n 2 3 -2 -1\n\njulia> binomial_exponents_to_ideal(A)\nideal(-x1*x2 + x4^2, x1^2*x2^3 - x3^2*x4)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#toric_ideal-Tuple{ZZMatrix}","page":"Normal Toric Varieties","title":"toric_ideal","text":"toric_ideal(pts::ZZMatrix)\n\nReturn the toric ideal generated from the linear relations between the points pts. This is the ideal generated by the set of binomials x^u-x^v u vinmathbbZ^n_ge 0 (pts)^Tcdot(u-v) = 0\n\nExamples\n\njulia> C = positive_hull([-2 5; 1 0]);\n\njulia> H = hilbert_basis(C);\n\njulia> toric_ideal(H)\nideal(x2*x3 - x4^2, -x1*x3 + x2^2*x4, -x1*x4 + x2^3, -x1*x3^2 + x2*x4^3, -x1*x3^3 + x4^5)\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/map_introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"AbstractAlgebra/map_introduction/","page":"Introduction","title":"Introduction","text":"Maps in AbstractAlgebra model maps on sets f D to C for some domain D and codomain C, which have no real limitations except that elements of the codomain and domain be represented by element objects in the system.","category":"page"},{"location":"AbstractAlgebra/map_introduction/","page":"Introduction","title":"Introduction","text":"Maps f D to C in AbstractAlgebra are modeled by Julia objects that are able to be called on a single element d in D of the domain to yield an element f(d) in C of the codomain. We say that the map is being applied.","category":"page"},{"location":"AbstractAlgebra/map_introduction/","page":"Introduction","title":"Introduction","text":"Maps can be constructed from Julia functions, or they can be represented by some other kind of data, e.g. a matrix, or built up from other maps.","category":"page"},{"location":"AbstractAlgebra/map_introduction/","page":"Introduction","title":"Introduction","text":"Maps in AbstractAlgebra have a domain and codomain, can be applied, composed with other maps. Various special kinds of map provide more functionality.","category":"page"},{"location":"AbstractAlgebra/map_introduction/","page":"Introduction","title":"Introduction","text":"For details please refer to the Map Interface documentation.","category":"page"},{"location":"AbstractAlgebra/map_introduction/","page":"Introduction","title":"Introduction","text":"For example, there are functional maps which wrap a Julia function, cached maps which cache values so they do not have to be recomputed each time they are applied to the same inputs and various kinds of maps with inverses, e.g. maps with sections, retractions and full inverses.","category":"page"},{"location":"AbstractAlgebra/map_introduction/","page":"Introduction","title":"Introduction","text":"The map system uses a complex four parameter Map type, however various helper functions are provided to make it easier to work with.","category":"page"},{"location":"Hecke/misc/conjugacy/#Conjugacy-of-integral-matrices","page":"Conjugacy of integral matrices","title":"Conjugacy of integral matrices","text":"","category":"section"},{"location":"Hecke/misc/conjugacy/","page":"Conjugacy of integral matrices","title":"Conjugacy of integral matrices","text":"is_GLZ_conjugate(::ZZMatrix, ::ZZMatrix)","category":"page"},{"location":"Hecke/misc/conjugacy/#is_GLZ_conjugate-Tuple{ZZMatrix, ZZMatrix}","page":"Conjugacy of integral matrices","title":"is_GLZ_conjugate","text":"is_GLZ_conjugate(A::MatElem, B::MatElem) -> Bool, MatElem\n\nGiven two integral or rational matrices, determine whether there exists an invertible integral matrix T with TA = BT. If true, the second argument is such a matrix T. Otherwise, the second argument is unspecified.\n\njulia> A = matrix(ZZ, 4, 4, [ 0, 1, 0, 0,\n -4, 0, 0, 0,\n 0, 0, 0, 1,\n 0, 0, -4, 0]);\n\njulia> B = matrix(ZZ, 4, 4, [ 0, 1, 4, 0,\n -4, 0, 0, -4,\n 0, 0, 0, 1,\n 0, 0, -4, 0]);\n\njulia> fl, T = is_GLZ_conjugate(A, B);\n\njulia> isone(abs(det(T))) && T * A == B * T\ntrue\n\n\n\n","category":"method"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/matgroup/#Matrix-groups","page":"Matrix groups","title":"Matrix groups","text":"","category":"section"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"matrix_group(R::Ring, m::Int, V::AbstractVector{T}; check::Bool=true) where T<:Union{MatElem,MatrixGroupElem}\nMatrixGroup{RE<:RingElem, T<:MatElem{RE}}\nMatrixGroupElem{RE<:RingElem, T<:MatElem{RE}}\nbase_ring(G::MatrixGroup)\ndegree(G::MatrixGroup)\ncentralizer(G::MatrixGroup{T}, x::MatrixGroupElem{T}) where T <: FinFieldElem","category":"page"},{"location":"Groups/matgroup/#matrix_group-Union{Tuple{T}, Tuple{Ring, Int64, AbstractVector{T}}} where T<:Union{MatElem, MatrixGroupElem}","page":"Matrix groups","title":"matrix_group","text":"matrix_group(R::Ring, m::Int, V::T...) where T<:Union{MatElem,MatrixGroupElem}\nmatrix_group(R::Ring, m::Int, V::AbstractVector{T}) where T<:Union{MatElem,MatrixGroupElem}\nmatrix_group(V::T...) where T<:Union{MatElem,MatrixGroupElem}\nmatrix_group(V::AbstractVector{T}) where T<:Union{MatElem,MatrixGroupElem}\n\nReturn the matrix group generated by matrices in V. If the degree m and coefficient ring R are not given, then V must be non-empty\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#MatrixGroup","page":"Matrix groups","title":"MatrixGroup","text":"MatrixGroup{RE<:RingElem, T<:MatElem{RE}} <: GAPGroup\n\nType of groups G of n x n matrices over the ring R, where n = degree(G) and R = base_ring(G).\n\n\n\n\n\n","category":"type"},{"location":"Groups/matgroup/#MatrixGroupElem","page":"Matrix groups","title":"MatrixGroupElem","text":"MatrixGroupElem{RE<:RingElem, T<:MatElem{RE}} <: AbstractMatrixGroupElem\n\nElements of a group of type MatrixGroup{RE<:RingElem, T<:MatElem{RE}}\n\n\n\n\n\n","category":"type"},{"location":"Groups/matgroup/#base_ring-Tuple{MatrixGroup}","page":"Matrix groups","title":"base_ring","text":"base_ring(G::MatrixGroup)\n\nReturn the base ring of the matrix group G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#degree-Tuple{MatrixGroup}","page":"Matrix groups","title":"degree","text":"degree(G::MatrixGroup)\n\nReturn the degree of the matrix group G, i.e. the number of rows of its matrices.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#centralizer-Union{Tuple{T}, Tuple{MatrixGroup{T, T1} where T1<:MatElem{T}, MatrixGroupElem{T, T1} where T1<:MatElem{T}}} where T<:FinFieldElem","page":"Matrix groups","title":"centralizer","text":"centralizer(G::MatrixGroup{T}, x::MatrixGroupElem{T})\n\nReturn (C,f), where C is the centralizer of x in C and f is the embedding of C into G. If G = GL(n,F) or SL(n,F), then f = nothing. In this case, to get the embedding homomorphism of C into G, use\n\nis_subgroup(C, G)[2]\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#Elements-of-matrix-groups","page":"Matrix groups","title":"Elements of matrix groups","text":"","category":"section"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"matrix(x::MatrixGroupElem)\nbase_ring(x::MatrixGroupElem)\nnrows(x::MatrixGroupElem)\ndet(x::MatrixGroupElem)\ntr(x::MatrixGroupElem)\nmultiplicative_jordan_decomposition(x::MatrixGroupElem)\nis_semisimple(x::MatrixGroupElem{T}) where T <: FinFieldElem\nis_unipotent(x::MatrixGroupElem{T}) where T <: FinFieldElem","category":"page"},{"location":"Groups/matgroup/#matrix-Tuple{MatrixGroupElem}","page":"Matrix groups","title":"matrix","text":"matrix(x::MatrixGroupElem)\n\nReturn the underlying matrix of x.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#base_ring-Tuple{MatrixGroupElem}","page":"Matrix groups","title":"base_ring","text":"base_ring(x::MatrixGroupElem)\n\nReturn the base ring of the underlying matrix of x.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#nrows-Tuple{MatrixGroupElem}","page":"Matrix groups","title":"nrows","text":"nrows(x::MatrixGroupElem)\n\nReturn the number of rows of the underlying matrix of x.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#det-Tuple{MatrixGroupElem}","page":"Matrix groups","title":"det","text":"det(x::MatrixGroupElem)\n\nReturn the determinant of the underlying matrix of x.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#tr-Tuple{MatrixGroupElem}","page":"Matrix groups","title":"tr","text":"tr(x::MatrixGroupElem)\n\nReturn the trace of the underlying matrix of x.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#multiplicative_jordan_decomposition-Tuple{MatrixGroupElem}","page":"Matrix groups","title":"multiplicative_jordan_decomposition","text":"multiplicative_jordan_decomposition(M::MatrixGroupElem)\n\nReturn S and U in the group G = parent(M) such that S is semisimple, U is unipotent and M = SU = US.\n\nwarning: WARNING:\nthis is NOT, in general, the same output returned when M has type MatElem.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_semisimple-Union{Tuple{MatrixGroupElem{T, T1} where T1<:MatElem{T}}, Tuple{T}} where T<:FinFieldElem","page":"Matrix groups","title":"is_semisimple","text":"is_semisimple(x::MatrixGroupElem{T}) where T <: FinFieldElem\n\nReturn whether x is semisimple, i.e. has order coprime with the characteristic of its base ring.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_unipotent-Union{Tuple{MatrixGroupElem{T, T1} where T1<:MatElem{T}}, Tuple{T}} where T<:FinFieldElem","page":"Matrix groups","title":"is_unipotent","text":"is_unipotent(x::MatrixGroupElem{T}) where T <: FinFieldElem\n\nReturn whether x is unipotent, i.e. its order is a power of the characteristic of its base ring.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#Sesquilinear-forms","page":"Matrix groups","title":"Sesquilinear forms","text":"","category":"section"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"SesquilinearForm{T<:RingElem}\nis_alternating(f::SesquilinearForm)\nis_hermitian(f::SesquilinearForm)\nis_quadratic(f::SesquilinearForm)\nis_symmetric(f::SesquilinearForm)\nalternating_form(B::MatElem{T}) where T <: FieldElem\nsymmetric_form(B::MatElem{T}) where T <: FieldElem\nhermitian_form(B::MatElem{T}) where T <: FieldElem\nquadratic_form(B::MatElem{T}) where T <: FieldElem\nquadratic_form(f::MPolyRingElem{T}) where T <: FieldElem\ncorresponding_bilinear_form(B::SesquilinearForm)\ncorresponding_quadratic_form(B::SesquilinearForm)\ngram_matrix(f::SesquilinearForm)\ndefining_polynomial(f::SesquilinearForm)\nradical(f::SesquilinearForm{T}) where T\nwitt_index(f::SesquilinearForm{T}) where T\nis_degenerate(f::SesquilinearForm{T}) where T\nis_singular(f::SesquilinearForm{T}) where T\nis_congruent(f::SesquilinearForm{T}, g::SesquilinearForm{T}) where T <: RingElem","category":"page"},{"location":"Groups/matgroup/#SesquilinearForm","page":"Matrix groups","title":"SesquilinearForm","text":"SesquilinearForm{T<:RingElem}\n\nType of groups G of n x n matrices over the ring R, where n = degree(G) and R = base_ring(G). At the moment, only rings of type fqPolyRepField are supported.\n\n\n\n\n\n","category":"type"},{"location":"Groups/matgroup/#is_alternating-Tuple{SesquilinearForm}","page":"Matrix groups","title":"is_alternating","text":"is_alternating(f::SesquilinearForm)\n\nReturn whether the form f is an alternating form.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_hermitian-Tuple{SesquilinearForm}","page":"Matrix groups","title":"is_hermitian","text":"is_hermitian(f::SesquilinearForm)\n\nReturn whether the form f is a hermitian form.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_quadratic-Tuple{SesquilinearForm}","page":"Matrix groups","title":"is_quadratic","text":"is_quadratic(f::SesquilinearForm)\n\nReturn whether the form f is a quadratic form.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_symmetric-Tuple{SesquilinearForm}","page":"Matrix groups","title":"is_symmetric","text":"is_symmetric(f::SesquilinearForm)\n\nReturn whether the form f is a symmetric form.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#alternating_form-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix groups","title":"alternating_form","text":"alternating_form(B::MatElem{T})\n\nReturn the alternating form with Gram matrix B.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#symmetric_form-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix groups","title":"symmetric_form","text":"symmetric_form(B::MatElem{T})\n\nReturn the symmetric form with Gram matrix B.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#hermitian_form-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix groups","title":"hermitian_form","text":"hermitian_form(B::MatElem{T})\n\nReturn the hermitian form with Gram matrix B.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#quadratic_form-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix groups","title":"quadratic_form","text":"quadratic_form(B::MatElem{T})\n\nReturn the quadratic form with Gram matrix B.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#quadratic_form-Union{Tuple{MPolyRingElem{T}}, Tuple{T}} where T<:FieldElem","page":"Matrix groups","title":"quadratic_form","text":"quadratic_form(f::MPolyRingElem{T}; check=true)\n\nReturn the quadratic form described by the polynomial f. Here, f must be a homogeneous polynomial of degree 2. If check is set as false, it does not check whether the polynomial is homogeneous of degree 2. To define quadratic forms of dimension 1, f can also have type PolyRingElem{T}.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#corresponding_bilinear_form-Tuple{SesquilinearForm}","page":"Matrix groups","title":"corresponding_bilinear_form","text":"corresponding_bilinear_form(Q::SesquilinearForm)\n\nGiven a quadratic form Q, return the bilinear form B defined by B(u,v) = Q(u+v)-Q(u)-Q(v).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#corresponding_quadratic_form-Tuple{SesquilinearForm}","page":"Matrix groups","title":"corresponding_quadratic_form","text":"corresponding_quadratic_form(Q::SesquilinearForm)\n\nGiven a symmetric form f, returns the quadratic form Q defined by Q(v) = f(v,v)/2. It is defined only in odd characteristic.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#gram_matrix-Tuple{SesquilinearForm}","page":"Matrix groups","title":"gram_matrix","text":"gram_matrix(B::SesquilinearForm)\n\nReturn the Gram matrix of a sesquilinear or quadratic form B.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#defining_polynomial-Tuple{SesquilinearForm}","page":"Matrix groups","title":"defining_polynomial","text":"defining_polynomial(f::SesquilinearForm)\n\nReturn the polynomial that defines the quadratic form f.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#radical-Union{Tuple{SesquilinearForm{T}}, Tuple{T}} where T","page":"Matrix groups","title":"radical","text":"radical(f::SesquilinearForm{T})\n\nReturn the radical of the sesquilinear form f, i.e. the subspace of all v such that f(u,v)=0 for all u. The radical of a quadratic form Q is the set of vectors v such that Q(v)=0 and v lies in the radical of the corresponding bilinear form.\n\n\n\n\n\n radical(A::AbsAlgAss) -> AbsAlgAssIdl\n\nReturns the Jacobson-Radical of A.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#witt_index-Union{Tuple{SesquilinearForm{T}}, Tuple{T}} where T","page":"Matrix groups","title":"witt_index","text":"witt_index(f::SesquilinearForm{T})\n\nReturn the Witt index of the form induced by f on V/Rad(f). The Witt Index is the dimension of a maximal totally isotropic (singular for quadratic forms) subspace.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_degenerate-Union{Tuple{SesquilinearForm{T}}, Tuple{T}} where T","page":"Matrix groups","title":"is_degenerate","text":"is_degenerate(f::SesquilinearForm{T})\n\nReturn whether f is degenerate, i.e. f has nonzero radical. A quadratic form is degenerate if the corresponding bilinear form is.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_singular-Union{Tuple{SesquilinearForm{T}}, Tuple{T}} where T","page":"Matrix groups","title":"is_singular","text":"is_singular(Q::SesquilinearForm{T})\n\nFor a quadratic form Q, return whether Q is singular, i.e. Q has nonzero radical.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_congruent-Union{Tuple{T}, Tuple{SesquilinearForm{T}, SesquilinearForm{T}}} where T<:RingElem","page":"Matrix groups","title":"is_congruent","text":"is_congruent(f::SesquilinearForm{T}, g::SesquilinearForm{T}) where T <: RingElem\n\nIf f and g are sesquilinear forms, return (true, C) if there exists a matrix C such that f^C = g, or equivalently, CBC* = A, where A and B are the Gram matrices of f and g respectively, and C* is the transpose-conjugate matrix of C. If such C does not exist, then return (false, nothing).\n\nIf f and g are quadratic forms, return (true, C) if there exists a matrix C such that f^A = ag for some scalar a. If such C does not exist, then return (false, nothing).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#Invariant-forms","page":"Matrix groups","title":"Invariant forms","text":"","category":"section"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"invariant_bilinear_forms(G::MatrixGroup{S,T}) where {S,T}\ninvariant_sesquilinear_forms(G::MatrixGroup{S,T}) where {S,T}\ninvariant_quadratic_forms(G::MatrixGroup{S,T}) where {S,T}\ninvariant_symmetric_forms(G::MatrixGroup{S,T}) where {S,T}\ninvariant_alternating_forms(G::MatrixGroup{S,T}) where {S,T}\ninvariant_hermitian_forms(G::MatrixGroup{S,T}) where {S,T}\ninvariant_bilinear_form(G::MatrixGroup)\ninvariant_sesquilinear_form(G::MatrixGroup)\ninvariant_quadratic_form(G::MatrixGroup)\npreserved_quadratic_forms(G::MatrixGroup{S,T}) where {S,T}\npreserved_sesquilinear_forms(G::MatrixGroup{S,T}) where {S,T}\nisometry_group(f::SesquilinearForm{T}) where T\northogonal_sign(G::MatrixGroup)","category":"page"},{"location":"Groups/matgroup/#invariant_bilinear_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"invariant_bilinear_forms","text":"invariant_bilinear_forms(G::MatrixGroup)\n\nReturn a generating set for the vector spaces of bilinear forms preserved by the group G.\n\nwarning: Note:\nAt the moment, elements of the generating set are returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_sesquilinear_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"invariant_sesquilinear_forms","text":"invariant_sesquilinear_forms(G::MatrixGroup)\n\nReturn a generating set for the vector spaces of sesquilinear non-bilinear forms preserved by the group G. An exception is thrown if base_ring(G) is not a finite field with even degree over its prime subfield.\n\nwarning: Note:\nAt the moment, elements of the generating set are returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_quadratic_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"invariant_quadratic_forms","text":"invariant_quadratic_forms(G::MatrixGroup)\n\nReturn a generating set for the vector spaces of quadratic forms preserved by the group G.\n\nwarning: Note:\nAt the moment, elements of the generating set are returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_symmetric_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"invariant_symmetric_forms","text":"invariant_symmetric_forms(G::MatrixGroup)\n\nReturn a generating set for the vector spaces of symmetric forms preserved by the group G.\n\nwarning: Note:\nAt the moment, elements of the generating set are returned of type mat_elem_type(G).\n\nwarning: Note:\nWork properly only in odd characteristic. In even characteristic, only alternating forms are found.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_alternating_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"invariant_alternating_forms","text":"invariant_alternating_forms(G::MatrixGroup)\n\nReturn a generating set for the vector spaces of alternating forms preserved by the group G.\n\nwarning: Note:\nAt the moment, elements of the generating set are returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_hermitian_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"invariant_hermitian_forms","text":"invariant_hermitian_forms(G::MatrixGroup)\n\nReturn a generating set for the vector spaces of hermitian forms preserved by the group G. An exception is thrown if base_ring(G) is not a finite field with even degree over its prime subfield.\n\nwarning: Note:\nAt the moment, elements of the generating set are returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_bilinear_form-Tuple{MatrixGroup}","page":"Matrix groups","title":"invariant_bilinear_form","text":"invariant_bilinear_form(G::MatrixGroup)\n\nReturn an invariant bilinear form for the group G. An exception is thrown if the module induced by the action of G is not absolutely irreducible.\n\nwarning: Note:\nAt the moment, the output is returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_sesquilinear_form-Tuple{MatrixGroup}","page":"Matrix groups","title":"invariant_sesquilinear_form","text":"invariant_sesquilinear_form(G::MatrixGroup)\n\nReturn an invariant sesquilinear (non bilinear) form for the group G. An exception is thrown if the module induced by the action of G is not absolutely irreducible or if the group is defined over a finite field of odd degree over the prime field.\n\nwarning: Note:\nAt the moment, the output is returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#invariant_quadratic_form-Tuple{MatrixGroup}","page":"Matrix groups","title":"invariant_quadratic_form","text":"invariant_quadratic_form(G::MatrixGroup)\n\nReturn an invariant quadratic form for the group G. An exception is thrown if the module induced by the action of G is not absolutely irreducible.\n\nwarning: Note:\nAt the moment, the output is returned of type mat_elem_type(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#preserved_quadratic_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"preserved_quadratic_forms","text":"preserved_quadratic_forms(G::MatrixGroup)\n\nUses random methods to find all of the quadratic forms preserved by G up to a scalar (i.e. such that G is a group of similarities for the forms). Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant quadratic forms.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#preserved_sesquilinear_forms-Union{Tuple{MatrixGroup{S, T}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Matrix groups","title":"preserved_sesquilinear_forms","text":"preserved_sesquilinear_forms(G::MatrixGroup)\n\nUses random methods to find all of the sesquilinear forms preserved by G up to a scalar (i.e. such that G is a group of similarities for the forms). Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant sesquilinear forms.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#isometry_group-Union{Tuple{SesquilinearForm{T}}, Tuple{T}} where T","page":"Matrix groups","title":"isometry_group","text":"isometry_group(f::SesquilinearForm{T})\n\nReturn the group of isometries for the sesquilinear form f.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#orthogonal_sign-Tuple{MatrixGroup}","page":"Matrix groups","title":"orthogonal_sign","text":"orthogonal_sign(G::MatrixGroup)\n\nFor absolutely irreducible G of degree n and such that base_ring(G) is a finite field, return\n\nnothing if G does not preserve a nonzero quadratic form,\n0 if n is odd and G preserves a nonzero quadratic form,\n1 if n is even and G preserves a nonzero quadratic form of + type,\n-1 if n is even and G preserves a nonzero quadratic form of - type.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#Utilities-for-matrices-(replace-by-available-functions,-or-document-elsewhere?)","page":"Matrix groups","title":"Utilities for matrices (replace by available functions, or document elsewhere?)","text":"","category":"section"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"pol_elementary_divisors(A::MatElem{T}) where T\ngeneralized_jordan_block(f::T, n::Int) where T<:PolyRingElem\ngeneralized_jordan_form(A::MatElem{T}; with_pol=false) where T\nmatrix(A::Vector{AbstractAlgebra.Generic.FreeModuleElem{T}}) where T <: RingElem\nupper_triangular_matrix(L)\nlower_triangular_matrix(L)\nconjugate_transpose(x::MatElem{T}) where T <: FinFieldElem\ncomplement(V::AbstractAlgebra.Generic.FreeModule{T}, W::AbstractAlgebra.Generic.Submodule{T}) where T <: FieldElem\npermutation_matrix(F::Ring, Q::AbstractVector{<:IntegerUnion})\nis_alternating(B::MatElem)\nis_hermitian(B::MatElem{T}) where T <: FinFieldElem","category":"page"},{"location":"Groups/matgroup/#pol_elementary_divisors-Union{Tuple{MatElem{T}}, Tuple{T}} where T","page":"Matrix groups","title":"pol_elementary_divisors","text":"pol_elementary_divisors(x::MatElem)\npol_elementary_divisors(x::MatrixGroupElem)\n\nReturn a list of pairs (f_i,m_i), for irreducible polynomials f_i and positive integers m_i, where the f_i^m_i are the elementary divisors of x.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#generalized_jordan_block-Union{Tuple{T}, Tuple{T, Int64}} where T<:PolyRingElem","page":"Matrix groups","title":"generalized_jordan_block","text":"generalized_jordan_block(f::T, n::Int) where T<:PolyRingElem\n\nReturn the Jordan block of dimension n corresponding to the polynomial f.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#generalized_jordan_form-Union{Tuple{MatElem{T}}, Tuple{T}} where T","page":"Matrix groups","title":"generalized_jordan_form","text":"generalized_jordan_form(A::MatElem{T}; with_pol::Bool=false) where T\n\nReturn (J,Z), where Z^-1*J*Z = A and J is a diagonal join of Jordan blocks (corresponding to irreducible polynomials).\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#matrix-Union{Tuple{Array{AbstractAlgebra.Generic.FreeModuleElem{T}, 1}}, Tuple{T}} where T<:RingElem","page":"Matrix groups","title":"matrix","text":"matrix(A::Vector{AbstractAlgebra.Generic.FreeModuleElem})\n\nReturn the matrix whose rows are the vectors in A. All vectors in A must have the same length and the same base ring.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#upper_triangular_matrix-Tuple{Any}","page":"Matrix groups","title":"upper_triangular_matrix","text":"upper_triangular_matrix(L)\n\nReturn the upper triangular matrix whose entries on and above the diagonal are the elements of L.\n\nAn exception is thrown whenever the length of L is not equal to n(n+1)2, for some integer n.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#lower_triangular_matrix-Tuple{Any}","page":"Matrix groups","title":"lower_triangular_matrix","text":"lower_triangular_matrix(L)\n\nReturn the upper triangular matrix whose entries on and below the diagonal are the elements of L.\n\nAn exception is thrown whenever the length of L is not equal to n(n+1)2, for some integer n.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#conjugate_transpose-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FinFieldElem","page":"Matrix groups","title":"conjugate_transpose","text":"conjugate_transpose(x::MatElem{T}) where T <: FinFieldElem\n\nIf the base ring of x is GF(q^2), return the matrix transpose( map ( y -> y^q, x) ). An exception is thrown if the base ring does not have even degree.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#complement-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.FreeModule{T}, AbstractAlgebra.Generic.Submodule{T}}} where T<:FieldElem","page":"Matrix groups","title":"complement","text":"complement(V::AbstractAlgebra.Generic.FreeModule{T}, W::AbstractAlgebra.Generic.Submodule{T}) where T <: FieldElem\n\nReturn a complement for W in V, i.e. a subspace U of V such that V is direct sum of U and W.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#permutation_matrix-Tuple{Ring, AbstractVector{<:Union{Integer, ZZRingElem}}}","page":"Matrix groups","title":"permutation_matrix","text":"permutation_matrix(F::Ring, Q::AbstractVector{T}) where T <: Int\npermutation_matrix(F::Ring, p::PermGroupElem)\n\nReturn the permutation matrix over the ring R corresponding to the sequence Q or to the permutation p. If Q is a sequence, then Q must contain exactly once every integer from 1 to some n.\n\nExamples\n\njulia> s = perm([3,1,2])\n(1,3,2)\n\njulia> permutation_matrix(QQ,s)\n[0 0 1]\n[1 0 0]\n[0 1 0]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_alternating-Tuple{MatElem}","page":"Matrix groups","title":"is_alternating","text":"is_alternating(B::MatElem)\n\nReturn whether the form corresponding to the matrix B is alternating, i.e. B = -transpose(B) and B has zeros on the diagonal. Return false if B is not a square matrix.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#is_hermitian-Union{Tuple{MatElem{T}}, Tuple{T}} where T<:FinFieldElem","page":"Matrix groups","title":"is_hermitian","text":"is_hermitian(B::MatElem{T}) where T <: FinFieldElem\n\nReturn whether the matrix B is hermitian, i.e. B = conjugate_transpose(B). Return false if B is not a square matrix, or the field has not even degree.\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#Classical-groups","page":"Matrix groups","title":"Classical groups","text":"","category":"section"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"general_linear_group(n::Int, F::Ring)\nspecial_linear_group(n::Int, F::Ring)\nsymplectic_group(n::Int, F::Ring)\northogonal_group(e::Int, n::Int, F::Ring)\nspecial_orthogonal_group(e::Int, n::Int, F::Ring)\nomega_group(e::Int, n::Int, F::Ring)\nunitary_group(n::Int, q::Int)\nspecial_unitary_group(n::Int, q::Int)","category":"page"},{"location":"Groups/matgroup/#general_linear_group-Tuple{Int64, Ring}","page":"Matrix groups","title":"general_linear_group","text":"general_linear_group(n::Int, q::Int)\ngeneral_linear_group(n::Int, R::Ring)\nGL = general_linear_group\n\nReturn the general linear group of dimension n over the ring R respectively the field GF(q).\n\nCurrently, this function only supports rings of type fqPolyRepField.\n\nExamples\n\njulia> F = GF(7,1)\nFinite field of degree 1 over GF(7)\n\njulia> H = general_linear_group(2,F)\nGL(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [3 0; 0 1]\n [6 1; 6 0]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#special_linear_group-Tuple{Int64, Ring}","page":"Matrix groups","title":"special_linear_group","text":"special_linear_group(n::Int, q::Int)\nspecial_linear_group(n::Int, R::Ring)\nSL = special_linear_group\n\nReturn the special linear group of dimension n over the ring R respectively the field GF(q).\n\nCurrently, this function only supports rings of type fqPolyRepField.\n\nExamples\n\njulia> F = GF(7,1)\nFinite field of degree 1 over GF(7)\n\njulia> H = special_linear_group(2,F)\nSL(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [3 0; 0 5]\n [6 1; 6 0]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#symplectic_group-Tuple{Int64, Ring}","page":"Matrix groups","title":"symplectic_group","text":"symplectic_group(n::Int, q::Int)\nsymplectic_group(n::Int, R::Ring)\nSp = symplectic_group\n\nReturn the symplectic group of dimension n over the ring R respectively the field GF(q). The dimension n must be even.\n\nCurrently, this function only supports rings of type fqPolyRepField.\n\nExamples\n\njulia> F = GF(7,1)\nFinite field of degree 1 over GF(7)\n\njulia> H = symplectic_group(2,F)\nSp(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [3 0; 0 5]\n [6 1; 6 0]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#orthogonal_group-Tuple{Int64, Int64, Ring}","page":"Matrix groups","title":"orthogonal_group","text":"orthogonal_group(e::Int, n::Int, R::Ring)\northogonal_group(e::Int, n::Int, q::Int)\nGO = orthogonal_group\n\nReturn the orthogonal group of dimension n over the ring R respectively the field GF(q), and of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.\n\nCurrently, this function only supports rings of type fqPolyRepField.\n\nExamples\n\njulia> F = GF(7,1)\nFinite field of degree 1 over GF(7)\n\njulia> H = symplectic_group(2,F)\nSp(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [3 0; 0 5]\n [6 1; 6 0]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#special_orthogonal_group-Tuple{Int64, Int64, Ring}","page":"Matrix groups","title":"special_orthogonal_group","text":"special_orthogonal_group(e::Int, n::Int, R::Ring)\nspecial_orthogonal_group(e::Int, n::Int, q::Int)\nSO = special_orthogonal_group\n\nReturn the special orthogonal group of dimension n over the ring R respectively the field GF(q), and of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.\n\nCurrently, this function only supports rings of type fqPolyRepField.\n\nExamples\n\njulia> F = GF(7,1)\nFinite field of degree 1 over GF(7)\n\njulia> H = special_orthogonal_group(1,2,F)\nSO+(2,7)\n\njulia> gens(H)\n3-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [3 0; 0 5]\n [5 0; 0 3]\n [1 0; 0 1]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#omega_group-Tuple{Int64, Int64, Ring}","page":"Matrix groups","title":"omega_group","text":"omega_group(e::Int, n::Int, R::Ring)\nomega_group(e::Int, n::Int, q::Int)\n\nReturn the Omega group of dimension n over the field GF(q) of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.\n\nCurrently, this function only supports rings of type fqPolyRepField.\n\nExamples\n\njulia> F = GF(7,1)\nFinite field of degree 1 over GF(7)\n\njulia> H = omega_group(1,2,F)\nOmega+(2,7)\n\njulia> gens(H)\n1-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [2 0; 0 4]\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#unitary_group-Tuple{Int64, Int64}","page":"Matrix groups","title":"unitary_group","text":"unitary_group(n::Int, q::Int)\nGU = unitary_group\n\nReturn the unitary group of dimension n over the field GF(q^2).\n\nExamples\n\njulia> H = unitary_group(2,3)\nGU(2,3)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [o 0; 0 2*o]\n [2 2*o+2; 2*o+2 0]\n\n\n\n\n\n","category":"method"},{"location":"Groups/matgroup/#special_unitary_group-Tuple{Int64, Int64}","page":"Matrix groups","title":"special_unitary_group","text":"special_unitary_group(n::Int, q::Int)\nSU = special_unitary_group\n\nReturn the special unitary group of dimension n over the field with q^2 elements.\n\nExamples\n\njulia> H = special_unitary_group(2,3)\nSU(2,3)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{fqPolyRepFieldElem, fqPolyRepMatrix}}:\n [1 2*o+2; 0 1]\n [0 2*o+2; 2*o+2 0]\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/padic/#Padics","page":"Padics","title":"Padics","text":"","category":"section"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"P-adic fields are provided in Nemo by Flint. This allows construction of p-adic fields for any prime p.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"P-adic fields are constructed using the FlintPadicField function. However, for convenience we define","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"PadicField = FlintPadicField","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"so that p-adic fields can be constructed using PadicField rather than FlintPadicField. Note that this is the name of the constructor, but not of padic field type.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"The types of p-adic fields in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Library Field Element type Parent type\nFlint mathbbQ_p padic PadicField","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"All the p-adic field types belong to the Field abstract type and the p-adic field element types belong to the FieldElem abstract type.","category":"page"},{"location":"Nemo/padic/#P-adic-functionality","page":"Padics","title":"P-adic functionality","text":"","category":"section"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"P-adic fields in Nemo implement all the AbstractAlgebra field functionality:.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Below, we document all the additional function that is provide by Nemo for p-adic fields.","category":"page"},{"location":"Nemo/padic/#Constructors","page":"Padics","title":"Constructors","text":"","category":"section"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"In order to construct p-adic field elements in Nemo, one must first construct the p-adic field itself. This is accomplished with one of the following constructors.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"FlintPadicField(::Integer, ::Int)","category":"page"},{"location":"Nemo/padic/#FlintPadicField-Tuple{Integer, Int64}","page":"Padics","title":"FlintPadicField","text":"FlintPadicField(p::Integer, prec::Int; kw...)\n\nReturns the parent object for the p-adic field for given prime p, where the default absolute precision of elements of the field is given by prec.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"It is also possible to call the inner constructor directly. It has the following form.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"FlintPadicField(p::ZZRingElem, prec::Int)","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Returns the parent object for the p-adic field for given prime p, where the default absolute precision of elements of the field is given by prec.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Here are some examples of creating p-adic fields and making use of the resulting parent objects to coerce various elements into those fields.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Examples","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"R = PadicField(7, 30)\nS = PadicField(ZZ(65537), 30)\n\na = R()\nb = S(1)\nc = S(ZZ(123))\nd = R(ZZ(1)//7^2)","category":"page"},{"location":"Nemo/padic/#Big-oh-notation","page":"Padics","title":"Big-oh notation","text":"","category":"section"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Elements of p-adic fields can be constructed using the big-oh notation. For this purpose we define the following functions.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"O(::FlintPadicField, ::Integer)\nO(::FlintPadicField, ::ZZRingElem)\nO(::FlintPadicField, ::QQFieldElem)","category":"page"},{"location":"Nemo/padic/#O-Tuple{FlintPadicField, Integer}","page":"Padics","title":"O","text":"O(R::FlintPadicField, m::Integer)\n\nConstruct the value 0 + O(p^n) given m = p^n. An exception results if m is not found to be a power of p = prime(R).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/#O-Tuple{FlintPadicField, ZZRingElem}","page":"Padics","title":"O","text":"O(R::FlintPadicField, m::ZZRingElem)\n\nConstruct the value 0 + O(p^n) given m = p^n. An exception results if m is not found to be a power of p = prime(R).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/#O-Tuple{FlintPadicField, QQFieldElem}","page":"Padics","title":"O","text":"O(R::FlintPadicField, m::QQFieldElem)\n\nConstruct the value 0 + O(p^n) given m = p^n. An exception results if m is not found to be a power of p = prime(R).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"The O(p^n) construction can be used to construct p-adic values of precision n by adding it to integer values representing the p-adic value modulo p^n as in the examples.","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Examples","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"R = PadicField(7, 30)\nS = PadicField(ZZ(65537), 30)\n\nc = 1 + 2*7 + 4*7^2 + O(R, 7^3)\nd = 13 + 357*ZZ(65537) + O(S, ZZ(65537)^12)\nf = ZZ(1)//7^2 + ZZ(2)//7 + 3 + 4*7 + O(R, 7^2)","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Beware that the expression 1 + 2*p + 3*p^2 + O(R, p^n) is actually computed as a normal Julia expression. Therefore if {Int} values are used instead of Flint integers or Julia bignums, overflow may result in evaluating the value.","category":"page"},{"location":"Nemo/padic/#Basic-manipulation","page":"Padics","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"prime(::FlintPadicField)","category":"page"},{"location":"Nemo/padic/#prime-Tuple{FlintPadicField}","page":"Padics","title":"prime","text":"prime(R::FlintPadicField)\n\nReturn the prime p for the given p-adic field.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"precision(::padic)","category":"page"},{"location":"Nemo/padic/#precision-Tuple{padic}","page":"Padics","title":"precision","text":"precision(a::padic)\n\nReturn the precision of the given p-adic field element, i.e. if the element is known to O(p^n) this function will return n.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"valuation(::padic)","category":"page"},{"location":"Nemo/padic/#valuation-Tuple{padic}","page":"Padics","title":"valuation","text":"valuation(a::padic)\n\nReturn the valuation of the given p-adic field element, i.e. if the given element is divisible by p^n but not a higher power of p then the function will return n.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"lift(::ZZRing, ::padic)\nlift(::QQField, ::padic)","category":"page"},{"location":"Nemo/padic/#lift-Tuple{ZZRing, padic}","page":"Padics","title":"lift","text":"lift(R::ZZRing, a::padic)\n\nReturn a lift of the given p-adic field element to mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/#lift-Tuple{QQField, padic}","page":"Padics","title":"lift","text":"lift(R::QQField, a::padic)\n\nReturn a lift of the given p-adic field element to mathbbQ.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Examples","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"R = PadicField(7, 30)\n\na = 1 + 2*7 + 4*7^2 + O(R, 7^3)\nb = 7^2 + 3*7^3 + O(R, 7^5)\nc = R(2)\n\nk = precision(a)\nm = prime(R)\nn = valuation(b)\np = lift(FlintZZ, a)\nq = lift(FlintQQ, divexact(a, b))","category":"page"},{"location":"Nemo/padic/#Square-root","page":"Padics","title":"Square root","text":"","category":"section"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Base.sqrt(::padic)","category":"page"},{"location":"Nemo/padic/#sqrt-Tuple{padic}","page":"Padics","title":"sqrt","text":"sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of the given Puiseux series a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nBase.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement\n\nReturn the square root of f. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.\n\n\n\n\n\nBase.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem\n\nReturn the square root of a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\nsqrt(a::FieldElem)\n\nReturn the square root of the element a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Examples","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"R = PadicField(7, 30)\n\na = 1 + 7 + 2*7^2 + O(R, 7^3)\nb = 2 + 3*7 + O(R, 7^5)\nc = 7^2 + 2*7^3 + O(R, 7^4)\n\nd = sqrt(a)\nf = sqrt(b)\nf = sqrt(c)\ng = sqrt(R(121))","category":"page"},{"location":"Nemo/padic/#Special-functions","page":"Padics","title":"Special functions","text":"","category":"section"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Base.exp(::padic)","category":"page"},{"location":"Nemo/padic/#exp-Tuple{padic}","page":"Padics","title":"exp","text":"exp(a::Generic.LaurentSeriesElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the exponential of the given Puiseux series a.\n\n\n\n\n\nexp(a::AbsPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\nexp(a::RelPowerSeriesRingElem)\n\nReturn the exponential of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"log(::padic)","category":"page"},{"location":"Nemo/padic/#log-Tuple{padic}","page":"Padics","title":"log","text":"log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the logarithm of the given Puiseux series a.\n\n\n\n\n\nlog(a::SeriesElem{T}) where T <: FieldElement\n\nReturn the logarithm of the power series a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"teichmuller(::padic)","category":"page"},{"location":"Nemo/padic/#teichmuller-Tuple{padic}","page":"Padics","title":"teichmuller","text":"teichmuller(a::padic)\n\nReturn the Teichmuller lift of the p-adic value a. We require the valuation of a to be nonnegative. The precision of the output will be the same as the precision of the input. For convenience, if a is congruent to zero modulo p we return zero. If the input is not valid an exception is thrown.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Examples","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"R = PadicField(7, 30)\n\na = 1 + 7 + 2*7^2 + O(R, 7^3)\nb = 2 + 5*7 + 3*7^2 + O(R, 7^3)\nc = 3*7 + 2*7^2 + O(R, 7^5)\n\nc = exp(c)\nd = log(a)\nc = exp(R(0))\nd = log(R(1))\nf = teichmuller(b)","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/introduction/","page":"Introduction","title":"Introduction","text":"The aim of this project is to provide methods for computing the orthogonal discriminants of the absolutely irreducible orthogonal representations of even degree that are listed in the Atlas of Finite Groups.","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/introduction/#Status","page":"Introduction","title":"Status","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/introduction/","page":"Introduction","title":"Introduction","text":"This part of OSCAR is in an experimental state; please see Adding new projects to experimental for what this means.","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/introduction/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/introduction/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/introduction/","page":"Introduction","title":"Introduction","text":"Thomas Breuer","category":"page"},{"location":"Nemo/rational/","page":"Rationals","title":"Rationals","text":"CurrentModule = Nemo","category":"page"},{"location":"Nemo/rational/#Rationals","page":"Rationals","title":"Rationals","text":"","category":"section"},{"location":"Nemo/rational/","page":"Rationals","title":"Rationals","text":"Nemo provides much functionality for the rational numbers. See the section on Fraction Fields where all the basic functionality is documented, along with the extra functionality only available for the rational numbers themselves.","category":"page"},{"location":"Hecke/number_fields/internal/","page":"Internals","title":"Internals","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/number_fields/internal/#Internals","page":"Internals","title":"Internals","text":"","category":"section"},{"location":"Hecke/number_fields/internal/#Types-of-number-fields","page":"Internals","title":"Types of number fields","text":"","category":"section"},{"location":"Hecke/number_fields/internal/","page":"Internals","title":"Internals","text":"Number fields, in Hecke, come in several different types:","category":"page"},{"location":"Hecke/number_fields/internal/","page":"Internals","title":"Internals","text":"AnticNumberField: a finite simple extension of the rational numbers mathbfQ\nNfAbsNS: a finite extension of mathbfQ given by several polynomials. We will refer to this as a non-simple field - even though mathematically we can find a primitive elements.\nNfRel: a finite simple extension of a number field. This is actually parametried by the (element) type of the coefficient field. The complete type of an extension of an absolute field (AnticNumberField) is NfRel{nf_elem}. The next extension thus will be NfRel{NfRelElem{nf_elem}}.\nNfRelNS: extensions of number fields given by several polynomials. This too will be referred to as a non-simple field.","category":"page"},{"location":"Hecke/number_fields/internal/","page":"Internals","title":"Internals","text":"The simple types AnticNumberField and NfRel are also called simple fields in the rest of this document, NfRel and NfRelNS are referred to as relative extensions while AnticNumberField and NfAbsNS are called absolute.","category":"page"},{"location":"Hecke/number_fields/internal/","page":"Internals","title":"Internals","text":"Internally, simple fields are essentially just (univariate) polynomial quotients in a dense representation, while non-simple fields are multivariate quotient rings, thus have a sparse presentation. In general, simple fields allow much faster arithmetic, while the non-simple fields give easy access to large degree fields.","category":"page"},{"location":"Hecke/number_fields/internal/#Absolute-simple-fields","page":"Internals","title":"Absolute simple fields","text":"","category":"section"},{"location":"Hecke/number_fields/internal/","page":"Internals","title":"Internals","text":"The most basic number field type is that of AnticNumberField. Internally this is essentially represented as a unvariate quotient with the arithmetic provided by the C-library antic with the binding provided by Nemo.","category":"page"},{"location":"Hecke/function_fields/elements/#Elements","page":"-","title":"Elements","text":"","category":"section"},{"location":"Hecke/function_fields/elements/","page":"-","title":"-","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/function_fields/elements/","page":"-","title":"-","text":"For details on element arithmetic in rational function fields and extensions, refer to the AbstractAlgebra documentation which can be found at https://nemocas.github.io/AbstractAlgebra.jl/stable/function_field/.","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/residue_interface/#Residue-Ring-Interface","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"","category":"section"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"Residue rings (currently a quotient ring modulo a principal ideal) are supported in AbstractAlgebra.jl, at least for Euclidean base rings. There is also partial support for residue rings of polynomial rings where the modulus has invertible leading coefficient.","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"In addition to the standard Ring interface, some additional functions are required to be present for residue rings.","category":"page"},{"location":"AbstractAlgebra/residue_interface/#Types-and-parents","page":"Residue Ring Interface","title":"Types and parents","text":"","category":"section"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"AbstractAlgebra provides four abstract types for residue rings and their elements:","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"ResidueRing{T} is the abstract type for residue ring parent types\nResidueField{T} is the abstract type for residue rings known to be fields\nResElem{T} is the abstract type for types of elements of residue rings (residues)\nResFieldElem{T} is the abstract type for types of elements of residue fields","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"We have that ResidueRing{T} <: AbstractAlgebra.Ring and ResElem{T} <: AbstractAlgebra.RingElem.","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"Note that these abstract types are parameterised. The type T should usually be the type of elements of the base ring of the residue ring/field.","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"If the parent object for a residue ring has type MyResRing and residues in that ring have type MyRes then one would have:","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"MyResRing <: ResidueRing{BigInt}\nMyRes <: ResElem{BigInt}","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"Residue rings should be made unique on the system by caching parent objects (unless an optional cache parameter is set to false). Residue rings should at least be distinguished based on their base ring and modulus (the principal ideal one is taking a quotient of the base ring by).","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"See src/generic/GenericTypes.jl for an example of how to implement such a cache (which usually makes use of a dictionary).","category":"page"},{"location":"AbstractAlgebra/residue_interface/#Required-functionality-for-residue-rings","page":"Residue Ring Interface","title":"Required functionality for residue rings","text":"","category":"section"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"In addition to the required functionality for the Ring interface the Residue Ring interface has the following required functions.","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"We suppose that R is a fictitious base ring, m is an element of that ring, and that S is the residue ring (quotient ring) R(m) with parent object S of type MyResRing{T}. We also assume the residues r pmodm in the residue ring have type MyRes{T}, where T is the type of elements of the base ring.","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"Note that the type T must (transitively) belong to the abstract type RingElem.","category":"page"},{"location":"AbstractAlgebra/residue_interface/#Data-type-and-parent-object-methods","page":"Residue Ring Interface","title":"Data type and parent object methods","text":"","category":"section"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"modulus(S::MyResRing{T}) where T <: AbstractAlgebra.RingElem","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"Return the modulus of the given residue ring, i.e. if the residue ring S was specified to be R(m), return m.","category":"page"},{"location":"AbstractAlgebra/residue_interface/#Basic-manipulation-of-rings-and-elements","page":"Residue Ring Interface","title":"Basic manipulation of rings and elements","text":"","category":"section"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"data(f::MyRes{T}) where T <: RingElem\nlift(f::MyRes{T}) where T <: RingElem","category":"page"},{"location":"AbstractAlgebra/residue_interface/","page":"Residue Ring Interface","title":"Residue Ring Interface","text":"Given a residue r pmodm, represented as such, return r. In the special case where machine integers are used to represent the residue, data will return the machine integer, whereas lift will return a multiprecision integer. Otherwise lift falls back to data by default.","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#Integer-Lattices","page":"Integer Lattices","title":"Integer Lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"An integer lattice L is a finitely generated mathbbZ-submodule of a quadratic vector space V = mathbbQ^n over the rational numbers. Integer lattices are also known as quadratic forms over the integers. We will refer to them as mathbbZ-lattices.","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"A mathbbZ-lattice L has the type ZZLat. It is given in terms of its ambient quadratic space V together with a basis matrix B whose rows span L, i.e. L = mathbbZ^r B where r is the (mathbbZ-module) rank of L.","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"To access V and B see ambient_space(L::ZZLat) and basis_matrix(L::ZZLat).","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#Creation-of-integer-lattices","page":"Integer Lattices","title":"Creation of integer lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/#From-a-gram-matrix","page":"Integer Lattices","title":"From a gram matrix","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"integer_lattice(B::QQMatrix)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#integer_lattice-Tuple{QQMatrix}","page":"Integer Lattices","title":"integer_lattice","text":"integer_lattice([B::MatElem]; gram) -> ZZLat\n\nReturn the Z-lattice with basis matrix B inside the quadratic space with Gram matrix gram.\n\nIf the keyword gram is not specified, the Gram matrix is the identity matrix. If B is not specified, the basis matrix is the identity matrix.\n\nExamples\n\njulia> L = integer_lattice(matrix(QQ, 2, 2, [1//2, 0, 0, 2]));\n\njulia> gram_matrix(L) == matrix(QQ, 2, 2, [1//4, 0, 0, 4])\ntrue\n\njulia> L = integer_lattice(gram = matrix(ZZ, [2 -1; -1 2]));\n\njulia> gram_matrix(L) == matrix(ZZ, [2 -1; -1 2])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#In-a-quadratic-space","page":"Integer Lattices","title":"In a quadratic space","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"lattice(V::QuadSpace{QQField, QQMatrix}, B::MatElem;)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#lattice-Tuple{Hecke.QuadSpace{QQField, QQMatrix}, MatElem}","page":"Integer Lattices","title":"lattice","text":"lattice(V::AbstractSpace, basis::MatElem ; check::Bool = true) -> AbstractLat\n\nGiven an ambient space V and a matrix basis, return the lattice spanned by the rows of basis inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.\n\nBy default, basis is checked to be of full rank. This test can be disabled by setting check to false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Special-lattices","page":"Integer Lattices","title":"Special lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"root_lattice(::Symbol, ::Int)\nhyperbolic_plane_lattice(n::Union{Int64, ZZRingElem})\ninteger_lattice(S::Symbol, n::Union{Int64, ZZRingElem})\nleech_lattice","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#root_lattice-Tuple{Symbol, Int64}","page":"Integer Lattices","title":"root_lattice","text":"root_lattice(R::Symbol, n::Int) -> ZZLat\n\nReturn the root lattice of type R given by :A, :D or :E with parameter n.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#hyperbolic_plane_lattice-Tuple{Union{Int64, ZZRingElem}}","page":"Integer Lattices","title":"hyperbolic_plane_lattice","text":"hyperbolic_plane_lattice(n::RationalUnion = 1) -> ZZLat\n\nReturn the hyperbolic plane with intersection form of scale n, that is, the unique (up to isometry) even unimodular hyperbolic mathbb Z-lattice of rank 2, rescaled by n.\n\nExamples\n\njulia> L = hyperbolic_plane_lattice(6);\n\njulia> gram_matrix(L)\n[0 6]\n[6 0]\n\njulia> L = hyperbolic_plane_lattice(ZZ(-13));\n\njulia> gram_matrix(L)\n[ 0 -13]\n[-13 0]\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#integer_lattice-Tuple{Symbol, Union{Int64, ZZRingElem}}","page":"Integer Lattices","title":"integer_lattice","text":"integer_lattice(S::Symbol, n::RationalUnion = 1) -> ZZlat\n\nGiven S = :H or S = :U, return a mathbb Z-lattice admitting n*J_2 as Gram matrix in some basis, where J_2 is the 2-by-2 matrix with 0's on the main diagonal and 1's elsewhere.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#leech_lattice","page":"Integer Lattices","title":"leech_lattice","text":"leech_lattice() -> ZZLat\n\nReturn the Leech lattice.\n\n\n\n\n\nleech_lattice(niemeier_lattice::ZZLat) -> ZZLat, QQMatrix, Int\n\nReturn a triple L, v, h where L is the Leech lattice.\n\nL is an h-neighbor of the Niemeier lattice N with respect to v. This means that L / L ∩ N ≅ ℤ / h ℤ. Here h is the Coxeter number of the Niemeier lattice.\n\nThis implements the 23 holy constructions of the Leech lattice in J. H. Conway, N. J. A. Sloane (1999).\n\nExamples\n\njulia> R = integer_lattice(gram=2 * identity_matrix(ZZ, 24));\n\njulia> N = maximal_even_lattice(R) # Some Niemeier lattice\nInteger lattice of rank 24 and degree 24\nwith gram matrix\n[2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0]\n[1 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0]\n[1 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0]\n[1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 2 1 1 1 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0]\n[0 0 0 0 1 2 1 1 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0]\n[0 0 0 0 1 1 2 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 2 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0]\n[0 0 0 0 0 0 0 0 1 2 1 1 0 0 0 0 0 0 0 0 1 0 1 1]\n[0 0 0 0 0 0 0 0 1 1 2 1 0 0 0 0 0 0 0 0 1 1 0 1]\n[0 0 0 0 0 0 0 0 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 1 1 1 0 0 0 0 0 2 1 1 1 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 1 1 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 1 0 1 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 2 0 0 0 0 0 0 0 0]\n[1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 1 1 0 0 0 0]\n[0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0]\n[1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 0 0]\n[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 0]\n[0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 2 1 1 1]\n[0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 2 0 0]\n[0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 2 0]\n[0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 2]\n\njulia> minimum(N)\n2\n\njulia> det(N)\n1\n\njulia> L, v, h = leech_lattice(N);\n\njulia> minimum(L)\n4\n\njulia> det(L)\n1\n\njulia> h == index(L, intersect(L, N))\ntrue\n\n\nWe illustrate how the Leech lattice is constructed from N, h and v.\n\njulia> Zmodh = residue_ring(ZZ, h);\n\njulia> V = ambient_space(N);\n\njulia> vG = map_entries(x->Zmodh(ZZ(x)), inner_product(V, v, basis_matrix(N)));\n\njulia> LN = transpose(lift(kernel(vG)[2]))*basis_matrix(N); # vectors whose inner product with `v` is divisible by `h`.\n\njulia> lattice(V, LN) == intersect(L, N)\ntrue\n\njulia> gensL = vcat(LN, 1//h * v);\n\njulia> lattice(V, gensL, isbasis=false) == L\ntrue\n\n\n\n\n\n\n","category":"function"},{"location":"Hecke/quad_forms/integer_lattices/#From-a-genus","page":"Integer Lattices","title":"From a genus","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"Integer lattices can be created as representatives of a genus. See (representative(L::ZZGenus))","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#Rescaling-the-Quadratic-Form","page":"Integer Lattices","title":"Rescaling the Quadratic Form","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"rescale(::ZZLat, ::RationalUnion)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#rescale-Tuple{ZZLat, Union{Integer, QQFieldElem, ZZRingElem, Rational}}","page":"Integer Lattices","title":"rescale","text":"rescale(L::ZZLat, r::RationalUnion) -> ZZLat\n\nReturn the lattice L in the quadratic space with form r \\Phi.\n\nExamples\n\nThis can be useful to apply methods intended for positive definite lattices.\n\njulia> L = integer_lattice(gram=ZZ[-1 0; 0 -1])\nInteger lattice of rank 2 and degree 2\nwith gram matrix\n[-1 0]\n[ 0 -1]\n\njulia> shortest_vectors(rescale(L, -1))\n2-element Vector{Vector{ZZRingElem}}:\n [0, 1]\n [1, 0]\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Attributes","page":"Integer Lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"ambient_space(L::ZZLat)\nbasis_matrix(L::ZZLat)\ngram_matrix(L::ZZLat)\nrational_span(L::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#ambient_space-Tuple{ZZLat}","page":"Integer Lattices","title":"ambient_space","text":"ambient_space(L::AbstractLat) -> AbstractSpace\n\nReturn the ambient space of the lattice L. If the ambient space is not known, an error is raised.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#basis_matrix-Tuple{ZZLat}","page":"Integer Lattices","title":"basis_matrix","text":"basis_matrix(L::ZZLat) -> QQMatrix\n\nReturn the basis matrix B of the integer lattice L.\n\nThe lattice is given by the row span of B seen inside of the ambient quadratic space of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#gram_matrix-Tuple{ZZLat}","page":"Integer Lattices","title":"gram_matrix","text":"gram_matrix(L::ZZLat) -> QQMatrix\n\nReturn the gram matrix of L.\n\nExamples\n\njulia> L = integer_lattice(matrix(ZZ, [2 0; -1 2]));\n\njulia> gram_matrix(L)\n[ 4 -2]\n[-2 5]\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#rational_span-Tuple{ZZLat}","page":"Integer Lattices","title":"rational_span","text":"rational_span(L::ZZLat) -> QuadSpace\n\nReturn the rational span of L, which is the quadratic space with Gram matrix equal to gram_matrix(L).\n\nExamples\n\njulia> L = integer_lattice(matrix(ZZ, [2 0; -1 2]));\n\njulia> rational_span(L)\nQuadratic space of dimension 2\n over rational field\nwith gram matrix\n[ 4 -2]\n[-2 5]\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Invariants","page":"Integer Lattices","title":"Invariants","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"rank(L::ZZLat)\ndet(L::ZZLat)\n\nscale(L::ZZLat)\nnorm(L::ZZLat)\niseven(L::ZZLat)\nis_integral(L::ZZLat)\n\nis_primary_with_prime(L::ZZLat)\nis_primary(L::ZZLat, p::Union{Integer, ZZRingElem})\nis_elementary_with_prime(L::ZZLat)\nis_elementary(L::ZZLat, p::Union{Integer, ZZRingElem})","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#rank-Tuple{ZZLat}","page":"Integer Lattices","title":"rank","text":"rank(L::AbstractLat) -> Int\n\nReturn the rank of the underlying module of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#det-Tuple{ZZLat}","page":"Integer Lattices","title":"det","text":"det(L::ZZLat) -> QQFieldElem\n\nReturn the determinant of the gram matrix of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#scale-Tuple{ZZLat}","page":"Integer Lattices","title":"scale","text":"scale(L::ZZLat) -> QQFieldElem\n\nReturn the scale of L.\n\nThe scale of L is defined as the positive generator of the mathbb Z-ideal generated by Phi(x y) x y in L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#norm-Tuple{ZZLat}","page":"Integer Lattices","title":"norm","text":"norm(L::ZZLat) -> QQFieldElem\n\nReturn the norm of L.\n\nThe norm of L is defined as the positive generator of the mathbb Z- ideal generated by Phi(xx) x in L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#iseven-Tuple{ZZLat}","page":"Integer Lattices","title":"iseven","text":"iseven(L::ZZLat) -> Bool\n\nReturn whether L is even.\n\nAn integer lattice L in the rational quadratic space (VPhi) is called even if Phi(xx) in 2mathbbZ for all x in L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_integral-Tuple{ZZLat}","page":"Integer Lattices","title":"is_integral","text":"is_integral(L::AbstractLat) -> Bool\n\nReturn whether the lattice L is integral.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_primary_with_prime-Tuple{ZZLat}","page":"Integer Lattices","title":"is_primary_with_prime","text":"is_primary_with_prime(L::ZZLat) -> Bool, ZZRingElem\n\nGiven a mathbb Z-lattice L, return whether L is primary, that is whether L is integral and its discriminant group (see discriminant_group) is a p-group for some prime number p. In case it is, p is also returned as second output.\n\nNote that for unimodular lattices, this function returns (true, 1). If the lattice is not primary, the second return value is -1 by default.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_primary-Tuple{ZZLat, Union{Integer, ZZRingElem}}","page":"Integer Lattices","title":"is_primary","text":"is_primary(L::ZZLat, p::Union{Integer, ZZRingElem}) -> Bool\n\nGiven an integral mathbb Z-lattice L and a prime number p, return whether L is p-primary, that is whether its discriminant group (see discriminant_group) is a p-group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_elementary_with_prime-Tuple{ZZLat}","page":"Integer Lattices","title":"is_elementary_with_prime","text":"is_elementary_with_prime(L::ZZLat) -> Bool, ZZRingElem\n\nGiven a mathbb Z-lattice L, return whether L is elementary, that is whether L is integral and its discriminant group (see discriminant_group) is an elemenentary p-group for some prime number p. In case it is, p is also returned as second output.\n\nNote that for unimodular lattices, this function returns (true, 1). If the lattice is not elementary, the second return value is -1 by default.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_elementary-Tuple{ZZLat, Union{Integer, ZZRingElem}}","page":"Integer Lattices","title":"is_elementary","text":"is_elementary(L::ZZLat, p::Union{Integer, ZZRingElem}) -> Bool\n\nGiven an integral mathbb Z-lattice L and a prime number p, return whether L is p-elementary, that is whether its discriminant group (see discriminant_group) is an elementary p-group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#The-Genus","page":"Integer Lattices","title":"The Genus","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"For an integral lattice The genus of an integer lattice collects its local invariants. genus(::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"mass(L::ZZLat)\ngenus_representatives(L::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#mass-Tuple{ZZLat}","page":"Integer Lattices","title":"mass","text":"mass(L::ZZLat) -> QQFieldElem\n\nReturn the mass of the genus of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#genus_representatives-Tuple{ZZLat}","page":"Integer Lattices","title":"genus_representatives","text":"genus_representatives(L::ZZLat) -> Vector{ZZLat}\n\nReturn representatives for the isometry classes in the genus of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Real-invariants","page":"Integer Lattices","title":"Real invariants","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"signature_tuple(L::ZZLat)\nis_positive_definite(L::ZZLat)\nis_negative_definite(L::ZZLat)\nis_definite(L::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#signature_tuple-Tuple{ZZLat}","page":"Integer Lattices","title":"signature_tuple","text":"signature_tuple(L::ZZLat) -> Tuple{Int,Int,Int}\n\nReturn the number of (positive, zero, negative) inertia of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_positive_definite-Tuple{ZZLat}","page":"Integer Lattices","title":"is_positive_definite","text":"is_positive_definite(L::AbstractLat) -> Bool\n\nReturn whether the rational span of the lattice L is positive definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_negative_definite-Tuple{ZZLat}","page":"Integer Lattices","title":"is_negative_definite","text":"is_negative_definite(L::AbstractLat) -> Bool\n\nReturn whether the rational span of the lattice L is negative definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_definite-Tuple{ZZLat}","page":"Integer Lattices","title":"is_definite","text":"is_definite(L::AbstractLat) -> Bool\n\nReturn whether the rational span of the lattice L is definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Isometries","page":"Integer Lattices","title":"Isometries","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"automorphism_group_generators(L::ZZLat)\nautomorphism_group_order(L::ZZLat)\nis_isometric(L::ZZLat, M::ZZLat)\nis_locally_isometric(L::ZZLat, M::ZZLat, p::Int)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#automorphism_group_generators-Tuple{ZZLat}","page":"Integer Lattices","title":"automorphism_group_generators","text":"automorphism_group_generators(E::EllCrv) -> Vector{EllCrvIso}\n\nReturn generators of the automorphism group of E.\n\n\n\n\n\nautomorphism_group_generators(L::AbstractLat; ambient_representation::Bool = true)\n -> Vector{MatElem}\n\nGiven a definite lattice L, return generators for the automorphism group of L. If ambient_representation == true (the default), the transformations are represented with respect to the ambient space of L. Otherwise, the transformations are represented with respect to the (pseudo-)basis of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#automorphism_group_order-Tuple{ZZLat}","page":"Integer Lattices","title":"automorphism_group_order","text":"automorphism_group_order(L::AbstractLat) -> Int\n\nGiven a definite lattice L, return the order of the automorphism group of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_isometric-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"is_isometric","text":"is_isometric(L::AbstractLat, M::AbstractLat) -> Bool\n\nReturn whether the lattices L and M are isometric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_locally_isometric-Tuple{ZZLat, ZZLat, Int64}","page":"Integer Lattices","title":"is_locally_isometric","text":"is_locally_isometric(L::ZZLat, M::ZZLat, p::Int) -> Bool\n\nReturn whether L and M are isometric over the p-adic integers.\n\ni.e. whether L otimes mathbbZ_p cong Motimes mathbbZ_p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Root-lattices","page":"Integer Lattices","title":"Root lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"root_lattice_recognition(L::ZZLat)\nroot_lattice_recognition_fundamental(L::ZZLat)\nADE_type(G::MatrixElem)\ncoxeter_number(ADE::Symbol, n)\nhighest_root(ADE::Symbol, n)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#root_lattice_recognition-Tuple{ZZLat}","page":"Integer Lattices","title":"root_lattice_recognition","text":"root_lattice_recognition(L::ZZLat)\n\nReturn the ADE type of the root sublattice of L.\n\nInput:\n\nL – a definite and integral mathbbZ-lattice.\n\nOutput:\n\nTwo lists, the first one containing the ADE types and the second one the irreducible root sublattices.\n\nFor more recognizable gram matrices use root_lattice_recognition_fundamental.\n\nExamples\n\njulia> L = integer_lattice(gram=ZZ[4 0 0 0 3 0 3 0;\n 0 16 8 12 2 12 6 10;\n 0 8 8 6 2 8 4 5;\n 0 12 6 10 2 9 5 8;\n 3 2 2 2 4 2 4 2;\n 0 12 8 9 2 12 6 9;\n 3 6 4 5 4 6 6 5;\n 0 10 5 8 2 9 5 8])\nInteger lattice of rank 8 and degree 8\nwith gram matrix\n[4 0 0 0 3 0 3 0]\n[0 16 8 12 2 12 6 10]\n[0 8 8 6 2 8 4 5]\n[0 12 6 10 2 9 5 8]\n[3 2 2 2 4 2 4 2]\n[0 12 8 9 2 12 6 9]\n[3 6 4 5 4 6 6 5]\n[0 10 5 8 2 9 5 8]\n\njulia> R = root_lattice_recognition(L)\n([(:A, 1), (:D, 6)], ZZLat[Integer lattice of rank 1 and degree 8, Integer lattice of rank 6 and degree 8])\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#root_lattice_recognition_fundamental-Tuple{ZZLat}","page":"Integer Lattices","title":"root_lattice_recognition_fundamental","text":"root_lattice_recognition_fundamental(L::ZZLat)\n\nReturn the ADE type of the root sublattice of L as well as the corresponding irreducible root sublattices with basis given by a fundamental root system.\n\nInput:\n\nL – a definite and integral mathbb Z-lattice.\n\nOutput:\n\nthe root sublattice, with basis given by a fundamental root system\nthe ADE types\na Vector consisting of the irreducible root sublattices.\n\nExamples\n\njulia> L = integer_lattice(gram=ZZ[4 0 0 0 3 0 3 0;\n 0 16 8 12 2 12 6 10;\n 0 8 8 6 2 8 4 5;\n 0 12 6 10 2 9 5 8;\n 3 2 2 2 4 2 4 2;\n 0 12 8 9 2 12 6 9;\n 3 6 4 5 4 6 6 5;\n 0 10 5 8 2 9 5 8])\nInteger lattice of rank 8 and degree 8\nwith gram matrix\n[4 0 0 0 3 0 3 0]\n[0 16 8 12 2 12 6 10]\n[0 8 8 6 2 8 4 5]\n[0 12 6 10 2 9 5 8]\n[3 2 2 2 4 2 4 2]\n[0 12 8 9 2 12 6 9]\n[3 6 4 5 4 6 6 5]\n[0 10 5 8 2 9 5 8]\n\njulia> R = root_lattice_recognition_fundamental(L);\n\njulia> gram_matrix(R[1])\n[2 0 0 0 0 0 0]\n[0 2 0 -1 0 0 0]\n[0 0 2 -1 0 0 0]\n[0 -1 -1 2 -1 0 0]\n[0 0 0 -1 2 -1 0]\n[0 0 0 0 -1 2 -1]\n[0 0 0 0 0 -1 2]\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#ADE_type-Tuple{MatrixElem}","page":"Integer Lattices","title":"ADE_type","text":"ADE_type(G::MatrixElem) -> Tuple{Symbol,Int64}\n\nReturn the type of the irreducible root lattice with gram matrix G.\n\nSee also root_lattice_recognition.\n\nExamples\n\njulia> Hecke.ADE_type(gram_matrix(root_lattice(:A,3)))\n(:A, 3)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#coxeter_number-Tuple{Symbol, Any}","page":"Integer Lattices","title":"coxeter_number","text":"coxeter_number(ADE::Symbol, n) -> Int\n\nReturn the Coxeter number of the corresponding ADE root lattice.\n\nIf L is a root lattice and R its set of roots, then the Coxeter number h is Rn where n is the rank of L.\n\nExamples\n\njulia> coxeter_number(:D, 4)\n6\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#highest_root-Tuple{Symbol, Any}","page":"Integer Lattices","title":"highest_root","text":"highest_root(ADE::Symbol, n) -> ZZMatrix\n\nReturn coordinates of the highest root of root_lattice(ADE, n).\n\nExamples\n\njulia> highest_root(:E, 6)\n[1 2 3 2 1 2]\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Module-operations","page":"Integer Lattices","title":"Module operations","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"Most module operations assume that the lattices live in the same ambient space. For instance only lattices in the same ambient space compare.","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"Base.:(==)(L1::ZZLat, L2::ZZLat)\nis_sublattice(M::ZZLat, N::ZZLat)\nis_sublattice_with_relations(M::ZZLat, N::ZZLat)\n+(M::ZZLat, N::ZZLat)\nBase.:(*)(a::RationalUnion, L::ZZLat)\nintersect(M::ZZLat, N::ZZLat)\nBase.in(v::Vector, L::ZZLat)\nBase.in(v::QQMatrix, L::ZZLat)\nprimitive_closure(M::ZZLat, N::ZZLat)\nis_primitive(M::ZZLat, N::ZZLat)\nis_primitive(::ZZLat, ::Union{Vector, QQMatrix})\ndivisibility(::ZZLat, ::Union{Vector, QQMatrix})","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#==-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"==","text":"Return true if both lattices have the same ambient quadratic space and the same underlying module.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_sublattice-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"is_sublattice","text":"is_sublattice(L::AbstractLat, M::AbstractLat) -> Bool\n\nReturn whether M is a sublattice of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_sublattice_with_relations-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"is_sublattice_with_relations","text":"is_sublattice_with_relations(M::ZZLat, N::ZZLat) -> Bool, QQMatrix\n\nReturns whether N is a sublattice of M. In this case, the second return value is a matrix B such that B B_M = B_N, where B_M and B_N are the basis matrices of M and N respectively.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#+-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"+","text":"+(L::AbstractLat, M::AbstractLat) -> AbstractLat\n\nReturn the sum of the lattices L and M.\n\nThe lattices L and M must have the same ambient space.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#*-Tuple{Union{Integer, QQFieldElem, ZZRingElem, Rational}, ZZLat}","page":"Integer Lattices","title":"*","text":"*(a::RationalUnion, L::ZZLat) -> ZZLat\n\nReturn the lattice aM inside the ambient space of M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#intersect-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"intersect","text":"intersect(L::AbstractLat, M::AbstractLat) -> AbstractLat\n\nReturn the intersection of the lattices L and M.\n\nThe lattices L and M must have the same ambient space.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#in-Tuple{Vector, ZZLat}","page":"Integer Lattices","title":"in","text":"Base.in(v::Vector, L::ZZLat) -> Bool\n\nReturn whether the vector v lies in the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#in-Tuple{QQMatrix, ZZLat}","page":"Integer Lattices","title":"in","text":"Base.in(v::QQMatrix, L::ZZLat) -> Bool\n\nReturn whether the row span of v lies in the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#primitive_closure-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"primitive_closure","text":"primitive_closure(M::ZZLat, N::ZZLat) -> ZZLat\n\nGiven two mathbb Z-lattices M and N with N subseteq mathbbQ M, return the primitive closure M cap mathbbQ N of N in M.\n\nExamples\n\njulia> M = root_lattice(:D, 6);\n\njulia> N = lattice_in_same_ambient_space(M, 3*basis_matrix(M)[1,:]);\n\njulia> basis_matrix(N)\n[3 0 0 0 0 0]\n\njulia> N2 = primitive_closure(M, N)\nInteger lattice of rank 1 and degree 6\nwith gram matrix\n[2]\n\njulia> basis_matrix(N2)\n[1 0 0 0 0 0]\n\njulia> M2 = primitive_closure(dual(M), M);\n\njulia> is_integral(M2)\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_primitive-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"is_primitive","text":"is_primitive(M::ZZLat, N::ZZLat) -> Bool\n\nGiven two mathbb Z-lattices N subseteq M, return whether N is a primitive sublattice of M.\n\nExamples\n\njulia> U = hyperbolic_plane_lattice(3);\n\njulia> bU = basis_matrix(U);\n\njulia> e1, e2 = bU[1,:], bU[2,:]\n([1 0], [0 1])\n\njulia> N = lattice_in_same_ambient_space(U, e1 + e2)\nInteger lattice of rank 1 and degree 2\nwith gram matrix\n[6]\n\njulia> is_primitive(U, N)\ntrue\n\njulia> M = root_lattice(:A, 3);\n\njulia> f = matrix(QQ, 3, 3, [0 1 1; -1 -1 -1; 1 1 0]);\n\njulia> N = kernel_lattice(M, f+1)\nInteger lattice of rank 1 and degree 3\nwith gram matrix\n[4]\n\njulia> is_primitive(M, N)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#is_primitive-Tuple{ZZLat, Union{QQMatrix, Vector}}","page":"Integer Lattices","title":"is_primitive","text":"is_primitive(L::ZZLat, v::Union{Vector, QQMatrix}) -> Bool\n\nReturn whether the vector v is primitive in L.\n\nA vector v in a mathbb Z-lattice L is called primitive if for all w in L such that v = dw for some integer d, then d = pm 1.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#divisibility-Tuple{ZZLat, Union{QQMatrix, Vector}}","page":"Integer Lattices","title":"divisibility","text":"divisibility(L::ZZLat, v::Union{Vector, QQMatrix}) -> QQFieldElem\n\nReturn the divisibility of v with respect to L.\n\nFor a vector v in the ambient quadratic space (V Phi) of L, we call the divisibility of v with the respect to L the non-negative generator of the fractional mathbb Z-ideal Phi(v L).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Embeddings","page":"Integer Lattices","title":"Embeddings","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/#Categorical-constructions","page":"Integer Lattices","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"direct_sum(x::Vector{ZZLat})\ndirect_product(x::Vector{ZZLat})\nbiproduct(x::Vector{ZZLat})","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#direct_sum-Tuple{Vector{ZZLat}}","page":"Integer Lattices","title":"direct_sum","text":"direct_sum(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}\ndirect_sum(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}\n\nGiven a collection of mathbb Z-lattices L_1 ldots L_n, return their direct sum L = L_1 oplus ldots oplus L_n, together with the injections L_i to L. (seen as maps between the corresponding ambient spaces).\n\nFor objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections L to L_i, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#direct_product-Tuple{Vector{ZZLat}}","page":"Integer Lattices","title":"direct_product","text":"direct_product(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}\ndirect_product(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}\n\nGiven a collection of mathbb Z-lattices L_1 ldots L_n, return their direct product L = L_1 times ldots times L_n, together with the projections L to L_i. (seen as maps between the corresponding ambient spaces).\n\nFor objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections L_i to L, one should call direct_sum(x). If one wants to obtain L as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#biproduct-Tuple{Vector{ZZLat}}","page":"Integer Lattices","title":"biproduct","text":"biproduct(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\nbiproduct(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\n\nGiven a collection of mathbb Z-lattices L_1 ldots L_n, return their biproduct L = L_1 oplus ldots oplus L_n, together with the injections L_i to L and the projections L to L_i. (seen as maps between the corresponding ambient spaces).\n\nFor objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections L_i to L, one should call direct_sum(x). If one wants to obtain L as a direct product with the projections L to L_i, one should call direct_product(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Orthogonal-sublattices","page":"Integer Lattices","title":"Orthogonal sublattices","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"orthogonal_submodule(::ZZLat, ::ZZLat)\nirreducible_components(::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#orthogonal_submodule-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"orthogonal_submodule","text":"orthogonal_submodule(L::ZZLat, S::ZZLat) -> ZZLat\n\nReturn the largest submodule of L orthogonal to S.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#irreducible_components-Tuple{ZZLat}","page":"Integer Lattices","title":"irreducible_components","text":"irreducible_components(L::ZZLat) -> Vector{ZZLat}\n\nReturn the irreducible components L_i of the positive definite lattice L.\n\nThis yields a maximal orthogonal splitting of L as\n\nL = bigoplus_i L_i\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Dual-lattice","page":"Integer Lattices","title":"Dual lattice","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"dual(L::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#dual-Tuple{ZZLat}","page":"Integer Lattices","title":"dual","text":"dual(L::AbstractLat) -> AbstractLat\n\nReturn the dual lattice of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Discriminant-group","page":"Integer Lattices","title":"Discriminant group","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"See discriminant_group(L::ZZLat).","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#Overlattices","page":"Integer Lattices","title":"Overlattices","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"glue_map(L::ZZLat, S::ZZLat, R::ZZLat; check=true)\noverlattice(glue_map::TorQuadModuleMor)\nlocal_modification(M::ZZLat, L::ZZLat, p)\nmaximal_integral_lattice(L::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#glue_map-Tuple{ZZLat, ZZLat, ZZLat}","page":"Integer Lattices","title":"glue_map","text":"glue_map(L::ZZLat, S::ZZLat, R::ZZLat; check=true)\n -> Tuple{TorQuadModuleMor, TorQuadModuleMor, TorQuadModuleMor}\n\nGiven three integral mathbb Z-lattices L, S and R, with S and R primitive sublattices of L and such that the sum of the ranks of S and R is equal to the rank of L, return the glue map gamma of the primitive extension S+R subseteq L, as well as the inclusion maps of the domain and codomain of gamma into the respective discriminant groups of S and R.\n\nExample\n\njulia> M = root_lattice(:E,8);\n\njulia> f = matrix(QQ, 8, 8, [-1 -1 0 0 0 0 0 0;\n 1 0 0 0 0 0 0 0;\n 0 1 1 0 0 0 0 0;\n 0 0 0 1 0 0 0 0;\n 0 0 0 0 1 0 0 0;\n 0 0 0 0 0 1 1 0;\n -2 -4 -6 -5 -4 -3 -2 -3;\n 0 0 0 0 0 0 0 1]);\n\njulia> S = kernel_lattice(M ,f-1)\nInteger lattice of rank 4 and degree 8\nwith gram matrix\n[12 -3 0 -3]\n[-3 2 -1 0]\n[ 0 -1 2 0]\n[-3 0 0 2]\n\njulia> R = kernel_lattice(M , f^2+f+1)\nInteger lattice of rank 4 and degree 8\nwith gram matrix\n[ 2 -1 0 0]\n[-1 2 -6 0]\n[ 0 -6 30 -3]\n[ 0 0 -3 2]\n\njulia> glue, iS, iR = glue_map(M, S, R)\n(Map with following data\nDomain:\n=======\nFinite quadratic module: (Z/3)^2 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data\nDomain:\n=======\nFinite quadratic module: (Z/3)^2 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: (Z/3)^2 -> Q/2Z, Map with following data\nDomain:\n=======\nFinite quadratic module: (Z/3)^2 -> Q/2Z\nCodomain:\n=========\nFinite quadratic module: (Z/3)^2 -> Q/2Z)\n\njulia> is_bijective(glue)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#overlattice-Tuple{TorQuadModuleMor}","page":"Integer Lattices","title":"overlattice","text":"overlattice(glue_map::TorQuadModuleMor) -> ZZLat\n\nGiven the glue map of a primitive extension of mathbb Z-lattices S+R subseteq L, return L.\n\nExample\n\njulia> M = root_lattice(:E,8);\n\njulia> f = matrix(QQ, 8, 8, [ 1 0 0 0 0 0 0 0;\n 0 1 0 0 0 0 0 0;\n 1 2 4 4 3 2 1 2;\n -2 -4 -6 -5 -4 -3 -2 -3;\n 2 4 6 4 3 2 1 3;\n -1 -2 -3 -2 -1 0 0 -2;\n 0 0 0 0 0 -1 0 0;\n -1 -2 -3 -3 -2 -1 0 -1]);\n\njulia> S = kernel_lattice(M ,f-1)\nInteger lattice of rank 4 and degree 8\nwith gram matrix\n[ 2 -1 0 0]\n[-1 2 -1 0]\n[ 0 -1 12 -15]\n[ 0 0 -15 20]\n\njulia> R = kernel_lattice(M , f^4+f^3+f^2+f+1)\nInteger lattice of rank 4 and degree 8\nwith gram matrix\n[10 -4 0 1]\n[-4 2 -1 0]\n[ 0 -1 4 -3]\n[ 1 0 -3 4]\n\njulia> glue, iS, iR = glue_map(M, S, R);\n\njulia> overlattice(glue) == M\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#local_modification-Tuple{ZZLat, ZZLat, Any}","page":"Integer Lattices","title":"local_modification","text":"local_modification(M::ZZLat, L::ZZLat, p)\n\nReturn a local modification of M that matches L at p.\n\nINPUT:\n\nM – a \\mathbb{Z}_p-maximal lattice\nL – the a lattice isomorphic to M over \\QQ_p\np – a prime number\n\nOUTPUT:\n\nan integral lattice M' in the ambient space of M such that M and M' are locally equal at all completions except at p where M' is locally isometric to the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#maximal_integral_lattice-Tuple{ZZLat}","page":"Integer Lattices","title":"maximal_integral_lattice","text":"maximal_integral_lattice(L::AbstractLat) -> AbstractLat\n\nGiven a lattice L, return a lattice M in the ambient space of L which is maximal integral and which contains L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Sublattices-defined-by-endomorphisms","page":"Integer Lattices","title":"Sublattices defined by endomorphisms","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"kernel_lattice(L::ZZLat, f::MatElem)\ninvariant_lattice(L::ZZLat, G::Vector{<:MatElem})\ncoinvariant_lattice(::ZZLat, ::Union{MatElem, Vector{<:MatElem}})","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#kernel_lattice-Tuple{ZZLat, MatElem}","page":"Integer Lattices","title":"kernel_lattice","text":"kernel_lattice(L::ZZLat, f::MatElem;\n ambient_representation::Bool = true) -> ZZLat\n\nGiven a mathbfZ-lattice L and a matrix f inducing an endomorphism of L, return ker(f) is a sublattice of L.\n\nIf ambient_representation is true (the default), the endomorphism is represented with respect to the ambient space of L. Otherwise, the endomorphism is represented with respect to the basis of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#invariant_lattice-Tuple{ZZLat, Vector{<:MatElem}}","page":"Integer Lattices","title":"invariant_lattice","text":"invariant_lattice(L::ZZLat, G::Vector{MatElem};\n ambient_representation::Bool = true) -> ZZLat\ninvariant_lattice(L::ZZLat, G::MatElem;\n ambient_representation::Bool = true) -> ZZLat\n\nGiven a mathbfZ-lattice L and a list of matrices G inducing endomorphisms of L (or just one matrix G), return the lattice L^G, consisting on elements fixed by G.\n\nIf ambient_representation is true (the default), the endomorphism is represented with respect to the ambient space of L. Otherwise, the endomorphism is represented with respect to the basis of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#coinvariant_lattice-Tuple{ZZLat, Union{MatElem, Vector{<:MatElem}}}","page":"Integer Lattices","title":"coinvariant_lattice","text":"coinvariant_lattice(L::ZZLat, G::Vector{MatElem};\n ambient_representation::Bool = true) -> ZZLat\ncoinvariant_lattice(L::ZZLat, G::MatElem;\n ambient_representation::Bool = true) -> ZZLat\n\nGiven a mathbfZ-lattice L and a list of matrices G inducing endomorphisms of L (or just one matrix G), return the orthogonal complement L_G in L of the fixed lattice L^G (see invariant_lattice).\n\nIf ambient_representation is true (the default), the endomorphism is represented with respect to the ambient space of L. Otherwise, the endomorphism is represented with respect to the basis of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Computing-embeddings","page":"Integer Lattices","title":"Computing embeddings","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"embed(S::ZZLat, G::ZZGenus)\nembed_in_unimodular(::ZZLat, ::IntegerUnion, ::IntegerUnion)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#embed-Tuple{ZZLat, ZZGenus}","page":"Integer Lattices","title":"embed","text":"embed(S::ZZLat, G::Genus, primitive::Bool=true) -> Bool, embedding\n\nReturn a (primitive) embedding of the integral lattice S into some lattice in the genus of G.\n\njulia> G = integer_genera((8,0), 1, even=true)[1];\n\njulia> L, S, i = embed(root_lattice(:A,5), G);\n\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#embed_in_unimodular-Tuple{ZZLat, Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Integer Lattices","title":"embed_in_unimodular","text":"embed_in_unimodular(S::ZZLat, pos::Int, neg::Int, primitive=true, even=true) -> Bool, L, S', iS, iR\n\nReturn a (primitive) embedding of the integral lattice S into some (even) unimodular lattice of signature (pos, neg).\n\nFor now this works only for even lattices.\n\njulia> NS = direct_sum(integer_lattice(:U), rescale(root_lattice(:A, 16), -1))[1];\n\njulia> LK3, iNS, i = embed_in_unimodular(NS, 3, 19);\n\njulia> genus(LK3)\nGenus symbol for integer lattices\nSignatures: (3, 0, 19)\nLocal symbol:\n Local genus symbol at 2: 1^22\n\njulia> iNS\nInteger lattice of rank 18 and degree 22\nwith gram matrix\n[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 -2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 1 -2 1 0 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 1 -2 1 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 1 -2 1 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 1 -2 1 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 0 1 -2 1 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 0 0 1 -2 1 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 1 -2 1 0 0 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 0 1 -2 1 0 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 0 0 1 -2 1 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 0 0 0 1 -2 1 0 0 0 0]\n[0 0 0 0 0 0 0 0 0 0 0 0 1 -2 1 0 0 0]\n[0 0 0 0 0 0 0 0 0 0 0 0 0 1 -2 1 0 0]\n[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -2 1 0]\n[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -2 1]\n[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -2]\n\njulia> is_primitive(LK3, iNS)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#LLL,-Short-and-Close-Vectors","page":"Integer Lattices","title":"LLL, Short and Close Vectors","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/#LLL-and-indefinite-LLL","page":"Integer Lattices","title":"LLL and indefinite LLL","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"lll(L::ZZLat; same_ambient::Bool = true)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#lll-Tuple{ZZLat}","page":"Integer Lattices","title":"lll","text":"lll(L::ZZLat, same_ambient::Bool = true) -> ZZLat\n\nGiven an integral mathbb Z-lattice L with basis matrix B, compute a basis C of L such that the gram matrix G_C of L with respect to C is LLL-reduced.\n\nBy default, it creates the lattice in the same ambient space as L. This can be disabled by setting same_ambient = false. Works with both definite and indefinite lattices.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Short-Vectors","page":"Integer Lattices","title":"Short Vectors","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"short_vectors\nshortest_vectors\nshort_vectors_iterator\nminimum(L::ZZLat)\nkissing_number(L::ZZLat)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#short_vectors","page":"Integer Lattices","title":"short_vectors","text":"short_vectors(L::ZZLat, [lb = 0], ub, [elem_type = ZZRingElem]; check::Bool = true)\n -> Vector{Tuple{Vector{elem_type}, QQFieldElem}}\n\nReturns all tuples (v, n) such that n = v G v^t satisfies lb <= n <= ub, where G is the Gram matrix of L and v is non-zero.\n\nNote that the vectors are computed up to sign (so only one of v and -v appears).\n\nIt is assumed and checked that L is positive definite.\n\nSee also short_vectors_iterator for an iterator version.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/quad_forms/integer_lattices/#shortest_vectors","page":"Integer Lattices","title":"shortest_vectors","text":"shortest_vectors(L::ZZLat, [elem_type = ZZRingElem]; check::Bool = true)\n -> QQFieldElem, Vector{elem_type}, QQFieldElem}\n\nReturns the list of shortest non-zero vectors. Note that the vectors are computed up to sign (so only one of v and -v appears).\n\nIt is assumed and checked that L is positive definite.\n\nSee also minimum.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/quad_forms/integer_lattices/#short_vectors_iterator","page":"Integer Lattices","title":"short_vectors_iterator","text":"short_vectors_iterator(L::ZZLat, [lb = 0], ub,\n [elem_type = ZZRingElem]; check::Bool = true)\n -> Tuple{Vector{elem_type}, QQFieldElem} (iterator)\n\nReturns an iterator for all tuples (v, n) such that n = v G v^t satisfies lb <= n <= ub, where G is the Gram matrix of L and v is non-zero.\n\nNote that the vectors are computed up to sign (so only one of v and -v appears).\n\nIt is assumed and checked that L is positive definite.\n\nSee also short_vectors.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/quad_forms/integer_lattices/#minimum-Tuple{ZZLat}","page":"Integer Lattices","title":"minimum","text":"minimum(L::ZZLat) -> QQFieldElem\n\nReturn the minimum squared length among the non-zero vectors in L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#kissing_number-Tuple{ZZLat}","page":"Integer Lattices","title":"kissing_number","text":"kissing_number(L::ZZLat) -> Int\n\nReturn the Kissing number of the sphere packing defined by L.\n\nThis is the number of non-overlapping spheres touching any other given sphere.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/#Close-Vectors","page":"Integer Lattices","title":"Close Vectors","text":"","category":"section"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"close_vectors(L::ZZLat, v::Vector, arg...; kw...)","category":"page"},{"location":"Hecke/quad_forms/integer_lattices/#close_vectors-Tuple{ZZLat, Vector, Vararg{Any}}","page":"Integer Lattices","title":"close_vectors","text":"close_vectors(L:ZZLat, v:Vector, [lb,], ub; check::Bool = false)\n -> Vector{Tuple{Vector{Int}}, QQFieldElem}\n\nReturn all tuples (x, d) where x is an element of L such that d = b(v - x, v - x) <= ub. If lb is provided, then also lb <= d.\n\nIf filter is not nothing, then only those x with filter(x) evaluating to true are returned.\n\nBy default, it will be checked whether L is positive definite. This can be disabled setting check = false.\n\nBoth input and output are with respect to the basis matrix of L.\n\nExamples\n\njulia> L = integer_lattice(matrix(QQ, 2, 2, [1, 0, 0, 2]));\n\njulia> close_vectors(L, [1, 1], 1)\n3-element Vector{Tuple{Vector{ZZRingElem}, QQFieldElem}}:\n ([2, 1], 1)\n ([0, 1], 1)\n ([1, 1], 0)\n\njulia> close_vectors(L, [1, 1], 1, 1)\n2-element Vector{Tuple{Vector{ZZRingElem}, QQFieldElem}}:\n ([2, 1], 1)\n ([0, 1], 1)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/integer/#Integers","page":"Integers","title":"Integers","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"The default integer type in Nemo is provided by Flint. The associated ring of integers is represented by the constant parent object called FlintZZ.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"For convenience we define","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"ZZ = FlintZZ","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"so that integers can be constructed using ZZ instead of FlintZZ. Note that this is the name of a specific parent object, not the name of its type.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"The types of the integer ring parent objects and elements of the associated rings of integers are given in the following table according to the library providing them.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Library Element type Parent type\nFlint ZZRingElem ZZRing","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"All integer element types belong directly to the abstract type RingElem and all the integer ring parent object types belong to the abstract type Ring.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"A lot of code will want to accept both ZZRingElem integers and Julia integers, that is, subtypes of Base.Integer. Thus for convenience we define","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"IntegerUnion = Union{Integer,ZZRingElem}","category":"page"},{"location":"Nemo/integer/#Integer-functionality","page":"Integers","title":"Integer functionality","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Nemo integers provide all of the ring and Euclidean ring functionality of AbstractAlgebra.jl.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/ring","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/euclidean_interface","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Below, we describe the functionality that is specific to the Nemo/Flint integer ring.","category":"page"},{"location":"Nemo/integer/#Constructors","page":"Integers","title":"Constructors","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"ZZ(n::Integer)","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Coerce a Julia integer value into the integer ring.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"ZZ(n::String)","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Parse the given string as an integer.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"ZZ(n::Float64)\nZZ(n::Float32)\nZZ(n::Float16)\nZZ(n::BigFloat)","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Coerce the given floating point number into the integer ring, assuming that it can be exactly represented as an integer.","category":"page"},{"location":"Nemo/integer/#Basic-manipulation","page":"Integers","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"sign(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#sign-Tuple{ZZRingElem}","page":"Integers","title":"sign","text":"sign(a::ZZRingElem)\n\nReturn the sign of a, i.e. +1, 0 or -1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"size(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#size-Tuple{ZZRingElem}","page":"Integers","title":"size","text":"size(a::ZZRingElem)\n\nReturn the number of limbs required to store the absolute value of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"fits(::Type{UInt}, ::ZZRingElem)\nfits(::Type{Int}, ::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#fits-Tuple{Type{UInt64}, ZZRingElem}","page":"Integers","title":"fits","text":"fits(::Type{UInt}, a::ZZRingElem)\n\nReturn true if a fits into a UInt, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#fits-Tuple{Type{Int64}, ZZRingElem}","page":"Integers","title":"fits","text":"fits(::Type{Int}, a::ZZRingElem)\n\nReturn true if a fits into an Int, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"denominator(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#denominator-Tuple{ZZRingElem}","page":"Integers","title":"denominator","text":"denominator(a::ZZRingElem)\n\nReturn the denominator of a thought of as a rational. Always returns 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"numerator(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#numerator-Tuple{ZZRingElem}","page":"Integers","title":"numerator","text":"numerator(a::ZZRingElem)\n\nReturn the numerator of a thought of as a rational. Always returns a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Examples","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"julia> a = ZZ(12)\n12\n\njulia> is_unit(a)\nfalse\n\njulia> sign(a)\n1\n\njulia> s = size(a)\n1\n\njulia> fits(Int, a)\ntrue\n\njulia> n = numerator(a)\n12\n\njulia> d = denominator(a)\n1","category":"page"},{"location":"Nemo/integer/#Euclidean-division","page":"Integers","title":"Euclidean division","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Nemo also provides a large number of Euclidean division operations. Recall that for a dividend a and divisor b, we can write a = bq + r with 0 leq r b. We call q the quotient and r the remainder.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"We distinguish three cases. If q is rounded towards zero, r will have the same sign as a. If q is rounded towards plus infinity, r will have the opposite sign to b. Finally, if q is rounded towards minus infinity, r will have the same sign as b.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"In the following table we list the division functions and their rounding behaviour. We also give the return value of the function, with q representing return of the quotient and r representing return of the remainder.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Function Return Rounding of the quotient\nmod r towards minus infinity\nrem r towards zero\ndiv q towards minus infinity\ndivrem(a::ZZRingElem, b::ZZRingElem) q, r towards minus infinity\ntdivrem(a::ZZRingElem, b::ZZRingElem) q, r towards zero\nfdivrem(a::ZZRingElem, b::ZZRingElem) q, r towards minus infinity\ncdivrem(a::ZZRingElem, b::ZZRingElem) q, r towards plus infinity\nntdivrem(a::ZZRingElem, b::ZZRingElem) q, r nearest integer, ties toward zero\nnfdivrem(a::ZZRingElem, b::ZZRingElem) q, r nearest integer, ties toward minus infinity\nncdivrem(a::ZZRingElem, b::ZZRingElem) q, r nearest integer, ties toward plus infinity","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"N.B: the internal definition of Nemo.div and Nemo.divrem are the same as fdiv and fdivrem. The definitions in the table are of Base.div and Base.divrem which agree with Julia's definitions of div and divrem.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Nemo also offers the following ad hoc division operators. The notation and description is as for the other Euclidean division functions.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Function Return Rounding\nmod(a::ZZRingElem, b::Int) r towards minus infinity\nrem(a::ZZRingElem, b::Int) r towards zero\ndiv(a::ZZRingElem, b::Int) q towards zero\ntdiv(a::ZZRingElem, b::Int) q towards zero\nfdiv(a::ZZRingElem, b::Int) q towards minus infinity\ncdiv(a::ZZRingElem, b::Int) q towards plus infinity","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"N.B: the internal definition of Nemo.div is the same as fdiv. The definition in the table is Base.div which agrees with Julia's definition of div.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"The following functions are also available, for the case where one is dividing by a power of 2. In other words, for Euclidean division of the form a = b2^d + r. These are useful for bit twiddling.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Function Return Rounding\ntdivpow2(a::ZZRingElem, d::Int) q towards zero\nfdivpow2(a::ZZRingElem, d::Int) q towards minus infinity\nfmodpow2(a::ZZRingElem, d::Int) r towards minus infinity\ncdivpow2(a::ZZRingElem, d::Int) q towards plus infinity","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Examples","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"julia> a = ZZ(12)\n12\n\njulia> b = ZZ(5)\n5\n\njulia> q, r = divrem(a, b)\n(2, 2)\n\njulia> c = cdiv(a, b)\n3\n\njulia> d = fdiv(a, b)\n2\n\njulia> f = tdivpow2(a, 2)\n3\n\njulia> g = fmodpow2(a, 3)\n4","category":"page"},{"location":"Nemo/integer/#Comparison","page":"Integers","title":"Comparison","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Instead of isless we implement a function cmp(a, b) which returns a positive value if a b, zero if a == b and a negative value if a b. We then implement all the other operators, including == in terms of cmp.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"For convenience we also implement a cmpabs(a, b) function which returns a positive value if a b, zero if a == b and a negative value if a b. This can be slightly faster than a call to cmp or one of the comparison operators when comparing nonnegative values for example.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Here is a list of the comparison functions implemented, with the understanding that cmp provides all of the comparison operators listed above.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Function\ncmp(a::ZZRingElem, b::ZZRingElem)\ncmpabs(a::ZZRingElem, b::ZZRingElem)","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"We also provide the following ad hoc comparisons which again provide all of the comparison operators mentioned above.","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Function\ncmp(a::ZZRingElem, b::Int)\ncmp(a::Int, b::ZZRingElem)\ncmp(a::ZZRingElem, b::UInt)\ncmp(a::UInt, b::ZZRingElem)","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Examples","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"julia> a = ZZ(12)\n12\n\njulia> b = ZZ(3)\n3\n\njulia> a < b\nfalse\n\njulia> a != b\ntrue\n\njulia> a > 4\ntrue\n\njulia> 5 <= b\nfalse\n\njulia> cmpabs(a, b)\n1","category":"page"},{"location":"Nemo/integer/#Shifting","page":"Integers","title":"Shifting","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"<<(::ZZRingElem, ::Int)","category":"page"},{"location":"Nemo/integer/#<<-Tuple{ZZRingElem, Int64}","page":"Integers","title":"<<","text":"<<(x::ZZRingElem, c::Int)\n\nReturn 2^cx where c geq 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":">>(::ZZRingElem, ::Int)","category":"page"},{"location":"Nemo/integer/#>>-Tuple{ZZRingElem, Int64}","page":"Integers","title":">>","text":">>(x::ZZRingElem, c::Int)\n\nReturn x2^c, discarding any remainder, where c geq 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Examples","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"julia> a = ZZ(12)\n12\n\njulia> a << 3\n96\n\njulia> a >> 5\n0","category":"page"},{"location":"Nemo/integer/#Modular-arithmetic","page":"Integers","title":"Modular arithmetic","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"sqrtmod(::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#sqrtmod-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"sqrtmod","text":"sqrtmod(x::ZZRingElem, m::ZZRingElem)\n\nReturn a square root of x (mod m) if one exists. The remainder will be in the range 0 m). We require that m is prime, otherwise the algorithm may not terminate.\n\nExamples\n\njulia> sqrtmod(ZZ(12), ZZ(13))\n5\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"crt(r1::ZZRingElem, m1::ZZRingElem, r2::ZZRingElem, m2::ZZRingElem, signed=false; check::Bool=true)","category":"page"},{"location":"Nemo/integer/#crt","page":"Integers","title":"crt","text":"crt(r1::ZZRingElem, m1::ZZRingElem, r2::ZZRingElem, m2::ZZRingElem, signed=false; check::Bool=true)\ncrt(r1::ZZRingElem, m1::ZZRingElem, r2::Union{Int, UInt}, m2::Union{Int, UInt}, signed=false; check::Bool=true)\ncrt(r::Vector{ZZRingElem}, m::Vector{ZZRingElem}, signed=false; check::Bool=true)\ncrt_with_lcm(r1::ZZRingElem, m1::ZZRingElem, r2::ZZRingElem, m2::ZZRingElem, signed=false; check::Bool=true)\ncrt_with_lcm(r1::ZZRingElem, m1::ZZRingElem, r2::Union{Int, UInt}, m2::Union{Int, UInt}, signed=false; check::Bool=true)\ncrt_with_lcm(r::Vector{ZZRingElem}, m::Vector{ZZRingElem}, signed=false; check::Bool=true)\n\nAs per the AbstractAlgebra crt interface, with the following option. If signed = true, the solution is the range (-m2 m2, otherwise it is in the range 0m), where m is the least common multiple of the moduli.\n\nExamples\n\njulia> crt(ZZ(5), ZZ(13), ZZ(7), ZZ(37), true)\n44\n\njulia> crt(ZZ(5), ZZ(13), 7, 37, true)\n44\n\n\n\n\n\n","category":"function"},{"location":"Nemo/integer/#Integer-logarithm","page":"Integers","title":"Integer logarithm","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"flog(::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#flog-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"flog","text":"flog(x::ZZRingElem, c::ZZRingElem)\nflog(x::ZZRingElem, c::Int)\n\nReturn the floor of the logarithm of x to base c.\n\nExamples\n\njulia> flog(ZZ(12), ZZ(2))\n3\n\njulia> flog(ZZ(12), 3)\n2\n\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"clog(::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#clog-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"clog","text":"clog(x::ZZRingElem, c::ZZRingElem)\nclog(x::ZZRingElem, c::Int)\n\nReturn the ceiling of the logarithm of x to base c.\n\nExamples\n\njulia> clog(ZZ(12), ZZ(2))\n4\n\njulia> clog(ZZ(12), 3)\n3\n\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#Integer-roots","page":"Integers","title":"Integer roots","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"isqrt(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#isqrt-Tuple{ZZRingElem}","page":"Integers","title":"isqrt","text":"isqrt(x::ZZRingElem)\n\nReturn the floor of the square root of x.\n\nExamples\n\njulia> isqrt(ZZ(13))\n3\n\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"isqrtrem(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#isqrtrem-Tuple{ZZRingElem}","page":"Integers","title":"isqrtrem","text":"isqrtrem(x::ZZRingElem)\n\nReturn a tuple s r consisting of the floor s of the square root of x and the remainder r, i.e. such that x = s^2 + r. We require x geq 0.\n\nExamples\n\njulia> isqrtrem(ZZ(13))\n(3, 4)\n\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"root(::ZZRingElem, ::Int)","category":"page"},{"location":"Nemo/integer/#root-Tuple{ZZRingElem, Int64}","page":"Integers","title":"root","text":"root(x::ZZRingElem, n::Int; check::Bool=true)\n\nReturn the n-the root of x. We require n 0 and that x geq 0 if n is even. By default the function tests whether the input was a perfect n-th power and if not raises an exception. If check=false this check is omitted.\n\nExamples\n\njulia> root(ZZ(27), 3; check=true)\n3\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"iroot(::ZZRingElem, ::Int)","category":"page"},{"location":"Nemo/integer/#iroot-Tuple{ZZRingElem, Int64}","page":"Integers","title":"iroot","text":"iroot(x::ZZRingElem, n::Int)\n\nReturn the integer truncation of the n-the root of x (round towards zero). We require n 0 and that x geq 0 if n is even.\n\nExamples\n\njulia> iroot(ZZ(13), 3)\n2\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#Number-theoretic-functionality","page":"Integers","title":"Number theoretic functionality","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"divisible(::ZZRingElem, ::Int)\ndivisible(::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#divisible-Tuple{ZZRingElem, Int64}","page":"Integers","title":"divisible","text":"divisible(x::ZZRingElem, y::Int)\n\nReturn true if x is divisible by y, otherwise return false. We require x neq 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#divisible-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"divisible","text":"divisible(x::ZZRingElem, y::ZZRingElem)\n\nReturn true if x is divisible by y, otherwise return false. We require x neq 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"is_square(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#is_square-Tuple{ZZRingElem}","page":"Integers","title":"is_square","text":"is_square(f::PolyRingElem{T}) where T <: RingElement\n\nReturn true if f is a perfect square.\n\n\n\n\n\nis_square(a::FracElem{T}) where T <: RingElem\n\nReturn true if a is a square.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"is_prime(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#is_prime-Tuple{ZZRingElem}","page":"Integers","title":"is_prime","text":"is_prime(x::ZZRingElem)\nis_prime(x::Int)\n\nReturn true if x is a prime number, otherwise return false.\n\nExamples\n\njulia> is_prime(ZZ(13))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"is_probable_prime(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#is_probable_prime-Tuple{ZZRingElem}","page":"Integers","title":"is_probable_prime","text":"is_probable_prime(x::ZZRingElem)\n\nReturn true if x is very probably a prime number, otherwise return false. No counterexamples are known to this test, but it is conjectured that infinitely many exist.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"factor(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#factor-Tuple{ZZRingElem}","page":"Integers","title":"factor","text":"factor(a::ZZRingElem)\nfactor(a::UInt)\nfactor(a::Int)\n\nReturn a factorisation of a using a Fac struct (see the documentation on factorisation in Nemo).\n\nExamples\n\njulia> factor(ZZ(12))\n1 * 2^2 * 3\n\njulia> factor(UInt(12))\n1 * 2^2 * 3\n\njulia> factor(12)\n1 * 2^2 * 3\n\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"divisor_lenstra(::ZZRingElem, ::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#divisor_lenstra-Tuple{ZZRingElem, ZZRingElem, ZZRingElem}","page":"Integers","title":"divisor_lenstra","text":"divisor_lenstra(n::ZZRingElem, r::ZZRingElem, m::ZZRingElem)\n\nIf n has a factor which lies in the residue class r (mod m) for 0 r m n, this function returns such a factor. Otherwise it returns 0. This is only efficient if m is at least the cube root of n. We require gcd(r m) = 1 and this condition is not checked.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"factorial(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#factorial-Tuple{ZZRingElem}","page":"Integers","title":"factorial","text":"factorial(x::ZZRingElem)\n\nReturn the factorial of x, i.e. x = 123ldots x. We require x geq 0.\n\nExamples\n\njulia> factorial(ZZ(100))\n93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"rising_factorial(::ZZRingElem, ::ZZRingElem)\nrising_factorial(::ZZRingElem, ::Int)\nrising_factorial(::Int, ::Int)","category":"page"},{"location":"Nemo/integer/#rising_factorial-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"rising_factorial","text":"rising_factorial(x::ZZRingElem, n::ZZRingElem)\n\nReturn the rising factorial of x, i.e. x(x + 1)(x + 2)cdots (x + n - 1). If n 0 we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#rising_factorial-Tuple{ZZRingElem, Int64}","page":"Integers","title":"rising_factorial","text":"rising_factorial(x::ZZRingElem, n::Int)\n\nReturn the rising factorial of x, i.e. x(x + 1)(x + 2)ldots (x + n - 1). If n 0 we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#rising_factorial-Tuple{Int64, Int64}","page":"Integers","title":"rising_factorial","text":"rising_factorial(x::Int, n::Int)\n\nReturn the rising factorial of x, i.e. x(x + 1)(x + 2)ldots (x + n - 1). If n 0 we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"primorial(::ZZRingElem)\nprimorial(::Int)","category":"page"},{"location":"Nemo/integer/#primorial-Tuple{ZZRingElem}","page":"Integers","title":"primorial","text":"primorial(x::ZZRingElem)\n\nReturn the primorial of x, i.e. the product of all primes less than or equal to x. If x 0 we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#primorial-Tuple{Int64}","page":"Integers","title":"primorial","text":"primorial(x::Int)\n\nReturn the primorial of x, i.e. the product of all primes less than or equal to x. If x 0 we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"fibonacci(::Int)\nfibonacci(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#fibonacci-Tuple{Int64}","page":"Integers","title":"fibonacci","text":"fibonacci(x::Int)\n\nReturn the x-th Fibonacci number F_x. We define F_1 = 1, F_2 = 1 and F_i + 1 = F_i + F_i - 1 for all integers i.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#fibonacci-Tuple{ZZRingElem}","page":"Integers","title":"fibonacci","text":"fibonacci(x::ZZRingElem)\n\nReturn the x-th Fibonacci number F_x. We define F_1 = 1, F_2 = 1 and F_i + 1 = F_i + F_i - 1 for all integers i.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"bell(::ZZRingElem)\nbell(::Int)","category":"page"},{"location":"Nemo/integer/#bell-Tuple{ZZRingElem}","page":"Integers","title":"bell","text":"bell(x::ZZRingElem)\n\nReturn the Bell number B_x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#bell-Tuple{Int64}","page":"Integers","title":"bell","text":"bell(x::Int)\n\nReturn the Bell number B_x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"binomial(::ZZRingElem, ::ZZRingElem)\nbinomial(::UInt, ::UInt, ::ZZRing)","category":"page"},{"location":"Nemo/integer/#binomial-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"binomial","text":"binomial(n::ZZRingElem, k::ZZRingElem)\n\nReturn the binomial coefficient fracn (n-1) cdots (n-k+1)k. If k 0 we return 0, and the identity binomial(n, k) == binomial(n - 1, k - 1) + binomial(n - 1, k) always holds for integers n and k.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#binomial-Tuple{UInt64, UInt64, ZZRing}","page":"Integers","title":"binomial","text":"binomial(n::UInt, k::UInt, ::ZZRing)\n\nReturn the binomial coefficient fracn(n - k)k as an ZZRingElem.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"moebius_mu(::Int)\nmoebius_mu(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#moebius_mu-Tuple{Int64}","page":"Integers","title":"moebius_mu","text":"moebius_mu(x::Int)\n\nReturn the Moebius mu function of x as an Int. The value returned is either -1, 0 or 1. If x leq 0 we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#moebius_mu-Tuple{ZZRingElem}","page":"Integers","title":"moebius_mu","text":"moebius_mu(x::ZZRingElem)\n\nReturn the Moebius mu function of x as an Int. The value returned is either -1, 0 or 1. If x leq 0 we throw a DomainError().\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"jacobi_symbol(::Int, ::Int)\njacobi_symbol(::ZZRingElem, ::ZZRingElem)\nkronecker_symbol(::Int, ::Int)","category":"page"},{"location":"Nemo/integer/#jacobi_symbol-Tuple{Int64, Int64}","page":"Integers","title":"jacobi_symbol","text":"jacobi_symbol(x::Int, y::Int)\n\nReturn the value of the Jacobi symbol left(fracxyright). The modulus y must be odd and positive, otherwise a DomainError is thrown.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#jacobi_symbol-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"jacobi_symbol","text":"jacobi_symbol(x::ZZRingElem, y::ZZRingElem)\n\nReturn the value of the Jacobi symbol left(fracxyright). The modulus y must be odd and positive, otherwise a DomainError is thrown.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#kronecker_symbol-Tuple{Int64, Int64}","page":"Integers","title":"kronecker_symbol","text":"kronecker_symbol(x::ZZRingElem, y::ZZRingElem)\nkronecker_symbol(x::Int, y::Int)\n\nReturn the value of the Kronecker symbol left(fracxyright). The definition is as per Henri Cohen's book, \"A Course in Computational Algebraic Number Theory\", Definition 1.4.8.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"divisor_sigma(::ZZRingElem, ::Int)","category":"page"},{"location":"Nemo/integer/#divisor_sigma-Tuple{ZZRingElem, Int64}","page":"Integers","title":"divisor_sigma","text":"divisor_sigma(x::ZZRingElem, y::Int)\ndivisor_sigma(x::ZZRingElem, y::ZZRingElem)\ndivisor_sigma(x::Int, y::Int)\n\nReturn the value of the sigma function, i.e. sum_0 d x d^y. If x leq 0 or y 0 we throw a DomainError().\n\nExamples\n\njulia> divisor_sigma(ZZ(32), 10)\n1127000493261825\n\njulia> divisor_sigma(ZZ(32), ZZ(10))\n1127000493261825\n\njulia> divisor_sigma(32, 10)\n1127000493261825\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"euler_phi(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#euler_phi-Tuple{ZZRingElem}","page":"Integers","title":"euler_phi","text":"euler_phi(x::ZZRingElem)\neuler_phi(x::Int)\n\nReturn the value of the Euler phi function at x, i.e. the number of positive integers up to x (inclusive) that are coprime with x. An exception is raised if x leq 0.\n\nExamples\n\njulia> euler_phi(ZZ(12480))\n3072\n\njulia> euler_phi(12480)\n3072\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"number_of_partitions(::Int)","category":"page"},{"location":"Nemo/integer/#number_of_partitions-Tuple{Int64}","page":"Integers","title":"number_of_partitions","text":"number_of_partitions(x::Int)\nnumber_of_partitions(x::ZZRingElem)\n\nReturn the number of partitions of x.\n\nExamples\n\njulia> number_of_partitions(100)\n190569292\n\njulia> number_of_partitions(ZZ(1000))\n24061467864032622473692149727991\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"is_perfect_power(::ZZRingElem)\nNemo.is_prime_power(::ZZRingElem)\nis_prime_power_with_data(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#is_perfect_power-Tuple{ZZRingElem}","page":"Integers","title":"is_perfect_power","text":"is_perfect_power(a::IntegerUnion)\n\nReturns whether a is a perfect power, that is, whether a = m^r for some integer m and r 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#is_prime_power-Tuple{ZZRingElem}","page":"Integers","title":"is_prime_power","text":"is_prime_power(q::IntegerUnion) -> Bool\n\nReturns whether q is a prime power.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#is_prime_power_with_data-Tuple{ZZRingElem}","page":"Integers","title":"is_prime_power_with_data","text":"is_prime_power_with_data(q::IntegerUnion) -> Bool, ZZRingElem, Int\n\nReturns a flag indicating whether q is a prime power and integers e p such that q = p^e. If q is a prime power, than p is a prime.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#Digits-and-bases","page":"Integers","title":"Digits and bases","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"bin(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#bin-Tuple{ZZRingElem}","page":"Integers","title":"bin","text":"bin(n::ZZRingElem)\n\nReturn n as a binary string.\n\nExamples\n\njulia> bin(ZZ(12))\n\"1100\"\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"oct(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#oct-Tuple{ZZRingElem}","page":"Integers","title":"oct","text":"oct(n::ZZRingElem)\n\nReturn n as a octal string.\n\nExamples\n\njulia> oct(ZZ(12))\n\"14\"\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"dec(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#dec-Tuple{ZZRingElem}","page":"Integers","title":"dec","text":"dec(n::ZZRingElem)\n\nReturn n as a decimal string.\n\nExamples\n\njulia> dec(ZZ(12))\n\"12\"\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"hex(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#hex-Tuple{ZZRingElem}","page":"Integers","title":"hex","text":"hex(n::ZZRingElem) = base(n, 16)\n\nReturn n as a hexadecimal string.\n\nExamples\n\njulia> hex(ZZ(12))\n\"c\"\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"base(::ZZRingElem, ::Integer)","category":"page"},{"location":"Nemo/integer/#base-Tuple{ZZRingElem, Integer}","page":"Integers","title":"base","text":"base(n::ZZRingElem, b::Integer)\n\nReturn n as a string in base b. We require 2 leq b leq 62.\n\nExamples\n\njulia> base(ZZ(12), 13)\n\"c\"\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"ndigits(::ZZRingElem, ::Integer)","category":"page"},{"location":"Nemo/integer/#ndigits-Tuple{ZZRingElem, Integer}","page":"Integers","title":"ndigits","text":"ndigits(x::ZZRingElem, b::Integer)\n\nReturn the number of digits of x in the base b (default is b = 10).\n\nExamples\n\njulia> ndigits(ZZ(12), 3)\n3\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"nbits(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#nbits-Tuple{ZZRingElem}","page":"Integers","title":"nbits","text":"nbits(x::ZZRingElem)\n\nReturn the number of binary bits of x. We return zero if x = 0.\n\nExamples\n\njulia> nbits(ZZ(12))\n4\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#Bit-twiddling","page":"Integers","title":"Bit twiddling","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"popcount(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#popcount-Tuple{ZZRingElem}","page":"Integers","title":"popcount","text":"popcount(x::ZZRingElem)\n\nReturn the number of ones in the binary representation of x.\n\nExamples\n\njulia> popcount(ZZ(12))\n2\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"prevpow2(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#prevpow2-Tuple{ZZRingElem}","page":"Integers","title":"prevpow2","text":"prevpow2(x::ZZRingElem)\n\nReturn the previous power of 2 up to including x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"nextpow2(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#nextpow2-Tuple{ZZRingElem}","page":"Integers","title":"nextpow2","text":"nextpow2(x::ZZRingElem)\n\nReturn the next power of 2 that is at least x.\n\nExamples\n\njulia> nextpow2(ZZ(12))\n16\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"trailing_zeros(::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#trailing_zeros-Tuple{ZZRingElem}","page":"Integers","title":"trailing_zeros","text":"trailing_zeros(x::ZZRingElem)\n\nReturn the number of trailing zeros in the binary representation of x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"clrbit!(::ZZRingElem, ::Int)\nsetbit!(::ZZRingElem, ::Int)\ncombit!(::ZZRingElem, ::Int)\ntstbit(::ZZRingElem, ::Int)","category":"page"},{"location":"Nemo/integer/#clrbit!-Tuple{ZZRingElem, Int64}","page":"Integers","title":"clrbit!","text":"clrbit!(x::ZZRingElem, c::Int)\n\nClear bit c of x, where the least significant bit is the 0-th bit. Note that this function modifies its input in-place.\n\nExamples\n\njulia> a = ZZ(12)\n12\n\njulia> clrbit!(a, 3)\n\njulia> a\n4\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#setbit!-Tuple{ZZRingElem, Int64}","page":"Integers","title":"setbit!","text":"setbit!(x::ZZRingElem, c::Int)\n\nSet bit c of x, where the least significant bit is the 0-th bit. Note that this function modifies its input in-place.\n\nExamples\n\njulia> a = ZZ(12)\n12\n\njulia> setbit!(a, 0)\n\njulia> a\n13\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#combit!-Tuple{ZZRingElem, Int64}","page":"Integers","title":"combit!","text":"combit!(x::ZZRingElem, c::Int)\n\nComplement bit c of x, where the least significant bit is the 0-th bit. Note that this function modifies its input in-place.\n\nExamples\n\njulia> a = ZZ(12)\n12\n\njulia> combit!(a, 2)\n\njulia> a\n8\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#tstbit-Tuple{ZZRingElem, Int64}","page":"Integers","title":"tstbit","text":"tstbit(x::ZZRingElem, c::Int)\n\nReturn bit i of x (numbered from 0) as true for 1 or false for 0.\n\nExamples\n\njulia> a = ZZ(12)\n12\n\njulia> tstbit(a, 0)\nfalse\n\njulia> tstbit(a, 2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#Random-generation","page":"Integers","title":"Random generation","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"rand_bits(::ZZRing, ::Int)","category":"page"},{"location":"Nemo/integer/#rand_bits-Tuple{ZZRing, Int64}","page":"Integers","title":"rand_bits","text":"rand_bits(::ZZRing, b::Int)\n\nReturn a random signed integer whose absolute value has b bits.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"rand_bits_prime(::ZZRing, ::Int, ::Bool)","category":"page"},{"location":"Nemo/integer/#rand_bits_prime-Tuple{ZZRing, Int64, Bool}","page":"Integers","title":"rand_bits_prime","text":"rand_bits_prime(::ZZRing, n::Int, proved::Bool=true)\n\nReturn a random prime number with the given number of bits. If only a probable prime is required, one can pass proved=false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Examples","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"a = rand_bits(ZZ, 23)\nb = rand_bits_prime(ZZ, 7)","category":"page"},{"location":"Nemo/integer/#Complex-Integers","page":"Integers","title":"Complex Integers","text":"","category":"section"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"The Gaussian integer type in Nemo is provided by a pair of Flint integers. The associated ring of integers and the fraction field can be retrieved by Nemo.GaussianIntegers() and Nemo.GaussianRationals().","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"Examples","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"julia> ZZi = Nemo.GaussianIntegers()\nGaussian integer ring\n\njulia> a = ZZ(5)*im\n5*im\n\njulia> b = ZZi(3, 4)\n3 + 4*im\n\njulia> is_unit(a)\nfalse\n\njulia> factor(a)\nim * (2 - im) * (2 + im)\n\njulia> a//b\n4//5 + 3//5*im\n\njulia> abs2(a//b)\n1","category":"page"},{"location":"Hecke/quad_forms/lattices/#Lattices","page":"Lattices","title":"Lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/quad_forms/lattices/#Creation-of-lattices","page":"Lattices","title":"Creation of lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/#Inside-a-given-ambient-space","page":"Lattices","title":"Inside a given ambient space","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"lattice(::AbstractSpace)\nlattice(::AbstractSpace, ::PMat)\nlattice(::AbstractSpace, ::MatElem)\nlattice(::AbstractSpace, ::Vector)","category":"page"},{"location":"Hecke/quad_forms/lattices/#lattice-Tuple{AbstractSpace}","page":"Lattices","title":"lattice","text":"lattice(V::AbstractSpace) -> AbstractLat\n\nGiven an ambient space V, return the lattice with the standard basis matrix. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#lattice-Tuple{AbstractSpace, Hecke.PMat}","page":"Lattices","title":"lattice","text":"lattice(V::AbstractSpace, B::PMat ; check::Bool = true) -> AbstractLat\n\nGiven an ambient space V and a pseudo-matrix B, return the lattice spanned by the pseudo-matrix B inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.\n\nBy default, B is checked to be of full rank. This test can be disabled by setting check to false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#lattice-Tuple{AbstractSpace, MatElem}","page":"Lattices","title":"lattice","text":"lattice(V::AbstractSpace, basis::MatElem ; check::Bool = true) -> AbstractLat\n\nGiven an ambient space V and a matrix basis, return the lattice spanned by the rows of basis inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.\n\nBy default, basis is checked to be of full rank. This test can be disabled by setting check to false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#lattice-Tuple{AbstractSpace, Vector}","page":"Lattices","title":"lattice","text":"lattice(V::AbstractSpace, gens::Vector) -> AbstractLat\n\nGiven an ambient space V and a list of generators gens, return the lattice spanned by gens in V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.\n\nIf gens is empty, the function returns the zero lattice in V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Quadratic-lattice-over-a-number-field","page":"Lattices","title":"Quadratic lattice over a number field","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"quadratic_lattice(::Field)\nquadratic_lattice(::Field, ::PMat)\nquadratic_lattice(::Field, ::MatElem)\nquadratic_lattice(::Field, ::Vector)","category":"page"},{"location":"Hecke/quad_forms/lattices/#quadratic_lattice-Tuple{Field}","page":"Lattices","title":"quadratic_lattice","text":"quadratic_lattice(K::Field ; gram::MatElem) -> Union{ZZLat, QuadLat}\n\nGiven a matrix gram and a field K, return the free quadratic lattice inside the quadratic space over K with Gram matrix gram.\n\nIf K = mathbbQ, then the output lattice is of type ZZLat, seen as a lattice over the ring mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#quadratic_lattice-Tuple{Field, Hecke.PMat}","page":"Lattices","title":"quadratic_lattice","text":"quadratic_lattice(K::Field, B::PMat ; gram = nothing,\n check:::Bool = true) -> QuadLat\n\nGiven a pseudo-matrix B with entries in a field K return the quadratic lattice spanned by the pseudo-matrix B inside the quadratic space over K with Gram matrix gram.\n\nIf gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the number of columns of B.\n\nBy default, B is checked to be of full rank. This test can be disabled by setting check to false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#quadratic_lattice-Tuple{Field, MatElem}","page":"Lattices","title":"quadratic_lattice","text":"quadratic_lattice(K::Field, basis::MatElem ; gram = nothing,\n check::Bool = true)\n -> Union{ZZLat, QuadLat}\n\nGiven a matrix basis and a field K, return the quadratic lattice spanned by the rows of basis inside the quadratic space over K with Gram matrix gram.\n\nIf gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the number of columns of basis.\n\nBy default, basis is checked to be of full rank. This test can be disabled by setting check to false.\n\nIf K = mathbbQ, then the output lattice is of type ZZLat, seen as a lattice over the ring mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#quadratic_lattice-Tuple{Field, Vector}","page":"Lattices","title":"quadratic_lattice","text":"quadratic_lattice(K::Field, gens::Vector ; gram = nothing) -> Union{ZZLat, QuadLat}\n\nGiven a list of vectors gens and a field K, return the quadratic lattice spanned by the elements of gens inside the quadratic space over K with Gram matrix gram.\n\nIf gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the length of the elements of gens.\n\nIf gens is empty, gram must be supplied and the function returns the zero lattice in the quadratic space over K with gram matrix gram.\n\nIf K = mathbbQ, then the output lattice is of type ZZLat, seen as a lattice over the ring mathbbZ.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Hermitian-lattice-over-a-degree-2-extension","page":"Lattices","title":"Hermitian lattice over a degree 2 extension","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"hermitian_lattice(::NumField)\nhermitian_lattice(::NumField, ::PMat)\nhermitian_lattice(::NumField, ::MatElem)\nhermitian_lattice(::NumField, ::Vector)","category":"page"},{"location":"Hecke/quad_forms/lattices/#hermitian_lattice-Tuple{NumField}","page":"Lattices","title":"hermitian_lattice","text":"hermitian_lattice(E::NumField; gram::MatElem) -> HermLat\n\nGiven a matrix gram and a number field E of degree 2, return the free hermitian lattice inside the hermitian space over E with Gram matrix gram.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#hermitian_lattice-Tuple{NumField, Hecke.PMat}","page":"Lattices","title":"hermitian_lattice","text":"hermitian_lattice(E::NumField, B::PMat; gram = nothing,\n\t\t\t check::Bool = true) -> HermLat\n\nGiven a pseudo-matrix B with entries in a number field E of degree 2, return the hermitian lattice spanned by the pseudo-matrix B inside the hermitian space over E with Gram matrix gram.\n\nIf gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the number of columns of B.\n\nBy default, B is checked to be of full rank. This test can be disabled by setting check to false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#hermitian_lattice-Tuple{NumField, MatElem}","page":"Lattices","title":"hermitian_lattice","text":"hermitian_lattice(E::NumField, basis::MatElem; gram = nothing,\n\t\t\t check::Bool = true) -> HermLat\n\nGiven a matrix basis and a number field E of degree 2, return the hermitian lattice spanned by the rows of basis inside the hermitian space over E with Gram matrix gram.\n\nIf gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the number of columns of basis.\n\nBy default, basis is checked to be of full rank. This test can be disabled by setting check to false.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#hermitian_lattice-Tuple{NumField, Vector}","page":"Lattices","title":"hermitian_lattice","text":"hermitian_lattice(E::NumField, gens::Vector ; gram = nothing) -> HermLat\n\nGiven a list of vectors gens and a number field E of degree 2, return the hermitian lattice spanned by the elements of gens inside the hermitian space over E with Gram matrix gram.\n\nIf gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the length of the elements of gens.\n\nIf gens is empty, gram must be supplied and the function returns the zero lattice in the hermitan space over E with Gram matrix gram.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"The two following examples will be used all along this section:","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];\nLquad = quadratic_lattice(K, gens, gram = D)\nD = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];\nLherm = hermitian_lattice(E, gens, gram = D)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Note that the format used here is the one given by the internal function Hecke.to_hecke() which prints REPL commands to get back the input lattice.","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];\nLherm = hermitian_lattice(E, gens, gram = D);\nHecke.to_hecke(Lherm)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Finally, one can access some databases in which are stored several quadratic and hermitian lattices. Up to now, these are not automatically available while running Hecke. It can nonethelss be used in the following way:","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nqld = Hecke.quadratic_lattice_database()\nlattice(qld, 1)\nhlb = Hecke.hermitian_lattice_database()\nlattice(hlb, 426)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Ambient-space-and-rational-span","page":"Lattices","title":"Ambient space and rational span","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"ambient_space(::AbstractLat)\nrational_span(::AbstractLat)\nbasis_matrix_of_rational_span(::AbstractLat)\ngram_matrix_of_rational_span(::AbstractLat)\ndiagonal_of_rational_span(::AbstractLat)","category":"page"},{"location":"Hecke/quad_forms/lattices/#ambient_space-Tuple{AbstractLat}","page":"Lattices","title":"ambient_space","text":"ambient_space(L::AbstractLat) -> AbstractSpace\n\nReturn the ambient space of the lattice L. If the ambient space is not known, an error is raised.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#rational_span-Tuple{AbstractLat}","page":"Lattices","title":"rational_span","text":"rational_span(L::AbstractLat) -> AbstractSpace\n\nReturn the rational span of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#basis_matrix_of_rational_span-Tuple{AbstractLat}","page":"Lattices","title":"basis_matrix_of_rational_span","text":"basis_matrix_of_rational_span(L::AbstractLat) -> MatElem\n\nReturn a basis matrix of the rational span of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#gram_matrix_of_rational_span-Tuple{AbstractLat}","page":"Lattices","title":"gram_matrix_of_rational_span","text":"gram_matrix_of_rational_span(L::AbstractLat) -> MatElem\n\nReturn the Gram matrix of the rational span of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#diagonal_of_rational_span-Tuple{AbstractLat}","page":"Lattices","title":"diagonal_of_rational_span","text":"diagonal_of_rational_span(L::AbstractLat) -> Vector\n\nReturn the diagonal of the rational span of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-2","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];\nLquad = quadratic_lattice(K, gens, gram = D);\nD = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];\nLherm = hermitian_lattice(E, gens, gram = D);\nambient_space(Lherm)\nrational_span(Lquad)\nbasis_matrix_of_rational_span(Lherm)\ngram_matrix_of_rational_span(Lherm)\ndiagonal_of_rational_span(Lquad)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Rational-equivalence","page":"Lattices","title":"Rational equivalence","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"hasse_invariant(L::QuadLat, p)\nwitt_invariant(L::QuadLat, p)\nis_rationally_isometric(::AbstractLat, ::AbstractLat, ::NfAbsOrdIdl)\nis_rationally_isometric(L::AbstractLat, M::AbstractLat)","category":"page"},{"location":"Hecke/quad_forms/lattices/#hasse_invariant-Tuple{QuadLat, Any}","page":"Lattices","title":"hasse_invariant","text":"hasse_invariant(L::AbstractLat, p::Union{InfPlc, NfOrdIdl}) -> Int\n\nReturn the Hasse invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#witt_invariant-Tuple{QuadLat, Any}","page":"Lattices","title":"witt_invariant","text":"witt_invariant(L::AbstractLat, p::Union{InfPlc, NfOrdIdl}) -> Int\n\nReturn the Witt invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_rationally_isometric-Tuple{AbstractLat, AbstractLat, NfAbsOrdIdl}","page":"Lattices","title":"is_rationally_isometric","text":"is_rationally_isometric(L::AbstractLat, M::AbstractLat, p::Union{InfPlc, NfAbsOrdIdl})\n -> Bool\n\nReturn whether the rational spans of the lattices L and M are isometric over the completion at the place p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_rationally_isometric-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"is_rationally_isometric","text":"is_rationally_isometric(L::AbstractLat, M::AbstractLat) -> Bool\n\nReturn whether the rational spans of the lattices L and M are isometric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-3","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"For now and for the rest of this section, the examples will include the new lattice Lquad2 which is quadratic. Moreover, all the completions are going to be done at the prime ideal p = 7*mathcal O_K.","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];\nLquad = quadratic_lattice(K, gens, gram = D);\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];\nLquad2 = quadratic_lattice(K, gens, gram = D)\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1]\nhasse_invariant(Lquad, p), witt_invariant(Lquad, p)\nis_rationally_isometric(Lquad, Lquad2, p)\nis_rationally_isometric(Lquad, Lquad2)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Attributes","page":"Lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Let L be a lattice over EK. We call a pseudo-basis of L any sequence of pairs (mathfrak A_i x_i)_1 leq i leq n where the mathfrak A_i's are fractional (left) ideals of mathcal O_E and (x_i)_1 leq i leq n is a basis of the rational span of L, and such that","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":" L = bigoplus_i = 1^n mathfrak A_ix_i","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Note that a pseudo-basis is not unique. Given a pseudo-basis (mathfrak A_i x_i)_1 leq i leq n of L, we define the corresponding pseudo-matrix of L to be the datum consisting of a list of coefficient ideals corresponding to the ideals mathfrak A_i's and a matrix whose rows are the coordinates of the x_i's in the canonical basis of the ambient space of L (conversely, given any such pseudo-matrix, one can define the corresponding pseudo-basis).","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"rank(L::AbstractLat)\ndegree(L::AbstractLat)\ndiscriminant(::AbstractLat)\nbase_field(::AbstractLat)\nbase_ring(::AbstractLat)\nfixed_field(::AbstractLat)\nfixed_ring(::AbstractLat)\ninvolution(::AbstractLat)\npseudo_matrix(::AbstractLat)\npseudo_basis(::AbstractLat)\ncoefficient_ideals(::AbstractLat)\nabsolute_basis_matrix(::AbstractLat)\nabsolute_basis(::AbstractLat)\ngenerators(L::AbstractLat; minimal::Bool = false)\ngram_matrix_of_generators(::AbstractLat; minimal::Bool = false)","category":"page"},{"location":"Hecke/quad_forms/lattices/#rank-Tuple{AbstractLat}","page":"Lattices","title":"rank","text":"rank(L::AbstractLat) -> Int\n\nReturn the rank of the underlying module of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#degree-Tuple{AbstractLat}","page":"Lattices","title":"degree","text":"degree(L::AbstractLat) -> Int\n\nReturn the dimension of the ambient space of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#discriminant-Tuple{AbstractLat}","page":"Lattices","title":"discriminant","text":"discriminant(L::AbstractLat) -> NfOrdFracIdl\n\nReturn the discriminant of the lattice L, that is, the generalized index ideal L^ L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#base_field-Tuple{AbstractLat}","page":"Lattices","title":"base_field","text":"base_field(L::AbstractLat) -> Field\n\nReturn the algebra over which the rational span of the lattice L is defined.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#base_ring-Tuple{AbstractLat}","page":"Lattices","title":"base_ring","text":"base_ring(L::AbstractLat) -> Ring\n\nReturn the order over which the lattice L is defined.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#fixed_field-Tuple{AbstractLat}","page":"Lattices","title":"fixed_field","text":"fixed_field(L::AbstractLat) -> Field\n\nReturns the fixed field of the involution of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#fixed_ring-Tuple{AbstractLat}","page":"Lattices","title":"fixed_ring","text":"fixed_ring(L::AbstractLat) -> Ring\n\nReturn the maximal order in the fixed field of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#involution-Tuple{AbstractLat}","page":"Lattices","title":"involution","text":"involution(L::AbstractLat) -> Map\n\nReturn the involution of the rational span of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#pseudo_matrix-Tuple{AbstractLat}","page":"Lattices","title":"pseudo_matrix","text":"pseudo_matrix(L::AbstractLat) -> PMat\n\nReturn a basis pseudo-matrix of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#pseudo_basis-Tuple{AbstractLat}","page":"Lattices","title":"pseudo_basis","text":"pseudo_basis(L::AbstractLat) -> Vector{Tuple{Vector, Ideal}}\n\nReturn a pseudo-basis of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#coefficient_ideals-Tuple{AbstractLat}","page":"Lattices","title":"coefficient_ideals","text":"coefficient_ideals(L::AbstractLat) -> Vector{NfOrdIdl}\n\nReturn the coefficient ideals of a pseudo-basis of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#absolute_basis_matrix-Tuple{AbstractLat}","page":"Lattices","title":"absolute_basis_matrix","text":"absolute_basis_matrix(L::AbstractLat) -> MatElem\n\nReturn a mathbfZ-basis matrix of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#absolute_basis-Tuple{AbstractLat}","page":"Lattices","title":"absolute_basis","text":"absolute_basis(L::AbstractLat) -> Vector\n\nReturn a mathbfZ-basis of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#generators-Tuple{AbstractLat}","page":"Lattices","title":"generators","text":"generators(L::AbstractLat; minimal = false) -> Vector{Vector}\n\nReturn a set of generators of the lattice L over the base ring of L.\n\nIf minimal == true, the number of generators is minimal. Note that computing minimal generators is expensive.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#gram_matrix_of_generators-Tuple{AbstractLat}","page":"Lattices","title":"gram_matrix_of_generators","text":"gram_matrix_of_generators(L::AbstractLat; minimal::Bool = false) -> MatElem\n\nReturn the Gram matrix of a generating set of the lattice L.\n\nIf minimal == true, then a minimal generating set is used. Note that computing minimal generators is expensive.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-4","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];\nLherm = hermitian_lattice(E, gens, gram = D);\nrank(Lherm), degree(Lherm)\ndiscriminant(Lherm)\nbase_field(Lherm)\nbase_ring(Lherm)\nfixed_field(Lherm)\nfixed_ring(Lherm)\ninvolution(Lherm)\npseudo_matrix(Lherm)\npseudo_basis(Lherm)\ncoefficient_ideals(Lherm)\nabsolute_basis_matrix(Lherm)\nabsolute_basis(Lherm)\ngenerators(Lherm)\ngram_matrix_of_generators(Lherm)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Module-operations","page":"Lattices","title":"Module operations","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Let L be a lattice over EK inside the space (V Phi). The dual lattice of L is defined to be the following lattice over EK in (V Phi):","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":" L^ = left x in V mid Phi(xL) subseteq mathcal O_E right","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"For any fractional (left) ideal mathfrak a of mathcal O_E, one can define the lattice mathfrak aL to be the lattice over EK, in the same space (V Phi), obtained by rescaling the coefficient ideals of a pseudo-basis of L by mathfrak a. In another flavour, for any non-zero element a in K, one defines the rescaled lattice L^a to be the lattice over EK with the same underlying module as L (i.e. the same pseudo-bases) but in space (V aPhi).","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Base.:(+)(::AbstractLat, ::AbstractLat)\nBase.:(*)(::NumFieldElem, ::AbstractLat)\nBase.:(*)(::NumFieldOrdIdl, ::AbstractLat)\nBase.:(*)(::NumFieldOrdFracIdl, ::AbstractLat)\nrescale(::AbstractLat, ::NumFieldElem)\ndual(::AbstractLat)\nintersect(::AbstractLat, ::AbstractLat)\nprimitive_closure(::AbstractLat, ::AbstractLat)\northogonal_submodule(::AbstractLat, ::AbstractLat)","category":"page"},{"location":"Hecke/quad_forms/lattices/#+-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"+","text":"+(L::AbstractLat, M::AbstractLat) -> AbstractLat\n\nReturn the sum of the lattices L and M.\n\nThe lattices L and M must have the same ambient space.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#*-Tuple{NumFieldElem, AbstractLat}","page":"Lattices","title":"*","text":"*(a::NumFieldElem, L::AbstractLat) -> AbstractLat\n\nReturn the lattice aL inside the ambient space of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#*-Tuple{NumFieldOrdIdl, AbstractLat}","page":"Lattices","title":"*","text":"*(a::NumFieldOrdIdl, L::AbstractLat) -> AbstractLat\n\nReturn the lattice aL inside the ambient space of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#*-Tuple{NumFieldOrdFracIdl, AbstractLat}","page":"Lattices","title":"*","text":"*(a::NumFieldOrdFracIdl, L::AbstractLat) -> AbstractLat\n\nReturn the lattice aL inside the ambient space of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#rescale-Tuple{AbstractLat, NumFieldElem}","page":"Lattices","title":"rescale","text":"rescale(L::AbstractLat, a::NumFieldElem) -> AbstractLat\n\nReturn the rescaled lattice L^a. Note that this has a different ambient space than the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#dual-Tuple{AbstractLat}","page":"Lattices","title":"dual","text":"dual(L::AbstractLat) -> AbstractLat\n\nReturn the dual lattice of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#intersect-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"intersect","text":"intersect(L::AbstractLat, M::AbstractLat) -> AbstractLat\n\nReturn the intersection of the lattices L and M.\n\nThe lattices L and M must have the same ambient space.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#primitive_closure-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"primitive_closure","text":"primitive_closure(M::AbstractLat, N::AbstractLat) -> AbstractLat\n\nGiven two lattices M and N defined over a number field E, with N subseteq Eotimes M, return the primitive closure M cap Eotimes N of N in M.\n\nOne can also use the alias saturate(L, M).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#orthogonal_submodule-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"orthogonal_submodule","text":"orthogonal_submodule(L::AbstractLat, M::AbstractLat) -> AbstractLat\n\nReturn the largest submodule of L orthogonal to M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-5","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];\nLquad = quadratic_lattice(K, gens, gram = D);\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];\nLquad2 = quadratic_lattice(K, gens, gram = D);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\npseudo_matrix(Lquad + Lquad2)\npseudo_matrix(intersect(Lquad, Lquad2))\npseudo_matrix(p*Lquad)\nambient_space(rescale(Lquad,3*a))\npseudo_matrix(Lquad)","category":"page"},{"location":"Hecke/quad_forms/lattices/#Categorical-constructions","page":"Lattices","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Given finite collections of lattices, one can construct their direct sums, which are also direct products in this context. They are also sometimes called biproducts. Depending on the user usage, it is possible to call one of the following functions.","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"direct_sum(::Vector{AbstractLat})\ndirect_product(::Vector{AbstractLat})\nbiproduct(::Vector{AbstractLat})","category":"page"},{"location":"Hecke/quad_forms/lattices/#direct_sum-Tuple{Vector{AbstractLat}}","page":"Lattices","title":"direct_sum","text":"direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T\n\nGiven modules M_1dots M_n, say, return the direct sum bigoplus_i=1^n M_i. \n\nAdditionally, return \n\na vector containing the canonical injections M_itobigoplus_i=1^n M_i if task = :sum (default),\na vector containing the canonical projections bigoplus_i=1^n M_ito M_i if task = :prod,\ntwo vectors containing the canonical injections and projections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_sum(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}\ndirect_sum(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian lattices L_1 ldots L_n, return their direct sum L = L_1 oplus ldots oplus L_n, together with the injections L_i to L (seen as maps between the corresponding ambient spaces).\n\nFor objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections L to L_i, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\n\n\n\n\ndirect_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls\n\nReturn the isometry class of the direct sum of two representatives.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#direct_product-Tuple{Vector{AbstractLat}}","page":"Lattices","title":"direct_product","text":"direct_product(F::FreeMod{T}...; task::Symbol = :prod) where T\n\nGiven free modules F_1dots F_n, say, return the direct product prod_i=1^n F_i.\n\nAdditionally, return\n\na vector containing the canonical projections prod_i=1^n F_ito F_i if task = :prod (default),\na vector containing the canonical injections F_itoprod_i=1^n F_i if task = :sum,\ntwo vectors containing the canonical projections and injections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_product(M::ModuleFP{T}...; task::Symbol = :prod) where T\n\nGiven modules M_1dots M_n, say, return the direct product prod_i=1^n M_i.\n\nAdditionally, return\n\na vector containing the canonical projections prod_i=1^n M_ito M_i if task = :prod (default),\na vector containing the canonical injections M_itoprod_i=1^n M_i if task = :sum,\ntwo vectors containing the canonical projections and injections, respectively, if task = :both,\nnone of the above maps if task = :none.\n\n\n\n\n\ndirect_product(algebras::AlgAss...; task::Symbol = :sum)\n -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\ndirect_product(algebras::Vector{AlgAss}; task::Symbol = :sum)\n -> AlgAss, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\n\nReturns the algebra A = A_1 times cdots times A_k. task can be \":sum\", \":prod\", \":both\" or \":none\" and determines which canonical maps are computed as well: \":sum\" for the injections, \":prod\" for the projections.\n\n\n\n\n\ndirect_product(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}\ndirect_product(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian lattices L_1 ldots L_n, return their direct product L = L_1 times ldots times L_n, together with the projections L to L_i (seen as maps between the corresponding ambient spaces).\n\nFor objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections L_i to L, one should call direct_sum(x). If one wants to obtain L as a biproduct with the injections L_i to L and the projections L to L_i, one should call biproduct(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#biproduct-Tuple{Vector{AbstractLat}}","page":"Lattices","title":"biproduct","text":"biproduct(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\nbiproduct(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}\n\nGiven a collection of quadratic or hermitian lattices L_1 ldots L_n, return their biproduct L = L_1 oplus ldots oplus L_n, together with the injections L_i to L and the projections L to L_i (seen as maps between the corresponding ambient spaces).\n\nFor objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct sum with the injections L_i to L, one should call direct_sum(x). If one wants to obtain L as a direct product with the projections L to L_i, one should call direct_product(x).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Invariants","page":"Lattices","title":"Invariants","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Let L be a lattice over EK, in the space (V Phi). We define:","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"the norm mathfrak n(L) of L to be the ideal of mathcal O_K generated by the squares leftPhi(xx) mid x in L right;\nthe scale mathfrak s(L) of L to be the set Phi(LL) = leftPhi(xy) mid xy in L right;\nthe volume mathfrak v(L) of L to be the index ideal","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":" lbrack L^ colon L rbrack_mathcal O_E = langle left sigma mid sigma in textHom_mathcal O_E(L^ L) right rangle_mathcal O_E","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"norm(::AbstractLat)\nscale(L::AbstractLat)\nvolume(L::AbstractLat)","category":"page"},{"location":"Hecke/quad_forms/lattices/#norm-Tuple{AbstractLat}","page":"Lattices","title":"norm","text":"norm(L::AbstractLat) -> NfAbsOrdFracIdl\n\nReturn the norm of the lattice L. This is a fractional ideal of the fixed field of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#scale-Tuple{AbstractLat}","page":"Lattices","title":"scale","text":"scale(L::AbstractLat) -> NfOrdFracIdl\n\nReturn the scale of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#volume-Tuple{AbstractLat}","page":"Lattices","title":"volume","text":"volume(L::AbstractLat) -> NfOrdFracIdl\n\nReturn the volume of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-6","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];\nLherm = hermitian_lattice(E, gens, gram = D);\nnorm(Lherm)\nscale(Lherm)\nvolume(Lherm)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Predicates","page":"Lattices","title":"Predicates","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Let L be a lattice over EK. It is said to be integral if its scale is an integral ideal, i.e. it is contained in mathcal O_E. Moreover, if mathfrak p is a prime ideal in mathcal O_K, then L is said to be modular (resp. locally modular at mathfrak p) if there exists a fractional ideal mathfrak a of mathcal O_E (resp. an integer v) such that mathfrak aL^ = L (resp. mathfrak p^vL_mathfrak p^ = L_mathfrak p).","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"is_integral(::AbstractLat)\nis_modular(::AbstractLat)\nis_modular(::AbstractLat, p)\nis_positive_definite(L::AbstractLat)\nis_negative_definite(L::AbstractLat)\nis_definite(L::AbstractLat)\ncan_scale_totally_positive(L::AbstractLat)","category":"page"},{"location":"Hecke/quad_forms/lattices/#is_integral-Tuple{AbstractLat}","page":"Lattices","title":"is_integral","text":"is_integral(L::AbstractLat) -> Bool\n\nReturn whether the lattice L is integral.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_modular-Tuple{AbstractLat}","page":"Lattices","title":"is_modular","text":"is_modular(L::AbstractLat) -> Bool, NfOrdFracIdl\n\nReturn whether the lattice L is modular. In this case, the second returned value is a fractional ideal mathfrak a of the base algebra of L such that mathfrak a L^ = L, where L^ is the dual of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_modular-Tuple{AbstractLat, Any}","page":"Lattices","title":"is_modular","text":"is_modular(L::AbstractLat, p) -> Bool, Int\n\nReturn whether the completion L_p of the lattice L at the prime ideal or integer p is modular. If it is the case the second returned value is an integer v such that L_p is p^v-modular.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_positive_definite-Tuple{AbstractLat}","page":"Lattices","title":"is_positive_definite","text":"is_positive_definite(L::AbstractLat) -> Bool\n\nReturn whether the rational span of the lattice L is positive definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_negative_definite-Tuple{AbstractLat}","page":"Lattices","title":"is_negative_definite","text":"is_negative_definite(L::AbstractLat) -> Bool\n\nReturn whether the rational span of the lattice L is negative definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_definite-Tuple{AbstractLat}","page":"Lattices","title":"is_definite","text":"is_definite(L::AbstractLat) -> Bool\n\nReturn whether the rational span of the lattice L is definite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#can_scale_totally_positive-Tuple{AbstractLat}","page":"Lattices","title":"can_scale_totally_positive","text":"can_scale_totally_positive(L::AbstractLat) -> Bool, NumFieldElem\n\nReturn whether there is a totally positive rescaled lattice of the lattice L. If so, the second returned value is an element a such that L^a is totally positive.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-7","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];\nLherm = hermitian_lattice(E, gens, gram = D);\nOK = maximal_order(K);\nis_integral(Lherm)\nis_modular(Lherm)[1]\np = prime_decomposition(OK, 7)[1][1];\nis_modular(Lherm, p)\nis_positive_definite(Lherm)\ncan_scale_totally_positive(Lherm)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Local-properties","page":"Lattices","title":"Local properties","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"local_basis_matrix(L::AbstractLat, p; type::Symbol = :any)\njordan_decomposition(L::AbstractLat, p::NfOrdIdl)\nis_isotropic(::AbstractLat, p)","category":"page"},{"location":"Hecke/quad_forms/lattices/#local_basis_matrix-Tuple{AbstractLat, Any}","page":"Lattices","title":"local_basis_matrix","text":"local_basis_matrix(L::AbstractLat, p::NfOrdIdl; type = :any) -> MatElem\n\nGiven a prime ideal p and a lattice L, return a basis matrix of a lattice M such that M_p = L_p. Note that if p is an ideal in the base ring of L, the completions are taken at the minimum of p (which is an ideal in the base ring of the order of p).\n\nIf type == :submodule, the lattice M will be a sublattice of L.\nIf type == :supermodule, the lattice M will be a superlattice of L.\nIf type == :any, there may not be any containment relation between M and L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#jordan_decomposition-Tuple{AbstractLat, NfOrdIdl}","page":"Lattices","title":"jordan_decomposition","text":"jordan_decomposition(L::AbstractLat, p::NfOrdIdl)\n -> Vector{MatElem}, Vector{MatElem}, Vector{Int}\n\nReturn a Jordan decomposition of the completion of the lattice L at a prime ideal p.\n\nThe returned value consists of three lists (M_i)_i, (G_i)_i and (s_i)_i of the same length r. The completions of the row spans of the matrices M_i yield a Jordan decomposition of L_p into modular sublattices L_i with Gram matrices G_i and scale of p-adic valuation s_i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_isotropic-Tuple{AbstractLat, Any}","page":"Lattices","title":"is_isotropic","text":"is_isotropic(L::AbstractLat, p::Union{NfOrdIdl, InfPlc}) -> Bool\n\nReturn whether the completion of the lattice L at the place p is isotropic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-8","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];\nLquad = quadratic_lattice(K, gens, gram = D);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\nlocal_basis_matrix(Lquad, p)\njordan_decomposition(Lquad, p)\nis_isotropic(Lquad, p)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Automorphisms-for-definite-lattices","page":"Lattices","title":"Automorphisms for definite lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Let L and L be two lattices over the same extension EK, inside their respective ambient spaces (V Phi) and (V Phi). Similarly to homomorphisms of spaces, we define a homomorphism of lattices from L to L to be an mathcalO_E-module$ homomorphism f colon L to L such that for all xy in L, one has","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":" Phi(f(x) f(y)) = Phi(xy)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Again, any automorphism of lattices is called an isometry and any monomorphism is called an embedding. We refer to the set of isometries from a lattice L to itself as the automorphism group of L.","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"automorphism_group_order(::AbstractLat)\nautomorphism_group_generators(::AbstractLat)","category":"page"},{"location":"Hecke/quad_forms/lattices/#automorphism_group_order-Tuple{AbstractLat}","page":"Lattices","title":"automorphism_group_order","text":"automorphism_group_order(L::AbstractLat) -> Int\n\nGiven a definite lattice L, return the order of the automorphism group of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#automorphism_group_generators-Tuple{AbstractLat}","page":"Lattices","title":"automorphism_group_generators","text":"automorphism_group_generators(L::AbstractLat; ambient_representation::Bool = true)\n -> Vector{MatElem}\n\nGiven a definite lattice L, return generators for the automorphism group of L. If ambient_representation == true (the default), the transformations are represented with respect to the ambient space of L. Otherwise, the transformations are represented with respect to the (pseudo-)basis of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-9","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];\nLquad = quadratic_lattice(K, gens, gram = D);\nis_definite(Lquad)\nautomorphism_group_order(Lquad)\nautomorphism_group_generators(Lquad)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Isometry","page":"Lattices","title":"Isometry","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"is_isometric(::AbstractLat, ::AbstractLat)\nis_isometric_with_isometry(::AbstractLat, ::AbstractLat)\nis_locally_isometric(::AbstractLat, ::AbstractLat, p::NfOrdIdl)","category":"page"},{"location":"Hecke/quad_forms/lattices/#is_isometric-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"is_isometric","text":"is_isometric(L::AbstractLat, M::AbstractLat) -> Bool\n\nReturn whether the lattices L and M are isometric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_isometric_with_isometry-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"is_isometric_with_isometry","text":"is_isometric_with_isometry(L::AbstractLat, M::AbstractLat; ambient_representation::Bool = true)\n -> (Bool, MatElem)\n\nReturn whether the lattices L and M are isometric. If this is the case, the second returned value is an isometry T from L to M.\n\nBy default, that isometry is represented with respect to the bases of the ambient spaces, that is, T V_M T^t = V_L where V_L and V_M are the Gram matrices of the ambient spaces of L and M respectively. If ambient_representation == false, then the isometry is represented with respect to the (pseudo-)bases of L and M, that is, T G_M T^t = G_L where G_M and G_L are the Gram matrices of the (pseudo-)bases of L and M respectively.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_locally_isometric-Tuple{AbstractLat, AbstractLat, NfOrdIdl}","page":"Lattices","title":"is_locally_isometric","text":"is_locally_isometric(L::AbstractLat, M::AbstractLat, p::NfOrdIdl) -> Bool\n\nReturn whether the completions of the lattices L and M at the prime ideal p are isometric.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-10","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];\nLquad = quadratic_lattice(K, gens, gram = D);\nD = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);\ngens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];\nLquad2 = quadratic_lattice(K, gens, gram = D);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\nis_isometric(Lquad, Lquad2)\nis_locally_isometric(Lquad, Lquad2, p)","category":"page"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/quad_forms/lattices/#Maximal-integral-lattices","page":"Lattices","title":"Maximal integral lattices","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"is_maximal_integral(::AbstractLat, p)\nis_maximal_integral(::AbstractLat)\nis_maximal(::AbstractLat, p)\nmaximal_integral_lattice(::AbstractLat, p)\nmaximal_integral_lattice(::AbstractLat)\nmaximal_integral_lattice(::AbstractSpace)","category":"page"},{"location":"Hecke/quad_forms/lattices/#is_maximal_integral-Tuple{AbstractLat, Any}","page":"Lattices","title":"is_maximal_integral","text":"is_maximal_integral(L::AbstractLat, p::NfOrdIdl) -> Bool, AbstractLat\n\nGiven a lattice L and a prime ideal p of the fixed ring mathcal O_K of L, return whether the completion of L at p is maximal integral. If it is not the case, the second returned value is a lattice in the ambient space of L whose completion at p is a minimal overlattice of L_p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_maximal_integral-Tuple{AbstractLat}","page":"Lattices","title":"is_maximal_integral","text":"is_maximal_integral(L::AbstractLat) -> Bool, AbstractLat\n\nGiven a lattice L, return whether L is maximal integral. If it is not, the second returned value is a minimal overlattice of L with integral norm.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#is_maximal-Tuple{AbstractLat, Any}","page":"Lattices","title":"is_maximal","text":"is_maximal(L::AbstractLat, p::NfOrdIdl) -> Bool, AbstractLat\n\nGiven a lattice L and a prime ideal p in the fixed ring mathcal O_K of L, check whether the norm of L_p is integral and return whether L is maximal at p. If it is locally integral but not locally maximal, the second returned value is a lattice in the same ambient space of L whose completion at p has integral norm and is a proper overlattice of L_p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#maximal_integral_lattice-Tuple{AbstractLat, Any}","page":"Lattices","title":"maximal_integral_lattice","text":"maximal_integral_lattice(L::AbstractLat, p::NfOrdIdl) -> AbstractLat\n\nGiven a lattice L and a prime ideal p of the fixed ring mathcal O_K of L, return a lattice M in the ambient space of L which is maximal integral at p and which agrees with L locally at all the places different from p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#maximal_integral_lattice-Tuple{AbstractLat}","page":"Lattices","title":"maximal_integral_lattice","text":"maximal_integral_lattice(L::AbstractLat) -> AbstractLat\n\nGiven a lattice L, return a lattice M in the ambient space of L which is maximal integral and which contains L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#maximal_integral_lattice-Tuple{AbstractSpace}","page":"Lattices","title":"maximal_integral_lattice","text":"maximal_integral_lattice(V::AbstractSpace) -> AbstractLat\n\nGiven a space V, return a lattice in V with integral norm and which is maximal in V satisfying this property.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/quad_forms/lattices/#Examples-11","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"using Hecke # hide\nK, a = rationals_as_number_field();\nKt, t = K[\"t\"];\ng = t^2 + 7;\nE, b = number_field(g, \"b\");\nD = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\ngens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];\nLherm = hermitian_lattice(E, gens, gram = D);\nOK = maximal_order(K);\np = prime_decomposition(OK, 7)[1][1];\nis_maximal_integral(Lherm, p)\nis_maximal_integral(Lherm)\nis_maximal(Lherm, p)\npseudo_basis(maximal_integral_lattice(Lherm, p))\npseudo_basis(maximal_integral_lattice(Lherm))\npseudo_basis(maximal_integral_lattice(ambient_space(Lherm)))","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/series/#Power-series-and-Laurent-series","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"","category":"section"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Nemo allows the creation of capped relative and absolute power series over any computable ring R. Capped relative power series are power series of the form a_jx^j + a_j+1x^j+1 + cdots + a_k-1x^k-1 + O(x^k) where j geq 0, a_j in R and the relative precision k - j is at most equal to some specified precision n. On the other hand capped absolute power series are power series of the form a_jx^j + a_j+1x^j+1 + cdots + a_n-1x^n-1 + O(x^n) where j geq 0, a_j in R and the precision n is fixed.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"There are two different kinds of implementation: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of power series over numerous specific rings, usually provided by C/C++ libraries.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"The following table shows each of the relative power series types available in Nemo, the base ring R, and the Julia/Nemo types for that kind of series (the type information is mainly of concern to developers).","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl `Generic.RelSeries{T} Generic.RelPowerSeriesRing{T}\nmathbbZ Flint ZZRelPowerSeriesRingElem ZZRelPowerSeriesRing\nmathbbZnmathbbZ (small n) Flint zzModRelPowerSeriesRingElem zzModRelPowerSeriesRing\nmathbbZnmathbbZ (large n) Flint ZZModRelPowerSeriesRingElem ZZModRelPowerSeriesRing\nmathbbQ Flint QQRelPowerSeriesRingElem QQRelPowerSeriesRing\nmathbbF_p (small n) Flint fpRelPowerSeriesRingElem fpRelPowerSeriesRing\nmathbbF_p (large n) Flint FpRelPowerSeriesRingElem FpRelPowerSeriesRing\nmathbbF_p^n (small p) Flint fqPolyRepRelPowerSeriesRingElem fqPolyRepRelPowerSeriesRing\nmathbbF_p^n (large p) Flint FqPolyRepRelPowerSeriesRingElem FqPolyRepRelPowerSeriesRing","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"All relative power series elements belong to the abstract type RelPowerSeriesRingElem and all of the relative power series ring types belong to the abstract type RelPowerSeriesRing.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"The maximum relative precision, the string representation of the variable and the base ring R of a generic power series are stored in its parent object. ","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Here is the corresponding table for the absolute power series types.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl Generic.AbsSeries{T} Generic.AbsPowerSeriesRing{T}\nmathbbZ Flint ZZAbsPowerSeriesRingElem ZZAbsPowerSeriesRing\nmathbbZnmathbbZ (small n) Flint zzModAbsPowerSeriesRingElem zzModAbsPowerSeriesRing\nmathbbZnmathbbZ (large n) Flint ZZModAbsPowerSeriesRingElem ZZModAbsPowerSeriesRing\nmathbbQ Flint QQAbsPowerSeriesRingElem QQAbsPowerSeriesRing\nmathbbF_p (small n) Flint fpAbsPowerSeriesRingElem fpAbsPowerSeriesRing\nmathbbF_p (large n) Flint FpAbsPowerSeriesRingElem FpAbsPowerSeriesRing\nmathbbF_p^n (small n) Flint fqPolyRepAbsPowerSeriesRingElem fqPolyRepAbsPowerSeriesRing\nmathbbF_p^n (large n) Flint FqPolyRepAbsPowerSeriesRingElem FqPolyRepAbsPowerSeriesRing","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"All absolute power series elements belong to the abstract type AbsPowerSeriesRingElem and all of the absolute power series ring types belong to the abstract type AbsPowerSeriesRing.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"The absolute precision, the string representation of the variable and the base ring R of a generic power series are stored in its parent object. ","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"All power series element types belong to the abstract type SeriesElem and all of the power series ring types belong to the abstract type SeriesRing. This enables one to write generic functions that can accept any Nemo power series type.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"AbstractAlgebra.jl also provides Nemo with a generic implementation of Laurent series over a given ring R. For completeness, we list it here.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Base ring Library Element type Parent type\nGeneric ring R AbstractAlgebra.jl Generic.LaurentSeriesRingElem{T} Generic.LaurentSeriesRing{T}\nGeneric field K AbstractAlgebra.jl Generic.LaurentSeriesFieldElem{T} Generic.LaurentSeriesField{T}","category":"page"},{"location":"Nemo/series/#Capped-relative-power-series","page":"Power series and Laurent series","title":"Capped relative power series","text":"","category":"section"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Capped relative power series have their maximum relative precision capped at some value prec_max. This means that if the leading term of a nonzero power series element is c_ax^a and the precision is b then the power series is of the form c_ax^a + c_a+1x^a+1 + ldots + O(x^a + b).","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"The zero power series is simply taken to be 0 + O(x^b).","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"The capped relative model has the advantage that power series are stable multiplicatively. In other words, for nonzero power series f and g we have that divexact(f*g), g) == f.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"However, capped relative power series are not additively stable, i.e. we do not always have (f + g) - g = f.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"In the capped relative model we say that two power series are equal if they agree up to the minimum absolute precision of the two power series. Thus, for example, x^5 + O(x^10) == 0 + O(x^5), since the minimum absolute precision is 5.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"During computations, it is possible for power series to lose relative precision due to cancellation. For example if f = x^3 + x^5 + O(x^8) and g = x^3 + x^6 + O(x^8) then f - g = x^5 - x^6 + O(x^8) which now has relative precision 3 instead of relative precision 5.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Amongst other things, this means that equality is not transitive. For example x^6 + O(x^11) == 0 + O(x^5) and x^7 + O(x^12) == 0 + O(x^5) but x^6 + O(x^11) neq x^7 + O(x^12).","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Sometimes it is necessary to compare power series not just for arithmetic equality, as above, but to see if they have precisely the same precision and terms. For this purpose we introduce the isequal function.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"For example, if f = x^2 + O(x^7) and g = x^2 + O(x^8) and h = 0 + O(x^2) then f == g, f == h and g == h, but isequal(f, g), isequal(f, h) and isequal(g, h) would all return false. However, if k = x^2 + O(x^7) then isequal(f, k) would return true.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"There are further difficulties if we construct polynomial over power series. For example, consider the polynomial in y over the power series ring in x over the rationals. Normalisation of such polynomials is problematic. For instance, what is the leading coefficient of (0 + O(x^10))y + (1 + O(x^10))?","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"If one takes it to be (0 + O(x^10)) then some functions may not terminate due to the fact that algorithms may require the degree of polynomials to decrease with each iteration. Instead, the degree may remain constant and simply accumulate leading terms which are arithmetically zero but not identically zero.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"On the other hand, when constructing power series over other power series, if we simply throw away terms which are arithmetically equal to zero, our computations may have different output depending on the order in which the power series are added!","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"One should be aware of these difficulties when working with power series. Power series, as represented on a computer, simply don't satisfy the axioms of a ring. They must be used with care in order to approximate operations in a mathematical power series ring.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Simply increasing the precision will not necessarily give a \"more correct\" answer and some computations may not even terminate due to the presence of arithmetic zeroes!","category":"page"},{"location":"Nemo/series/#Capped-absolute-power-series","page":"Power series and Laurent series","title":"Capped absolute power series","text":"","category":"section"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"An absolute power series ring over a ring R with precision p behaves very much like the quotient Rx(x^p) of the polynomial ring over R.","category":"page"},{"location":"Nemo/series/#Power-series-functionality","page":"Power series and Laurent series","title":"Power series functionality","text":"","category":"section"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Power series rings in Nemo provide all the functionality described for power series in AbstractAlgebra:","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/series","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"In addition, generic power series and Laurent series are provided by AbstractAlgebra.","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"We list below only the functionality that is Nemo specific for power series rings.","category":"page"},{"location":"Nemo/series/#Special-functions","page":"Power series and Laurent series","title":"Special functions","text":"","category":"section"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"Examples","category":"page"},{"location":"Nemo/series/","page":"Power series and Laurent series","title":"Power series and Laurent series","text":"julia> T, z = power_series_ring(QQ, 30, \"z\")\n(Univariate power series ring over QQ, z + O(z^31))\n\njulia> a = 1 + z + 3z^2 + O(z^5)\n1 + z + 3*z^2 + O(z^5)\n\njulia> b = z + 2z^2 + 5z^3 + O(z^5)\nz + 2*z^2 + 5*z^3 + O(z^5)\n\njulia> d = divexact(z, exp(z + O(z^40)) - 1)\n1 - 1//2*z + 1//12*z^2 - 1//720*z^4 + 1//30240*z^6 - 1//1209600*z^8 + 1//47900160*z^10 - 691//1307674368000*z^12 + 1//74724249600*z^14 - 3617//10670622842880000*z^16 + 43867//5109094217170944000*z^18 - 174611//802857662698291200000*z^20 + 77683//14101100039391805440000*z^22 - 236364091//1693824136731743669452800000*z^24 + 657931//186134520519971831808000000*z^26 - 3392780147//37893265687455865519472640000000*z^28 + O(z^29)\n\njulia> f = exp(b)\n1 + z + 5//2*z^2 + 43//6*z^3 + 193//24*z^4 + O(z^5)\n\njulia> g = log(a)\nz + 5//2*z^2 - 8//3*z^3 - 7//4*z^4 + O(z^5)\n\njulia> h = sqrt(a)\n1 + 1//2*z + 11//8*z^2 - 11//16*z^3 - 77//128*z^4 + O(z^5)\n\njulia> k = sin(b)\nz + 2*z^2 + 29//6*z^3 - z^4 + O(z^5)\n\njulia> m = atanh(b)\nz + 2*z^2 + 16//3*z^3 + 2*z^4 + O(z^5)","category":"page"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/","page":"General schemes","title":"General schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/#General-schemes","page":"General schemes","title":"General schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/","page":"General schemes","title":"General schemes","text":"Arbitrary schemes over a commutative base ring mathbb k with unit are instances of the abstract type","category":"page"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/","page":"General schemes","title":"General schemes","text":"Scheme{BaseRingType<:Ring}","category":"page"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/#Scheme","page":"General schemes","title":"Scheme","text":"Scheme{BaseRingType<:Ring}\n\nA scheme over a ring 𝕜 of type BaseRingType.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/","page":"General schemes","title":"General schemes","text":"Morphisms of schemes shall be derived from the abstract type","category":"page"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/","page":"General schemes","title":"General schemes","text":" SchemeMor{DomainType, CodomainType, MorphismType, BaseMorType}","category":"page"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/#SchemeMor","page":"General schemes","title":"SchemeMor","text":"SchemeMor{DomainType, CodomainType, MorphismType, BaseMorType}\n\nA morphism of schemes f X Y of type MorphismType with X of type DomainType and Y of type CodomainType. \n\nWhen X and Y are defined over schemes BX and BY other than Spec(𝕜), BaseMorType is the type of the underlying morphism BX BY; otherwise, it can be set to Nothing.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/#Change-of-base","page":"General schemes","title":"Change of base","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/","page":"General schemes","title":"General schemes","text":" base_change(phi::Any, X::Scheme)\n base_change(phi::Any, f::SchemeMor;\n domain_map::AbsSchemeMor, codomain_map::AbsSchemeMor\n )","category":"page"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/#base_change-Tuple{Any, Scheme}","page":"General schemes","title":"base_change","text":"base_change(phi::Any, X::Scheme)\n\nFor a Scheme X over a base_ring 𝕜 and a map φ 𝕜 R we compute X = X ₖ Spec(R) and return a pair (X', f) where f X X is the canonical morphism.\n\nnote: Note\nWe do not restrict phi to be a Hecke.Map so that one can also use coercion, anonymous functions, etc. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/GeneralSchemes/#base_change-Tuple{Any, SchemeMor}","page":"General schemes","title":"base_change","text":"base_change(phi::Any, f::SchemeMor;\n domain_map::SchemeMor, codomain_map::SchemeMor\n )\n\nFor a morphism f X Y with both X and Y defined over a base_ring 𝕜 and a map φ 𝕜 R return a triple (a, F, b) where a X X is the morphism from base_change(phi, X), b Y Y the one for Y, and F X Y the induced morphism on those fiber products.\n\nnote: Note\nWe do not restrict phi to be a Hecke.Map so that one can also use coercion, anonymous functions, etc. \n\nnote: Note\nThe morphisms a and b can be passed as the optional arguments domain_map and codomain_map, respectively. \n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/number_fields/elements/#Element-operations","page":"Element operations","title":"Element operations","text":"","category":"section"},{"location":"Hecke/number_fields/elements/#Creation","page":"Element operations","title":"Creation","text":"","category":"section"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"gen(::SimpleNumField)\ngens(::NonSimpleNumField)","category":"page"},{"location":"Hecke/number_fields/elements/#gen-Tuple{SimpleNumField}","page":"Element operations","title":"gen","text":"gen(L::SimpleNumField) -> NumFieldElem\n\nGiven a simple number field L = Kx(f) over K, this functions returns the class of x, which is the canonical primitive element of L over K.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#gens-Tuple{NonSimpleNumField}","page":"Element operations","title":"gens","text":"gens(L::NonSimpleNumField) -> Vector{NumFieldElem}\n\nGiven a non-simple number field L = Kx_1dotscx_n(f_1dotscf_n) over K, this functions returns the list bar x_1dotscbar x_n.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"Elements can also be created by specifying the coordinates with respect to the basis of the number field:","category":"page"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":" (L::number_field)(c::Vector{NumFieldElem}) -> NumFieldElem","category":"page"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"Given a number field LK of degree d and a vector c length d, this constructs the element a with coordinates(a) == c.","category":"page"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"julia> Qx, x = QQ[\"x\"];\n\njulia> K, a = number_field(x^2 - 2, \"a\");\n\njulia> K([1, 2])\n2*a + 1\n\njulia> L, b = radical_extension(3, a, \"b\")\n(Relative number field of degree 3 over number field, b)\n\njulia> L([a, 1, 1//2])\n1//2*b^2 + b + a","category":"page"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"quadratic_defect(a::NumFieldElem, p)\nhilbert_symbol(a::nf_elem, b::nf_elem, p::Union{NfAbsOrdIdl, NfRelOrdIdl})\nrepresentation_matrix(::NumFieldElem)\nbasis_matrix(::Vector{nf_elem})\ncoefficients(::SimpleNumFieldElem)\ncoordinates(::NumFieldElem)\nabsolute_coordinates(::NumFieldElem)\ncoeff(::SimpleNumFieldElem, ::Int)\nvaluation(::NumFieldElem, ::Any)\ntorsion_unit_order(::nf_elem, ::Int)\ntr(::NumFieldElem)\nabsolute_tr(::NumFieldElem)\nalgebraic_split(::nf_elem)","category":"page"},{"location":"Hecke/number_fields/elements/#quadratic_defect-Tuple{NumFieldElem, Any}","page":"Element operations","title":"quadratic_defect","text":"quadratic_defect(a::Union{NumFieldElem,Rational,QQFieldElem}, p) -> Union{Inf, PosInf}\n\nReturns the valuation of the quadratic defect of the element a at p, which can either be prime object or an infinite place of the parent of a.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#hilbert_symbol-Tuple{nf_elem, nf_elem, Union{NfAbsOrdIdl, Hecke.NfRelOrdIdl}}","page":"Element operations","title":"hilbert_symbol","text":"hilbert_symbol(a::NumFieldElem, b::NumFieldElem, p::NfOrdIdl) -> Int\n\nReturns the local Hilbert symbol (ab)_p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#representation_matrix-Tuple{NumFieldElem}","page":"Element operations","title":"representation_matrix","text":"representation_matrix(a::NumFieldElem) -> MatElem\n\nReturns the representation matrix of a, that is, the matrix representing multiplication with a with respect to the canonical basis of the parent of a.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#basis_matrix-Tuple{Vector{nf_elem}}","page":"Element operations","title":"basis_matrix","text":"basis_matrix(v::Vector{NumFieldElem}) -> Mat\n\nGiven a vector v of n elements of a number field K of degree d, this function returns an n times d matrix with entries in the base field of K, where row i contains the coefficients of vi with respect of the canonical basis of K.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#coefficients-Tuple{SimpleNumFieldElem}","page":"Element operations","title":"coefficients","text":"coefficients(a::SimpleNumFieldElem, i::Int) -> Vector{FieldElem}\n\nGiven a number field element a of a simple number field extension L/K, this function returns the coefficients of a, when expanded in the canonical power basis of L.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#coordinates-Tuple{NumFieldElem}","page":"Element operations","title":"coordinates","text":"coordinates(x::NumFieldElem{T}) -> Vector{T}\n\nGiven an element x in a number field K, this function returns the coordinates of x with respect to the basis of K (the output of the 'basis' function).\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#absolute_coordinates-Tuple{NumFieldElem}","page":"Element operations","title":"absolute_coordinates","text":"absolute_coordinates(x::NumFieldElem{T}) -> Vector{T}\n\nGiven an element x in a number field K, this function returns the coordinates of x with respect to the basis of K over the rationals (the output of the absolute_basis function).\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#coeff-Tuple{SimpleNumFieldElem, Int64}","page":"Element operations","title":"coeff","text":"coeff(a::SimpleNumFieldElem, i::Int) -> FieldElem\n\nGiven a number field element a of a simple number field extension L/K, this function returns the i-th coefficient of a, when expanded in the canonical power basis of L. The result is an element of K.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#valuation-Tuple{NumFieldElem, Any}","page":"Element operations","title":"valuation","text":"valuation(a::NumFieldElem, p::NfOrdIdl) -> ZZRingElem\n\nComputes the mathfrak p-adic valuation of a, that is, the largest i such that a is contained in mathfrak p^i.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#torsion_unit_order-Tuple{nf_elem, Int64}","page":"Element operations","title":"torsion_unit_order","text":"torsion_unit_order(x::nf_elem, n::Int)\n\nGiven a torsion unit x together with a multiple n of its order, compute the order of x, that is, the smallest k in mathbb Z_geq 1 such that x^k = 1.\n\nIt is not checked whether x is a torsion unit.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#tr-Tuple{NumFieldElem}","page":"Element operations","title":"tr","text":"tr(a::NumFieldElem) -> NumFieldElem\n\nReturns the trace of an element a of a number field extension LK. This will be an element of K.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#absolute_tr-Tuple{NumFieldElem}","page":"Element operations","title":"absolute_tr","text":"absolute_tr(a::NumFieldElem) -> QQFieldElem\n\nGiven a number field element a, returns the absolute trace of a.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#algebraic_split-Tuple{nf_elem}","page":"Element operations","title":"algebraic_split","text":"algebraic_split(a::nf_elem) -> nf_elem, nf_elem\n\nWrites the input as a quotient of two \"small\" algebraic integers.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#Conjugates","page":"Element operations","title":"Conjugates","text":"","category":"section"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"conjugates(::NumFieldElem, ::AcbField)\nconjugates(::NumFieldElem)\nconjugates_log(::nf_elem, ::Int)\nconjugates_real(::nf_elem)\nconjugates_complex(::nf_elem)\nconjugates_arb_log_normalise(::nf_elem)\nminkowski_map(::nf_elem)","category":"page"},{"location":"Hecke/number_fields/elements/#conjugates-Tuple{NumFieldElem, AcbField}","page":"Element operations","title":"conjugates","text":"conjugates(x::nf_elem, C::AcbField) -> Vector{acb}\n\nCompute the conjugates of x as elements of type acb. Recall that we order the complex conjugates sigma_r+1(x)sigma_r+2s(x) such that sigma_i(x) = overlinesigma_i + s(x) for r + 1 leq i leq r + s.\n\nLet p be the precision of C, then every entry y of the vector returned satisfies radius(real(y)) < 2^-p and radius(imag(y)) < 2^-p respectively.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#conjugates-Tuple{NumFieldElem}","page":"Element operations","title":"conjugates","text":"conjugates(x::nf_elem, abs_tol::Int) -> Vector{acb}\n\nCompute the conjugates of x as elements of type acb. Recall that we order the complex conjugates sigma_r+1(x)sigma_r+2s(x) such that sigma_i(x) = overlinesigma_i + s(x) for r + 1 leq i leq r + s.\n\nEvery entry y of the vector returned satisfies radius(real(y)) < 2^-abs_tol and radius(imag(y)) < 2^-abs_tol respectively.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#conjugates_log-Tuple{nf_elem, Int64}","page":"Element operations","title":"conjugates_log","text":"conjugates_arb_log(x::nf_elem, abs_tol::Int) -> Vector{arb}\n\nReturns the elements (log(lvert sigma_1(x) rvert)dotsclog(lvertsigma_r(x) rvert) dotsc2log(lvert sigma_r+1(x) rvert)dotsc 2log(lvert sigma_r+s(x)rvert)) as elements of type arb with radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#conjugates_real-Tuple{nf_elem}","page":"Element operations","title":"conjugates_real","text":"conjugates_arb_real(x::nf_elem, abs_tol::Int) -> Vector{arb}\n\nCompute the real conjugates of x as elements of type arb.\n\nEvery entry y of the array returned satisfies radius(y) < 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#conjugates_complex-Tuple{nf_elem}","page":"Element operations","title":"conjugates_complex","text":"conjugates_complex(x::nf_elem, abs_tol::Int) -> Vector{acb}\n\nCompute the complex conjugates of x as elements of type acb. Recall that we order the complex conjugates sigma_r+1(x)sigma_r+2s(x) such that sigma_i(x) = overlinesigma_i + s(x) for r + 1 leq i leq r + s.\n\nEvery entry y of the array returned satisfies radius(real(y)) < 2^-abs_tol and radius(imag(y)) < 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#conjugates_arb_log_normalise-Tuple{nf_elem}","page":"Element operations","title":"conjugates_arb_log_normalise","text":"conjugates_arb_log_normalise(x::nf_elem, p::Int = 10)\nconjugates_arb_log_normalise(x::FacElem{nf_elem, AnticNumberField}, p::Int = 10)\n\nThe \"normalised\" logarithms, i.e. the array c_ilog x^(i) - 1nlogN(x), so the (weighted) sum adds up to zero.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#minkowski_map-Tuple{nf_elem}","page":"Element operations","title":"minkowski_map","text":"minkowski_map(a::nf_elem, abs_tol::Int) -> Vector{arb}\n\nReturns the image of a under the Minkowski embedding. Every entry of the array returned is of type arb with radius less then 2^(-abs_tol).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#Predicates","page":"Element operations","title":"Predicates","text":"","category":"section"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"is_integral(::NumFieldElem)\nis_torsion_unit(::nf_elem)\nis_local_norm(::NumField, ::NumFieldElem, ::Any)\nis_norm_divisible(::nf_elem, ::ZZRingElem)\nis_norm(::AnticNumberField, ::ZZRingElem)","category":"page"},{"location":"Hecke/number_fields/elements/#is_integral-Tuple{NumFieldElem}","page":"Element operations","title":"is_integral","text":"is_integral(a::NumFieldElem) -> Bool\n\nReturns whether a is integral, that is, whether the minimal polynomial of a has integral coefficients.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#is_torsion_unit-Tuple{nf_elem}","page":"Element operations","title":"is_torsion_unit","text":"is_torsion_unit(x::nf_elem, checkisunit::Bool = false) -> Bool\n\nReturns whether x is a torsion unit, that is, whether there exists n such that x^n = 1.\n\nIf checkisunit is true, it is first checked whether x is a unit of the maximal order of the number field x is lying in.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#is_local_norm-Tuple{NumField, NumFieldElem, Any}","page":"Element operations","title":"is_local_norm","text":"is_local_norm(L::NumField, a::NumFieldElem, P)\n\nGiven a number field LK, an element a in K and a prime ideal P of K, returns whether a is a local norm at P.\n\nThe number field LK must be a simple extension of degree 2.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#is_norm_divisible-Tuple{nf_elem, ZZRingElem}","page":"Element operations","title":"is_norm_divisible","text":"is_norm_divisible(a::nf_elem, n::ZZRingElem) -> Bool\n\nChecks if the norm of a is divisible by n, assuming that the norm of a is an integer.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#is_norm-Tuple{AnticNumberField, ZZRingElem}","page":"Element operations","title":"is_norm","text":"is_norm(K::AnticNumberField, a::ZZRingElem; extra::Vector{ZZRingElem}) -> Bool, nf_elem\n\nFor a ZZRingElem a, try to find T in K s.th. N(T) = a holds. If successful, return true and T, otherwise false and some element. In \\testtt{extra} one can pass in additional prime numbers that are allowed to occur in the solution. This will then be supplemented. The element will be returned in factored form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#Invariants","page":"Element operations","title":"Invariants","text":"","category":"section"},{"location":"Hecke/number_fields/elements/","page":"Element operations","title":"Element operations","text":"norm(::NumFieldElem)\nabsolute_norm(::NumFieldElem)\nminpoly(::NumFieldElem)\nabsolute_minpoly(::NumFieldElem)\ncharpoly(::NumFieldElem)\nabsolute_charpoly(::NumFieldElem)\nnorm(::NumFieldElem, ::NumField)","category":"page"},{"location":"Hecke/number_fields/elements/#norm-Tuple{NumFieldElem}","page":"Element operations","title":"norm","text":"norm(a::NumFieldElem) -> NumFieldElem\n\nReturns the norm of an element a of a number field extension LK. This will be an element of K.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#absolute_norm-Tuple{NumFieldElem}","page":"Element operations","title":"absolute_norm","text":"absolute_norm(a::NumFieldElem) -> QQFieldElem\n\nGiven a number field element a, returns the absolute norm of a.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#minpoly-Tuple{NumFieldElem}","page":"Element operations","title":"minpoly","text":"minpoly(a::NumFieldElem) -> PolyElem\n\nGiven a number field element a of a number field K, this function returns the minimal polynomial of a over the base field of K.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#absolute_minpoly-Tuple{NumFieldElem}","page":"Element operations","title":"absolute_minpoly","text":"absolute_minpoly(a::NumFieldElem) -> PolyElem\n\nGiven a number field element a of a number field K, this function returns the minimal polynomial of a over the rationals mathbfQ.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#charpoly-Tuple{NumFieldElem}","page":"Element operations","title":"charpoly","text":"charpoly(a::NumFieldElem) -> PolyElem\n\nGiven a number field element a of a number field K, this function returns the characteristic polynomial of a over the base field of K.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#absolute_charpoly-Tuple{NumFieldElem}","page":"Element operations","title":"absolute_charpoly","text":"absolute_charpoly(a::NumFieldElem) -> PolyElem\n\nGiven a number field element a of a number field K, this function returns the characteristic polynomial of a over the rationals mathbfQ.\n\n\n\n","category":"method"},{"location":"Hecke/number_fields/elements/#norm-Tuple{NumFieldElem, NumField}","page":"Element operations","title":"norm","text":"norm(a::NumFieldElem, k::NumField) -> NumFieldElem\n\nReturns the norm of an element a of a number field L with respect to a subfield k of L. This will be an element of k.\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Sparse-linear-algebra","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/sparse/intro/#Introduction","page":"Sparse linear algebra","title":"Introduction","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"This chapter deals with sparse linear algebra over commutative rings and fields.","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Sparse linear algebra, that is, linear algebra with sparse matrices, plays an important role in various algorithms in algebraic number theory. For example, it is one of the key ingredients in the computation of class groups and discrete logarithms using index calculus methods.","category":"page"},{"location":"Hecke/sparse/intro/#Sparse-rows","page":"Sparse linear algebra","title":"Sparse rows","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Building blocks for sparse matrices are sparse rows, which are modelled by objects of type SRow. More precisely, the type is of parametrized form SRow{T}, where T is the element type of the base ring R. For example, SRow{ZZRingElem} is the type for sparse rows over the integers.","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"It is important to note that sparse rows do not have a fixed number of columns, that is, they represent elements of (x_i)_i in R^mathbbN mid x_i = 0 text for almost all i. In particular any two sparse rows over the same base ring can be added.","category":"page"},{"location":"Hecke/sparse/intro/#Creation","page":"Sparse linear algebra","title":"Creation","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparse_row(::ZZRing, ::Vector{Tuple{Int, ZZRingElem}})\nsparse_row(::ZZRing, ::Vector{Tuple{Int, Int}})\nsparse_row(::ZZRing, ::Vector{Int}, ::Vector{ZZRingElem})","category":"page"},{"location":"Hecke/sparse/intro/#sparse_row-Tuple{ZZRing, Vector{Tuple{Int64, ZZRingElem}}}","page":"Sparse linear algebra","title":"sparse_row","text":"sparse_row(R::Ring, J::Vector{Tuple{Int, T}}) -> SRow{T}\n\nConstructs the sparse row (a_i)_i with a_i_j = x_j, where J = (i_j x_j)_j. The elements x_i must belong to the ring R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#sparse_row-Tuple{ZZRing, Vector{Tuple{Int64, Int64}}}","page":"Sparse linear algebra","title":"sparse_row","text":"sparse_row(R::Ring, J::Vector{Tuple{Int, T}}) -> SRow{T}\n\nConstructs the sparse row (a_i)_i with a_i_j = x_j, where J = (i_j x_j)_j. The elements x_i must belong to the ring R.\n\n\n\n\n\nsparse_row(R::Ring, J::Vector{Tuple{Int, Int}}) -> SRow\n\nConstructs the sparse row (a_i)_i over R with a_i_j = x_j, where J = (i_j x_j)_j.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#sparse_row-Tuple{ZZRing, Vector{Int64}, Vector{ZZRingElem}}","page":"Sparse linear algebra","title":"sparse_row","text":"sparse_row(R::Ring, J::Vector{Int}, V::Vector{T}) -> SRow{T}\n\nConstructs the sparse row (a_i)_i over R with a_i_j = x_j, where J = (i_j)_j and V = (x_j)_j.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Basic-operations","page":"Sparse linear algebra","title":"Basic operations","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Rows support the usual operations:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"+, -, ==\nmultiplication by scalars\ndiv, divexact","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"getindex(::SRow{ZZRingElem}, ::Int)\nadd_scaled_row(::SRow{ZZRingElem}, ::SRow{ZZRingElem}, ::ZZRingElem)\nadd_scaled_row(::SRow{T}, ::SRow{T}, ::T) where {T}\ntransform_row(::SRow{T}, ::SRow{T}, ::T, ::T, ::T, ::T) where {T}\nlength(::SRow)","category":"page"},{"location":"Hecke/sparse/intro/#getindex-Tuple{SRow{ZZRingElem}, Int64}","page":"Sparse linear algebra","title":"getindex","text":"getindex(A::SRow, j::Int) -> RingElem\n\nGiven a sparse row (a_i)_i and an index j return a_j.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#add_scaled_row-Tuple{SRow{ZZRingElem}, SRow{ZZRingElem}, ZZRingElem}","page":"Sparse linear algebra","title":"add_scaled_row","text":"add_scaled_row(A::SRow{T}, B::SRow{T}, c::T) -> SRow{T}\n\nReturns the row c A + B.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#add_scaled_row-Union{Tuple{T}, Tuple{SRow{T}, SRow{T}, T}} where T","page":"Sparse linear algebra","title":"add_scaled_row","text":"add_scaled_row(A::SRow{T}, B::SRow{T}, c::T) -> SRow{T}\n\nReturns the row c A + B.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#transform_row-Union{Tuple{T}, Tuple{SRow{T}, SRow{T}, Vararg{T, 4}}} where T","page":"Sparse linear algebra","title":"transform_row","text":"transform_row(A::SRow{T}, B::SRow{T}, i::Int, j::Int, a::T, b::T, c::T, d::T)\n\nReturns the tuple (aA + bB cA + dB).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#length-Tuple{SRow}","page":"Sparse linear algebra","title":"length","text":"length(A::SRow)\n\nReturns the number of nonzero entries of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Change-of-base-ring","page":"Sparse linear algebra","title":"Change of base ring","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"change_base_ring(::ZZRing, ::SRow{ZZRingElem})","category":"page"},{"location":"Hecke/sparse/intro/#change_base_ring-Tuple{ZZRing, SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"change_base_ring","text":"change_base_ring(R::Ring, A::SRow) -> SRow\n\nCreate a new sparse row by coercing all elements into the ring R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Maximum,-minimum-and-2-norm","page":"Sparse linear algebra","title":"Maximum, minimum and 2-norm","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"maximum(::SRow)\nmaximum(::SRow{ZZRingElem})\nminimum(::SRow{ZZRingElem})\nminimum(::SRow)\nnorm2(::SRow{ZZRingElem})","category":"page"},{"location":"Hecke/sparse/intro/#maximum-Tuple{SRow}","page":"Sparse linear algebra","title":"maximum","text":"maximum(A::SRow{T}) -> T\n\nReturns the largest entry of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#maximum-Tuple{SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"maximum","text":"maximum(A::SRow{T}) -> T\n\nReturns the largest entry of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#minimum-Tuple{SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"minimum","text":"minimum(A::SRow{T}) -> T\n\nReturns the smallest entry of A.\n\n\n\n\n\n minimum(A::NfRelOrdIdl) -> NfOrdIdl\n minimum(A::NfRelOrdIdl) -> NfRelOrdIdl\n\nReturns the ideal A cap O where O is the maximal order of the coefficient ideals of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#minimum-Tuple{SRow}","page":"Sparse linear algebra","title":"minimum","text":"minimum(A::SRow{T}) -> T\n\nReturns the smallest entry of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#norm2-Tuple{SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"norm2","text":"norm2(A::SRow{T} -> T\n\nReturns A cdot A^t.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Functionality-for-integral-sparse-rows","page":"Sparse linear algebra","title":"Functionality for integral sparse rows","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"lift(::SRow{zzModRingElem})\nmod!(::SRow{ZZRingElem}, ::ZZRingElem)\nmod_sym!(::SRow{ZZRingElem}, ::ZZRingElem)\nmod_sym!(::SRow{ZZRingElem}, ::Integer)\nmaximum(::typeof(abs), ::SRow{ZZRingElem})","category":"page"},{"location":"Hecke/sparse/intro/#lift-Tuple{SRow{zzModRingElem}}","page":"Sparse linear algebra","title":"lift","text":"lift(A::SRow{zzModRingElem}) -> SRow{ZZRingElem}\n\nReturn the sparse row obtained by lifting all entries in A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#mod!-Tuple{SRow{ZZRingElem}, ZZRingElem}","page":"Sparse linear algebra","title":"mod!","text":"mod!(A::SRow{ZZRingElem}, n::ZZRingElem) -> SRow{ZZRingElem}\n\nInplace reduction of all entries of A modulo n to the positive residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#mod_sym!-Tuple{SRow{ZZRingElem}, ZZRingElem}","page":"Sparse linear algebra","title":"mod_sym!","text":"mod_sym!(A::SRow{ZZRingElem}, n::ZZRingElem) -> SRow{ZZRingElem}\n\nInplace reduction of all entries of A modulo n to the symmetric residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#mod_sym!-Tuple{SRow{ZZRingElem}, Integer}","page":"Sparse linear algebra","title":"mod_sym!","text":"mod_sym!(A::SRow{ZZRingElem}, n::Integer) -> SRow{ZZRingElem}\n\nInplace reduction of all entries of A modulo n to the symmetric residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#maximum-Tuple{typeof(abs), SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"maximum","text":"maximum(abs, A::SRow{ZZRingElem}) -> ZZRingElem\n\nReturns the largest, in absolute value, entry of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Sparse-matrices","page":"Sparse linear algebra","title":"Sparse matrices","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Let R be a commutative ring. Sparse matrices with base ring R are modelled by objects of type SMat. More precisely, the type is of parametrized form SRow{T}, where T is the element type of the base ring. For example, SMat{ZZRingElem} is the type for sparse matrices over the integers.","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"In contrast to sparse rows, sparse matrices have a fixed number of rows and columns, that is, they represent elements of the matrices space mathrmMat_ntimes m(R). Internally, sparse matrices are implemented as an array of sparse rows. As a consequence, unlike their dense counterparts, sparse matrices have a mutable number of rows and it is very performant to add additional rows.","category":"page"},{"location":"Hecke/sparse/intro/#Construction","page":"Sparse linear algebra","title":"Construction","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparse_matrix(::Ring)\nsparse_matrix(::Ring, ::Int, ::Int)","category":"page"},{"location":"Hecke/sparse/intro/#sparse_matrix-Tuple{Ring}","page":"Sparse linear algebra","title":"sparse_matrix","text":"sparse_matrix(R::Ring) -> SMat\n\nReturn an empty sparse matrix with base ring R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#sparse_matrix-Tuple{Ring, Int64, Int64}","page":"Sparse linear algebra","title":"sparse_matrix","text":"sparse_matrix(R::Ring, n::Int, m::Int) -> SMat\n\nReturn a sparse n times m zero matrix over R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Sparse matrices can also be created from dense matrices as well as from julia arrays:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparse_matrix(::MatElem; keepzrows)\nsparse_matrix(::Matrix{T}) where {T}\nsparse_matrix(::Ring, ::Matrix{T}) where {T}","category":"page"},{"location":"Hecke/sparse/intro/#sparse_matrix-Tuple{MatElem}","page":"Sparse linear algebra","title":"sparse_matrix","text":"sparse_matrix(A::MatElem; keepzrows::Bool = true)\n\nConstructs the sparse matrix corresponding to the dense matrix A. If keepzrows is false, then the constructor will drop any zero row of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#sparse_matrix-Union{Tuple{Matrix{T}}, Tuple{T}} where T","page":"Sparse linear algebra","title":"sparse_matrix","text":"sparse_matrix(R::Ring, A::Matrix{T}) -> SMat\n\nConstructs the sparse matrix over R corresponding to A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#sparse_matrix-Union{Tuple{T}, Tuple{Ring, Matrix{T}}} where T","page":"Sparse linear algebra","title":"sparse_matrix","text":"sparse_matrix(R::Ring, A::Matrix{T}) -> SMat\n\nConstructs the sparse matrix over R corresponding to A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"The normal way however, is to add rows:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"push!(::SMat{T}, ::SRow{T}) where {T}","category":"page"},{"location":"Hecke/sparse/intro/#push!-Union{Tuple{T}, Tuple{SMat{T}, SRow{T}}} where T","page":"Sparse linear algebra","title":"push!","text":"push!(A::SMat{T}, B::SRow{T}) where T\n\nAppends the sparse row B to A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Sparse matrices can also be concatenated to form larger ones:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"vcat!(::SMat{T}, ::SMat{T}) where {T}\nvcat(::SMat{T}, ::SMat{T}) where {T}\nhcat!(::SMat{T}, ::SMat{T}) where {T}\nhcat(::SMat{T}, ::SMat{T}) where {T}","category":"page"},{"location":"Hecke/sparse/intro/#vcat!-Union{Tuple{T}, Tuple{SMat{T}, SMat{T}}} where T","page":"Sparse linear algebra","title":"vcat!","text":"vcat!(A::SMat, B::SMat) -> SMat\n\nVertically joins A and B inplace, that is, the rows of B are appended to A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#vcat-Union{Tuple{T}, Tuple{SMat{T}, SMat{T}}} where T","page":"Sparse linear algebra","title":"vcat","text":"vcat(A::SMat, B::SMat) -> SMat\n\nVertically joins A and B.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#hcat!-Union{Tuple{T}, Tuple{SMat{T}, SMat{T}}} where T","page":"Sparse linear algebra","title":"hcat!","text":"hcat!(A::SMat, B::SMat) -> SMat\n\nHorizontally concatenates A and B, inplace, changing A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#hcat-Union{Tuple{T}, Tuple{SMat{T}, SMat{T}}} where T","page":"Sparse linear algebra","title":"hcat","text":"hcat(A::SMat, B::SMat) -> SMat\n\nHorizontally concatenates A and B.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"(Normal julia cat is also supported)","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"There are special constructors:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"identity_matrix(::Type{SMat}, ::Ring, ::Int)\nzero_matrix(::Type{SMat}, ::Ring, ::Int)\nzero_matrix(::Type{SMat}, ::Ring, ::Int, ::Int)","category":"page"},{"location":"Hecke/sparse/intro/#identity_matrix-Tuple{Type{SMat}, Ring, Int64}","page":"Sparse linear algebra","title":"identity_matrix","text":"identity_matrix(::Type{SMat}, R::Ring, n::Int)\n\nReturn a sparse n times n identity matrix over R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#zero_matrix-Tuple{Type{SMat}, Ring, Int64}","page":"Sparse linear algebra","title":"zero_matrix","text":"zero_matrix(::Type{SMat}, R::Ring, n::Int)\n\nReturn a sparse n times n zero matrix over R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#zero_matrix-Tuple{Type{SMat}, Ring, Int64, Int64}","page":"Sparse linear algebra","title":"zero_matrix","text":"zero_matrix(::Type{SMat}, R::Ring, n::Int, m::Int)\n\nReturn a sparse n times m zero matrix over R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Slices:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sub(::SMat{T}, ::AbstractUnitRange, ::AbstractUnitRange) where {T}","category":"page"},{"location":"Hecke/sparse/intro/#sub-Union{Tuple{T}, Tuple{SMat{T}, AbstractUnitRange, AbstractUnitRange}} where T","page":"Sparse linear algebra","title":"sub","text":"sub(A::SMat, r::AbstractUnitRange, c::AbstractUnitRange) -> SMat\n\nReturn the submatrix of A, where the rows correspond to r and the columns correspond to c.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Transpose:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"transpose(A::SMat)","category":"page"},{"location":"Hecke/sparse/intro/#transpose-Tuple{SMat}","page":"Sparse linear algebra","title":"transpose","text":"transpose(A::SMat) -> SMat\n\nReturns the transpose of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Elementary-Properties","page":"Sparse linear algebra","title":"Elementary Properties","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparsity(::SMat)\ndensity(::SMat)\nnnz(::SMat)\nnrows(::SMat)\nncols(::SMat)\nisone(::SMat)\niszero(::SMat)\nisupper_triangular(::SMat)\nmaximum(::SMat)\nminimum(::SMat)\nmaximum(::typeof(abs), ::SMat{ZZRingElem})\nelementary_divisors(::SMat{ZZRingElem})\nHecke.solve_dixon_sf(::SMat{ZZRingElem}, ::SRow{ZZRingElem})\nHecke.hadamard_bound2(::SMat)\nHecke.echelon_with_transform(::SMat{zzModRingElem})\nHecke.reduce_full(::SMat{ZZRingElem}, ::SRow{ZZRingElem})\nhnf!(::SMat{ZZRingElem})\nhnf(::SMat{ZZRingElem})\nsnf(::SMat{ZZRingElem})\nhnf_extend!(::SMat{ZZRingElem}, ::SMat{ZZRingElem})\nis_diagonal(::SMat)\ndet(::SMat{ZZRingElem})\ndet_mc(::SMat{ZZRingElem})\nvalence_mc(::SMat)\nsaturate(::SMat{ZZRingElem})\nHecke.hnf_kannan_bachem(::SMat{ZZRingElem})\ndiagonal_form(::SMat{ZZRingElem})","category":"page"},{"location":"Hecke/sparse/intro/#sparsity-Tuple{SMat}","page":"Sparse linear algebra","title":"sparsity","text":"sparsity(A::SMat) -> Float64\n\nReturn the sparsity of A, that is, the number of zero-valued elements divided by the number of all elements.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#density-Tuple{SMat}","page":"Sparse linear algebra","title":"density","text":"density(A::SMat) -> Float64\n\nReturn the density of A, that is, the number of nonzero-valued elements divided by the number of all elements.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#nnz-Tuple{SMat}","page":"Sparse linear algebra","title":"nnz","text":"nnz(A::SMat) -> Int\n\nReturn the number of non-zero entries of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#nrows-Tuple{SMat}","page":"Sparse linear algebra","title":"nrows","text":"nrows(A::SMat) -> Int\n\nReturn the number of rows of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#ncols-Tuple{SMat}","page":"Sparse linear algebra","title":"ncols","text":"ncols(A::SMat) -> Int\n\nReturn the number of columns of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#isone-Tuple{SMat}","page":"Sparse linear algebra","title":"isone","text":"isone(A::SMat)\n\nTests if A is an identity matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#iszero-Tuple{SMat}","page":"Sparse linear algebra","title":"iszero","text":"iszero(A::SMat)\n\nTests if A is a zero matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#isupper_triangular-Tuple{SMat}","page":"Sparse linear algebra","title":"isupper_triangular","text":"isupper_triangular(A::SMat)\n\nReturns true if and only if A is upper (right) triangular.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#maximum-Tuple{SMat}","page":"Sparse linear algebra","title":"maximum","text":"maximum(A::SMat{T}) -> T\n\nFinds the largest entry of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#minimum-Tuple{SMat}","page":"Sparse linear algebra","title":"minimum","text":"minimum(A::SMat{T}) -> T\n\nFinds the smallest entry of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#maximum-Tuple{typeof(abs), SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"maximum","text":"maximum(abs, A::SMat{ZZRingElem}) -> ZZRingElem\n\nFinds the largest, in absolute value, entry of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#elementary_divisors-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"elementary_divisors","text":"elementary_divisors(A::SMat{ZZRingElem}) -> Vector{ZZRingElem}\n\nThe elementary divisors of A, i.e. the diagonal elements of the Smith normal form of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#solve_dixon_sf-Tuple{SMat{ZZRingElem}, SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"solve_dixon_sf","text":"solve_dixon_sf(A::SMat{ZZRingElem}, b::SRow{ZZRingElem}, is_int::Bool = false) -> SRow{ZZRingElem}, ZZRingElem\nsolve_dixon_sf(A::SMat{ZZRingElem}, B::SMat{ZZRingElem}, is_int::Bool = false) -> SMat{ZZRingElem}, ZZRingElem\n\nFor a sparse square matrix A of full rank and a sparse matrix (row), find a sparse matrix (row) x and an integer d s.th. x A = bd holds. The algorithm is a Dixon-based linear p-adic lifting method. If \\code{is_int} is given, then d is assumed to be 1. In this case rational reconstruction is avoided.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#hadamard_bound2-Tuple{SMat}","page":"Sparse linear algebra","title":"hadamard_bound2","text":"hadamard_bound2(A::SMat{T}) -> T\n\nThe square of the product of the norms of the rows of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#echelon_with_transform-Tuple{SMat{zzModRingElem}}","page":"Sparse linear algebra","title":"echelon_with_transform","text":"echelon_with_transform(A::SMat{zzModRingElem}) -> SMat, SMat\n\nFind a unimodular matrix T and an upper-triangular E s.th. TA = E holds.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#reduce_full-Tuple{SMat{ZZRingElem}, SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"reduce_full","text":"reduce_full(A::SMat{ZZRingElem}, g::SRow{ZZRingElem},\n trafo = Val{false}) -> SRow{ZZRingElem}, Vector{Int}\n\nReduces g modulo A and assumes that A is upper triangular.\n\nThe second return value is the array of pivot elements of A that changed.\n\nIf trafo is set to Val{true}, then additionally an array of transformations is returned.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#hnf!-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"hnf!","text":"hnf!(A::SMat{ZZRingElem})\n\nInplace transform of A into upper right Hermite normal form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#hnf-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"hnf","text":"hnf(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}\n\nReturn the upper right Hermite normal form of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#snf-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"snf","text":"snf(A::SMat{ZZRingElem})\n\nThe Smith normal form (snf) of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#hnf_extend!-Tuple{SMat{ZZRingElem}, SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"hnf_extend!","text":"hnf_extend!(A::SMat{ZZRingElem}, b::SMat{ZZRingElem}, offset::Int = 0) -> SMat{ZZRingElem}\n\nGiven a matrix A in HNF, extend this to get the HNF of the concatenation with b.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#is_diagonal-Tuple{SMat}","page":"Sparse linear algebra","title":"is_diagonal","text":"is_diagonal(A::SMat) -> Bool\n\nTrue iff only the i-th entry in the i-th row is non-zero.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#det-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"det","text":"det(A::SMat{ZZRingElem})\n\nThe determinant of A using a modular algorithm. Uses the dense (zzModMatrix) determinant on A for various primes p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#det_mc-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"det_mc","text":"det_mc(A::SMat{ZZRingElem})\n\nComputes the determinant of A using a LasVegas style algorithm, i.e. the result is not proven to be correct. Uses the dense (zzModMatrix) determinant on A for various primes p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#valence_mc-Tuple{SMat}","page":"Sparse linear algebra","title":"valence_mc","text":"valence_mc{T}(A::SMat{T}; extra_prime = 2, trans = Vector{SMatSLP_add_row{T}}()) -> T\n\nUses a Monte-Carlo algorithm to compute the valence of A. The valence is the valence of the minimal polynomial f of transpose(A)*A, thus the last non-zero coefficient, typically f(0).\n\nThe valence is computed modulo various primes until the computation stabilises for extra_prime many.\n\ntrans, if given, is a SLP (straight-line-program) in GL(n, Z). Then the valence of trans * A is computed instead.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#saturate-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"saturate","text":"saturate(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}\n\nComputes the saturation of A, that is, a basis for mathbfQotimes M meet mathbfZ^n, where M is the row span of A and n the number of rows of A.\n\nEquivalently, return TA for an invertible rational matrix T, such that TA is integral and the elementary divisors of TA are all trivial.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#hnf_kannan_bachem-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"hnf_kannan_bachem","text":"hnf_kannan_bachem(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}\n\nCompute the Hermite normal form of A using the Kannan-Bachem algorithm.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#diagonal_form-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"diagonal_form","text":"diagonal_form(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}\n\nA matrix D that is diagonal and obtained via unimodular row and column operations. Like a snf without the divisibility condition.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Manipulation/-Access","page":"Sparse linear algebra","title":"Manipulation/ Access","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"getindex(::SMat{T}, ::Int, ::Int) where {T}\ngetindex(::SMat{T}, ::Int) where {T}\nsetindex!(::SMat{T}, ::SRow{T}, ::Int) where {T}\nswap_rows!(::SMat, ::Int, I::Int)\nswap_cols!(::SMat, ::Int, I::Int)\nscale_row!(::SMat{T}, ::Int, ::T) where {T}\nadd_scaled_col!(::SMat{T}, ::Int, ::Int, ::T) where {T}\nadd_scaled_row!(::SMat{T}, ::Int, ::Int, ::T) where {T}\ntransform_row!(::SMat{T}, ::Int, ::Int, ::T, ::T, ::T, ::T) where {T}\ndiagonal(::SMat)\nreverse_rows!(::SMat)\nmod_sym!(::SMat{ZZRingElem}, ::ZZRingElem)\nfind_row_starting_with(::SMat, ::Int)\nreduce(::SMat{ZZRingElem}, ::SRow{ZZRingElem}, ::ZZRingElem)\nreduce(::SMat{ZZRingElem}, ::SRow{ZZRingElem})\nreduce(::SMat{T}, ::SRow{T}) where {T <: FieldElement}\nrand_row(::SMat{T}) where {T}","category":"page"},{"location":"Hecke/sparse/intro/#getindex-Union{Tuple{T}, Tuple{SMat{T}, Int64, Int64}} where T","page":"Sparse linear algebra","title":"getindex","text":"getindex(A::SMat, i::Int, j::Int)\n\nGiven a sparse matrix A = (a_ij)_i j, return the entry a_ij.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#getindex-Union{Tuple{T}, Tuple{SMat{T}, Int64}} where T","page":"Sparse linear algebra","title":"getindex","text":"getindex(A::SMat, i::Int) -> SRow\n\nGiven a sparse matrix A and an index i, return the i-th row of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#setindex!-Union{Tuple{T}, Tuple{SMat{T}, SRow{T}, Int64}} where T","page":"Sparse linear algebra","title":"setindex!","text":"setindex!(A::SMat, b::SRow, i::Int)\n\nGiven a sparse matrix A, a sparse row b and an index i, set the i-th row of A equal to b.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#swap_rows!-Tuple{SMat, Int64, Int64}","page":"Sparse linear algebra","title":"swap_rows!","text":"swap_rows!(A::SMat{T}, i::Int, j::Int)\n\nSwap the i-th and j-th row of A inplace.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#swap_cols!-Tuple{SMat, Int64, Int64}","page":"Sparse linear algebra","title":"swap_cols!","text":"swap_cols!(A::SMat, i::Int, j::Int)\n\nSwap the i-th and j-th column of A inplace.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#scale_row!-Union{Tuple{T}, Tuple{SMat{T}, Int64, T}} where T","page":"Sparse linear algebra","title":"scale_row!","text":"scale_row!(A::SMat{T}, i::Int, c::T)\n\nMultiply the i-th row of A by c inplace.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#add_scaled_col!-Union{Tuple{T}, Tuple{SMat{T}, Int64, Int64, T}} where T","page":"Sparse linear algebra","title":"add_scaled_col!","text":"add_scaled_col!(A::SMat{T}, i::Int, j::Int, c::T)\n\nAdd c times the i-th column to the j-th column of A inplace, that is, A_j rightarrow A_j + c cdot A_i, where (A_i)_i denote the columns of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#add_scaled_row!-Union{Tuple{T}, Tuple{SMat{T}, Int64, Int64, T}} where T","page":"Sparse linear algebra","title":"add_scaled_row!","text":"add_scaled_row!(A::SMat{T}, i::Int, j::Int, c::T)\n\nAdd c times the i-th row to the j-th row of A inplace, that is, A_j rightarrow A_j + c cdot A_i, where (A_i)_i denote the rows of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#transform_row!-Union{Tuple{T}, Tuple{SMat{T}, Int64, Int64, Vararg{T, 4}}} where T","page":"Sparse linear algebra","title":"transform_row!","text":"transform_row!(A::SMat{T}, i::Int, j::Int, a::T, b::T, c::T, d::T)\n\nApplies the transformation (A_i A_j) rightarrow (aA_i + bA_j cA_i + dA_j) to A, where (A_i)_i are the rows of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#diagonal-Tuple{SMat}","page":"Sparse linear algebra","title":"diagonal","text":"diagonal(A::SMat) -> ZZRingElem[]\n\nThe diagonal elements of A in an array.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#reverse_rows!-Tuple{SMat}","page":"Sparse linear algebra","title":"reverse_rows!","text":"reverse_rows!(A::SMat)\n\nInplace inversion of the rows of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#mod_sym!-Tuple{SMat{ZZRingElem}, ZZRingElem}","page":"Sparse linear algebra","title":"mod_sym!","text":"mod_sym!(A::SMat{ZZRingElem}, n::ZZRingElem)\n\nInplace reduction of all entries of A modulo n to the symmetric residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#find_row_starting_with-Tuple{SMat, Int64}","page":"Sparse linear algebra","title":"find_row_starting_with","text":"find_row_starting_with(A::SMat, p::Int) -> Int\n\nTries to find the index i such that A_ip neq 0 and A_i p-j = 0 for all j 1. It is assumed that A is upper triangular. If such an index does not exist, find the smallest index larger.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#reduce-Tuple{SMat{ZZRingElem}, SRow{ZZRingElem}, ZZRingElem}","page":"Sparse linear algebra","title":"reduce","text":"reduce(A::SMat{ZZRingElem}, g::SRow{ZZRingElem}, m::ZZRingElem) -> SRow{ZZRingElem}\n\nGiven an upper triangular matrix A over the integers, a sparse row g and an integer m, this function reduces g modulo A and returns g modulo m with respect to the symmetric residue system.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#reduce-Tuple{SMat{ZZRingElem}, SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"reduce","text":"reduce(A::SMat{ZZRingElem}, g::SRow{ZZRingElem}) -> SRow{ZZRingElem}\n\nGiven an upper triangular matrix A over a field and a sparse row g, this function reduces g modulo A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#reduce-Union{Tuple{T}, Tuple{SMat{T}, SRow{T}}} where T<:FieldElement","page":"Sparse linear algebra","title":"reduce","text":"reduce(A::SMat{T}, g::SRow{T}) -> SRow{T}\n\nGiven an upper triangular matrix A over a field and a sparse row g, this function reduces g modulo A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#rand_row-Union{Tuple{SMat{T}}, Tuple{T}} where T","page":"Sparse linear algebra","title":"rand_row","text":"rand_row(A::SMat) -> SRow\n\nReturn a random row of the sparse matrix A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Changing of the ring:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"map_entries(f, ::SMat)\nchange_base_ring(::Ring, ::SMat)","category":"page"},{"location":"Hecke/sparse/intro/#map_entries-Tuple{Any, SMat}","page":"Sparse linear algebra","title":"map_entries","text":"map_entries(f, A::SMat) -> SMat\n\nGiven a sparse matrix A and a callable object f, this function will construct a new sparse matrix by applying f to all elements of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#change_base_ring-Tuple{Ring, SMat}","page":"Sparse linear algebra","title":"change_base_ring","text":"change_base_ring(R::Ring, A::SMat)\n\nCreate a new sparse matrix by coercing all elements into the ring R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Arithmetic","page":"Sparse linear algebra","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Matrices support the usual operations as well","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"+, -, ==\ndiv, divexact by scalars\nmultiplication by scalars","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Various products:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Hecke.mul(::SMat{T}, ::AbstractVector{T}) where {T}\nHecke.mul(::SMat{T}, ::AbstractMatrix{T}) where {T}\nHecke.mul(::SMat{T}, ::MatElem{T}) where {T}\nHecke.mul(::SRow{T}, ::SMat{T}) where {T}","category":"page"},{"location":"Hecke/sparse/intro/#mul-Union{Tuple{T}, Tuple{SMat{T}, AbstractVector{T}}} where T","page":"Sparse linear algebra","title":"mul","text":"mul(A::SMat{T}, b::AbstractVector{T}) -> Vector{T}\n\nReturn the product A cdot b as a dense vector.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#mul-Union{Tuple{T}, Tuple{SMat{T}, AbstractMatrix{T}}} where T","page":"Sparse linear algebra","title":"mul","text":"mul(A::SMat{T}, b::AbstractMatrix{T}) -> Matrix{T}\n\nReturn the product A cdot b as a dense array.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#mul-Union{Tuple{T}, Tuple{SMat{T}, MatElem{T}}} where T","page":"Sparse linear algebra","title":"mul","text":"mul(A::SMat{T}, b::MatElem{T}) -> MatElem\n\nReturn the product A cdot b as a dense matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#mul-Union{Tuple{T}, Tuple{SRow{T}, SMat{T}}} where T","page":"Sparse linear algebra","title":"mul","text":"mul(A::SRow, B::SMat) -> SRow\n\nReturn the product Acdot B as a sparse row.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Other:","category":"page"},{"location":"Hecke/sparse/intro/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparse(::SMat)\nZZMatrix(::SMat{ZZRingElem})\nZZMatrix(::SMat{T}) where {T <: Integer}\nArray(::SMat{T}) where {T}","category":"page"},{"location":"Hecke/sparse/intro/#sparse-Tuple{SMat}","page":"Sparse linear algebra","title":"sparse","text":"sparse(A::SMat) -> SparseMatrixCSC\n\nThe same matrix, but as a sparse matrix of julia type SparseMatrixCSC.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#ZZMatrix-Tuple{SMat{ZZRingElem}}","page":"Sparse linear algebra","title":"ZZMatrix","text":"ZZMatrix(A::SMat{ZZRingElem})\n\nThe same matrix A, but as an ZZMatrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#ZZMatrix-Union{Tuple{SMat{T}}, Tuple{T}} where T<:Integer","page":"Sparse linear algebra","title":"ZZMatrix","text":"ZZMatrix(A::SMat{T}) where {T <: Integer}\n\nThe same matrix A, but as an ZZMatrix. Requires a conversion from the base ring of A to mathbb ZZ.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/sparse/intro/#Array-Union{Tuple{SMat{T}}, Tuple{T}} where T","page":"Sparse linear algebra","title":"Array","text":"Array(A::SMat{T}) -> Matrix{T}\n\nThe same matrix, but as a two-dimensional julia array.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Module-Homomorphisms","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"Abstract Algebra provides homomorphisms of finitely presented modules.","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Generic-module-homomorphism-types","page":"Module Homomorphisms","title":"Generic module homomorphism types","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"AbstractAlgebra defines two module homomorphism types, namely Generic.ModuleHomomorphism and Generic.ModuleIsomorphism. Functionality for these is implemented in src/generic/ModuleHomomorphism.jl.","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Abstract-types","page":"Module Homomorphisms","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"The Generic.ModuleHomomorphism and Generic.ModuleIsomorphism types inherit from Map(FPModuleHomomorphism).","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Generic-functionality","page":"Module Homomorphisms","title":"Generic functionality","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"The following generic functionality is provided for module homomorphisms.","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Constructors","page":"Module Homomorphisms","title":"Constructors","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"Homomorphisms of AbstractAlgebra modules, f R^s to R^t, can be represented by stimes t matrices over R.","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"ModuleHomomorphism(M1::FPModule{T}, M2::FPModule{T}, m::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#ModuleHomomorphism-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}, MatElem{T}}} where T<:RingElement","page":"Module Homomorphisms","title":"ModuleHomomorphism","text":"ModuleHomomorphism(M1::FPModule{T},\n M2::FPModule{T}, m::MatElem{T}) where T <: RingElement\n\nCreate the homomorphism f M_1 to M_2 represented by the matrix m.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"ModuleIsomorphism(M1::FPModule{T}, M2::FPModule{T}, m::MatElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#ModuleIsomorphism-Union{Tuple{T}, Tuple{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}, MatElem{T}}} where T<:RingElement","page":"Module Homomorphisms","title":"ModuleIsomorphism","text":"ModuleIsomorphism(M1::FPModule{T}, M2::FPModule{T}, M::MatElem{T},\n minv::MatElem{T}) where T <: RingElement\n\nCreate the isomorphism f M_1 to M_2 represented by the matrix M. The inverse morphism is automatically computed.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"julia> M = FreeModule(ZZ, 2)\nFree module of rank 2 over integers\n\njulia> f = ModuleHomomorphism(M, M, matrix(ZZ, 2, 2, [1, 2, 3, 4]))\nModule homomorphism\n from free module of rank 2 over integers\n to free module of rank 2 over integers\n\njulia> m = M([ZZ(1), ZZ(2)])\n(1, 2)\n\njulia> f(m)\n(7, 10)\n","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"They can also be created by giving images (in the codomain) of the generators of the domain:","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"ModuleHomomorphism(M1::FPModule{T}, M2::FPModule{T}, v::Vector{<:FPModuleElem{T}}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Kernels","page":"Module Homomorphisms","title":"Kernels","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"kernel(f::Map(FPModuleHomomorphism))","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#kernel-Tuple{Map{D, C, <:AbstractAlgebra.FPModuleHomomorphism, T} where {D, C, T}}","page":"Module Homomorphisms","title":"kernel","text":"kernel(f::ModuleHomomorphism{T}) where T <: RingElement\n\nReturn a pair K, g consisting of the kernel object K of the given module homomorphism f (as a submodule of its domain) and the canonical injection from the kernel into the domain of f\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"Examples","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"julia> M = FreeModule(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> m = M([ZZ(1), ZZ(2), ZZ(3)])\n(1, 2, 3)\n\njulia> S, f = sub(M, [m])\n(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 3 over integers)\n\njulia> Q, g = quo(M, S)\n(Quotient module over Integers with 2 generators and no relations, Hom: Free module of rank 3 over integers -> Quotient module over Integers with 2 generators and no relations)\n\njulia> kernel(g)\n(Submodule over Integers with 1 generator and no relations, Hom: Submodule over Integers with 1 generator and no relations -> Free module of rank 3 over integers)\n","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Images","page":"Module Homomorphisms","title":"Images","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"image(::Map(FPModuleHomomorphism))","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#image-Tuple{Map{D, C, <:AbstractAlgebra.FPModuleHomomorphism, T} where {D, C, T}}","page":"Module Homomorphisms","title":"image","text":"image(f::Map(FPModuleHomomorphism))\n\nReturn a pair I, g consisting of the image object I of the given module homomorphism f (as a submodule of its codomain) and the canonical injection from the image into the codomain of f\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"M = FreeModule(ZZ, 3)\n\nm = M([ZZ(1), ZZ(2), ZZ(3)])\n\nS, f = sub(M, [m])\nQ, g = quo(M, S)\nK, k = kernel(g)\n\nimage(compose(k, g))","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Preimages","page":"Module Homomorphisms","title":"Preimages","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"preimage(::Map(FPModuleHomomorphism), ::FPModuleElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#preimage-Union{Tuple{T}, Tuple{Map{D, C, <:AbstractAlgebra.FPModuleHomomorphism, T} where {D, C, T}, AbstractAlgebra.FPModuleElem{T}}} where T<:RingElement","page":"Module Homomorphisms","title":"preimage","text":"preimage(f::Map(FPModuleHomomorphism),\n v::FPModuleElem{T}) where T <: RingElement\n\nReturn a preimage of v under the homomorphism f, i.e. an element of the domain of f that maps to v under f. Note that this has no special mathematical properties. It is an element of the set theoretical preimage of the map f as a map of sets, if one exists. The preimage is neither unique nor chosen in a canonical way in general. When no such element exists, an exception is raised.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"M = FreeModule(ZZ, 3)\n\nm = M([ZZ(1), ZZ(2), ZZ(3)])\n\nS, f = sub(M, [m])\nQ, g = quo(M, S)\n\nm = rand(M, -10:10)\nn = g(m)\n\np = preimage(g, n)","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#Inverses","page":"Module Homomorphisms","title":"Inverses","text":"","category":"section"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"Module isomorphisms can be cheaply inverted.","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"Base.inv(::Map(Generic.ModuleIsomorphism))","category":"page"},{"location":"AbstractAlgebra/module_homomorphism/#inv-Tuple{Map{AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModule{T}, AbstractAlgebra.FPModuleHomomorphism, AbstractAlgebra.Generic.ModuleIsomorphism} where T<:RingElement}","page":"Module Homomorphisms","title":"inv","text":"Base.inv(f::Map(ModuleIsomorphism))\n\nReturn the inverse map of the given module isomorphism. This is computed cheaply.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/module_homomorphism/","page":"Module Homomorphisms","title":"Module Homomorphisms","text":"M = FreeModule(ZZ, 2)\nN = matrix(ZZ, 2, 2, BigInt[1, 0, 0, 1])\nf = ModuleIsomorphism(M, M, N)\n\ng = inv(f)","category":"page"},{"location":"AbstractAlgebra/constructors/#Constructing-mathematical-objects-in-AbstractAlgebra.jl","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/constructors/#Constructing-objects-in-Julia","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing objects in Julia","text":"","category":"section"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"In Julia, one constructs objects of a given type by calling a type constructor. This is simply a function with the same name as the type itself. For example, to construct a BigInt object from an Int in Julia, we simply call the BigInt constructor:","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"n = BigInt(123)","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"Note that a number literal too big to fit in an Int or Int128 automatically creates a BigInt:","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"julia> typeof(12345678765456787654567890987654567898765678909876567890)\nBigInt","category":"page"},{"location":"AbstractAlgebra/constructors/#How-we-construct-objects-in-AbstractAlgebra.jl","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"How we construct objects in AbstractAlgebra.jl","text":"","category":"section"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"As we explain in Elements and parents, Julia types don't contain enough information to properly model groups, rings, fields, etc. Instead of using types to construct objects, we use special objects that we refer to as parent objects. They behave a lot like Julia types.","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"Consider the following simple example, to create a multiprecision integer:","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"n = ZZ(12345678765456787654567890987654567898765678909876567890)","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"Here ZZ is not a Julia type, but a callable object. However, for most purposes one can think of such a parent object as though it were a type.","category":"page"},{"location":"AbstractAlgebra/constructors/#Constructing-parent-objects","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing parent objects","text":"","category":"section"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"For more complicated groups, rings, fields, etc., one first needs to construct the parent object before one can use it to construct element objects.","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"AbstractAlgebra.jl provides a set of functions for constructing such parent objects. For example, to create a parent object for univariate polynomials over the integers, we use the polynomial_ring parent object constructor.","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"R, x = polynomial_ring(ZZ, \"x\")\nf = x^3 + 3x + 1\ng = R(12)","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"In this example, R is the parent object and we use it to convert the Int value 12 to an element of the polynomial ring mathbbZx.","category":"page"},{"location":"AbstractAlgebra/constructors/#List-of-parent-object-constructors","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"List of parent object constructors","text":"","category":"section"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"For convenience, we provide a list of all the parent object constructors in AbstractAlgebra.jl and explain what mathematical domains they represent.","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"Mathematics AbstractAlgebra.jl constructor\nR = mathbbZ R = ZZ\nR = mathbbQ R = QQ\nR = mathbbF_p R = GF(p)\nR = mathbbZnmathbbZ R = residue_ring(ZZ, n)\nS = Rx S, x = polynomial_ring(R, \"x\")\nS = Rx y S, (x, y) = polynomial_ring(R, [\"x\", \"y\"])\nS = Rx (to precision n) S, x = power_series_ring(R, n, \"x\")\nS = R((x)) (to precision n) S, x = laurent_series_ring(R, n, \"x\")\nS = K((x)) (to precision n) S, x = laurent_series_field(K, n, \"x\")\nS = mathrmFrac_R S = fraction_field(R)\nS = R(f) S = residue_ring(R, f)\nS = R(f) (with (f) maximal) S = residue_field(R, f)\nS = mathrmMat_mtimes n(R) S = matrix_space(R, m, n)\nS = mathbbQx(f) S, a = number_field(f, \"a\")","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/FTheoryTools/literature/#Literature-constructions","page":"Literature constructions","title":"Literature constructions","text":"","category":"section"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"Certain models have been studied in the physics literature over and over again. Thereby, these constructions became famous and some were given special names. We aim to provide support for such standard constructions. An example of such a model is the following:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"su5_tate_model_over_arbitrary_3d_base()","category":"page"},{"location":"Experimental/FTheoryTools/literature/#su5_tate_model_over_arbitrary_3d_base-Tuple{}","page":"Literature constructions","title":"su5_tate_model_over_arbitrary_3d_base","text":"su5_tate_model_over_arbitrary_3d_base()\n\nReturn the SU(5) Tate model over an arbitrary 3-dimensional base space. For more details see e.g. Timo Weigand (2018) and references therein.\n\njulia> tm = su5_tate_model_over_arbitrary_3d_base()\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base\n\njulia> v = underlying_toric_variety(ambient_space(tm))\nNormal toric variety\n\njulia> a10,a21,a32,a43,a65,w,x,y,z = gens(cox_ring(v));\n\njulia> I = ideal([x,y,w]);\n\njulia> v2 = domain(blow_up(v,I))\nNormal toric variety\n\njulia> cox_ring(v2)\nMultivariate polynomial ring in 10 variables over QQ graded by \n a10 -> [1 0 0 0]\n a21 -> [0 1 0 0]\n a32 -> [-1 2 0 0]\n a43 -> [-2 3 0 0]\n a65 -> [-4 5 0 0]\n w -> [0 0 1 0]\n x -> [0 1 1 2]\n y -> [1 1 1 3]\n z -> [0 0 0 1]\n e -> [2 -1 -1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"More generally, we support literature constructions.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"literature_model(; doi::String=\"\", arxiv_id::String=\"\", version::String=\"\", equation::String=\"\")","category":"page"},{"location":"Experimental/FTheoryTools/literature/#literature_model-Tuple{}","page":"Literature constructions","title":"literature_model","text":"literature_model(; doi::String=\"\", arxiv_id::String=\"\", version=\"\", equation::String=\"\")\n\nMany models have been created in the F-theory literature. A significant number of them have even been given specific names, for instance the \"U(1)-restricted SU(5)-GUT model\". This method has access to a database, from which it can look up such literature models.\n\nCurrently, you can provide any combination of the following optional arguments to the method literature_model:\n\ndoi: A string representing the DOI of the publication that\n\nintroduced the model in question.\n\nequation: A string representing the number of the equation that introduced\n\nthe model in question. For papers, that were posted on the arXiv, we can instead of the doi also provide the following:\n\narxiv_id: A string that represents the arXiv identifier of the paper that\n\nintroduced the model in question.\n\nversion: A string representing the version of the arXiv upload.\n\nThe method literature_model attempts to find a model in our database for which the provided data matches the information in our record. If no such model can be found, or multiple models exist with information matching the provided information, then an error is raised.\n\nSome literature models require additional parameters to specified to single out a model from a family of models. Such models can be provided using the optional argument model_parameters, which should be a dictionary such as Dict(\"k\" => 5).\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> v = ambient_space(t)\nScheme of a toric variety\n\njulia> a1,a21,a32,a43,w,x,y,z = gens(cox_ring(v));\n\njulia> I = ideal([x,y,w]);\n\njulia> v2 = domain(blow_up(underlying_toric_variety(v),I))\nNormal toric variety\n\njulia> cox_ring(v2)\nMultivariate polynomial ring in 9 variables over QQ graded by\n a1 -> [1 0 0 0]\n a21 -> [0 1 0 0]\n a32 -> [-1 2 0 0]\n a43 -> [-2 3 0 0]\n w -> [0 0 1 0]\n x -> [0 1 1 2]\n y -> [1 1 1 3]\n z -> [0 0 0 1]\n e -> [2 -1 -1 0]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#Attributes","page":"Literature constructions","title":"Attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"For literature models, we provide the following attributes:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"arxiv_id(m::AbstractFTheoryModel)\narxiv_doi(m::AbstractFTheoryModel)\narxiv_link(m::AbstractFTheoryModel)\narxiv_model_equation_number(m::AbstractFTheoryModel)\narxiv_model_page(m::AbstractFTheoryModel)\narxiv_model_section(m::AbstractFTheoryModel)\narxiv_version(m::AbstractFTheoryModel)\nassociated_literature_models(m::AbstractFTheoryModel)\ngenerating_sections(m::AbstractFTheoryModel)\njournal_doi(m::AbstractFTheoryModel)\njournal_link(m::AbstractFTheoryModel)\njournal_model_equation_number(m::AbstractFTheoryModel)\njournal_model_page(m::AbstractFTheoryModel)\njournal_model_section(m::AbstractFTheoryModel)\njournal_pages(m::AbstractFTheoryModel)\njournal_report_numbers(m::AbstractFTheoryModel)\njournal_volume(m::AbstractFTheoryModel)\njournal_year(m::AbstractFTheoryModel)\nliterature_identifier(m::AbstractFTheoryModel)\nmodel_description(m::AbstractFTheoryModel)\nmodel_parameters(m::AbstractFTheoryModel)\npaper_authors(m::AbstractFTheoryModel)\npaper_buzzwords(m::AbstractFTheoryModel)\npaper_description(m::AbstractFTheoryModel)\npaper_title(m::AbstractFTheoryModel)\nrelated_literature_models(m::AbstractFTheoryModel)\nresolutions(m::AbstractFTheoryModel)\nresolution_generating_sections(m::AbstractFTheoryModel)\nresolution_zero_sections(m::AbstractFTheoryModel)\nweighted_resolutions(m::AbstractFTheoryModel)\nweighted_resolution_generating_sections(m::AbstractFTheoryModel)\nweighted_resolution_zero_sections(m::AbstractFTheoryModel)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#arxiv_id-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"arxiv_id","text":"arxiv_id(m::AbstractFTheoryModel)\n\nReturn the arxiv_id of the preprint that introduced the given model. If no arxiv_id is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> arxiv_id(m)\n\"1109.3454\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#arxiv_doi-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"arxiv_doi","text":"arxiv_doi(m::AbstractFTheoryModel)\n\nReturn the arxiv_doi of the preprint that introduced the given model. If no arxiv_doi is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> arxiv_doi(m)\n\"10.48550/arXiv.1109.3454\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#arxiv_link-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"arxiv_link","text":"arxiv_link(m::AbstractFTheoryModel)\n\nReturn the arxiv_link (formatted as string) to the arXiv version of the paper that introduced the given model. If no arxiv_link is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> arxiv_link(m)\n\"https://arxiv.org/abs/1109.3454v2\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#arxiv_model_equation_number-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"arxiv_model_equation_number","text":"arxiv_model_equation_number(m::AbstractFTheoryModel)\n\nReturn the arxiv_model_equation_number in which the given model was introduced in the arXiv preprint in our record. If no arxiv_model_equation_number is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> arxiv_model_equation_number(m)\n\"3.1\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#arxiv_model_page-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"arxiv_model_page","text":"arxiv_model_page(m::AbstractFTheoryModel)\n\nReturn the arxiv_model_page on which the given model was introduced in the arXiv preprint in our record. If no arxiv_model_page is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> arxiv_model_page(m)\n\"10\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#arxiv_model_section-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"arxiv_model_section","text":"arxiv_model_section(m::AbstractFTheoryModel)\n\nReturn the arxiv_model_section in which the given model was introduced in the arXiv preprint in our record. If no arxiv_model_section is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> arxiv_model_section(m)\n\"3\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#arxiv_version-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"arxiv_version","text":"arxiv_version(m::AbstractFTheoryModel)\n\nReturn the arxiv_version of the arXiv preprint that introduced the given model. If no arxiv_version is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> arxiv_version(m)\n\"2\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#associated_literature_models-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"associated_literature_models","text":"associated_literature_models(m::AbstractFTheoryModel)\n\nReturn a list of the unique identifiers any associated_literature_models of the given model. These are either other presentations (Weierstrass, Tate, ...) of the given model, or other version of the same model from a different paper in the literature. If no associated_literature_models are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1507.05954\", equation = \"A.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base -- U(1)xU(1) Weierstrass model based on arXiv paper 1507.05954 Eq. (A.1)\n\njulia> associated_literature_models(m)\n1-element Vector{String}:\n \"1507_05954-1\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#generating_sections-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"generating_sections","text":"generating_sections(m::AbstractFTheoryModel)\n\nReturn a list of the known Mordell–Weil generating sections of the given model. If no generating sections are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> generating_sections(m)\n1-element Vector{Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n [0, 0, 1]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_doi-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_doi","text":"journal_doi(m::AbstractFTheoryModel)\n\nReturn the journal_doi of the publication that introduced the given model. If no journal_doi is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_doi(m)\n\"10.1016/j.nuclphysb.2011.12.013\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_link-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_link","text":"journal_link(m::AbstractFTheoryModel)\n\nReturn the journal_link (formatted as string) to the published version of the paper that introduced the given model. If no journal_link is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_link(m)\n\"https://www.sciencedirect.com/science/article/pii/S0550321311007115\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_model_equation_number-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_model_equation_number","text":"journal_model_equation_number(m::AbstractFTheoryModel)\n\nReturn the journal_model_equation_number in which the given model was introduced in the published paper in our record. If no journal_model_equation_number is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_model_equation_number(m)\n\"3.1\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_model_page-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_model_page","text":"journal_model_page(m::AbstractFTheoryModel)\n\nReturn the journal_model_page on which the given model was introduced in the published paper in our record. If no journal_model_page is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_model_page(m)\n\"9\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_model_section-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_model_section","text":"journal_model_section(m::AbstractFTheoryModel)\n\nReturn the journal_model_section in which the given model was introduced in the published paper in our record. If no journal_model_section is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_model_section(m)\n\"3\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_pages-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_pages","text":"journal_pages(m::AbstractFTheoryModel)\n\nReturn the journal_pages of the published paper in which the given model was introduced. If no journal_pages are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_pages(m)\n\"1–47\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_report_numbers-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_report_numbers","text":"journal_report_numbers(m::AbstractFTheoryModel)\n\nReturn the journal_report_numbers of the published paper in which the given model was introduced. If no journal_report_numbers is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1507.05954\", equation = \"A.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base -- U(1)xU(1) Weierstrass model based on arXiv paper 1507.05954 Eq. (A.1)\n\njulia> journal_report_numbers(m)\n3-element Vector{String}:\n \"UPR-1274-T\"\n \"CERN-PH-TH-2015-157\"\n \"MIT-CTP-4678\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_volume-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_volume","text":"journal_volume(m::AbstractFTheoryModel)\n\nReturn the journal_volume of the published paper in which the given model was introduced. If no journal_volume are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_volume(m)\n\"858\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_year-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_year","text":"journal_year(m::AbstractFTheoryModel)\n\nReturn the journal_year of the published paper in which the given model was introduced. If no journal_year is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> journal_year(m)\n\"2012\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#literature_identifier-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"literature_identifier","text":"literature_identifier(m::AbstractFTheoryModel)\n\nReturn the literature_identifier of the given mode, which is a unique string that distinguishes the model from all others in the literature model database. If no literature_identifier is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> literature_identifier(m)\n\"1109_3454\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#model_description-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"model_description","text":"model_description(m::AbstractFTheoryModel)\n\nReturn the model_description of the given model. If no model_description is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> model_description(m)\n\"SU(5)xU(1) restricted Tate model\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#model_parameters-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"model_parameters","text":"model_parameters(m::AbstractFTheoryModel)\n\nReturn the model_parameters of the given model. If no model_parameters are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1212.2949\", equation = \"3.2\", model_parameters = Dict(\"k\" => 5))\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(2k+1) Tate model with parameter values (k = 5) based on arXiv paper 1212.2949 Eq. (3.2)\n\njulia> model_parameters(m)\nDict{String, Int64} with 1 entry:\n \"k\" => 5\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#paper_authors-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"paper_authors","text":"paper_authors(m::AbstractFTheoryModel)\n\nReturn the paper_authors of the paper that introduced the given model. If no paper_authors are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> paper_authors(m)\n3-element Vector{String}:\n \"Sven Krause\"\n \"Christoph Mayrhofer\"\n \"Timo Weigand\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#paper_buzzwords-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"paper_buzzwords","text":"paper_buzzwords(m::AbstractFTheoryModel)\n\nReturn the paper_buzzwords of the paper that introduced the given model. If no paper_buzzwords are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> paper_buzzwords(m)\n4-element Vector{String}:\n \"GUT model\"\n \"Tate\"\n \"U(1)\"\n \"SU(5)\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#paper_description-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"paper_description","text":"paper_description(m::AbstractFTheoryModel)\n\nReturn the paper_description of the paper that introduced the given model. If no paper_description is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> paper_description(m)\n\"SU(5)xU(1) restricted Tate model\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#paper_title-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"paper_title","text":"paper_title(m::AbstractFTheoryModel)\n\nReturn the paper_title of the arXiv preprint that introduced the given model. If no paper_title is known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> paper_title(m)\n\"\\$G_4\\$ flux, chiral matter and singularity resolution in F-theory compactifications\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#related_literature_models-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"related_literature_models","text":"related_literature_models(m::AbstractFTheoryModel)\n\nReturn a list of the unique identifiers of any related_literature_models of the given model. These are models that are introduced in the same paper as the given model, but that are distinct from the given model. If no related_literature_models are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1212.2949\", equation = \"3.2\", model_parameters = Dict(\"k\" => 5))\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(2k+1) Tate model with parameter values (k = 5) based on arXiv paper 1212.2949 Eq. (3.2)\n\njulia> related_literature_models(m)\n6-element Vector{String}:\n \"1212_2949-2\"\n \"1212_2949-3\"\n \"1212_2949-4\"\n \"1212_2949-5\"\n \"1212_2949-6\"\n \"1212_2949-7\"\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#resolutions-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"resolutions","text":"resolutions(m::AbstractFTheoryModel)\n\nReturn the list of all known resolutions for the given model. If no resolutions are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> resolutions(m)\n1-element Vector{Vector{Vector}}:\n [[[\"x\", \"y\", \"w\"], [\"y\", \"e1\"], [\"x\", \"e4\"], [\"y\", \"e2\"], [\"x\", \"y\"]], [\"e1\", \"e4\", \"e2\", \"e3\", \"s\"]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#resolution_generating_sections-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"resolution_generating_sections","text":"resolution_generating_sections(m::AbstractFTheoryModel)\n\nReturn a list of lists of known Mordell–Weil generating sections for the given model after each known resolution. Each element of the outer list corresponds to a known resolution (in the same order), and each element of the list associated to a given resolution corresponds to a known generating section (in the same order). If no resolution generating sections are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> resolution_generating_sections(m)\n1-element Vector{Vector{Vector{Vector{String}}}}:\n [[[\"0\", \"0\", \"1\"], [\"0\", \"0\", \"1\"], [\"0\", \"1\"], [\"0\", \"1\"], [\"0\", \"1\"], [\"a32\", \"-a43\"]]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#resolution_zero_sections-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"resolution_zero_sections","text":"resolution_zero_sections(m::AbstractFTheoryModel)\n\nReturn a list of known Mordell–Weil zero sections for the given model after each known resolution. Each element of the list corresponds to a known resolution (in the same order). If no resolution zero sections are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> resolution_zero_sections(m)\n1-element Vector{Vector{Vector{String}}}:\n [[\"1\", \"1\", \"0\"], [\"1\", \"1\", \"w\"], [\"1\", \"1\"], [\"1\", \"1\"], [\"1\", \"1\"], [\"1\", \"1\"]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#weighted_resolutions-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"weighted_resolutions","text":"weighted_resolutions(m::AbstractFTheoryModel)\n\nReturn the list of all known weighted resolutions for the given model. If no weighted resolutions are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> weighted_resolutions(m)\n1-element Vector{Vector{Vector}}:\n [Vector{Vector{Any}}[[[\"x\", \"y\", \"w\"], [1, 1, 1]], [[\"x\", \"y\", \"w\"], [1, 2, 1]], [[\"x\", \"y\", \"w\"], [2, 2, 1]], [[\"x\", \"y\", \"w\"], [2, 3, 1]], [[\"x\", \"y\"], [1, 1]]], [\"e1\", \"e4\", \"e2\", \"e3\", \"s\"]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#weighted_resolution_generating_sections-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"weighted_resolution_generating_sections","text":"weighted_resolution_generating_sections(m::AbstractFTheoryModel)\n\nReturn a list of lists of known Mordell–Weil generating sections for the given model after each known weighted resolution. Each element of the outer list corresponds to a known weighted resolution (in the same order), and each element of the list associated to a given weighted resolution corresponds to a known generating section (in the same order). If no weighted resolution generating sections are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> weighted_resolution_generating_sections(m)\n1-element Vector{Vector{Vector{Vector{String}}}}:\n [[[\"0\", \"0\", \"1\"], [\"0\", \"0\", \"1\"], [\"0\", \"0\", \"1\"], [\"0\", \"0\", \"1\"], [\"0\", \"0\", \"1\"], [\"a32\", \"-a43\"]]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#weighted_resolution_zero_sections-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"weighted_resolution_zero_sections","text":"weighted_resolution_zero_sections(m::AbstractFTheoryModel)\n\nReturn a list of known Mordell–Weil zero sections for the given model after each known weighted resolution. Each element of the list corresponds to a known weighted resolution (in the same order). If no weighted resolution zero sections are known, an error is raised.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> weighted_resolution_zero_sections(m)\n1-element Vector{Vector{Vector{String}}}:\n [[\"1\", \"1\", \"0\"], [\"1\", \"1\", \"w\"], [\"1\", \"1\", \"w\"], [\"1\", \"1\", \"w\"], [\"1\", \"1\", \"w\"], [\"1\", \"1\"]]\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"One can add this information for a model that does not have it:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"set_description(m::AbstractFTheoryModel, description::String)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#set_description-Tuple{AbstractFTheoryModel, String}","page":"Literature constructions","title":"set_description","text":"set_description(m::AbstractFTheoryModel, description::String)\n\nSet a description for a model.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> set_description(m, \"An SU(5)xU(1) GUT-model\")\n\njulia> m\nGlobal Tate model over a not fully specified base -- An SU(5)xU(1) GUT-model based on arXiv paper 1109.3454 Eq. (3.1)\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"Note however, that these changes will (currently) not be stored in our data base. One can also check if a model has a particular set of information. This is achieved with the following methods:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"has_arxiv_id(m::AbstractFTheoryModel),\nhas_arxiv_doi(m::AbstractFTheoryModel),\nhas_arxiv_link(m::AbstractFTheoryModel),\nhas_arxiv_model_equation_number(m::AbstractFTheoryModel),\nhas_arxiv_model_page(m::AbstractFTheoryModel),\nhas_arxiv_model_section(m::AbstractFTheoryModel),\nhas_arxiv_version(m::AbstractFTheoryModel),\nhas_associated_literature_models(m::AbstractFTheoryModel),\nhas_generating_sections(m::AbstractFTheoryModel),\nhas_journal_doi(m::AbstractFTheoryModel),\nhas_journal_link(m::AbstractFTheoryModel),\nhas_journal_model_equation_number(m::AbstractFTheoryModel),\nhas_journal_model_page(m::AbstractFTheoryModel),\nhas_journal_model_section(m::AbstractFTheoryModel),\nhas_journal_pages(m::AbstractFTheoryModel),\nhas_journal_report_numbers(m::AbstractFTheoryModel),\nhas_journal_volume(m::AbstractFTheoryModel),\nhas_journal_year(m::AbstractFTheoryModel),\nhas_literature_identifier(m::AbstractFTheoryModel),\nhas_model_description(m::AbstractFTheoryModel),\nhas_model_parameters(m::AbstractFTheoryModel),\nhas_paper_authors(m::AbstractFTheoryModel),\nhas_paper_buzzwords(m::AbstractFTheoryModel),\nhas_paper_description(m::AbstractFTheoryModel),\nhas_paper_title(m::AbstractFTheoryModel),\nhas_related_literature_models(m::AbstractFTheoryModel),\nhas_resolutions(m::AbstractFTheoryModel),\nhas_resolution_generating_sections(m::AbstractFTheoryModel),\nhas_resolution_zero_sections(m::AbstractFTheoryModel),\nhas_weighted_resolutions(m::AbstractFTheoryModel),\nhas_weighted_resolution_generating_sections(m::AbstractFTheoryModel),\nhas_weighted_resolution_zero_sections(m::AbstractFTheoryModel),\nhas_zero_section(m::AbstractFTheoryModel).","category":"page"},{"location":"Experimental/FTheoryTools/literature/#Methods","page":"Literature constructions","title":"Methods","text":"","category":"section"},{"location":"Experimental/FTheoryTools/literature/#Resolution(s)-of-a-singular-model","page":"Literature constructions","title":"Resolution(s) of a singular model","text":"","category":"section"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"A central task in F-theory is to resolve a singular model. For literature models, we have stored resolutions in our data base. Upon construction of a literature model, we load these known resolutions.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"In addition to listing the known resolutions with resolutions(m::AbstractFTheoryModel), the user might want to add a resolution. This can be achieved with the following method:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"add_resolution(m::AbstractFTheoryModel, centers::Vector{Vector{String}}, exceptionals::Vector{String})","category":"page"},{"location":"Experimental/FTheoryTools/literature/#add_resolution-Tuple{AbstractFTheoryModel, Vector{Vector{String}}, Vector{String}}","page":"Literature constructions","title":"add_resolution","text":"add_resolution(m::AbstractFTheoryModel, centers::Vector{Vector{String}}, exceptionals::Vector{String})\n\nAdd a known resolution for a model.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> add_resolution(m, [[\"x\", \"y\"], [\"y\", \"s\", \"w\"], [\"s\", \"e4\"], [\"s\", \"e3\"], [\"s\", \"e1\"]], [\"s\", \"w\", \"e3\", \"e1\", \"e2\"])\n\njulia> length(resolutions(m))\n2\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"Provided that a resolution for a model is known, we can (attempt to) resolve the model.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"resolve(m::AbstractFTheoryModel, index::Int)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#resolve-Tuple{AbstractFTheoryModel, Int64}","page":"Literature constructions","title":"resolve","text":"resolve(m::AbstractFTheoryModel, index::Int)\n\nResolve a model with the index-th resolution that is known.\n\nCareful: Currently, this assumes that all blowups are toric blowups. We hope to remove this requirement in the near future.\n\njulia> m = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nGlobal Tate model over a not fully specified base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> v = resolve(m, 1)\nScheme of a toric variety\n\njulia> cox_ring(v)\nMultivariate polynomial ring in 13 variables over QQ graded by \n a1 -> [1 0 0 0 0 0 0 0]\n a21 -> [0 1 0 0 0 0 0 0]\n a32 -> [-1 2 0 0 0 0 0 0]\n a43 -> [-2 3 0 0 0 0 0 0]\n w -> [0 0 1 0 0 0 0 0]\n x -> [0 0 0 1 0 0 0 0]\n y -> [0 0 0 0 1 0 0 0]\n z -> [0 0 0 0 0 1 0 0]\n e1 -> [0 0 0 0 0 0 1 0]\n e4 -> [0 0 0 0 0 0 0 1]\n e2 -> [1 -1 -1 -1 1 -1 -1 0]\n e3 -> [1 0 0 1 -1 1 0 -1]\n s -> [-2 2 2 -1 0 2 1 1]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/group_characters/#Group-characters","page":"Group characters","title":"Group characters","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"Let G be a finite group, and let rho G to GL(n R) be a group homomorphism, for some ring R. We call chi G to R, defined by chi(g) = Trace(rho(g)), the character afforded by rho.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"Since chi is constant on conjugacy classes of G, it can be represented by an array l of values such that the value on the i-th conjugacy class of G (see conjugacy_classes) is stored at li. Note that this makes sense only if we assume that the ordering of conjugacy classes of G is fixed once the classes have been computed.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"We deal only with the cases that either R can be embedded into some number field, or that R is a finite field.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"In the former case, the eigenvalues of the matrix rho(g), for g in G, are k-th roots of unity, where k is the order of g, thus all values of chi can be represented by elements in the abelian closure of the field of rational numbers, see abelian_closure. The characters obtained this way are called ordinary characters.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"In the latter case, the list of traces of rho(g) (the so-called Frobenius character of rho) is often not so interesting; instead, one considers the Brauer character of rho, which is defined on (conjugacy classes of) elements g whose order is coprime to the characteristic of R (the so-called p-regular elements resp. classes), by first lifting the eigenvalues of rho(g) to complex roots of unity and then summing up these roots; this way, one gets again a list of values in the abelian closure of the field of rationals.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"The pointwise sum and product of two characters are again characters, they are afforded by the direct sum and the tensor product of the underlying representations. A character that is not the sum of two characters is called absolutely irreducible.","category":"page"},{"location":"Groups/group_characters/#Character-tables","page":"Group characters","title":"Character tables","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"Putting the values of the absolutely irreducible ordinary characters of a group G into an array such that the rows correspond to the characters and the columns correspond to the conjugacy classes yields the ordinary character table of G, which is in fact a square matrix. Analogously, the absolutely irreducible Brauer characters of G, for a given characteristic p, yield a square matrix, the p-modular Brauer character table.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"Ordinary character tables can be computed with character_table from a given group. The computation of p-modular Brauer tables is currently restricted to the case of p-solvable groups.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"Character tables contain a lot of information about their groups, many questions about a finite group can be answered by computations only with its characters. Thus it makes sense to deal also with character tables without an explicit labeling of the columns of the table by conjugacy classes of a group. For example, the character tables shown in Atlas of Finite Groups J. H. Conway, R. T. Curtis, S. P. Norton, R. A. Parker, R. A. Wilson (1985) and from the Atlas of Brauer Characters C. Jansen, K. Lux, R. Parker, R. Wilson (1995) are available in OSCAR. Such character tables can be fetched with character_table from the database, via their names.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"In OSCAR, a character table t is identified with the array of absolutely irreducible characters of G, in the sense that t[i] yields the i-th irreducible character of G, and t[i, j] is the value of this character on the j-th conjugacy class of G (or the j-th conjugacy class of p-regular elements in the case of Brauer tables).","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"Ordinary and p-modular Brauer tables in OSCAR are distinguished by their characteristic(tbl::GAPGroupCharacterTable); its value is 0 for ordinary tables and p otherwise.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"GAPGroupCharacterTable\ncharacter_table\nBase.show(io::IO, ::MIME\"text/plain\", tbl::GAPGroupCharacterTable)\ncharacteristic(tbl::GAPGroupCharacterTable)\nBase.mod(tbl::GAPGroupCharacterTable, p::Int)\nall_character_table_names","category":"page"},{"location":"Groups/group_characters/#GAPGroupCharacterTable","page":"Group characters","title":"GAPGroupCharacterTable","text":"GAPGroupCharacterTable <: GroupCharacterTable\n\nThis is the type of (ordinary or Brauer) character tables that can delegate tasks to an underlying character table object in the GAP system (field GAPTable).\n\nThe value of the field characteristic determines whether the table is an ordinary one (value 0) or a p-modular one (value p).\n\nA group can (but need not) be stored in the field group. If it is available then also the field isomorphism is available, its value is a bijective map from the group value to a group in GAP.\n\nObjects of type GAPGroupCharacterTable support get_attribute, for example in order to store the already computed p-modular tables in an ordinary table, and to store the corresponding ordinary table in a p-modular table.\n\n\n\n\n\n","category":"type"},{"location":"Groups/group_characters/#character_table","page":"Group characters","title":"character_table","text":"character_table(G::GAPGroup, p::T = 0) where T <: IntegerUnion\n\nReturn the ordinary (if p == 0) or p-modular character table of the finite group G. If the p-modular character table of G cannot be computed by GAP then nothing is returned.\n\nExamples\n\njulia> Oscar.with_unicode() do\n show(stdout, MIME(\"text/plain\"), character_table(symmetric_group(3)))\n end;\nSym( [ 1 .. 3 ] )\n\n 2 1 1 .\n 3 1 . 1\n \n 1a 2a 3a\n2P 1a 1a 3a\n3P 1a 2a 1a\n \nχ₁ 1 -1 1\nχ₂ 2 . -1\nχ₃ 1 1 1\n\njulia> Oscar.with_unicode() do\n show(stdout, MIME(\"text/plain\"), character_table(symmetric_group(3), 2))\n end;\nSym( [ 1 .. 3 ] ) mod 2\n\n 2 1 .\n 3 1 1\n \n 1a 3a\n2P 1a 3a\n3P 1a 1a\n \nχ₁ 1 1\nχ₂ 2 -1\n\n\n\n\n\ncharacter_table(id::String, p::Int = 0)\n\nReturn the ordinary (if p == 0) or p-modular character table for which id is an admissible name in GAP's library of character tables. If no such table is available then nothing is returned.\n\nExamples\n\njulia> println(character_table(\"A5\"))\ncharacter table of A5\n\njulia> println(character_table(\"A5\", 2))\n2-modular Brauer table of A5\n\njulia> println(character_table(\"J5\"))\nnothing\n\n\n\n\n\ncharacter_table(series::Symbol, parameter::Any)\n\nReturn the ordinary character table of the group described by the series series and the parameter parameter.\n\nExamples\n\njulia> println(character_table(:Symmetric, 5))\ncharacter table of Sym(5)\n\njulia> println(character_table(:WeylB, 3))\ncharacter table of W(B3)\n\nCurrently the following series are supported.\n\nSeries Parameter\n:Cyclic pos. integer\n:Dihedral even pos. integer\n:Symmetric pos. integer\n:Alternating integer > 1\n:WeylB pos. integer\n:WeylD integer > 1\n:DoubleCoverSymmetric pos. integer\n:DoubleCoverAlternating pos. integer\n:GL2 prime power\n:SL2odd odd prime power\n:SL2even even prime power\n:PSL2odd odd prime power q s. t. (q-1)/2 is odd\n:PSL2even odd prime power q s. t. (q-1)/2 is even\n:Suzuki odd power of 2\n:GU3 prime power\n:SU3 prime power\nSymbol(\"P:Q\") array [p, q] with prime p and q dividing p-1\n:ExtraspecialPlusOdd odd power of odd prime\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#show-Tuple{IO, MIME{Symbol(\"text/plain\")}, Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"show","text":"Base.show(io::IO, ::MIME\"text/plain\", tbl::GAPGroupCharacterTable)\n\nDisplay the irreducible characters of tbl and context information as a two-dimensional array.\n\nFirst a header is shown. If tbl stores a group then the header describes this group, otherwise it is equal to the identifier(tbl::GAPGroupCharacterTable) value of tbl.\nThen the irreducible characters of tbl are shown in column portions that fit on the screen, together with column labels above each portion and row labels on the left of each portion.\nThe column labels consist of the factored centralizer orders (see orders_centralizers, one row for each prime divisor of the group order), followed by one row showing the class names (see class_names), followed by the power maps (one row for each stored power map).\nThe row labels are X_1, X_2, ... (or χ with subscripts 1, 2, ... if unicode output is allowed). If io is an IOContext with key :indicator set to true then a second column of row labels shows the 2nd Frobenius-Schur indicator of the irreducibles (see indicator); analogously, setting the key :character_field to true yields a column showing the degrees of the character fields (see character_field), and setting the key :OD to true yields a column showing the known orthogonal discriminants of those irreducibles that have indicator + and even degree.\nDepending on the way how irrational character values are shown, a footer may be shown in the end. By default, irrationalities are shown as sums of roots of unity, where z_n (or ζ with subscript n if unicode output is allowed) denotes the primitive n-th root exp(2 pi in). If io is an IOContext with key :with_legend set to true then irrationalities are abbreviated as A, B, ..., and these names together with the corresponding expression as sums of roots of unity appear in the footer.\n\nOutput in LaTeX syntax can be created by calling show with second argument MIME(\"text/latex\").\n\nExamples\n\njulia> tbl = character_table(:Cyclic, 3);\n\njulia> Oscar.with_unicode() do\n show(stdout, MIME(\"text/plain\"), tbl)\n end;\nC3\n\n 3 1 1 1\n \n 1a 3a 3b\n3P 1a 1a 1a\n \nχ₁ 1 1 1\nχ₂ 1 ζ₃ -ζ₃ - 1\nχ₃ 1 -ζ₃ - 1 ζ₃\n\njulia> Oscar.with_unicode() do\n show(IOContext(stdout, :with_legend => true), MIME(\"text/plain\"), tbl)\n end;\nC3\n\n 3 1 1 1\n \n 1a 3a 3b\n3P 1a 1a 1a\n \nχ₁ 1 1 1\nχ₂ 1 A A̅\nχ₃ 1 A̅ A\n\nA = ζ₃\nA̅ = -ζ₃ - 1\n\njulia> Oscar.with_unicode() do\n show(IOContext(stdout, :indicator => true), MIME(\"text/plain\"), tbl)\n end;\nC3\n\n 3 1 1 1\n \n 1a 3a 3b\n 3P 1a 1a 1a\n 2 \nχ₁ + 1 1 1\nχ₂ o 1 ζ₃ -ζ₃ - 1\nχ₃ o 1 -ζ₃ - 1 ζ₃\n\njulia> Oscar.with_unicode() do\n show(IOContext(stdout, :character_field => true), MIME(\"text/plain\"), tbl)\n end;\nC3\n\n 3 1 1 1\n \n 1a 3a 3b\n 2P 1a 3b 3a\n 3P 1a 1a 1a\n d \nχ₁ 1 1 1 1\nχ₂ 2 1 ζ₃ -ζ₃ - 1\nχ₃ 2 1 -ζ₃ - 1 ζ₃\n\njulia> Oscar.with_unicode() do\n show(IOContext(stdout, :with_legend => true), MIME(\"text/latex\"), tbl)\n end;\n$C3\n\n\\begin{array}{rrrr}\n3 & 1 & 1 & 1 \\\\\n & & & \\\\\n & 1a & 3a & 3b \\\\\n2P & 1a & 3b & 3a \\\\\n3P & 1a & 1a & 1a \\\\\n & & & \\\\\n\\chi_{1} & 1 & 1 & 1 \\\\\n\\chi_{2} & 1 & A & \\overline{A} \\\\\n\\chi_{3} & 1 & \\overline{A} & A \\\\\n\\end{array}\n\n\\begin{array}{l}\nA = \\zeta_{3} \\\\\n\\overline{A} = -\\zeta_{3} - 1 \\\\\n\\end{array}\n$\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#characteristic-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"characteristic","text":"characteristic(::Type{T} = Int, tbl::GAPGroupCharacterTable) where T <: IntegerUnion\n\nReturn T(0) if tbl is an ordinary character table, and T(p) if tbl is a p-modular character table.\n\nExamples\n\njulia> tbl = character_table(\"A5\");\n\njulia> characteristic(tbl)\n0\n\njulia> characteristic(tbl % 2)\n2\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#mod-Tuple{Oscar.GAPGroupCharacterTable, Int64}","page":"Group characters","title":"mod","text":"mod(tbl::GAPGroupCharacterTable, p::T) where T <: IntegerUnion\nrem(tbl::GAPGroupCharacterTable, p::T) where T <: IntegerUnion\n\nReturn the p-modular character table of tbl, or nothing if this table cannot be computed.\n\nThe syntax tbl % p is also supported.\n\nAn exception is thrown if tbl is not an ordinary character table.\n\nExamples\n\njulia> show(character_table(\"A5\") % 2)\n2-modular Brauer table of A5\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#all_character_table_names","page":"Group characters","title":"all_character_table_names","text":"all_character_table_names(L...; ordered_by = nothing)\n\nReturn an array of strings that contains all those names of character tables in the character table library that satisfy the conditions in the array L.\n\nExamples\n\njulia> spor_names = all_character_table_names(is_sporadic_simple => true,\n is_duplicate_table => false);\n\njulia> println(spor_names[1:5])\n[\"B\", \"Co1\", \"Co2\", \"Co3\", \"F3+\"]\n\njulia> spor_names = all_character_table_names(is_sporadic_simple,\n !is_duplicate_table; ordered_by = order);\n\njulia> println(spor_names[1:5])\n[\"M11\", \"M12\", \"J1\", \"M22\", \"J2\"]\n\njulia> length(all_character_table_names(number_conjugacy_classes => 1))\n1\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#Attributes-of-group-characters","page":"Group characters","title":"Attributes of group characters","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"character_field\nconj(chi::GAPGroupClassFunction)\nNemo.degree(chi::GAPGroupClassFunction)\nindicator\nis_faithful(chi::GAPGroupClassFunction)\nis_rational(chi::GAPGroupClassFunction)\nis_irreducible(chi::GAPGroupClassFunction)\nschur_index(chi::GAPGroupClassFunction, recurse::Bool = true)\ndet(chi::GAPGroupClassFunction)\norder(chi::GAPGroupClassFunction)\norder_field_of_definition(chi::GAPGroupClassFunction)","category":"page"},{"location":"Groups/group_characters/#character_field","page":"Group characters","title":"character_field","text":"character_field(chi::GAPGroupClassFunction)\n\nIf chi is an ordinary character then return the pair (F, phi) where F is a number field that is generated by the character values of chi, and phi is the embedding of F into abelian_closure(QQ).\n\nIf chi is a Brauer character in characteristic p then return the pair (F, phi) where F is the finite field that is generated by the p-modular reductions of the values of chi, and phi is the identity map on F.\n\nExamples\n\njulia> t = character_table(\"A5\");\n\njulia> character_field(t[2])[1]\nNumber field with defining polynomial x^2 + x - 1\n over rational field\n\njulia> flds_2 = map(character_field, mod(t, 2));\n\njulia> println([degree(x[1]) for x in flds_2])\n[1, 2, 2, 1]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#conj-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"conj","text":"conj(chi::GAPGroupClassFunction)\n\nReturn the class function whose values are the complex conjugates of the values of chi.\n\nExamples\n\njulia> tbl = character_table(alternating_group(4));\n\njulia> println([findfirst(y -> y == conj(x), tbl) for x in tbl])\n[1, 3, 2, 4]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#degree-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"degree","text":"degree(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)\n where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}\n\nReturn chi[1], as an instance of T.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#indicator","page":"Group characters","title":"indicator","text":"indicator(chi::GAPGroupClassFunction, n::Int = 2)\n\nReturn the n-th Frobenius-Schur indicator of chi, that is, the value (_g G chi(g^n))G, where G is the group of chi.\n\nIf chi is irreducible then indicator(chi) is 0 if chi is not real-valued, 1 if chi is afforded by a real representation of G, and -1 if chi is real-valued but not afforded by a real representation of G.\n\nExamples\n\njulia> tbl = character_table(\"U3(3)\");\n\njulia> println([indicator(chi) for chi in tbl])\n[1, -1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#is_faithful-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"is_faithful","text":"is_faithful(chi::GAPGroupClassFunction)\n\nReturn true if the value of chi at the identity element does not occur as value of chi at any other element, and false otherwise.\n\nIf chi is an ordinary character then true is returned if and only if the representations affording chi have trivial kernel.\n\nExamples\n\njulia> println(map(is_faithful, character_table(symmetric_group(3))))\nBool[0, 1, 0]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_rational-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"is_rational","text":"is_rational(chi::GAPGroupClassFunction)\n\nReturn true if all values of chi are rational, i.e., in QQ, and false otherwise.\n\nExamples\n\njulia> all(is_rational, character_table(symmetric_group(4)))\ntrue\n\njulia> all(is_rational, character_table(alternating_group(4)))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_irreducible-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"is_irreducible","text":"is_irreducible(chi::GAPGroupClassFunction)\n\nReturn true if chi is an irreducible character, and false otherwise.\n\nA character is irreducible if it cannot be written as the sum of two characters. For ordinary characters this can be checked using the scalar product of class functions (see scalar_product. For Brauer characters there is no generic method for checking irreducibility.\n\nExamples\n\njulia> g = symmetric_group(4);\n\njulia> all(is_irreducible, character_table(g))\ntrue\n\njulia> is_irreducible(natural_character(g))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#schur_index","page":"Group characters","title":"schur_index","text":"schur_index(chi::GAPGroupClassFunction) -> Int\n\nFor an ordinary irreducible character chi, return the minimal integer m such that the character m * chi is afforded by a representation over the character field of chi, or throw an exception if the currently used character theoretic criteria do not suffice for computing m.\n\nExamples\n\njulia> t = character_table(quaternion_group(8));\n\njulia> println(map(schur_index, t))\n[1, 1, 1, 1, 2]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#det-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"det","text":"det(chi::GAPGroupClassFunction)\n\nReturn the determinant character of the character chi. This is defined to be the character obtained by taking the determinant of representing matrices of any representation affording chi.\n\nExamples\n\njulia> t = character_table(symmetric_group(4));\n\njulia> all(chi -> det(chi) == exterior_power(chi, Int(degree(chi))), t)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#order-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"order","text":"order(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction)\n where T <: IntegerUnion\n\nReturn the determinantal order of the character chi. This is defined to be the multiplicative order of det(chi).\n\nExamples\n\njulia> println([order(chi) for chi in character_table(symmetric_group(4))])\nZZRingElem[2, 1, 2, 2, 1]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#order_field_of_definition-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"order_field_of_definition","text":"order_field_of_definition(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction) where T <: IntegerUnion\n\nReturn p^n, as an instance of T, if chi is a p-modular Brauer character such that the p-modular reductions of the values of chi span the field with p^n elements.\n\nNote that one need not compute the character_field value of chi in order to compute order_field_of_definition(chi).\n\nExamples\n\njulia> tbl = character_table(\"A5\", 2);\n\njulia> println([order_field_of_definition(chi) for chi in tbl])\nZZRingElem[2, 4, 4, 2]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#Attributes-of-character-tables","page":"Group characters","title":"Attributes of character tables","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"character_parameters\nclass_names(tbl::GAPGroupCharacterTable)\nclass_parameters\nconjugacy_classes(tbl::GAPGroupCharacterTable)\ndecomposition_matrix\nidentifier\ninduced_cyclic(tbl::GAPGroupCharacterTable)\nis_duplicate_table\nmaxes\nnames_of_fusion_sources\nclass_lengths\norders_centralizers\norders_class_representatives\nordinary_table(tbl::GAPGroupCharacterTable)\ntrivial_character(tbl::GAPGroupCharacterTable)","category":"page"},{"location":"Groups/group_characters/#character_parameters","page":"Group characters","title":"character_parameters","text":"character_parameters(tbl::GAPGroupCharacterTable)\n\nReturn a vector of character parameters for the rows of tbl if such parameters are stored, and nothing otherwise.\n\nExamples\n\njulia> character_parameters(character_table(\"S5\"))\n7-element Vector{Vector{Int64}}:\n [5]\n [1, 1, 1, 1, 1]\n [3, 1, 1]\n [4, 1]\n [2, 1, 1, 1]\n [3, 2]\n [2, 2, 1]\n\njulia> character_parameters(character_table(\"M11\"))\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#class_names-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"class_names","text":"class_names(tbl::GAPGroupCharacterTable)\n\nReturn a vector of strings corresponding to the columns of tbl. The i-th entry consists of the element order for the i-th column, followed by at least one distinguishing letter. For example, the classes of elements of order two have class names `\"2a\", \"2b\", and so on.\n\nExamples\n\njulia> println(class_names(character_table(\"S5\")))\n[\"1a\", \"2a\", \"3a\", \"5a\", \"2b\", \"4a\", \"6a\"]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#class_parameters","page":"Group characters","title":"class_parameters","text":"class_parameters(tbl::GAPGroupCharacterTable)\n\nReturn a vector of class parameters for the columns of tbl if such parameters are stored, and nothing otherwise.\n\nExamples\n\njulia> class_parameters(character_table(\"S5\"))\n7-element Vector{Vector{Int64}}:\n [1, 1, 1, 1, 1]\n [2, 2, 1]\n [3, 1, 1]\n [5]\n [2, 1, 1, 1]\n [4, 1]\n [3, 2]\n\njulia> class_parameters(character_table(\"M11\"))\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#conjugacy_classes-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"conjugacy_classes","text":"conjugacy_classes(tbl::GAPGroupCharacterTable)\n\nReturn the vector of conjugacy classes of group(tbl), ordered such that they correspond to the columns of tbl and to the GAPWrap.ConjugacyClasses value of the underlying GAP character table. Note that the vector conjugacy_classes(group(tbl)) can be independent of the vector of conjugacy classes stored in the group of the underlying GAP character table.\n\nAn error is thrown if tbl does not store a group.\n\nExamples\n\njulia> g = symmetric_group(4); tbl = character_table(g);\n\njulia> [length(c) for c in conjugacy_classes(tbl)] == class_lengths(tbl)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#decomposition_matrix","page":"Group characters","title":"decomposition_matrix","text":"decomposition_matrix(modtbl::GAPGroupCharacterTable)\n\nReturn the decomposition matrix (of type ZZMatrix) of the Brauer character table modtbl. The rows and columns are indexed by the irreducible characters of the ordinary character table of modtbl and the irreducible characters of modtbl, respectively,\n\nExamples\n\njulia> t = character_table(\"A5\"); t2 = mod(t, 2);\n\njulia> decomposition_matrix(t2)\n[1 0 0 0]\n[1 0 1 0]\n[1 1 0 0]\n[0 0 0 1]\n[1 1 1 0]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#identifier","page":"Group characters","title":"identifier","text":"identifier(tbl::GAPGroupCharacterTable)\n\nReturn a string that identifies tbl. It is used mainly for library tables.\n\nExamples\n\njulia> identifier(character_table(\"A5\"))\n\"A5\"\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#induced_cyclic-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"induced_cyclic","text":"induced_cyclic(tbl::GAPGroupCharacterTable)\n\nReturn the array of permutation characters of tbl that are induced from cyclic subgroups.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_duplicate_table","page":"Group characters","title":"is_duplicate_table","text":"is_duplicate_table(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is an ordinary table from the character table library that was constructed from another library character table by permuting rows and columns.\n\nOne application of this function is to restrict the search with all_character_table_names to only one library character table for each class of permutation equivalent tables.\n\nExamples\n\njulia> is_duplicate_table(character_table(\"A5\"))\nfalse\n\njulia> is_duplicate_table(character_table(\"A6M2\"))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#maxes","page":"Group characters","title":"maxes","text":"maxes(tbl::GAPGroupCharacterTable)\n\nReturn either nothing (if the value is not known) or an array of identifiers of the ordinary character tables of all maximal subgroups of tbl. There is no default method to compute this value from tbl.\n\nIf the maxes value of tbl is stored then it lists exactly one representative for each conjugacy class of maximal subgroups of the group of tbl, and the character tables of these maximal subgroups are available in the character table library, and compatible class fusions to tbl are stored on these tables.\n\nExamples\n\njulia> println(maxes(character_table(\"M11\")))\n[\"A6.2_3\", \"L2(11)\", \"3^2:Q8.2\", \"A5.2\", \"2.S4\"]\n\njulia> maxes(character_table(\"M\")) === nothing # not (yet) known\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#names_of_fusion_sources","page":"Group characters","title":"names_of_fusion_sources","text":"names_of_fusion_sources(tbl::GAPGroupCharacterTable)\n\nReturn the array of strings that are identifiers of those character tables which store a class fusion to tbl, which must be an ordinary character table.\n\nExamples\n\njulia> tbl = character_table(\"A5\");\n\njulia> println(maxes(tbl))\n[\"a4\", \"D10\", \"S3\"]\n\njulia> all(x -> x in names_of_fusion_sources(tbl), maxes(tbl))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#class_lengths","page":"Group characters","title":"class_lengths","text":"class_lengths(tbl::GAPGroupCharacterTable)\n\nExamples\n\njulia> println(class_lengths(character_table(\"A5\")))\nZZRingElem[1, 15, 20, 12, 12]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#orders_centralizers","page":"Group characters","title":"orders_centralizers","text":"orders_centralizers(tbl::GAPGroupCharacterTable)\n\nReturn the array of the orders of centralizers of conjugacy class representatives for tbl in the group of tbl, ordered according to the columns of tbl.\n\nExamples\n\njulia> println(orders_centralizers(character_table(\"A5\")))\nZZRingElem[60, 4, 3, 5, 5]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#orders_class_representatives","page":"Group characters","title":"orders_class_representatives","text":"orders_class_representatives(tbl::GAPGroupCharacterTable)\n\nReturn the array of the orders of conjugacy class representatives for tbl, ordered according to the columns of tbl.\n\nExamples\n\njulia> println(orders_class_representatives(character_table(\"A5\")))\n[1, 2, 3, 5, 5]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#ordinary_table-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"ordinary_table","text":"ordinary_table(tbl::GAPGroupCharacterTable)\n\nReturn the ordinary character table of tbl, provided that tbl is a Brauer character table.\n\nExamples\n\njulia> tbl = character_table(\"A5\");\n\njulia> ordinary_table(tbl % 2) === tbl\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#trivial_character-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"trivial_character","text":"trivial_character(tbl::GAPGroupCharacterTable)\n\nReturn the character of tbl that has the value QQAbElem(1) in each position.\n\nExamples\n\njulia> t = character_table(symmetric_group(4));\n\njulia> all(x -> x == 1, trivial_character(t))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#Construct-group-characters-from-groups","page":"Group characters","title":"Construct group characters from groups","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"natural_character(G::PermGroup)\nnatural_character(G::Union{MatrixGroup{QQFieldElem}, MatrixGroup{nf_elem}})\nnatural_character(G::MatrixGroup{T, MT}) where T <: FinFieldElem where MT\nnatural_character(rho::GAPGroupHomomorphism)\ntrivial_character(G::GAPGroup)","category":"page"},{"location":"Groups/group_characters/#natural_character-Tuple{PermGroup}","page":"Group characters","title":"natural_character","text":"natural_character(G::PermGroup)\n\nReturn the permutation character of degree degree(G) that maps each element of G to the number of its fixed points.\n\nExamples\n\njulia> g = symmetric_group(4);\n\njulia> degree(natural_character(g))\n4\n\njulia> degree(natural_character(stabilizer(g, 4)[1]))\n4\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#natural_character-Tuple{Union{MatrixGroup{QQFieldElem, T} where T<:MatElem{QQFieldElem}, MatrixGroup{nf_elem, T} where T<:MatElem{nf_elem}}}","page":"Group characters","title":"natural_character","text":"natural_character(G::Union{MatrixGroup{QQFieldElem}, MatrixGroup{nf_elem}})\n\nReturn the character that maps each element of G to its trace. We assume that the entries of the elements of G are either of type QQFieldElem or contained in a cyclotomic field.\n\nExamples\n\njulia> g = matrix_group(matrix(ZZ, [0 1; 1 0]));\n\njulia> println(values(natural_character(g)))\nQQAbElem{nf_elem}[2, 0]\n\n\n\n\n\nnatural_character(G::MatrixGroup{FinFieldElem})\n\nReturn the character that maps each p-regular element of G, where p is the characteristic of the base field of G, to its Brauer character value.\n\nExamples\n\njulia> g = general_linear_group(2, 2);\n\njulia> println(values(natural_character(g)))\nQQAbElem{nf_elem}[2, -1]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#natural_character-Union{Tuple{MatrixGroup{T, MT}}, Tuple{T}, Tuple{MT}} where {MT, T<:FinFieldElem}","page":"Group characters","title":"natural_character","text":"natural_character(G::MatrixGroup{FinFieldElem})\n\nReturn the character that maps each p-regular element of G, where p is the characteristic of the base field of G, to its Brauer character value.\n\nExamples\n\njulia> g = general_linear_group(2, 2);\n\njulia> println(values(natural_character(g)))\nQQAbElem{nf_elem}[2, -1]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#natural_character-Tuple{GAPGroupHomomorphism}","page":"Group characters","title":"natural_character","text":"natural_character(rho::GAPGroupHomomorphism)\n\nReturn the character of domain(rho) that is afforded by the representation rho, where codomain(rho) must be a permutation group or a matrix group. In the latter case, an ordinary character is returned if the characteristic of the base field is zero, and a p-modular Brauer character is returned if the characteristic is p 0.\n\nExamples\n\njulia> g = symmetric_group(3); h = general_linear_group(2, 2);\n\njulia> mp = hom(g, h, [g([2,1]), g([1, 3, 2])], gens(h));\n\njulia> println(values(natural_character(mp)))\nQQAbElem{nf_elem}[2, -1]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#trivial_character-Tuple{Oscar.GAPGroup}","page":"Group characters","title":"trivial_character","text":"trivial_character(G::GAPGroup)\n\nReturn the character of (the ordinary character table of) G that has the value QQAbElem(1) in each position.\n\nExamples\n\njulia> g = symmetric_group(4);\n\njulia> all(x -> x == 1, trivial_character(g))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#Operations-for-group-characters","page":"Group characters","title":"Operations for group characters","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"length and iteration:","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"The length of a class function is the number of conjugacy classes of its group, iteration is defined w.r.t. the ordering of conjugacy classes.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"arithmetic operations:","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"chi == psi: two class functions are equal if and only if they belong to the same character table and have the same values,\nchi + psi and chi - psi are the pointwise sum and difference, respectively, of the two class functions chi, psi,\nn*chi is the pointwise n-fold sum of chi, for an integer n,\nchi*psi is the pointwise (tensor) product of chi and psi,\nzero(chi) is the class function that is zero on all classes,\none(chi) is the trivial character of the character table of chi,\nchi^n is the n-th tensor power of chi, for positive integers n,\nchi(g) is the value of chi at the element g of the group of chi,\nchi^g is the conjugate character of chi under the action of a group element g that normalizes the group G of chi; we have chi^g(x) == chi(g*x*g^-1) for all x in G,\nchi^galaut is the Galois conjugate character of chi under the pointwise action of the field automorphism galaut (If galaut was created as QQAbAutomorphism(k) then the action raises each root of unity to its k-th power; this action defines a field automorphism of the n-th cyclotomic field whenever n and k are coprime.)\nchi^tbl is the character of the character table tbl that is induced from chi, where the group of chi is a subgroup of the group of tbl.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"scalar_product\ncoordinates(chi::GAPGroupClassFunction)\nmultiplicities_eigenvalues\ninduce(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable)\nrestrict(chi::GAPGroupClassFunction, subtbl::GAPGroupCharacterTable)","category":"page"},{"location":"Groups/group_characters/#scalar_product","page":"Group characters","title":"scalar_product","text":"scalar_product(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)\n where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}\n\nReturn sum_g in G chi(g) conj(psi)(g) / G, where G is the group of both chi and psi. The result is an instance of T.\n\nNote that we do not support dot(chi, psi) and its infix notation because the documentation of dot states that the result is equal to the sum of dot results of corresponding entries, which does not hold for the scalar product of characters.\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#coordinates-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"coordinates","text":"coordinates(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)\n where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}\n\nReturn the vector a_1 a_2 ldots a_n of scalar products (see scalar_product) of chi with the irreducible characters t1 t2 ldots tn of the character table t of chi, that is, chi is equal to sum_i==1^n a_i ti. The result is an instance of Vector{T}.\n\nExamples\n\njulia> g = symmetric_group(4)\nSym( [ 1 .. 4 ] )\n\njulia> chi = natural_character(g);\n\njulia> coordinates(Int, chi)\n5-element Vector{Int64}:\n 0\n 0\n 0\n 1\n 1\n\njulia> t = chi.table; t3 = mod(t, 3); chi3 = restrict(chi, t3);\n\njulia> coordinates(Int, chi3)\n4-element Vector{Int64}:\n 0\n 1\n 0\n 1\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#multiplicities_eigenvalues","page":"Group characters","title":"multiplicities_eigenvalues","text":"multiplicities_eigenvalues(::Type{T} = Int, chi::GAPGroupClassFunction, i::Int) where T <: IntegerUnion\n\nLet M be a representing matrix of an element in the i-th conjugacy class of the character table of chi, in a representation affording the character chi, and let n be the order of the elements in this conjugacy class.\n\nReturn the vector (m_1 m_2 ldots m_n) of integers of type T such that m_j is the multiplicity of zeta_n^j as an eigenvalue of M.\n\nExamples\n\njulia> t = character_table(\"A5\"); chi = t[4];\n\njulia> println(values(chi))\nQQAbElem{nf_elem}[4, 0, 1, -1, -1]\n\njulia> println(multiplicities_eigenvalues(chi, 5))\n[1, 1, 1, 1, 0]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#induce-Tuple{Oscar.GAPGroupClassFunction, Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"induce","text":"induce(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable[, fusion::Vector{Int}])\n\nReturn the class function of tbl that is induced from chi, which is a class function of a subgroup of the group of tbl. The default for the class fusion fus is given either by the fusion of the conjugacy classes of the two character tables (if groups are stored in the tables) or by the class fusion given by known_class_fusion for the two tables.\n\nExamples\n\njulia> s = character_table(\"A5\"); t = character_table(\"A6\");\n\njulia> maps = possible_class_fusions(s, t); length(maps)\n4\n\njulia> chi = trivial_character(s);\n\njulia> ind = [induce(chi, t, x) for x in maps];\n\njulia> length(Set(ind))\n2\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#restrict-Tuple{Oscar.GAPGroupClassFunction, Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"restrict","text":"restrict(chi::GAPGroupClassFunction, subtbl::GAPGroupCharacterTable[, fusion::Vector{Int}])\n\nReturn the class function of subtbl that is the restriction of chi, which is a class function of a supergroup of the group of subtbl. The default for the class fusion fus is given either by the fusion of the conjugacy classes of the two character tables (if groups are stored in the tables) or by the class fusion given by known_class_fusion for the two tables.\n\nExamples\n\njulia> s = character_table(\"A5\"); t = character_table(\"A6\");\n\njulia> maps = possible_class_fusions(s, t); length(maps)\n4\n\njulia> chi = t[2]; rest = [restrict(chi, s, x) for x in maps];\n\njulia> length(Set(rest))\n2\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#Symmetrizations-of-group-characters","page":"Group characters","title":"Symmetrizations of group characters","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"symmetrizations(characters::Vector{GAPGroupClassFunction}, n::Int)\nsymmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)\nanti_symmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)\nexterior_power(chi::GAPGroupClassFunction, n::Int)\nsymmetric_power(chi::GAPGroupClassFunction, n::Int)\northogonal_components(characters::Vector{GAPGroupClassFunction}, n::Int)\nsymplectic_components(characters::Vector{GAPGroupClassFunction}, n::Int)","category":"page"},{"location":"Groups/group_characters/#symmetrizations-Tuple{Vector{Oscar.GAPGroupClassFunction}, Int64}","page":"Group characters","title":"symmetrizations","text":"symmetrizations(characters::Vector{GAPGroupClassFunction}, n::Int)\n\nReturn the vector of symmetrizations of characters with the ordinary irreducible characters of the symmetric group of degree n.\n\nThe symmetrization chi^lambda of the character chi with the character lambda of the symmetric group S_n of degree n is defined by\n\nchi^lambda(g) =\n(sum_rhoin S_n lambda(rho) prod_k=1^n chi(g^k)^a_k(rho) ) n\n\nwhere a_k(rho) is the number of cycles of length k in rho.\n\nNote that the returned list may contain zero class functions, and duplicates are not deleted.\n\nFor special kinds of symmetrizations, see symmetric_parts, anti_symmetric_parts, orthogonal_components, symplectic_components, exterior_power, symmetric_power.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#symmetric_parts-Tuple{Vector{Oscar.GAPGroupClassFunction}, Int64}","page":"Group characters","title":"symmetric_parts","text":"symmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)\n\nReturn the vector of symmetrizations of characters with the trivial character of the symmetric group of degree n, see symmetrizations.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#anti_symmetric_parts-Tuple{Vector{Oscar.GAPGroupClassFunction}, Int64}","page":"Group characters","title":"anti_symmetric_parts","text":"anti_symmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)\n\nReturn the vector of symmetrizations of characters with the sign character of the symmetric group of degree n, see symmetrizations.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#exterior_power-Tuple{Oscar.GAPGroupClassFunction, Int64}","page":"Group characters","title":"exterior_power","text":"exterior_power(chi::GAPGroupClassFunction, n::Int)\n\nReturn the class function of the n-th exterior power of the module that is afforded by chi.\n\nThis exterior power is the symmetrization of chi with the sign character of the symmetric group of degree n, see also symmetrizations and anti_symmetric_parts.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#symmetric_power-Tuple{Oscar.GAPGroupClassFunction, Int64}","page":"Group characters","title":"symmetric_power","text":"symmetric_power(chi::GAPGroupClassFunction, n::Int)\n\nReturn the class function of the n-th symmetric power of the module that is afforded by chi.\n\nThis symmetric power is the symmetrization of chi with the trivial character of the symmetric group of degree n, see also symmetrizations and symmetric_parts.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#orthogonal_components-Tuple{Vector{Oscar.GAPGroupClassFunction}, Int64}","page":"Group characters","title":"orthogonal_components","text":"orthogonal_components(characters::Vector{GAPGroupClassFunction}, n::Int)\n\nReturn the vector of the so-called Murnaghan components of the m-th tensor powers of the entries of characters, for m up to n, where n must be at least 2 and at most 6 and where we assume that the entries of characters are irreducible characters with Frobenius-Schur indicator +1, see indicator.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#symplectic_components-Tuple{Vector{Oscar.GAPGroupClassFunction}, Int64}","page":"Group characters","title":"symplectic_components","text":"symplectic_components(characters::Vector{GAPGroupClassFunction}, n::Int)\n\nReturn the vector of the Murnaghan components of the m-th tensor powers of the entries of characters, for m up to n, where n must be at least 2 and at most 6 and where we assume that the entries of characters are irreducible characters with Frobenius-Schur indicator -1, see indicator.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#Operations-for-character-tables","page":"Group characters","title":"Operations for character tables","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"class_multiplication_coefficient\nknown_class_fusion\norder(tbl::GAPGroupCharacterTable)\npossible_class_fusions","category":"page"},{"location":"Groups/group_characters/#class_multiplication_coefficient","page":"Group characters","title":"class_multiplication_coefficient","text":"class_multiplication_coefficient(::Type{T} = ZZRingElem, tbl::GAPGroupCharacterTable, i::Int, j::Int, k::Int) where T <: IntegerUnion\n\nReturn the class multiplication coefficient of the classes i, j, and k of the group G with ordinary character table tbl, as an instance of T.\n\nThe class multiplication coefficient c_ijk of the classes i j k equals the number of pairs (x y) of elements x y in G such that x lies in class i, y lies in class j, and their product xy is a fixed element of class k.\n\nIn the center of the group algebra of G, these numbers are found as coefficients of the decomposition of the product of two class sums K_i and K_j into class sums:\n\nK_i K_j = sum_k c_ijk K_k\n\nGiven the character table of a finite group G, whose classes are C_1 ldots C_r with representatives g_i in C_i, the class multiplication coefficient c_ijk can be computed with the following formula:\n\n c_ijk = C_i C_j G\n sum_chi in Irr(G) chi(g_i) chi(g_j) chi(g_k^-1)\n chi(1)\n\nOn the other hand the knowledge of the class multiplication coefficients admits the computation of the irreducible characters of G.\n\nExamples\n\njulia> class_multiplication_coefficient(character_table(\"A5\"), 2, 3, 4)\n5\n\njulia> class_multiplication_coefficient(character_table(\"A5\"), 2, 4, 4)\n0\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#known_class_fusion","page":"Group characters","title":"known_class_fusion","text":"known_class_fusion(tbl1::GAPGroupCharacterTable, tbl2::GAPGroupCharacterTable)\n\nReturn (flag, fus) where flag == true if a class fusion to tbl2 is stored on tbl1, and flag == false otherwise.\n\nIn the former case, fus is the vector of integers, of length ncols(tbl1), such that the i-th conjugacy class of tbl1 corresponds to the fus[i]-th conjugacy class of tbl2, in the following sense.\n\nIf the group of tbl1 is a subgroup of the group of tbl2 then the i-th conjugacy class of tbl1 is contained in the fus[i]-th conjugacy class of tbl2. If the group of tbl2 is a factor group of the group of tbl1 then the image of the i-th conjugacy class tbl1 under the relevant epimorphism is the fus[i]-th conjugacy class of tbl2.\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#order-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"order","text":"order(::Type{T} = ZZRingElem, tbl::GAPGroupCharacterTable) where T <: IntegerUnion\n\nReturn the order of the group for which tbl is the character table, as an instance of T.\n\nExamples\n\njulia> order(character_table(symmetric_group(4)))\n24\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#possible_class_fusions","page":"Group characters","title":"possible_class_fusions","text":"possible_class_fusions(subtbl::GAPGroupCharacterTable, tbl::GAPGroupCharacterTable)\n\nReturn the array of possible class fusions from subtbl to tbl. Each entry is an array of positive integers, where the value at position i is the position of the conjugacy class in tbl that contains the i-th class of subtbl.\n\nExamples\n\njulia> possible_class_fusions(character_table(\"A5\"), character_table(\"A6\"))\n4-element Vector{Vector{Int64}}:\n [1, 2, 3, 6, 7]\n [1, 2, 3, 7, 6]\n [1, 2, 4, 6, 7]\n [1, 2, 4, 7, 6]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#Character-tables-and-normal-subgroups","page":"Group characters","title":"Character tables and normal subgroups","text":"","category":"section"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"Normal subgroups of a group G are unions of conjugacy classes of elements of G. Thus one can often turn questions about a normal subgroup N of G into questions about the array of those positions in the list of conjugacy classes of G that contain the elements of N.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"center(chi::GAPGroupClassFunction)\nclass_positions_of_center\nkernel(chi::GAPGroupClassFunction)\nclass_positions_of_kernel\npcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)\nclass_positions_of_pcore","category":"page"},{"location":"Groups/group_characters/#center-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"center","text":"center(chi::GAPGroupClassFunction)\n\nReturn C, f where C is the center of chi (i.e. the largest normal subgroup of the underlying group G of chi such that chi maps each element of C to chi[1] times a root of unity) and f is the embedding morphism of C into G.\n\nExamples\n\njulia> t = character_table(symmetric_group(4));\n\njulia> chi = t[3]; chi[1]\n2\n\njulia> C, f = center(chi); order(C)\n4\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#class_positions_of_center","page":"Group characters","title":"class_positions_of_center","text":"class_positions_of_center(chi::GAPGroupClassFunction)\n\nReturn the array of those integers i such that chi[i] is chi[1] times a root of unity.\n\nExamples\n\njulia> println(class_positions_of_center(character_table(\"2.A5\")[2]))\n[1, 2]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#kernel-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"kernel","text":"kernel(chi::GAPGroupClassFunction)\n\nReturn C, f where C is the kernel of chi (i.e. the largest normal subgroup of the underlying group G of chi such that chi maps each element of C to chi[1]) and f is the embedding morphism of C into G.\n\nExamples\n\njulia> t = character_table(symmetric_group(4));\n\njulia> chi = t[3]; chi[1]\n2\n\njulia> C, f = kernel(chi); order(C)\n4\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#class_positions_of_kernel","page":"Group characters","title":"class_positions_of_kernel","text":"class_positions_of_kernel(chi::GAPGroupClassFunction)\n\nReturn the array of those integers i such that chi[i] == chi[1] holds.\n\nExamples\n\njulia> println(class_positions_of_kernel(character_table(\"2.A5\")[2]))\n[1, 2]\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#pcore-Tuple{Oscar.GAPGroupCharacterTable, Union{Integer, ZZRingElem}}","page":"Group characters","title":"pcore","text":"pcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)\n\nReturn the p-core of the group of tbl, see pcore(G::GAPGroup, p::IntegerUnion), but computed character-theoretically (see class_positions_of_pcore).\n\nExamples\n\njulia> order(pcore(character_table(symmetric_group(4)), 2)[1])\n4\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#class_positions_of_pcore","page":"Group characters","title":"class_positions_of_pcore","text":"class_positions_of_pcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)\n\nReturn the array of integers i such that the i-th conjugacy class of tbl is contained in the p-core of the group of tbl, see pcore(G::GAPGroup, p::IntegerUnion).\n\nExamples\n\njulia> println(class_positions_of_pcore(character_table(\"2.A5\"), 2))\n[1, 2]\n\n\n\n\n\n","category":"function"},{"location":"Hecke/misc/Map/#Map-from-julia-functions","page":"Map from julia functions","title":"Map from julia functions","text":"","category":"section"},{"location":"Hecke/misc/Map/","page":"Map from julia functions","title":"Map from julia functions","text":"For the situation where it is desirable to create a Map given arbitrary callable julia objects (like anonymous functions), the type MapFromFunc is provided.","category":"page"},{"location":"Hecke/misc/Map/","page":"Map from julia functions","title":"Map from julia functions","text":"MapFromFunc","category":"page"},{"location":"Hecke/misc/Map/#MapFromFunc","page":"Map from julia functions","title":"MapFromFunc","text":"MapFromFunc(D, C, f, [g])\n\nCreates the map D -> C, x -> f(x) given the callable object f. If g is provided, it is assumed to satisfy f(g(x)) = x and will be used as the preimage function.\n\nExample\n\njulia> F = GF(2);\n\njulia> f = MapFromFunc(QQ, F, x -> F(numerator(x)) * inv(F(denominator(x))))\nMap from\nRational field to Finite field of characteristic 2 defined by a julia-function\n\njulia> f(QQ(1//3))\n1\n\njulia> f = MapFromFunc(QQ, F, x -> F(numerator(x)) * inv(F(denominator(x))), y -> QQ(lift(y)),)\nMap from\nRational field to Finite field of characteristic 2 defined by a julia-function with inverse\n\njulia> preimage(f, F(1))\n1\n\n\n\n\n\n","category":"type"},{"location":"Hecke/misc/Map/","page":"Map from julia functions","title":"Map from julia functions","text":"note: Note\nWhen applying an object f of type MapFromFunc to an element x, it will be checked whether the parent of x coincides with the domain and whether the parent of f(x) coincides with the codomain of f. Similar for the optional preimage function.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/module_interface/#Module-Interface","page":"Module Interface","title":"Module Interface","text":"","category":"section"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"note: Note\nThe module infrastructure in AbstractAlgebra should be considered experimental at this stage. This means that the interface may change in the future.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"AbstractAlgebra allows the construction of finitely presented modules (i.e. with finitely many generators and relations), starting from free modules. The generic code provided by AbstractAlgebra will only work for modules over euclidean domains, however there is nothing preventing a library from implementing more general modules using the same interface.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"All finitely presented module types in AbstractAlgebra follow the following interface which is a loose interface of functions, without much generic infrastructure built on top.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Free modules can be built over both commutative and noncommutative rings. Other types of module are restricted to fields and euclidean rings.","category":"page"},{"location":"AbstractAlgebra/module_interface/#Abstract-types","page":"Module Interface","title":"Abstract types","text":"","category":"section"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"AbstractAlgebra provides two abstract types for finitely presented modules and their elements:","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"FPModule{T} is the abstract type for finitely presented module parent","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"types","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"FPModuleElem{T} is the abstract type for finitely presented module","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"element types","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Note that the abstract types are parameterised. The type T should usually be the type of elements of the ring the module is over.","category":"page"},{"location":"AbstractAlgebra/module_interface/#Required-functionality-for-modules","page":"Module Interface","title":"Required functionality for modules","text":"","category":"section"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"We suppose that R is a fictitious base ring and that S is a module over R with parent object S of type MyModule{T}. We also assume the elements in the module have type MyModuleElem{T}, where T is the type of elements of the ring the module is over.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Of course, in practice these types may not be parameterised, but we use parameterised types here to make the interface clearer.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Note that the type T must (transitively) belong to the abstract type RingElement or NCRingElem.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"We describe the functionality below for modules over commutative rings, i.e. with element type belonging to RingElement, however similar constructors should be available for element types belonging to NCRingElem instead, for free modules over a noncommutative ring.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Although not part of the module interface, implementations of modules that wish to follow our interface should use the same function names for submodules, quotient modules, direct sums and module homomorphisms if they wish to remain compatible with our module generics in the future.","category":"page"},{"location":"AbstractAlgebra/module_interface/#Basic-manipulation","page":"Module Interface","title":"Basic manipulation","text":"","category":"section"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"iszero(m::MyModuleElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Return true if the given module element is zero.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"ngens(M::MyModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Return the number of generators of the module M in its current representation.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"gen(M::MyModule{T}, i::Int) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Return the i-th generator (indexed from 1) of the module M.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"gens(M::MyModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Return a Julia array of the generators of the module M.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"rels(M::MyModule{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Return a Julia vector of all the relations between the generators of M. Each relation is given as an AbstractAlgebra row matrix.","category":"page"},{"location":"AbstractAlgebra/module_interface/#Element-constructors","page":"Module Interface","title":"Element constructors","text":"","category":"section"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"We can construct elements of a module M by specifying linear combinations of the generators of M. This is done by passing a vector of ring elements.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"(M::Module{T})(v::Vector{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Construct the element of the module M corresponding to sum_i givi where gi are the generators of the module M. The resulting element will lie in the module M.","category":"page"},{"location":"AbstractAlgebra/module_interface/#Coercions","page":"Module Interface","title":"Coercions","text":"","category":"section"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Given a module M and an element n of a module N, it is possible to coerce n into M using the notation M(n) in certain circumstances.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"In particular the element n will be automatically coerced along any canonical injection of a submodule map and along any canonical projection of a quotient map. There must be a path from N to M along such maps.","category":"page"},{"location":"AbstractAlgebra/module_interface/#Arithmetic-operators","page":"Module Interface","title":"Arithmetic operators","text":"","category":"section"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"Elements of a module can be added, subtracted or multiplied by an element of the ring the module is defined over and compared for equality.","category":"page"},{"location":"AbstractAlgebra/module_interface/","page":"Module Interface","title":"Module Interface","text":"In the case of a noncommutative ring, both left and right scalar multiplication are defined.","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Morphisms-of-affine-schemes","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Constructors","page":"Morphisms of affine schemes","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#General-constructors","page":"Morphisms of affine schemes","title":"General constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"SpecMor(X::AbsSpec, Y::AbsSpec, f::Vector{<:RingElem}; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#SpecMor-Tuple{AbsSpec, AbsSpec, Vector{<:RingElem}}","page":"Morphisms of affine schemes","title":"SpecMor","text":"SpecMor(X::AbsSpec, Y::AbsSpec, f::Vector{<:RingElem}; check::Bool=true)\n\nThis method constructs a morphism from the scheme X to the scheme Y. For this one has to specify the images of the coordinates (the generators of ambient_coordinate_ring(Y)) under the pullback map 𝒪(Y) 𝒪(X) as third argument.\n\nNote that expensive checks can be turned off by setting check=false.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> Y = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> SpecMor(X, Y, gens(OO(X)))\nMorphism\n from [x1, x2, x3] affine 3-space over QQ\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> x1\n x2 -> x2\n x3 -> x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Special-constructors","page":"Morphisms of affine schemes","title":"Special constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"identity_map(X::AbsSpec{<:Any, <:MPolyRing})\ninclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true)\ncompose(f::AbsSpecMor, g::AbsSpecMor)\nrestrict(f::SpecMor, U::AbsSpec, V::AbsSpec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#identity_map-Tuple{AbsSpec{<:Any, <:MPolyRing}}","page":"Morphisms of affine schemes","title":"identity_map","text":"identity_map(X::AbsSpec{<:Any, <:MPolyRing})\n\nThis method constructs the identity morphism from an affine scheme to itself.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> identity_map(X)\nMorphism\n from [x1, x2, x3] affine 3-space over QQ\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> x1\n x2 -> x2\n x3 -> x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#inclusion_morphism-Tuple{AbsSpec, AbsSpec}","page":"Morphisms of affine schemes","title":"inclusion_morphism","text":"inclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true)\n\nReturn the inclusion map from X to Y.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> f = inclusion_morphism(Y, X)\nMorphism\n from [x1, x2, x3] spec of quotient of multivariate polynomial ring\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> 0\n x2 -> x2\n x3 -> x3\n\njulia> I = kernel(pullback(f)) # this is a way to obtain the ideal ``I ⊆ O(X)`` cutting out ``Y`` from ``X``.\nideal(x1)\n\njulia> base_ring(I) == OO(X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#compose-Tuple{AbsSpecMor, AbsSpecMor}","page":"Morphisms of affine schemes","title":"compose","text":"compose(f::AbsSpecMor, g::AbsSpecMor)\n\nThis method computes the composition of two morphisms.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> m1 = inclusion_morphism(Y, X)\nMorphism\n from [x1, x2, x3] spec of quotient of multivariate polynomial ring\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> 0\n x2 -> x2\n x3 -> x3\n\njulia> m2 = identity_map(X)\nMorphism\n from [x1, x2, x3] affine 3-space over QQ\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> x1\n x2 -> x2\n x3 -> x3\n\njulia> m3 = identity_map(Y)\nMorphism\n from [x1, x2, x3] spec of quotient of multivariate polynomial ring\n to [x1, x2, x3] spec of quotient of multivariate polynomial ring\ngiven by the pullback function\n x1 -> 0\n x2 -> x2\n x3 -> x3\n\njulia> compose(m3, compose(m1, m2)) == m1\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#restrict-Tuple{SpecMor, AbsSpec, AbsSpec}","page":"Morphisms of affine schemes","title":"restrict","text":"restrict(f::SpecMor, U::AbsSpec, V::AbsSpec)\n\nThis method restricts the domain of the morphism f to U and its codomain to V.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> restrict(identity_map(X), Y, Y) == identity_map(Y)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Attributes","page":"Morphisms of affine schemes","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#General-attributes","page":"Morphisms of affine schemes","title":"General attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"domain(f::AbsSpecMor)\ncodomain(f::AbsSpecMor)\npullback(f::AbsSpecMor)\ngraph(f::AbsSpecMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#domain-Tuple{AbsSpecMor}","page":"Morphisms of affine schemes","title":"domain","text":"domain(f::AbsSpecMor)\n\nOn a morphism f X Y of affine schemes, this returns X.\n\nExamples\n\njulia> Y = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(Y)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> X = subscheme(Y, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> f = inclusion_morphism(X, Y)\nMorphism\n from [x1, x2, x3] spec of quotient of multivariate polynomial ring\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> 0\n x2 -> x2\n x3 -> x3\n\njulia> domain(f)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#codomain-Tuple{AbsSpecMor}","page":"Morphisms of affine schemes","title":"codomain","text":"codomain(f::AbsSpecMor)\n\nOn a morphism f X Y of affine schemes, this returns Y.\n\nExamples\n\njulia> Y = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(Y)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> X = subscheme(Y, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> f = inclusion_morphism(X, Y)\nMorphism\n from [x1, x2, x3] spec of quotient of multivariate polynomial ring\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> 0\n x2 -> x2\n x3 -> x3\n\njulia> codomain(f)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#pullback-Tuple{AbsSpecMor}","page":"Morphisms of affine schemes","title":"pullback","text":"pullback(f::AbsSpecMor)\n\nOn a morphism f X Y of affine schemes X = Spec(S) and Y = Spec(R), this returns the ring homomorphism f^* R S.\n\nExamples\n\njulia> Y = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(Y)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> X = subscheme(Y, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> pullback(inclusion_morphism(X, Y))\nMap with following data\nDomain:\n=======\nMultivariate polynomial ring in 3 variables over QQ\nCodomain:\n=========\nQuotient of multivariate polynomial ring by ideal with 1 generator\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#graph-Tuple{AbsSpecMor}","page":"Morphisms of affine schemes","title":"graph","text":"graph(f::AbsSpecMor)\n\nReturn the graph of f X Y as a subscheme of XY as well as the two projections to X and Y.\n\nExamples\n\njulia> Y = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(Y)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> X = subscheme(Y, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> f = inclusion_morphism(X, Y)\nMorphism\n from [x1, x2, x3] spec of quotient of multivariate polynomial ring\n to [x1, x2, x3] affine 3-space over QQ\ngiven by the pullback function\n x1 -> 0\n x2 -> x2\n x3 -> x3\n\njulia> graph(f)\n(Spec of quotient of multivariate polynomial ring, Morphism: spec of quotient of multivariate polynomial ring -> spec of quotient of multivariate polynomial ring, Morphism: spec of quotient of multivariate polynomial ring -> affine 3-space over QQ with coordinates [x1, x2, x3])\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Special-attributes","page":"Morphisms of affine schemes","title":"Special attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"In addition to the standard getters and methods for instances of SpecMor, we also have","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":" image_ideal(f::ClosedEmbedding)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#image_ideal-Tuple{ClosedEmbedding}","page":"Morphisms of affine schemes","title":"image_ideal","text":"image_ideal(f::ClosedEmbedding)\n\nFor a closed embedding f X Y of affine schemes X = Spec(S) into Y = Spec(R) such that S RI via f for some ideal I R this returns I.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Undocumented","page":"Morphisms of affine schemes","title":"Undocumented","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"The following functions do exist but are currently undocumented:","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"underlying_morphism,\ncomplement_ideal,\ncomplement_scheme,\npreimage,\ninverse,\nvarious type getters.","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Properties","page":"Morphisms of affine schemes","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"is_isomorphism(f::AbsSpecMor)\nis_inverse_of(f::AbsSpecMor, g::AbsSpecMor)\nis_identity_map(f::AbsSpecMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#is_isomorphism-Tuple{AbsSpecMor}","page":"Morphisms of affine schemes","title":"is_isomorphism","text":"is_isomorphism(f::AbsSpecMor)\n\nThis method checks if a morphism is an isomorphism.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#is_inverse_of-Tuple{AbsSpecMor, AbsSpecMor}","page":"Morphisms of affine schemes","title":"is_inverse_of","text":"is_inverse_of(f::AbsSpecMor, g::AbsSpecMor)\n\nThis method checks if a morphism f is the inverse of a morphism g.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#is_identity_map-Tuple{AbsSpecMor}","page":"Morphisms of affine schemes","title":"is_identity_map","text":"is_identity_map(f::AbsSpecMor)\n\nThis method checks if a morphism is the identity map.\n\nExamples\n\njulia> X = affine_space(QQ,3)\nAffine space of dimension 3\n over rational field\nwith coordinates [x1, x2, x3]\n\njulia> R = OO(X)\nMultivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n\njulia> (x1,x2,x3) = gens(R)\n3-element Vector{QQMPolyRingElem}:\n x1\n x2\n x3\n\njulia> Y = subscheme(X, x1)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables over QQ\n by ideal(x1)\n\njulia> is_identity_map(inclusion_morphism(Y, X))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#Methods","page":"Morphisms of affine schemes","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/","page":"Morphisms of affine schemes","title":"Morphisms of affine schemes","text":"fiber_product(f::SpecMor{SpecType, SpecType, <:Any}, g::SpecMor{SpecType, SpecType, <:Any}) where {SpecType<:StdSpec}\nproduct(X::AbsSpec, Y::AbsSpec)\nsimplify(X::AbsSpec{<:AbstractAlgebra.Field})","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#fiber_product-Union{Tuple{SpecType}, Tuple{SpecMor{SpecType, SpecType, <:Any}, SpecMor{SpecType, SpecType, <:Any}}} where SpecType<:(AbsSpec{<:Ring, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}})","page":"Morphisms of affine schemes","title":"fiber_product","text":"fiber_product(f::SpecMor{SpecType, SpecType, <:Any}, g::SpecMor{SpecType, SpecType, <:Any}) where {SpecType<:StdSpec}\n\nFor morphisms f Y X and g Z X return the fiber product YZ over X together with its two canonical projections.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#product-Tuple{AbsSpec, AbsSpec}","page":"Morphisms of affine schemes","title":"product","text":"product(X::AbsSpec, Y::AbsSpec)\n\nReturn a triple (XY p₁ p₂) consisting of the product XY over the common base ring 𝕜 and the two projections p₁ XY X and p₂ XY Y.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#simplify-Tuple{AbsSpec{<:Field}}","page":"Morphisms of affine schemes","title":"simplify","text":"simplify(X::AbsSpec{<:Field})\n\nGiven an affine scheme X with coordinate ring R = 𝕜x₁xₙI (or a localization thereof), use Singular's elimpart to try to eliminate variables xᵢ to arrive at a simpler presentation R R = 𝕜y₁yₘJ for some ideal J; return a SimplifiedSpec Y with X as its original.\n\n***Note:*** The ambient_coordinate_ring of the output Y will be different from the one of X and hence the two schemes will not compare using ==.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"PolyhedralGeometry/Polyhedra/intro/","page":"Introduction","title":"Introduction","text":"Let mathbbF be an ordered field; the default is that mathbbF=mathbbQ is the field of rational numbers and other fields are not yet supported everywhere in the implementation.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/intro/","page":"Introduction","title":"Introduction","text":"A set P subseteq mathbbF^n is called a (convex) polyhedron if it can be written as the intersection of finitely many closed affine halfspaces in mathbbF^n. That is, there exists a matrix A and a vector b such that P = P(Ab) = x in mathbbF^n mid Ax leq b Writing P as above is called an H-representation of P.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/intro/","page":"Introduction","title":"Introduction","text":"When a polyhedron P subset mathbbF^n is bounded, it is called a polytope and the fundamental theorem of polytopes states that it may be written as the convex hull of finitely many points. That is P = textrmconv(p_1ldotsp_N) p_i in mathbbF^n Writing P in this way is called a V-representation. Polytopes are necessarily compact, i.e., they form convex bodies.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/intro/","page":"Introduction","title":"Introduction","text":"Each polytope has a unique V-representation which is minimal with respect to inclusion (or cardinality). Conversely, a polyhedron which is full-dimensional, has a unique minimal H-representation. If the polyhedron is not full-dimensional, then there is no canonical choice of an H-representation.","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"CurrentModule = Oscar\nDocTestSetup = quote\n using Oscar\nend","category":"page"},{"location":"Groups/basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"Groups/basics/#elements_of_groups","page":"Basics","title":"Elements of groups","text":"","category":"section"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"Given a group G, it is always possible to have access to some particular elements.","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"GAPGroup\nBasicGAPGroupElem{T<:GAPGroup}\nelem_type(::Type{T}) where T <: GAPGroup\none(x::GAPGroup)\none(x::GAPGroupElem)\nis_finiteorder(x::GAPGroupElem)\ngens(::GAPGroup)\nhas_gens(::GAPGroup)\nngens(G::GAPGroup)\ngen(::GAPGroup, i::Int)\nsmall_generating_set(G::GAPGroup)\nBase.rand(G::GAPGroup)\nrand_pseudo(G::GAPGroup)","category":"page"},{"location":"Groups/basics/#GAPGroup","page":"Basics","title":"GAPGroup","text":"GAPGroup <: AbstractAlgebra.Group\n\nEach object of the abstract type GAPGroup stores a group object from the GAP system, and thus can delegate questions about this object to GAP.\n\nFor expert usage, you can extract the underlying GAP object via GapObj, i.e., if G is a GAPGroup, then GapObj(G) is the GapObj underlying G.\n\nConcrete subtypes of GAPGroup are PermGroup, FPGroup, PcGroup, and MatrixGroup.\n\n\n\n\n\n","category":"type"},{"location":"Groups/basics/#BasicGAPGroupElem","page":"Basics","title":"BasicGAPGroupElem","text":"BasicGAPGroupElem{T<:GAPGroup} <: GAPGroupElem{T}\n\nThe type BasicGAPGroupElem gathers all types of group elements described only by an underlying GAP object.\n\nIf x is an element of the group G of type T, then the type of x is BasicGAPGroupElem{T}.\n\n\n\n\n\n","category":"type"},{"location":"Groups/basics/#elem_type-Union{Tuple{Type{T}}, Tuple{T}} where T<:Oscar.GAPGroup","page":"Basics","title":"elem_type","text":"elem_type(::Type{T}) where T <: GAPGroup\nelem_type(::T) where T <: GAPGroup\n\nelem_type maps (the type of) a group to the type of its elements. For now, a group of type T has elements of type BasicGAPGroupElem{T}. So we provide it mostly for consistency with other parts of OSCAR. In the future, a more elaborate setup for group element types might also be needed.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#one-Tuple{Oscar.GAPGroup}","page":"Basics","title":"one","text":"one(G::GAPGroup) -> elem_type(G)\n\nReturn the identity of the group G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#one-Tuple{GAPGroupElem}","page":"Basics","title":"one","text":"one(x::GAPGroupElem{T}) -> GAPGroupElem{T}\n\nReturn the identity of the parent group of x.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_finiteorder-Tuple{GAPGroupElem}","page":"Basics","title":"is_finiteorder","text":"is_finiteorder(g::GAPGroupElem) -> Bool\n\nReturn true if g has finite order, and false otherwise.\n\nExamples\n\njulia> is_finiteorder(gen(symmetric_group(5), 1))\ntrue\n\njulia> is_finiteorder(gen(free_group(2), 1))\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#gens-Tuple{Oscar.GAPGroup}","page":"Basics","title":"gens","text":"gens(G::Group)\n\nReturn a vector of generators of G. To get the i-th generator, use G[i] or gen(G,i) (see gen) instead of gens(G)[i], as that is more efficient.\n\nExamples\n\njulia> g = symmetric_group(5); gens(g)\n2-element Vector{PermGroupElem}:\n (1,2,3,4,5)\n (1,2)\n\njulia> g[2]\n(1,2)\n\n\nnote: Note\nThe output of gens(G) is not, in general, the minimal list of generators for G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#has_gens-Tuple{Oscar.GAPGroup}","page":"Basics","title":"has_gens","text":"has_gens(G::Group)\n\nReturn whether generators for the group G are known.\n\nExamples\n\njulia> F = free_group(2)\n\n\njulia> has_gens(F)\ntrue\n\njulia> H = derived_subgroup(F)[1]\nGroup()\n\njulia> has_gens(H)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#ngens-Tuple{Oscar.GAPGroup}","page":"Basics","title":"ngens","text":"ngens(G::GAPGroup) -> Int\n\nReturn the length of the vector gens(G).\n\nwarning: WARNING:\nthis is NOT, in general, the minimum number of generators for G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#gen-Tuple{Oscar.GAPGroup, Int64}","page":"Basics","title":"gen","text":"gen(G::GAPGroup, i::Int)\n\nReturn the i-th element of the vector gens(G). This is equivalent to G[i], and returns gens(G)[i] but may be more efficient than the latter.\n\nAn exception is thrown if i is larger than the length of gens(G).\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#small_generating_set-Tuple{Oscar.GAPGroup}","page":"Basics","title":"small_generating_set","text":"small_generating_set(G::GAPGroup)\n\nReturn a reasonably short vector of elements in G that generate G; in general the length of this vector is not minimal.\n\nExamples\n\njulia> length(small_generating_set(abelian_group(PcGroup, [2,3,4])))\n2\n\njulia> length(small_generating_set(abelian_group(PermGroup, [2,3,4])))\n3\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#rand-Tuple{Oscar.GAPGroup}","page":"Basics","title":"rand","text":"rand(rng::Random.AbstractRNG = Random.GLOBAL_RNG, G::Group)\n\nReturn a random element of G, using the random number generator rng.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#rand_pseudo-Tuple{Oscar.GAPGroup}","page":"Basics","title":"rand_pseudo","text":"rand_pseudo(G::GAPGroup)\n\nReturn a pseudo random element of G. This works faster than rand, but the returned elements are not necessarily uniformly distributed.\n\nIt is sometimes necessary to work with finite groups that we cannot effectively enumerate, e.g. matrix groups over finite fields. We may not even know the size of these groups. Yet many algorithms need to sample elements from the group \"as randomly as possible\", whatever that means; but also they need this fast.\n\nThe function rand_pseudo returns elements that are cheap to compute and somehow random, but makes no guarantees about their distribution.\n\nFor finitely presented groups, it returns random words of bounded length.\n\nFor finite permutation and matrix groups, it uses a variant of the product replacement algorithm. For most inputs, the resulting stream of elements relatively quickly converges to a uniform distribution.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"It is also possible to obtain the generators of G by typing","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"f1,f2,f3 = gens(G)","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"This is equivalent to","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"f1=G[1]; f2=G[2]; f3=G[3];","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"For a group G that has been created as a subgroup of another group, generated by a list L of elements, gens(G) is equal to L.","category":"page"},{"location":"Groups/basics/#Operations-on-group-elements","page":"Basics","title":"Operations on group elements","text":"","category":"section"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"OSCAR supports the following operations and functions on group elements.","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"*, multiplication between two elements in a group.\ninv(x) and x^-1, the inverse of x.\nx/y, the element x y^-1.\nx^n, the n-th power of x; if n == 0, the identity of the group is returned; if n < 0, the -n-th power of the inverse of x is returned.\nisone(x) returns whether x is the identity of the group.\nconj(x,y) and x^y, the conjugate of x by y, i.e., the element y^-1 x y.\ncomm(x,y), the commutator of x and y, i.e., the element x^-1 y^-1 x y.","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"note: Note\nIn OSCAR, the expression x^y^z is equivalent to x^(y^z). In other words, conjugations are evaluated from the right to the left.","category":"page"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"comm(x::GAPGroupElem, y::GAPGroupElem)","category":"page"},{"location":"Groups/basics/#comm-Tuple{GAPGroupElem, GAPGroupElem}","page":"Basics","title":"comm","text":"comm(x::GAPGroupElem, y::GAPGroupElem)\n\nReturn the commutator of x and y, which is defined as x^-1*y^-1*x*y, and usually denoted as [x,y] in the literature.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#Properties-of-groups","page":"Basics","title":"Properties of groups","text":"","category":"section"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"is_finite(G::GAPGroup)\nis_trivial(G::GAPGroup)\nis_cyclic(G::GAPGroup)\nis_abelian(G::GAPGroup)\nis_elementary_abelian\nis_pgroup\nis_pgroup_with_prime\nis_nilpotent\nis_supersolvable\nis_solvable\nis_perfect\nis_simple(G::GAPGroup)\nis_almostsimple\nis_quasisimple\nis_sporadic_simple\nis_finitelygenerated","category":"page"},{"location":"Groups/basics/#is_finite-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_finite","text":"is_finite(G::GAPGroup) -> Bool\n\nReturn true if G is finite, and false otherwise.\n\nExamples\n\njulia> is_finite(symmetric_group(5))\ntrue\n\njulia> is_finite(free_group(2))\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_trivial-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_trivial","text":"is_trivial(G::GAPGroup)\n\nReturn true if G has order 1, and false otherwise.\n\nExamples\n\njulia> is_trivial(symmetric_group(1))\ntrue\n\njulia> is_trivial(symmetric_group(2))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_cyclic-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_cyclic","text":"is_cyclic(G::GAPGroup)\n\nReturn true if G is cyclic, i.e., if G can be generated by one element.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_abelian-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_abelian","text":"is_abelian(G::Group)\n\nReturn true if G is abelian (commutative), that is, x*y = y*x holds for all elements x y in G.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_elementary_abelian","page":"Basics","title":"is_elementary_abelian","text":"is_elementary_abelian(G::Group)\n\nReturn true if G is a abelian (see is_abelian) and if there is a prime p such that the order of each element in G divides p.\n\nExamples\n\njulia> g = alternating_group(5);\n\njulia> is_elementary_abelian(sylow_subgroup(g, 2)[1])\ntrue\n\njulia> g = alternating_group(6);\n\njulia> is_elementary_abelian(sylow_subgroup(g, 2)[1])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_pgroup","page":"Basics","title":"is_pgroup","text":"is_pgroup(G)\n\nReturn true if G is a p-group for some prime p, that is, if the order of every element in G is a power of p.\n\nNote that a finite group is a p-group if and only if its order is a prime power. In particular, the trivial group is a p-group for every prime.\n\nExamples\n\njulia> is_pgroup(symmetric_group(1))\ntrue\n\njulia> is_pgroup(symmetric_group(2))\ntrue\n\njulia> is_pgroup(symmetric_group(3))\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_pgroup_with_prime","page":"Basics","title":"is_pgroup_with_prime","text":"is_pgroup_with_prime(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion\n\nReturn (true, nothing) if G is the trivial group, (true, p) if the order of every element in G is a power of a prime p, and (false, nothing) otherwise.\n\nFor finite groups G, the first return value is true if and only if the order of G is a prime power.\n\nExamples\n\njulia> is_pgroup_with_prime(symmetric_group(1))\n(true, nothing)\n\njulia> is_pgroup_with_prime(symmetric_group(2))\n(true, 2)\n\njulia> is_pgroup_with_prime(symmetric_group(3))\n(false, nothing)\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_nilpotent","page":"Basics","title":"is_nilpotent","text":"is_nilpotent(a::ResElem{ZZRingElem}) -> Bool\nis_nilpotent(a::ResElem{Integer}) -> Bool\n\nTests if a is nilpotent.\n\n\n\n\n\nis_nilpotent(G::GAPGroup)\n\nReturn whether G is nilpotent, i.e., whether the lower central series of G reaches the trivial subgroup in a finite number of steps.\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_supersolvable","page":"Basics","title":"is_supersolvable","text":"is_supersolvable(G::GAPGroup)\n\nReturn whether G is supersolvable, i.e., G is finite and has a normal series with cyclic factors.\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_solvable","page":"Basics","title":"is_solvable","text":"is_solvable(G::GAPGroup)\n\nReturn whether G is solvable, i.e., whether derived_series(G) reaches the trivial subgroup in a finite number of steps.\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_perfect","page":"Basics","title":"is_perfect","text":"is_perfect(G::GAPGroup)\n\nReturn whether G is a perfect group, i.e., equal to its derived subgroup.\n\nExamples\n\njulia> is_perfect(special_linear_group(2, 5))\ntrue\n\njulia> is_perfect(symmetric_group(5))\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_simple-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_simple","text":"is_simple(G::GAPGroup)\n\nReturn whether G is a simple group, i.e., G is not trivial and has no non-trivial normal subgroups.\n\nExamples\n\njulia> is_simple(alternating_group(5))\ntrue\n\njulia> is_simple(symmetric_group(5))\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_almostsimple","page":"Basics","title":"is_almostsimple","text":"is_almostsimple(G::GAPGroup)\n\nReturn whether G is an almost simple group, i.e., G is isomorphic to a group H with the property S leq H leq Aut(S), for some non-abelian simple group S.\n\nExamples\n\njulia> is_almostsimple(symmetric_group(5))\ntrue\n\njulia> is_almostsimple(special_linear_group(2, 5))\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_quasisimple","page":"Basics","title":"is_quasisimple","text":"is_quasisimple(G::GAPGroup)\n\nReturn whether G is a quasisimple group, i.e., G is perfect such that the factor group modulo its centre is a non-abelian simple group.\n\nExamples\n\njulia> is_quasisimple(special_linear_group(2, 5))\ntrue\n\njulia> is_quasisimple(symmetric_group(5))\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_sporadic_simple","page":"Basics","title":"is_sporadic_simple","text":"is_sporadic_simple(G::GAPGroup)\n\nReturn whether G is a sporadic simple group.\n\nExamples\n\njulia> is_sporadic_simple(mathieu_group(11))\ntrue\n\njulia> is_sporadic_simple(mathieu_group(10))\nfalse\n\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#is_finitelygenerated","page":"Basics","title":"is_finitelygenerated","text":"is_finitelygenerated(G)\n\nReturn whether G is a finitely generated group.\n\nExamples\n\njulia> F = free_group(2)\n\n\njulia> is_finitelygenerated(F)\ntrue\n\njulia> H = derived_subgroup(F)[1]\nGroup()\n\njulia> is_finitelygenerated(H)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#Attributes-of-groups","page":"Basics","title":"Attributes of groups","text":"","category":"section"},{"location":"Groups/basics/","page":"Basics","title":"Basics","text":"order(::Type{T}, x::Union{GAPGroupElem, GAPGroup}) where T <: IntegerUnion\ncyclic_generator(G::GAPGroup)\nexponent(G::GAPGroup)\ndescribe(G::GAPGroup)\nnilpotency_class(G::GAPGroup)\nprime_of_pgroup","category":"page"},{"location":"Groups/basics/#order-Union{Tuple{T}, Tuple{Type{T}, Union{Oscar.GAPGroup, GAPGroupElem}}} where T<:Union{Integer, ZZRingElem}","page":"Basics","title":"order","text":"order(::Type{T} = ZZRingElem, x::Union{GAPGroupElem, GAPGroup}) where T <: IntegerUnion\n\nReturn the order of x, as an instance of T.\n\nFor a group element x in the group G, the order of x is the smallest positive integer n such that x^n is the identity of G. For a group x, the order of x is the number of elements in x.\n\nAn exception is thrown if the order of x is infinite, use is_finite for checking the finiteness of a group, and is_finiteorder for checking whether a group element has finite order.\n\nExamples\n\njulia> g = symmetric_group(3);\n\njulia> order(g)\n6\n\njulia> order(gen(g, 1))\n3\n\njulia> g = free_group(1);\n\njulia> is_finite(g)\nfalse\n\njulia> is_finiteorder(gen(g, 1))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#cyclic_generator-Tuple{Oscar.GAPGroup}","page":"Basics","title":"cyclic_generator","text":"cyclic_generator(G::GAPGroup)\n\nReturn an element of G that generates G if G is cyclic, and throw an error otherwise.\n\nExamples\n\njulia> g = permutation_group(5, [cperm(1:3), cperm(4:5)])\nGroup([ (1,2,3), (4,5) ])\n\njulia> cyclic_generator(g)\n(1,2,3)(4,5)\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#exponent-Tuple{Oscar.GAPGroup}","page":"Basics","title":"exponent","text":"exponent(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion\n\nReturn the exponent of G, as an instance of T, i.e., the smallest positive integer e such that g^e is the identity of G for every g in G.\n\nExamples\n\njulia> exponent(symmetric_group(3))\n6\n\njulia> exponent(symmetric_group(13))\n360360\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#describe-Tuple{Oscar.GAPGroup}","page":"Basics","title":"describe","text":"describe(G::GAPGroup)\n\nReturn a string that describes some aspects of the structure of G.\n\nFor finite groups, the function works well if G is an abelian group or a finite simple group or a group in one of the following series: symmetric, dihedral, quasidihedral, generalized quaternion, general linear, special linear.\n\nFor other finite groups, the function tries to decompose G as a direct product or a semidirect product, and if this is not possible as a non-splitting extension of a normal subgroup N with the factor group GN, where N is the center or the derived subgroup or the Frattini subgroup of G.\n\nFor infinite groups, if the group is known to be finitely generated and abelian or free, a reasonable description is printed.\n\nFor general infinite groups, or groups for which finiteness is not (yet) known, not much if anything can be done. In particular we avoid potentially expensive checks such as computing the size of the group or whether it is abelian. While we do attempt a few limited fast checks for finiteness and commutativity, these will not detect all finite or commutative groups.\n\nThus calling describe again on the same group after additional information about it becomes known to Oscar may yield different outputs.\n\nnote: Note\nfor finitely presented groups, even deciding if the group is trivial is impossible in general; the same holds for most other properties, like whether the group is finite, abelian, etc.,\nthere is in general no \"nice\" decomposition of G,\nthere may be several decompositions of G,\nnonisomorphic groups may yield the same describe result,\nisomorphic groups may yield different describe results,\nthe computations can take a long time (for example in the case of large p-groups), and the results are still often not very helpful.\n\nThe following notation is used in the returned string.\n\nDescription Syntax\ntrivial group 1\nfinite cyclic group C\ninfinite cyclic group Z\nalternating group A\nsymmetric group S\ndihedral group D\nquaternion group Q\nquasidihedral group QD\nprojective special linear group PSL(,)\nspecial linear group SL(,)\ngeneral linear group GL(,)\nproj. special unitary group PSU(,)\northogonal group, type B O(2+1,)\northogonal group, type D O+(2,)\northogonal group, type 2D O-(2,)\nproj. special symplectic group PSp(2,)\nSuzuki group (type 2B) Sz()\nRee group (type 2F or 2G) Ree()\nLie group of exceptional type E(6,), E(7,), E(8,), 2E(6,), F(4,), G(2,)\nSteinberg triality group 3D(4,)\nsporadic simple group M11, M12, M22, M23, M24, J1, J2, J3, J4, Co1, Co2, Co3, Fi22, Fi23, Fi24', Suz, HS, McL, He, HN, Th, B, M, ON, Ly, Ru\nTits group 2F(4,2)'\nthe indicated group from the library of perfect groups PerfectGroup(,)\ndirect product A x B\nsemidirect product N : H\nnon-split extension Z(G) . G/Z(G) = G' . G/G', Phi(G) . G/Phi(G)\n\nExamples\n\njulia> g = symmetric_group(6);\n\njulia> describe(g)\n\"S6\"\n\njulia> describe(sylow_subgroup(g,2)[1])\n\"C2 x D8\"\n\njulia> describe(sylow_subgroup(g, 3)[1])\n\"C3 x C3\"\n\njulia> describe(free_group(3))\n\"a free group of rank 3\"\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#nilpotency_class-Tuple{Oscar.GAPGroup}","page":"Basics","title":"nilpotency_class","text":"nilpotency_class(G::GAPGroup) -> Int\n\nReturn the nilpotency class of G, i.e., the smallest integer n such that G has a central series of length n.\n\nAn exception is thrown if G is not nilpotent.\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#prime_of_pgroup","page":"Basics","title":"prime_of_pgroup","text":"prime_of_pgroup(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion\n\nReturn the prime p if G is a non-trivial p-group.\n\nAn exception is thrown if G is not a p-group or is a trivial group.\n\nExamples\n\njulia> prime_of_pgroup(quaternion_group(8))\n2\n\njulia> prime_of_pgroup(UInt16, quaternion_group(8))\n0x0002\n\njulia> prime_of_pgroup(symmetric_group(1))\nERROR: ArgumentError: only supported for non-trivial p-groups\n\njulia> prime_of_pgroup(symmetric_group(3))\nERROR: ArgumentError: only supported for non-trivial p-groups\n\n\n\n\n\n\n","category":"function"}] -} diff --git a/previews/PR2578/siteinfo.js b/previews/PR2578/siteinfo.js deleted file mode 100644 index cd311f9fd7e5..000000000000 --- a/previews/PR2578/siteinfo.js +++ /dev/null @@ -1 +0,0 @@ -var DOCUMENTER_CURRENT_VERSION = "previews/PR2578";